diff options
Diffstat (limited to 'gtk')
| -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); | 
