Hi!

I'd like to submit a patch for navit, which changes the map dragging 
rendering method for the gtk interface (which is used on the Neo). 
Before the patch navit rerendered the map on each drag increment, which 
was too slow on the neo. Now it simply repositions the rendered pixmap 
and does the rendering of the map as soon as the drag is finished. In 
addition the text rendering has been improved a bit (there is still 
room for improvement though, i.e. caching rendered glyph bitmaps). 
Please find two patches attached: The patch for the navit source (as of 
SVN revision 1255) and a openembedded patch, which changes the 
buildsystem to build from SVN. For your convenience I uploaded an ipk 
to:

http://www.acoveo.org/navit_0.1.0+svnrev1255-r0_armv4t.ipk

Cheers,
        Florian
-- 
DI Florian Hackenberger
[EMAIL PROTECTED]
www.hackenberger.at
Index: navit/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp
===================================================================
--- navit/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp	(revision 1255)
+++ navit/navit/graphics/qt_qpainter/graphics_qt_qpainter.cpp	(working copy)
@@ -631,6 +631,7 @@
 	draw_image,
 	draw_image_warp,
 	draw_restore,
+	NULL,
 	font_new,
 	gc_new,
 	background_gc,
Index: navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c
===================================================================
--- navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c	(revision 1255)
+++ navit/navit/graphics/gtk_drawing_area/graphics_gtk_drawing_area.c	(working copy)
@@ -27,6 +27,7 @@
 #include <fontconfig/fontconfig.h>
 #include <ft2build.h>
 #include FT_FREETYPE_H
+#include FT_CACHE_H
 #include <freetype/ftglyph.h>
 #ifdef HAVE_IMLIB2
 #include <Imlib2.h>
@@ -51,6 +52,7 @@
 #define GDK_Calendar XF86XK_Calendar
 #endif
 
+#define Printfx(x) printf("%ld.%ld", x >> 16, 100 * (unsigned long) ((x) & 0x00ff) >> 16)
 
 struct graphics_priv {
 	GdkEventButton button_event;
@@ -88,7 +90,15 @@
 
 
 struct graphics_font_priv {
-        FT_Face face;
+	FTC_Manager manager;
+	FTC_ImageCache image_cache;
+	FTC_CMapCache charmap_cache;
+	FTC_SBitCache sbit_cache;
+	FTC_ScalerRec scaler;
+	char* fontfile;
+	int fontindex;
+	int charmap_index;
+	struct graphics_priv *graphics;
 };
 
 struct graphics_gc_priv {
@@ -106,6 +116,10 @@
 static void
 graphics_destroy(struct graphics_priv *gr)
 {
+	if(gr->background_ready && gr->background != NULL) {
+                g_object_unref(gr->background);
+		gr->background_ready = 0;
+	}
 	FcFini();
 }
 
@@ -124,14 +138,34 @@
 
 static void font_destroy(struct graphics_font_priv *font)
 {
+	if(font->fontfile != NULL) {
+		g_free(font->fontfile);
+	}
+	if(font->manager != NULL) {
+		FTC_Manager_Done(font->manager);
+	}
 	g_free(font);
-	/* TODO: free font->face */
 }
 
 static struct graphics_font_methods font_methods = {
 	font_destroy
 };
 
+static FT_Error face_requester( FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face* aface )
+{
+	struct graphics_font_priv *font_priv = (struct graphics_font_priv *)request_data;
+	FT_Error ret = FT_New_Face( font_priv->graphics->library, font_priv->fontfile, font_priv->fontindex, aface );
+	if(ret) {
+		fprintf(stderr, "Error while creating freetype face: %d\n", ret);
+		return ret;
+	}
+	if((ret = FT_Select_Charmap(*aface, FT_ENCODING_UNICODE))) {
+		fprintf(stderr, "Error while creating freetype face: %d\n", ret);
+	}
+	font_priv->charmap_index = (*aface)->charmap ? FT_Get_Charmap_Index( (*aface)->charmap ) : 0;
+	return 0;
+}
+
 /**
  * Load a new font using the fontconfig library.
  * First search for each of the font families and require and exact match on family
@@ -140,7 +174,8 @@
 static struct graphics_font_priv *font_new(struct graphics_priv *gr, struct graphics_font_methods *meth, int size, int flags)
 {
 	struct graphics_font_priv *font=g_new(struct graphics_font_priv, 1);
-
+	font->manager = NULL;
+	font->fontfile = NULL;
 	*meth=font_methods;
 	int exact, found;
 	char **family;
@@ -149,11 +184,25 @@
 		FT_Init_FreeType( &gr->library );
 		gr->library_init=1;
 	}
+	FTC_Manager_New( gr->library, 0, 0, 0, &face_requester, font, &(font->manager));
+	FTC_ImageCache_New( font->manager, &(font->image_cache));
+	FTC_CMapCache_New( font->manager, &(font->charmap_cache));
+	FTC_SBitCache_New( font->manager, &(font->sbit_cache)); 
+	font->graphics = gr;
+	
+	//Setup the image type.
+	font->scaler.face_id = (FT_Pointer)font;
+	font->scaler.width = 0;
+	font->scaler.height = size;
+	font->scaler.pixel = 0;
+	font->scaler.x_res = 300;
+	font->scaler.y_res = 300;
+
 	found=0;
 	for (exact=1;!found && exact>=0;exact--) {
 		family=fontfamilies;
 		while (*family && !found) {
-			dbg(1, "Looking for font family %s. exact=%d\n", *family, exact);
+			dbg(1, "Looking for font family %s. exact=%d, size=%d\n", *family, exact, size);
 			FcPattern *required = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, *family, NULL);
 			if (flags)
 				FcPatternAddInteger(required,FC_WEIGHT,FC_WEIGHT_BOLD);
@@ -170,8 +219,9 @@
 				FcResult r1 = FcPatternGetString(matched, FC_FILE, 0, &fontfile);
 				FcResult r2 = FcPatternGetInteger(matched, FC_INDEX, 0, &fontindex);
 				if ((r1 == FcResultMatch) && (r2 == FcResultMatch) && (FcValueEqual(v1,v2) || !exact)) {
-					dbg(2, "About to load font from file %s index %d\n", fontfile, fontindex);
-					FT_New_Face( gr->library, (char *)fontfile, fontindex, &font->face );
+					dbg(2, "Font matching font in file %s index %d\n", fontfile, fontindex);
+					font->fontfile = (char*)FcStrCopy(fontfile);
+					font->fontindex = fontindex;
 					found=1;
 				}
 				FcPatternDestroy(matched);
@@ -185,8 +235,6 @@
 		g_free(font);
 		return NULL;
 	}
-        FT_Set_Char_Size(font->face, 0, size, 300, 300);
-	FT_Select_Charmap(font->face, FT_ENCODING_UNICODE);
 	return font;
 }
 
@@ -437,9 +485,10 @@
 #endif
 
 static struct text_render *
-display_text_render(char *text, struct graphics_font_priv *font, int dx, int dy, int x, int y)
+display_text_render(char *text, struct graphics_font_priv *font, FT_Fixed dx, FT_Fixed dy, int x, int y)
 {
-       	FT_GlyphSlot  slot = font->face->glyph;  // a small shortcut
+	// The bitshifts >>/<< 10 in this method are due to fixed point arithmetic in freetype.
+	printf("display_text_render called\n");
 	FT_Matrix matrix;
 	FT_Vector pen;
 	FT_UInt  glyph_index;
@@ -461,35 +510,46 @@
 	pen.y = 0 * 64;
 	x <<= 6;
 	y <<= 6;
-	FT_Set_Transform( font->face, &matrix, &pen );
 
 	for ( n = 0; n < len; n++ )
 	{
+		FT_Face face = NULL;
+		FT_Glyph glyph = NULL;
+		FTC_Node anode = NULL;
+		FTC_Manager_LookupFace( font->manager, (FT_Pointer)font, &face);
+		glyph_index = FTC_CMapCache_Lookup( font->charmap_cache, (FT_Pointer)font, font->charmap_index, g_utf8_get_char(p));
+		FTC_ImageCache_LookupScaler( font->image_cache, &font->scaler, FT_LOAD_DEFAULT, glyph_index, &glyph, &anode);
+		FT_Glyph temp_glyph = NULL;
+		FT_BitmapGlyph  glyph_bitmap = NULL;
+		if(FT_Glyph_Copy(glyph, &temp_glyph)) {
+			fprintf(stderr, "Error copying glyph\n");
+			FTC_Node_Unref(anode, font->manager);
+			continue;
+		}
+		FT_Glyph_Transform(temp_glyph, &matrix, &pen);
+		if(!FT_Glyph_To_Bitmap(&temp_glyph, ft_render_mode_normal, NULL, TRUE)) {
+			glyph_bitmap = (FT_BitmapGlyph)temp_glyph;
+			curr=g_malloc(sizeof(*curr)+glyph_bitmap->bitmap.rows*glyph_bitmap->bitmap.pitch);
+			ret->glyph[n]=curr;
 
-		glyph_index = FT_Get_Char_Index(font->face, g_utf8_get_char(p));
-		FT_Load_Glyph(font->face, glyph_index, FT_LOAD_DEFAULT );
-		FT_Render_Glyph(font->face->glyph, ft_render_mode_normal );
-
-		curr=g_malloc(sizeof(*curr)+slot->bitmap.rows*slot->bitmap.pitch);
-		ret->glyph[n]=curr;
-
-		curr->x=(x>>6)+slot->bitmap_left;
-		curr->y=(y>>6)-slot->bitmap_top;
-		curr->w=slot->bitmap.width;
-		curr->h=slot->bitmap.rows;
-		if (slot->bitmap.width && slot->bitmap.rows) {
-			memcpy(curr->pixmap, slot->bitmap.buffer, slot->bitmap.rows*slot->bitmap.pitch);
-			curr->shadow=display_text_render_shadow(curr);
+			curr->x=(x>>6)+glyph_bitmap->left;
+			curr->y=(y>>6)-glyph_bitmap->top;
+			curr->w=glyph_bitmap->bitmap.width;
+			curr->h=glyph_bitmap->bitmap.rows;
+			if (glyph_bitmap->bitmap.width && glyph_bitmap->bitmap.rows) {
+				memcpy(curr->pixmap, glyph_bitmap->bitmap.buffer, glyph_bitmap->bitmap.rows*glyph_bitmap->bitmap.pitch);
+				curr->shadow=display_text_render_shadow(curr);
+			}
+			else
+				curr->shadow=NULL;
+		
+	         	x += ((temp_glyph->advance.x) >> 10);
+       		  	y -= ((temp_glyph->advance.y) >> 10);
+			FT_Done_Glyph(temp_glyph);
+		}else {
+			fprintf(stderr, "Error creating transformed glyph bitmap");
 		}
-		else
-			curr->shadow=NULL;
-#if 0
-		printf("height=%d\n", slot->metrics.height);
-		printf("height2=%d\n", face->height);
-		printf("bbox %d %d %d %d\n", face->bbox.xMin, face->bbox.yMin, face->bbox.xMax, face->bbox.yMax);
-#endif
-         	x += slot->advance.x;
-         	y -= slot->advance.y;
+		FTC_Node_Unref(anode, font->manager);
 		p=g_utf8_next_char(p);
 	}
 	return ret;
@@ -568,7 +628,6 @@
 	char *p=text;
 	FT_BBox bbox;
 	FT_UInt  glyph_index;
-       	FT_GlyphSlot  slot = font->face->glyph;  // a small shortcut
 	FT_Glyph glyph;
 	FT_Matrix matrix;
 	FT_Vector pen;
@@ -582,22 +641,27 @@
 
 	bbox.xMin = bbox.yMin = 32000;
 	bbox.xMax = bbox.yMax = -32000; 
-	FT_Set_Transform( font->face, &matrix, &pen );
 	len=g_utf8_strlen(text, -1);
 	for ( n = 0; n < len; n++ ) {
 		FT_BBox glyph_bbox;
-		glyph_index = FT_Get_Char_Index(font->face, g_utf8_get_char(p));
+		FT_Face face = NULL;
+		FTC_Node anode = NULL;
+		FTC_Manager_LookupFace( font->manager, (FT_Pointer)font, &face);
+		glyph_index = FTC_CMapCache_Lookup( font->charmap_cache, (FT_Pointer)font, font->charmap_index, g_utf8_get_char(p));
 		p=g_utf8_next_char(p);
-		FT_Load_Glyph(font->face, glyph_index, FT_LOAD_DEFAULT );
-		FT_Get_Glyph(font->face->glyph, &glyph);
-		FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_pixels, &glyph_bbox );
-		FT_Done_Glyph(glyph);
+		FTC_ImageCache_LookupScaler( font->image_cache, &font->scaler, FT_LOAD_DEFAULT, glyph_index, &glyph, &anode);
+		FT_Glyph temp_glyph = NULL;
+                FT_Glyph_Copy(glyph, &temp_glyph);
+                FT_Glyph_Transform(temp_glyph, &matrix, &pen);
+		FT_Glyph_Get_CBox(temp_glyph, ft_glyph_bbox_pixels, &glyph_bbox );
 		glyph_bbox.xMin += x >> 6;
 		glyph_bbox.xMax += x >> 6;
 		glyph_bbox.yMin += y >> 6;
 		glyph_bbox.yMax += y >> 6;
-         	x += slot->advance.x;
-         	y -= slot->advance.y;
+         	x += temp_glyph->advance.x >> 10;
+         	y -= temp_glyph->advance.y >> 10;
+		FT_Done_Glyph(temp_glyph);
+		FTC_Node_Unref(anode, font->manager);
 		if ( glyph_bbox.xMin < bbox.xMin )
 			bbox.xMin = glyph_bbox.xMin;
 		if ( glyph_bbox.yMin < bbox.yMin )
@@ -739,7 +803,25 @@
                         widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
                         gr->drawable,
                         p->x, p->y, p->x, p->y, w, h);
+}
 
+static void
+draw_drag(struct graphics_priv *gr, struct point *p)
+{
+	GtkWidget *widget=gr->widget;
+	if(!gr->background_ready) {
+		gr->background = gdk_pixmap_new(widget->window, gr->width, gr->width, -1);
+		gdk_draw_rectangle(gr->background, gr->background_gc->gc, TRUE, 0, 0, gr->width, gr->height);
+		gr->background_ready = 1;
+	}
+	gdk_draw_drawable(widget->window,
+			widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+			gr->background,
+			0, 0, 0, 0, -1, -1);
+	gdk_draw_drawable(widget->window,
+                        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+                        gr->drawable,
+                        0, 0, p->x, p->y, -1, -1);
 }
 
 static void
@@ -789,6 +871,10 @@
 	if (gra->drawable != NULL) {
                 g_object_unref(gra->drawable);
         }
+	if(gra->background_ready && gra->background != NULL) {
+		g_object_unref(gra->background);
+		gra->background_ready = 0;
+	}
 	gra->width=widget->allocation.width;
 	gra->height=widget->allocation.height;
         gra->drawable = gdk_pixmap_new(widget->window, gra->width, gra->height, -1);
@@ -1062,6 +1148,7 @@
 	NULL,
 #endif
 	draw_restore,
+	draw_drag,
 	font_new,
 	gc_new,
 	background_gc,
Index: navit/navit/graphics.c
===================================================================
--- navit/navit/graphics.c	(revision 1255)
+++ navit/navit/graphics.c	(working copy)
@@ -325,6 +325,16 @@
 }
 
 //##############################################################################################################
+//# Description:
+//# Comment:
+//# Authors: Martin Schaller (04/2008)
+//##############################################################################################################
+void graphics_draw_drag(struct graphics *this_, struct point *p)
+{
+	this_->meth.draw_drag(this_->priv, p);
+}
+
+//##############################################################################################################
 //# Description: 
 //# Comment: 
 //# Authors: Martin Schaller (04/2008)
Index: navit/navit/graphics.h
===================================================================
--- navit/navit/graphics.h	(revision 1255)
+++ navit/navit/graphics.h	(working copy)
@@ -56,6 +56,7 @@
 	void (*draw_image)(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, struct graphics_image_priv *img);
 	void (*draw_image_warp)(struct graphics_priv *gr, struct graphics_gc_priv *fg, struct point *p, int count, char *data);
 	void (*draw_restore)(struct graphics_priv *gr, struct point *p, int w, int h);
+	void (*draw_drag)(struct graphics_priv *gr, struct point *p);
 	struct graphics_font_priv *(*font_new)(struct graphics_priv *gr, struct graphics_font_methods *meth, int size, int flags);
 	struct graphics_gc_priv *(*gc_new)(struct graphics_priv *gr, struct graphics_gc_methods *meth);
 	void (*background_gc)(struct graphics_priv *gr, struct graphics_gc_priv *gc);
@@ -143,6 +144,7 @@
 struct graphics_image *graphics_image_new(struct graphics *gra, char *path);
 void graphics_image_free(struct graphics *gra, struct graphics_image *img);
 void graphics_draw_restore(struct graphics *this_, struct point *p, int w, int h);
+void graphics_draw_drag(struct graphics *this_, struct point *p);
 void graphics_draw_mode(struct graphics *this_, enum draw_mode_num mode);
 void graphics_draw_lines(struct graphics *this_, struct graphics_gc *gc, struct point *p, int count);
 void graphics_draw_circle(struct graphics *this_, struct graphics_gc *gc, struct point *p, int r);
Index: navit/navit/navit.c
===================================================================
--- navit/navit/navit.c	(revision 1255)
+++ navit/navit/navit.c	(working copy)
@@ -284,6 +284,7 @@
 static void
 navit_button(void *data, int pressed, int button, struct point *p)
 {
+	printf("navit_button\n");
 	struct navit *this=data;
 	if (! this->popup_callback)
 		this->popup_callback=callback_new_1(navit_popup, this);
@@ -297,13 +298,13 @@
 	struct navit *this_=data;
 	int dx, dy;
 
-	dx=(this_->current.x-this_->last.x);
-	dy=(this_->current.y-this_->last.y);
+	dx=(this_->current.x-this_->pressed.x);
+	dy=(this_->current.y-this_->pressed.y);
 	if (dx || dy) {
-		this_->last=this_->current;
-		graphics_overlay_disable(this_->gra, 1);
-		graphics_displaylist_move(this_->displaylist, dx, dy);
-		graphics_displaylist_draw(this_->gra, this_->displaylist, this_->trans, this_->layout_current, 0);
+		struct point point;
+		point.x = dx;
+		point.y = dy;
+		graphics_draw_drag(this_->gra, &point);
 		this_->moved=1;
 	}
 	this_->motion_timeout=0;
diff --git a/conf/distro/include/sane-srcrevs.inc b/conf/distro/include/sane-srcrevs.inc
index 0c19362..5c845cd 100644
--- a/conf/distro/include/sane-srcrevs.inc
+++ b/conf/distro/include/sane-srcrevs.inc
@@ -97,7 +97,7 @@ SRCREV_pn-mpd-alsa ?= "6952"
 SRCREV_pn-mplayer ?= "27047"
 SRCREV_pn-mplayer-maemo ?= "342"
 SRCREV_pn-multitap-pad ?= "373"
-SRCREV_pn-navit ?= "1096"
+SRCREV_pn-navit ?= "1255"
 SRCREV_pn-neod ?= "4471"
 SRCREV_pn-netsurf ?= "3859"
 SRCREV_pn-networkmanager ?= "3202"
diff --git a/packages/navit/navit.inc b/packages/navit/navit.inc
index 011c058..ca571c1 100644
--- a/packages/navit/navit.inc
+++ b/packages/navit/navit.inc
@@ -6,7 +6,7 @@ RRECOMMENDS = "gpsd speechd flite"

 inherit autotools

-EXTRA_OECONF = "--disable-binding-python --disable-gui-sdl --disable-samplemap --enable-avoid-float --enable-avoid-unaligned"
+EXTRA_OECONF = "--disable-binding-python --disable-gui-sdl --disable-samplemap --disable-graphics-qt-qpainter --disable-graphics-sdl --disable-postgr

 PACKAGES = "${PN}-dbg ${PN}-dev ${PN} ${PN}-doc ${PN}-locale"

diff --git a/packages/navit/navit_0.0.4.bb b/packages/navit/navit_0.0.4.bb
index 104495f..edd4519 100644
--- a/packages/navit/navit_0.0.4.bb
+++ b/packages/navit/navit_0.0.4.bb
@@ -4,4 +4,7 @@ PR = "r0"

 SRC_URI = "${SOURCEFORGE_MIRROR}/navit/navit-${PV}.tar.gz"

+DEFAULT_PREFERENCE = "-1"
+
 SRC_URI_append +=  "file://navit.xml-so.patch;patch=1"
+SRC_URI_append +=  "file://font_scaling_patch.diff;patch=1"
diff --git a/packages/navit/navit_svn.bb b/packages/navit/navit_svn.bb
index dad9a4e..7de8e37 100644
--- a/packages/navit/navit_svn.bb
+++ b/packages/navit/navit_svn.bb
@@ -3,10 +3,10 @@ require navit.inc
 PV = "0.1.0+svnrev${SRCPV}"
 PR = "r0"

-DEFAULT_PREFERENCE = "-1"
-
 S = "${WORKDIR}/navit"

 SRC_URI = "svn://[EMAIL PROTECTED]/svnroot/navit/trunk;module=navit;proto=https"

+SRC_URI_append +=  "file://font_scaling_patch.diff;patch=1"
+
 EXTRA_AUTORECONF = " -I m4"

_______________________________________________
Openmoko community mailing list
community@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/community

Reply via email to