diff options
Diffstat (limited to 'gtk')
| -rw-r--r-- | gtk/PlatGTK.cxx | 85 | 
1 files changed, 56 insertions, 29 deletions
| diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx index 56ead18a3..f476af33f 100644 --- a/gtk/PlatGTK.cxx +++ b/gtk/PlatGTK.cxx @@ -44,34 +44,35 @@  #pragma warning(disable: 4505)  #endif +enum encodingType { singleByte, UTF8, dbcs}; +  // On GTK+ 1.x holds a GdkFont* but on GTK+ 2.x can hold a GdkFont* or a  // PangoFontDescription*.  class FontHandle { +	int width[128]; +	encodingType et;  public:  	int ascent; -	int width[128];  	GdkFont *pfont;  #ifdef USE_PANGO  	PangoFontDescription *pfd;  #endif  	FontHandle(GdkFont *pfont_) { +		et = singleByte;  		ascent = 0;  		pfont = pfont_;  #ifdef USE_PANGO  		pfd = 0;  #endif -		for (int i=0;i<128;i++) { -			width[i] = 0; -		} +		ResetWidths(et);  	}  #ifdef USE_PANGO  	FontHandle(PangoFontDescription *pfd_) { +		et = singleByte;  		ascent = 0;  		pfont = 0;  		pfd = pfd_; -		for (int i=0;i<128;i++) { -			width[i] = 0; -		} +		ResetWidths(et);  	}  #endif  	~FontHandle() { @@ -84,6 +85,28 @@ public:  		pfd = 0;  #endif  	} +	void ResetWidths(encodingType et_) { +		et = et_; +		for (int i=0; i<=127; i++) { +			width[i] = 0; +		} +	} +	int CharWidth(unsigned char ch, encodingType et_) { +		if (ch <= 127) { +			if (et != et_) { +				return 0; +			} +		} +		return width[ch]; +	} +	void SetCharWidth(unsigned char ch, int w, encodingType et_) { +		if (ch <= 127) { +			if (et != et_) { +				ResetWidths(et_); +			} +			width[ch] = w; +		} +	}  };  struct LOGFONT { @@ -629,8 +652,7 @@ void Font::Release() {  }  class SurfaceImpl : public Surface { -	bool unicodeMode; -	bool dbcsMode; +	encodingType et;  	GdkDrawable *drawable;  	GdkGC *gc;  	GdkPixmap *ppixmap; @@ -687,7 +709,7 @@ public:  	void SetDBCSMode(int codePage);  }; -SurfaceImpl::SurfaceImpl() : unicodeMode(false), dbcsMode(false), drawable(0), gc(0), ppixmap(0), +SurfaceImpl::SurfaceImpl() : et(singleByte), drawable(0), gc(0), ppixmap(0),  x(0), y(0), inited(false), createdGC(false)  #ifdef USE_PANGO  , pcontext(0), layout(0) @@ -1001,10 +1023,10 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char  #ifdef USE_PANGO  		if (PFont(font_)->pfd) {  			char *utfForm = 0; -			if (unicodeMode) { +			if (et == UTF8) {  				pango_layout_set_text(layout, s, len);  			} else { -				if (dbcsMode) { +				if (et == dbcs) {  					// Convert to utf8  					utfForm = UTF8FromDBCS(s, len);  				} @@ -1022,13 +1044,13 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char  		// Draw text as a series of segments to avoid limitations in X servers  		const int segmentLength = 1000;  		bool draw8bit = true; -		if (unicodeMode || dbcsMode) { +		if (et != singleByte) {  			GdkWChar wctext[maxLengthTextRun];  			int wclen; -			if (unicodeMode) { +			if (et == UTF8) {  				wclen = UCS2FromUTF8(s, len,  					reinterpret_cast<wchar_t *>(wctext), maxLengthTextRun - 1); -			} else {	// dbcsMode, so convert using current locale +			} else {	// dbcs, so convert using current locale  				wclen = gdk_mbstowcs(  					wctext, s, maxLengthTextRun - 1);  			} @@ -1093,13 +1115,16 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi  		int totalWidth = 0;  #ifdef USE_PANGO  		if (PFont(font_)->pfd) { -			if (len == 1 && (static_cast<unsigned char>(*s) <= 127) && PFont(font_)->width[*s]) { -				positions[0] = PFont(font_)->width[*s]; -				return; +			if (len == 1) { +				int width = PFont(font_)->CharWidth(*s); +				if (width) { +					positions[0] = width; +					return; +				}  			}  			PangoRectangle pos;  			pango_layout_set_font_description(layout, PFont(font_)->pfd); -			if (unicodeMode) { +			if (et == UTF8) {  				// Simple and direct as UTF-8 is native Pango encoding  				pango_layout_set_text(layout, s, len);  				int i = 0; @@ -1147,18 +1172,18 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi  					delete []utfForm;  				}  			} -			if (len == 1 && (static_cast<unsigned char>(*s) <= 127)) { -				PFont(font_)->width[*s] = positions[0]; +			if (len == 1) { +				PFont(font_)->SetCharWidth(*s, positions[0]);  			}  			return;  		}  #endif  		GdkFont *gf = PFont(font_)->pfont;  		bool measure8bit = true; -		if (unicodeMode || dbcsMode) { +		if (et != singleByte) {  			GdkWChar wctext[maxLengthTextRun];  			int wclen; -			if (unicodeMode) { +			if (et == UTF8) {  				wclen = UCS2FromUTF8(s, len,  					reinterpret_cast<wchar_t *>(wctext), maxLengthTextRun - 1);  			} else {	// dbcsMode, so convert using current locale @@ -1174,7 +1199,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi  					int width = gdk_char_width_wc(gf, wctext[iU]);  					totalWidth += width;  					size_t lenChar; -					if (unicodeMode) { +					if (et == UTF8) {  						lenChar = UTF8Len(s[i]);  					} else {  						lenChar = mblen(s+i, MB_CUR_MAX); @@ -1211,10 +1236,10 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {  			char *utfForm = 0;  			pango_layout_set_font_description(layout, PFont(font_)->pfd);  			PangoRectangle pos; -			if (unicodeMode) { +			if (et == UTF8) {  				pango_layout_set_text(layout, s, len);  			} else { -				if (dbcsMode) { +				if (et == dbcs) {  					// Convert to utf8  					utfForm = UTF8FromDBCS(s, len);  				} @@ -1228,7 +1253,7 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {  			return width;  		}  #endif -		if (unicodeMode) { +		if (et == UTF8) {  			GdkWChar wctext[maxLengthTextRun];  			size_t wclen = UCS2FromUTF8(s, len, (wchar_t *)wctext, sizeof(wctext) / sizeof(GdkWChar) - 1);  			wctext[wclen] = L'\0'; @@ -1360,11 +1385,13 @@ void SurfaceImpl::SetClip(PRectangle rc) {  void SurfaceImpl::FlushCachedState() {}  void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { -	unicodeMode = unicodeMode_; +	if (unicodeMode_) +		et = UTF8;  }  void SurfaceImpl::SetDBCSMode(int codePage) { -	dbcsMode = codePage == SC_CP_DBCS; +	if (codePage == SC_CP_DBCS) +		et = dbcs;  }  Surface *Surface::Allocate() { | 
