From: <sil...@li...> - 2005-08-22 20:31:28
|
Update of /cvsroot/silgraphite/silgraphite/contrib/pangomod In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18489 Modified Files: pangographite.cpp Log Message: Sort glyphs into display order for the PangoGlyphString This fixes the cursor going way past the end of words issue still one more major cursor issue to go Index: pangographite.cpp =================================================================== RCS file: /cvsroot/silgraphite/silgraphite/contrib/pangomod/pangographite.cpp,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- pangographite.cpp 19 Aug 2005 23:10:56 -0000 1.13 +++ pangographite.cpp 22 Aug 2005 20:31:18 -0000 1.14 @@ -295,6 +295,15 @@ } #endif + +// Sort function for sorting glyphs into display order +int xpos_sort(gconstpointer a, gconstpointer b, gpointer user_data) +{ + int * x_pos = (int *)user_data; + return x_pos[*(gint *)a] - x_pos[*(gint *)b]; +} + + void graphite_PangoGlyphString(const char *text, int length, PangoFont *xftfont, PangoGlyphString *glyphs) { GrGraphics * pgrfx; @@ -384,19 +393,31 @@ Rect rs(0,0,100,100); Rect rd(0,0,100,100); - // Get the number of chars first + // Get the number of glyphs first pgrseg->GetGlyphsAndPositions(0, pgrfx, rs, rd, 0, &n_glyphs, NULL, NULL, NULL, NULL); prgchGlyphs = new utf16[n_glyphs]; - prgxd = new int[n_glyphs]; + prgxd = new int[n_glyphs+1]; prgyd = new int[n_glyphs]; prgdxdAdv = new int[n_glyphs]; // now get the list of glyphs, xoffsets, yoffsets and advances - pgrseg->GetUniscribeGlyphsAndPositions(0, pgrfx, + pgrseg->GetGlyphsAndPositions(0, pgrfx, rs, rd, n_glyphs, &n_glyphs, prgchGlyphs, prgxd, prgyd, prgdxdAdv); + + // get a sorted list of glyphs sorted into display order + GArray *sorted = g_array_sized_new(FALSE, FALSE, sizeof(gint), n_glyphs); + for (int i=0; i< n_glyphs; i++) { + g_array_append_val(sorted, i); + } + for (int i = 0; i < n_glyphs; i++) + if (g_array_index (sorted, gint, i) != i) + g_print ("ERROR: got %d instead of %d\n", + g_array_index (sorted, gint, i), i); + g_array_sort_with_data(sorted, &xpos_sort, prgxd); + int n_chars; int * prg1stOfCluster; bool * pfClusterStart; @@ -492,58 +513,74 @@ PangoRectangle logical_rect; int curr_offset = 0; + int curr_glyph; int i, j; - for (int i=0; i<n_glyphs; i++) + for (i=0; i<n_glyphs-1; i++) { - glyphs->glyphs[i].glyph = prgchGlyphs[i]; // which of these 2??? - glyphs->glyphs[i].geometry.y_offset = prgyd[i]*PANGO_SCALE; + curr_glyph = g_array_index (sorted, gint, i); + glyphs->glyphs[i].glyph = prgchGlyphs[curr_glyph]; + glyphs->glyphs[i].geometry.y_offset = prgyd[curr_glyph]*PANGO_SCALE; + + if (pfClusterStart[curr_glyph]) + { + if (prg1stCharInClust[curr_glyph]==-1) + g_warning("oops cluster wrong at %d", curr_glyph); + first_char_in_cluster = prg1stCharInClust[curr_glyph]; + } + glyphs->glyphs[i].geometry.x_offset = 0; + glyphs->glyphs[i].geometry.width = (prgxd[g_array_index (sorted, gint, i+1)] - prgxd[curr_glyph]) * PANGO_SCALE; + #ifdef WDGDEBUG + g_message("width between glyphs %d(%d) and %d(%d) is (%d - %d) * 1024 = %d", i+1, g_array_index (sorted, gint, i+1), + i, curr_glyph, prgxd[g_array_index (sorted, gint, i+1)], prgxd[curr_glyph], + glyphs->glyphs[i].geometry.width); + #endif + + glyphs->log_clusters[i] = g_utf8_offset_to_pointer(text, first_char_in_cluster) - text; - pango_font_get_glyph_extents (xftfont, glyphs->glyphs[i].glyph, NULL, &logical_rect); - - - if (pfClusterStart[i]) - { - if (prg1stCharInClust[i]==-1) - g_warning("oops cluster wrong at %d", i); - first_char_in_cluster = prg1stCharInClust[i]; - } - #if 1 - glyphs->glyphs[i].geometry.width = logical_rect.width; - glyphs->glyphs[i].geometry.x_offset = (PANGO_SCALE * prgxd[i]); - #else - if (pfClusterStart[i]) - { - glyphs->glyphs[i].geometry.width = logical_rect.width; - glyphs->glyphs[i].geometry.x_offset = 0; - } - else - { - glyphs->glyphs[i].geometry.width = 0; - glyphs->glyphs[i].geometry.x_offset = curr_offset + (PANGO_SCALE * prgxd[i]) + logical_rect.width; - curr_offset += logical_rect.width; - } - #endif + #ifdef WDGDEBUG + //g_message("glyph %d(%d) has lh%d lw%d lx%d ly%d xoff%d yoff%d wid%d logcl%d", i, + g_message("glyph %d(%d) has xoff%d yoff%d (adv%d) wid%d logcl%d", i, + glyphs->glyphs[i].glyph, + glyphs->glyphs[i].geometry.x_offset, glyphs->glyphs[i].geometry.y_offset, + PANGO_SCALE * prgdxdAdv[i], + glyphs->glyphs[i].geometry.width, + glyphs->log_clusters[i]); + #endif + } - - //tmp[i] = first_char_in_cluster; - #if !NEW_LOG_CLUST - glyphs->log_clusters[i] = g_utf8_offset_to_pointer(text, first_char_in_cluster) - text; - #endif - //g_message("log_cluster %d is %d of glyph %d", i, glyphs->log_clusters[i], glyphs->glyphs[i].glyph); - #ifdef WDGDEBUG - g_message("glyph %d(%d) has lh%d lw%d lx%d ly%d xoff%d yoff%d wid%d logcl%d", i, - glyphs->glyphs[i].glyph, - logical_rect.height, logical_rect.width, - logical_rect.x, logical_rect.y, - glyphs->glyphs[i].geometry.x_offset, glyphs->glyphs[i].geometry.y_offset, - glyphs->glyphs[i].geometry.width, - glyphs->log_clusters[i]); - #endif + + i = n_glyphs-1; + curr_glyph = g_array_index (sorted, gint, i); + glyphs->glyphs[i].glyph = prgchGlyphs[curr_glyph]; + glyphs->glyphs[i].geometry.y_offset = prgyd[curr_glyph]*PANGO_SCALE; + + if (pfClusterStart[curr_glyph]) + { + if (prg1stCharInClust[curr_glyph]==-1) + g_warning("oops cluster wrong at %d", curr_glyph); + first_char_in_cluster = prg1stCharInClust[curr_glyph]; } + glyphs->glyphs[i].geometry.x_offset = 0; + pango_font_get_glyph_extents (xftfont, prgchGlyphs[curr_glyph], NULL, &logical_rect); + glyphs->glyphs[i].geometry.width = logical_rect.width; + glyphs->log_clusters[i] = g_utf8_offset_to_pointer(text, first_char_in_cluster) - text; + #ifdef WDGDEBUG + g_message("glyph %d(%d) has xoff%d yoff%d (adv%d) wid%d logcl%d", i, + glyphs->glyphs[i].glyph, + glyphs->glyphs[i].geometry.x_offset, glyphs->glyphs[i].geometry.y_offset, + PANGO_SCALE * prgdxdAdv[i], + glyphs->glyphs[i].geometry.width, + glyphs->log_clusters[i]); + #endif + + + + glyphs->num_glyphs = n_glyphs; + g_array_free(sorted, TRUE); delete[] prgchGlyphs; delete[] prgxd; delete[] prgyd; |