summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Wong <gtw@gnu.org>2009-09-03 09:54:20 -0600
committerGary Wong <gtw@gnu.org>2009-09-03 09:54:20 -0600
commit34f65098ed115aaed51299fbb3cec631587743d0 (patch)
tree5d37dde9ddc4172c96efd20ade77c45876263fb0
parent5508fa4a9733b8f6e382b3b98d8de0481ebceaef (diff)
Clean up UTF-8 processing for core text, too.
-rw-r--r--ChangeLog5
-rw-r--r--decorate-core.c117
2 files changed, 47 insertions, 75 deletions
diff --git a/ChangeLog b/ChangeLog
index d5dd37f..93cb66c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-09-03 Gary Wong <gtw@gnu.org>
+
+ * decorate-core.c (core_text): Use utf8_next().
+ (core_window_size): Use utf8_length().
+
2009-09-02 Gary Wong <gtw@gnu.org>
* utf8.c (utf8_illegal, utf8_length, utf8_next)
diff --git a/decorate-core.c b/decorate-core.c
index c21325a..56ba206 100644
--- a/decorate-core.c
+++ b/decorate-core.c
@@ -34,6 +34,7 @@
#include "button.h"
#include "decorate-core.h"
#include "frame.h"
+#include "utf8.h"
#define FONT_SIZE 12
#define STRING2(x) #x
@@ -55,81 +56,44 @@ static xcb_void_cookie_t core_text( xcb_drawable_t drawable, int screen,
int i, len;
const unsigned char *p;
uint8_t *param, *out;
- uint32_t n;
-
- if( !text || !*text ) {
- xcb_void_cookie_t r = { 0 };
-
- return r;
- }
-
- n = gwm_screens[ screen ].pixels[ col ];
- xcb_change_gc( c, gcs[ screen ], XCB_GC_FOREGROUND, &n );
+ uint32_t g, n;
len = 0;
- p = (const unsigned char *) text;
- for(;;)
- if( !p[ 0 ] )
- /* End of string. */
- break;
- else if( !( p[ 0 ] & 0x80 ) ) {
- /* Legal single byte character. */
- len++;
- p++;
- } else if( *p >= 0xC2 && *p <= 0xDF &&
- p[ 1 ] >= 0x80 && p[ 1 ] <= 0xBF ) {
- /* Legal two byte character. */
- len++;
- p += 2;
- } else if( *p >= 0xE0 && *p <= 0xEF &&
- p[ 1 ] >= 0x80 && p[ 1 ] <= 0xBF &&
- p[ 2 ] >= 0x80 && p[ 2 ] <= 0xBF ) {
- /* Legal three byte character. */
- len++;
- p += 3;
- } else
- /* Illegal character, or a four byte character which lies outside
- the BMP and so won't be included in a core font. Either way,
- ignore this byte and continue. */
- p++;
-
- out = param = alloca( ( len + ( len >> 7 ) + 1 ) << 1 );
-
- for( p = (const unsigned char *) text, i = 0; i < len; i++, out += 2 ) {
- if( !( i & 0x7F ) ) {
- out[ 0 ] = len - i > 0x7F ? 0x80 : len - i; /* length */
- out[ 1 ] = 0; /* delta */
- out += 2;
- }
+ if( text ) {
+ p = (const unsigned char *) text;
+ while( ( g = utf8_next( &p ) ) )
+ if( g < 0x10000 )
+ len++;
+ }
- retry:
- assert( *p );
-
- if( !( p[ 0 ] & 0x80 ) ) {
- /* One byte character. */
- out[ 0 ] = 0;
- out[ 1 ] = *p++;
- } else if( *p >= 0xC2 && *p <= 0xDF &&
- p[ 1 ] >= 0x80 && p[ 1 ] <= 0xBF ) {
- /* Two byte character. */
- out[ 0 ] = ( p[ 0 ] >> 2 ) & 0x07;
- out[ 1 ] = ( ( p[ 0 ] & 3 ) << 6 ) | ( p[ 1 ] & 0x3F );
- p += 2;
- } else if( *p >= 0xE0 && *p <= 0xEF &&
- p[ 1 ] >= 0x80 && p[ 1 ] <= 0xBF &&
- p[ 2 ] >= 0x80 && p[ 2 ] <= 0xBF ) {
- /* Three byte character. */
- out[ 0 ] = ( ( p[ 0 ] & 0x0F ) << 4 ) | ( ( p[ 1 ] & 0x3C ) >> 2 );
- out[ 1 ] = ( ( p[ 1 ] & 3 ) << 6 ) | ( p[ 2 ] & 0x3F );
- p += 3;
- } else {
- p++;
- goto retry;
+ if( len ) {
+ n = gwm_screens[ screen ].pixels[ col ];
+ xcb_change_gc( c, gcs[ screen ], XCB_GC_FOREGROUND, &n );
+
+ out = param = alloca( ( len + ( len >> 7 ) + 1 ) << 1 );
+
+ for( p = (const unsigned char *) text, i = 0; i < len;
+ i++, out += 2 ) {
+ if( !( i & 0x7F ) ) {
+ out[ 0 ] = len - i > 0x7F ? 0x80 : len - i; /* length */
+ out[ 1 ] = 0; /* delta */
+ out += 2;
+ }
+
+ while( assert( *p ), ( g = utf8_next( &p ) ) > 0xFFFF )
+ ;
+
+ out[ 0 ] = g >> 8;
+ out[ 1 ] = g & 0xFF;
}
+
+ return xcb_poly_text_16( c, drawable, gcs[ screen ], x, y, out - param,
+ param );
+ } else {
+ xcb_void_cookie_t r = { 0 };
+
+ return r;
}
-
- return xcb_poly_text_16( c, drawable, gcs[ screen ], x, y,
- out - param, param );
}
extern void core_update_window( struct gwm_window *window ) {
@@ -184,11 +148,14 @@ extern void core_window_size( struct gwm_window *window, int *width,
switch( window->type ) {
case WINDOW_MENUITEM:
- /* This is nasty. But then again, core fonts are fairly nasty...
- this code is only here in case RENDER isn't available, so
- hopefully it will never be used. */
- *width = FONT_SIZE << 4;
- *height = FONT_SIZE + 4;
+ if( window->u.menuitem.label ) {
+ *width = FONT_SIZE * utf8_length( (const unsigned char *)
+ window->u.menuitem.label );
+ *height = FONT_SIZE + 4;
+ } else {
+ *width = 8;
+ *height = 4;
+ }
return;
case WINDOW_FEEDBACK: