diff options
Diffstat (limited to 'gtk')
| -rw-r--r-- | gtk/PlatGTK.cxx | 44 | 
1 files changed, 30 insertions, 14 deletions
| diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx index 2edae58c7..32445cc4e 100644 --- a/gtk/PlatGTK.cxx +++ b/gtk/PlatGTK.cxx @@ -26,6 +26,9 @@  #pragma warning(disable: 4505)  #endif +// X has a 16 bit coordinate space, so stop drawing here to avoid wrapping +static const int maxCoordinate = 32000; +  static GdkFont *PFont(Font &f)  {  	return reinterpret_cast<GdkFont *>(f.GetID());  } @@ -379,7 +382,7 @@ void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAlloc  void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {  	PenColour(back); -	if (drawable && (rc.left < 32000)) {	// Protect against out of range +	if (drawable && (rc.left < maxCoordinate)) {	// Protect against out of range  		gdk_draw_rectangle(drawable, gc, 1,  		                   rc.left, rc.top,  		                   rc.right - rc.left, rc.bottom - rc.top); @@ -460,29 +463,42 @@ void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const ch                         ColourAllocated fore, ColourAllocated back) {  	FillRectangle(rc, back);  	PenColour(fore); -	if (gc && drawable) -		gdk_draw_text(drawable, PFont(font_), gc, rc.left, ybase, s, len); +	if (gc && drawable) { +		// Draw text as a series of segments to avoid limitations in X servers +		// TODO: make this DBCS and UTF-8 safe by not splitting multibyte characters +		const int segmentLength = 1000; +		int x = rc.left; +		while ((len > 0) && (x < maxCoordinate)) { +			int lenDraw = Platform::Minimum(len, segmentLength); +			gdk_draw_text(drawable, PFont(font_), gc, x, ybase, s, lenDraw); +			len -= lenDraw; +			if (len > 0) { +				x += gdk_text_width(PFont(font_), s, lenDraw); +			} +			s += lenDraw; +		} +	}  }  // On GTK+, exactly same as DrawTextNoClip  void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len,                                ColourAllocated fore, ColourAllocated back) { -	FillRectangle(rc, back); -	PenColour(fore); -	if (gc && drawable) -		gdk_draw_text(drawable, PFont(font_), gc, rc.left, ybase, s, len); +	DrawTextNoClip(rc, font_, ybase, s, len, fore, back);  }  void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) { -	int totalWidth = 0; -	for (int i = 0;i < len;i++) { -		if (font_.GetID()) { -			int width = gdk_char_width(PFont(font_), s[i]); +	if (font_.GetID()) { +		int totalWidth = 0; +		GdkFont *gf = PFont(font_); +		for (int i = 0; i < len; i++) { +			int width = gdk_char_width(gf, s[i]);  			totalWidth += width; -		} else { -			totalWidth++; +			positions[i] = totalWidth; +		} +	} else { +		for (int i = 0; i < len; i++) { +			positions[i] = i + 1;  		} -		positions[i] = totalWidth;  	}  } | 
