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