On Monday 18 August 2008, Charles-Henri Gros wrote:
> gdk_window_begin_paint_region
> gdk_window_end_paint
> It's funny, I did the opposite of what you did while working on my
> own version of tangoGPS, because I didn't like the white rectangles
> around. I'm afraid that using that method will negate any of your
> speed gains though.

Thanks for identifying the relevant methods. I modified my patch and 
updated the ipk files on my server. I could not identify any negative 
impact on speed though. It seems to work just fine, panning feels a lot 
smoother compared to the previous version.

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.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;
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,28 @@
                         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;
+	}
+	GdkRegion* region = gdk_drawable_get_clip_region(GDK_DRAWABLE (widget->window));
+	gdk_window_begin_paint_region(widget->window, region);
+	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);
+	gdk_window_end_paint(widget->window);
 }
 
 static void
@@ -789,6 +874,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 +1151,7 @@
 	NULL,
 #endif
 	draw_restore,
+	draw_drag,
 	font_new,
 	gc_new,
 	background_gc,
_______________________________________________
Openmoko community mailing list
community@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/community

Reply via email to