diff options
-rw-r--r-- | gtk/PlatGTK.cxx | 103 |
1 files changed, 59 insertions, 44 deletions
diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx index 82d0a9b99..97b085587 100644 --- a/gtk/PlatGTK.cxx +++ b/gtk/PlatGTK.cxx @@ -1287,7 +1287,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char pango_layout_set_text(layout, utfForm, len); } pango_layout_set_font_description(layout, PFont(font_)->pfd); - PangoLayoutLine *pll = pango_layout_get_line(layout,0); + PangoLayoutLine *pll = pango_layout_get_line_readonly(layout,0); gdk_draw_layout_line(drawable, gc, xText, ybase, pll); if (useGFree) { g_free(utfForm); @@ -1371,6 +1371,40 @@ void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, int ybase, con } } +class ClusterIterator { + PangoLayoutIter *iter; + PangoRectangle pos; + int lenPositions; +public: + bool finished; + int positionStart; + int position; + int distance; + int curIndex; + ClusterIterator(PangoLayout *layout, int len) : lenPositions(len), finished(false), + positionStart(0), position(0), distance(0) { + iter = pango_layout_get_iter(layout); + pango_layout_iter_get_cluster_extents(iter, NULL, &pos); + } + ~ClusterIterator() { + pango_layout_iter_free(iter); + } + + void Next() { + positionStart = position; + if (pango_layout_iter_next_cluster(iter)) { + pango_layout_iter_get_cluster_extents(iter, NULL, &pos); + position = PANGO_PIXELS(pos.x); + curIndex = pango_layout_iter_get_index(iter); + } else { + finished = true; + position = PANGO_PIXELS(pos.x + pos.width); + curIndex = lenPositions; + } + distance = position - positionStart; + } +}; + void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) { if (font_.GetID()) { int totalWidth = 0; @@ -1384,32 +1418,24 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi return; } } - PangoRectangle pos; pango_layout_set_font_description(layout, PFont(font_)->pfd); if (et == UTF8) { // Simple and direct as UTF-8 is native Pango encoding - pango_layout_set_text(layout, s, len); - PangoLayoutIter *iter = pango_layout_get_iter(layout); - pango_layout_iter_get_cluster_extents(iter, NULL, &pos); int i = 0; - while (pango_layout_iter_next_cluster(iter)) { - pango_layout_iter_get_cluster_extents(iter, NULL, &pos); - int position = PANGO_PIXELS(pos.x); - int curIndex = pango_layout_iter_get_index(iter); - int places = curIndex - i; - int distance = position - positions[i-1]; - while (i < curIndex) { + pango_layout_set_text(layout, s, len); + ClusterIterator iti(layout, lenPositions); + while (!iti.finished) { + iti.Next(); + int places = iti.curIndex - i; + while (i < iti.curIndex) { // Evenly distribute space among bytes of this cluster. // Would be better to find number of characters and then // divide evenly between characters with each byte of a character // being at the same position. - positions[i] = position - (curIndex - 1 - i) * distance / places; + positions[i] = iti.position - (iti.curIndex - 1 - i) * iti.distance / places; i++; } } - while (i < lenPositions) - positions[i++] = PANGO_PIXELS(pos.x + pos.width); - pango_layout_iter_free(iter); PLATFORM_ASSERT(i == lenPositions); } else { int positionsCalculated = 0; @@ -1423,26 +1449,23 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi Converter convMeasure("UCS-2", CharacterSetID(characterSet), false); pango_layout_set_text(layout, utfForm, strlen(utfForm)); int i = 0; - int utfIndex = 0; - PangoLayoutIter *iter = pango_layout_get_iter(layout); - pango_layout_iter_get_cluster_extents(iter, NULL, &pos); - while (pango_layout_iter_next_cluster(iter)) { - pango_layout_iter_get_cluster_extents (iter, NULL, &pos); - int position = PANGO_PIXELS(pos.x); - int utfIndexNext = pango_layout_iter_get_index(iter); - while (utfIndex < utfIndexNext) { + int clusterStart = 0; + ClusterIterator iti(layout, strlen(utfForm)); + while (!iti.finished) { + iti.Next(); + int clusterEnd = iti.curIndex; + int places = g_utf8_strlen(utfForm + clusterStart, clusterEnd - clusterStart); + int place = 1; + while (clusterStart < clusterEnd) { size_t lenChar = MultiByteLenFromIconv(convMeasure, s+i, len-i); - //size_t lenChar = mblen(s+i, MB_CUR_MAX); while (lenChar--) { - positions[i++] = position; + positions[i++] = iti.position - (places - place) * iti.distance / places; positionsCalculated++; } - utfIndex += UTF8CharLength(utfForm+utfIndex); + clusterStart += UTF8CharLength(utfForm+clusterStart); + place++; } } - while (i < lenPositions) - positions[i++] = PANGO_PIXELS(pos.x + pos.width); - pango_layout_iter_free(iter); delete []utfForm; PLATFORM_ASSERT(i == lenPositions); } @@ -1456,29 +1479,21 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi utfForm = UTF8FromLatin1(s, len); } pango_layout_set_text(layout, utfForm, len); - PangoLayoutIter *iter = pango_layout_get_iter(layout); - pango_layout_iter_get_cluster_extents(iter, NULL, &pos); int i = 0; - int positionStart = 0; int clusterStart = 0; // Each Latin1 input character may take 1 or 2 bytes in UTF-8 // and groups of up to 3 may be represented as ligatures. - while (pango_layout_iter_next_cluster(iter)) { - pango_layout_iter_get_cluster_extents(iter, NULL, &pos); - int position = PANGO_PIXELS(pos.x); - int distance = position - positionStart; - int clusterEnd = pango_layout_iter_get_index(iter); + ClusterIterator iti(layout, strlen(utfForm)); + while (!iti.finished) { + iti.Next(); + int clusterEnd = iti.curIndex; int ligatureLength = g_utf8_strlen(utfForm + clusterStart, clusterEnd - clusterStart); PLATFORM_ASSERT(ligatureLength > 0 && ligatureLength <= 3); for (int charInLig=0; charInLig<ligatureLength; charInLig++) { - positions[i++] = position - (ligatureLength - 1 - charInLig) * distance / ligatureLength; + positions[i++] = iti.position - (ligatureLength - 1 - charInLig) * iti.distance / ligatureLength; } - positionStart = position; clusterStart = clusterEnd; } - while (i < lenPositions) - positions[i++] = PANGO_PIXELS(pos.x + pos.width); - pango_layout_iter_free(iter); if (useGFree) { g_free(utfForm); } else { @@ -1575,7 +1590,7 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) { } pango_layout_set_text(layout, utfForm, len); } - PangoLayoutLine *pangoLine = pango_layout_get_line(layout, 0); + PangoLayoutLine *pangoLine = pango_layout_get_line_readonly(layout, 0); pango_layout_line_get_extents(pangoLine, NULL, &pos); if (useGFree) { g_free(utfForm); |