aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gtk/PlatGTK.cxx103
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);