diff options
Diffstat (limited to 'src/xutf8/utf8Wrap.c')
| -rw-r--r-- | src/xutf8/utf8Wrap.c | 298 |
1 files changed, 221 insertions, 77 deletions
diff --git a/src/xutf8/utf8Wrap.c b/src/xutf8/utf8Wrap.c index 67b3d8da0..66094b890 100644 --- a/src/xutf8/utf8Wrap.c +++ b/src/xutf8/utf8Wrap.c @@ -37,7 +37,7 @@ /* External auto generated functions : */ #include "ucs2fontmap.c" -/* +/* * extern int ucs2fontmap(char *s, unsigned int ucs, int enc); * extern int encoding_number(const char *enc); * extern const char *encoding_name(int num); @@ -63,15 +63,15 @@ Fl_XChar2b; /*********************************************************************/ /** extract a list of font from the base font name list **/ /*********************************************************************/ -static int +static int get_font_list( - const char *base_font_name_list, + const char *base_font_name_list, char ***flist) { const char *ptr; const char *p; int nb; int nb_name; - + ptr = base_font_name_list; p = NULL; nb = 0; @@ -103,28 +103,28 @@ get_font_list( free(*flist); *flist = (char**)NULL; } - return nb; + return nb; } /*********************************************************************/ /** get the font name used as encoding for "fontspecific" encoding **/ /** (mainly used for adobe-symbol and adobe-zapfdingbats) **/ /*********************************************************************/ -static int +static int font_spec_enc(char *font) { int ret; char *enc; char *end; enc = font; - while (*enc != '-') enc++; + while (*enc != '-') enc++; enc++; while (*enc != '-') enc++; enc++; end = enc; while (*end != '-') end++; *end = '\0'; - + ret = encoding_number(enc); *end = '-'; @@ -159,14 +159,14 @@ get_range(const char *enc, val = strtol(ptr1, NULL, 0); if (val < *min) *min = val; if (val > *max) *max = val; - } + } } /*********************************************************************/ /** get the internal encoding number of each fonts **/ /*********************************************************************/ static int * -get_encodings(char **font_name_list, +get_encodings(char **font_name_list, int *ranges, int nb_font) { @@ -183,7 +183,7 @@ get_encodings(char **font_name_list, font_encoding_list[i] = -1; ranges[i * 2] = 0; ranges[i * 2 + 1] = 0xFFFF; - + if (ptr && strstr(ptr, "fontspecific")) { font_encoding_list[i] = font_spec_enc(ptr); ptr = NULL; @@ -194,13 +194,13 @@ get_encodings(char **font_name_list, if (ec == 13) { font_encoding_list[i] = encoding_number(ptr + 1); if (font_encoding_list[i] == 0) { - get_range(ptr + 1, + get_range(ptr + 1, ranges + i * 2, ranges + i * 2 + 1); } break; } - } + } ptr++; } if (font_encoding_list[i] < 0) font_encoding_list[i] = 1; @@ -234,8 +234,8 @@ find_best_font(Display *dpy, /*********************************************************************/ /** load all fonts **/ /*********************************************************************/ -static void -load_fonts(Display *dpy, +static void +load_fonts(Display *dpy, XUtf8FontStruct *font_set) { int i; @@ -246,8 +246,8 @@ load_fonts(Display *dpy, font_set->fonts = (XFontStruct**) malloc(sizeof(XFontStruct*) * font_set->nb_font); - - font_set->ranges = (int*) malloc(sizeof(int) * + + font_set->ranges = (int*) malloc(sizeof(int) * font_set->nb_font * 2); font_set->descent = 0; @@ -257,7 +257,7 @@ load_fonts(Display *dpy, while (i < font_set->nb_font) { XFontStruct *fnt; - fnt = font_set->fonts[i] = + fnt = font_set->fonts[i] = find_best_font(dpy, &(font_set->font_name_list[i])); if (fnt) { font_set->fid = fnt->fid; @@ -274,8 +274,8 @@ load_fonts(Display *dpy, i++; } - font_set->encodings = - get_encodings(font_set->font_name_list, + font_set->encodings = + get_encodings(font_set->font_name_list, font_set->ranges, font_set->nb_font); /* unload fonts with same encoding */ @@ -297,7 +297,7 @@ load_fonts(Display *dpy, } } } - } + } } /*********************************************************************/ @@ -309,14 +309,14 @@ XCreateUtf8FontStruct(Display *dpy, const char *base_font_name_list) { XUtf8FontStruct *font_set; - + font_set = (XUtf8FontStruct*)malloc(sizeof(XUtf8FontStruct)); if (!font_set) { return NULL; } - font_set->nb_font = get_font_list(base_font_name_list, + font_set->nb_font = get_font_list(base_font_name_list, &font_set->font_name_list); if (font_set->nb_font < 1) { @@ -333,13 +333,13 @@ XCreateUtf8FontStruct(Display *dpy, /*****************************************************************************/ /** draw a Right To Left UTF-8 string using multiple fonts as needed. **/ /*****************************************************************************/ -void -XUtf8DrawRtlString(Display *display, +void +XUtf8DrawRtlString(Display *display, Drawable d, - XUtf8FontStruct *font_set, - GC gc, - int x, - int y, + XUtf8FontStruct *font_set, + GC gc, + int x, + int y, const char *string, int num_bytes) { @@ -361,14 +361,14 @@ XUtf8DrawRtlString(Display *display, /* there is no font in the font_set :-( */ return; } - + ranges = font_set->ranges; fonts = font_set->fonts; encodings = font_set->encodings; i = 0; fnum = 0; ptr = buf + 128; - + while(fnum < nb_font && !fonts[fnum]) fnum++; if (fnum >= nb_font) { /* there is no valid font for the X server */ @@ -392,21 +392,21 @@ XUtf8DrawRtlString(Display *display, ptr = buf + 128; } - ulen = XFastConvertUtf8ToUcs((unsigned char*)string, num_bytes, &ucs); + ulen = XFastConvertUtf8ToUcs((unsigned char*)string, num_bytes, &ucs); - if (ulen < 1) ulen = 1; + if (ulen < 1) ulen = 1; no_spc = XUtf8IsNonSpacing(ucs); - if (no_spc) ucs = no_spc; + if (no_spc) ucs = no_spc; - /* - * find the first encoding which can be used to - * draw the glyph + /* + * find the first encoding which can be used to + * draw the glyph */ fnum = first; while (fnum < nb_font) { if (fonts[fnum] && ucs2fontmap(glyph, ucs, encodings[fnum]) >= 0) { - if (encodings[fnum] != 0 || + if (encodings[fnum] != 0 || (ucs >= ranges[fnum * 2] && ucs <= ranges[fnum * 2 + 1])) { break; } @@ -454,13 +454,13 @@ XUtf8DrawRtlString(Display *display, /*****************************************************************************/ /** draw an UTF-8 string using multiple fonts as needed. **/ /*****************************************************************************/ -void -XUtf8DrawString(Display *display, +void +XUtf8DrawString(Display *display, Drawable d, - XUtf8FontStruct *font_set, - GC gc, - int x, - int y, + XUtf8FontStruct *font_set, + GC gc, + int x, + int y, const char *string, int num_bytes) { @@ -472,7 +472,7 @@ XUtf8DrawString(Display *display, int first; /* first valid font index */ int last_fnum; /* font index of the previous char */ int nb_font; /* quantity of fonts in the font array */ - char glyph[2]; /* byte1 and byte1 value of the UTF-8 char */ + char glyph[2]; /* byte0 and byte1 value of the UTF-8 char */ int *ranges; /* sub range of iso10646 */ nb_font = font_set->nb_font; @@ -486,7 +486,7 @@ XUtf8DrawString(Display *display, encodings = font_set->encodings; i = 0; fnum = 0; - + while(fnum < nb_font && !fonts[fnum]) fnum++; if (fnum >= nb_font) { /* there is no valid font for the X server */ @@ -509,21 +509,21 @@ XUtf8DrawString(Display *display, i = 0; } - ulen = XFastConvertUtf8ToUcs((unsigned char*)string, num_bytes, &ucs); + ulen = XFastConvertUtf8ToUcs((unsigned char*)string, num_bytes, &ucs); - if (ulen < 1) ulen = 1; + if (ulen < 1) ulen = 1; no_spc = XUtf8IsNonSpacing(ucs); - if (no_spc) ucs = no_spc; + if (no_spc) ucs = no_spc; - /* - * find the first encoding which can be used to - * draw the glyph + /* + * find the first encoding which can be used to + * draw the glyph */ fnum = first; while (fnum < nb_font) { if (fonts[fnum] && ucs2fontmap(glyph, ucs, encodings[fnum]) >= 0) { - if (encodings[fnum] != 0 || + if (encodings[fnum] != 0 || (ucs >= ranges[fnum * 2] && ucs <= ranges[fnum * 2 + 1])) { break; @@ -564,12 +564,156 @@ XUtf8DrawString(Display *display, } +/*****************************************************************************/ +/** Measure the inked extents of a UTF-8 string using multiple fonts as **/ +/** needed. Tries to mirror the behaviour of the draw function **/ +/** XUtf8DrawString as closely as possible. **/ +/*****************************************************************************/ +void +XUtf8_measure_extents( + Display *display, + Drawable d, + XUtf8FontStruct *font_set, + GC gc, + int *xx, /* x-offset from origin */ + int *yy, /* y-offset from origin */ + int *ww, /* overall inked width */ + int *hh, /* maximum inked height */ + const char *string, /* text to measure */ + int num_bytes) { + int *encodings; /* encodings array */ + XFontStruct **fonts; /* fonts array */ + Fl_XChar2b buf[128]; /* drawing buffer */ + int fnum; /* index of the current font in the fonts array*/ + int i; /* current byte in the XChar2b buffer */ + int first; /* first valid font index */ + int last_fnum; /* font index of the previous char */ + int nb_font; /* quantity of fonts in the font array */ + char glyph[2]; /* byte0 and byte1 value of the UTF-8 char */ + int *ranges; /* sub range of iso10646 */ + + int wd = 0; /* accumulates the width */ + int ht = 0; /* find max height in text */ + int yt = 0x7FFFFFFF; /* delta-y found */ + int res, hs; + + XCharStruct sizes; + int dir_ret = 0; + int fnt_asc = 0; + int fnt_dsc = 0; + + nb_font = font_set->nb_font; + + if (nb_font < 1) { + /* there is no font in the font_set :-( */ + return; + } + ranges = font_set->ranges; + fonts = font_set->fonts; + encodings = font_set->encodings; + i = 0; + fnum = 0; + + while(fnum < nb_font && !fonts[fnum]) fnum++; + if (fnum >= nb_font) { + /* there is no valid font for the X server */ + return; + } + + first = fnum; + last_fnum = fnum; + + while (num_bytes > 0) { + int ulen; /* byte length of the UTF-8 char */ + unsigned int ucs; /* Unicode value of the UTF-8 char */ + unsigned int no_spc; /* Spacing char equivalent of a non-spacing char */ + + if (i > 120) { + /*** draw the buffer **/ + XSetFont(display, gc, fonts[fnum]->fid); + res = XTextExtents16(fonts[fnum], buf, i, &dir_ret, &fnt_asc, &fnt_dsc, &sizes); + /* recover the dimensions - should verify that res == 0 first! */ + wd += sizes.width; /* accumulate the width */ + hs = sizes.ascent + sizes.descent; /* total height */ + if(hs > ht) ht = hs; /* new height exceeds previous height */ + if(yt > (-sizes.ascent)) yt = -sizes.ascent; /* delta y offset */ + i = 0; + } + + ulen = XFastConvertUtf8ToUcs((unsigned char*)string, num_bytes, &ucs); + + if (ulen < 1) ulen = 1; + + no_spc = XUtf8IsNonSpacing(ucs); + if (no_spc) ucs = no_spc; + + /* + * find the first encoding which can be used to + * draw the glyph + */ + fnum = first; + while (fnum < nb_font) { + if (fonts[fnum] && ucs2fontmap(glyph, ucs, encodings[fnum]) >= 0) { + if (encodings[fnum] != 0 || + (ucs >= ranges[fnum * 2] && + ucs <= ranges[fnum * 2 + 1])) { + break; + } + } + fnum++; + } + if (fnum == nb_font) { + /* the char is not valid in all encodings -> + * draw it using the first font :-( + */ + fnum = first; + ucs2fontmap(glyph, '?', encodings[fnum]); + } + + if (last_fnum != fnum || no_spc) { + XSetFont(display, gc, fonts[last_fnum]->fid); + res = XTextExtents16(fonts[last_fnum], buf, i, &dir_ret, &fnt_asc, &fnt_dsc, &sizes); + /* recover the dimensions - should verify that res == 0 first! */ + wd += sizes.width; /* accumulate the width */ + hs = sizes.ascent + sizes.descent; /* total height */ + if(hs > ht) ht = hs; /* new height exceeds previous height */ + if(yt > (-sizes.ascent)) yt = -sizes.ascent; /* delta y offset */ + i = 0; + (*buf).byte1 = glyph[0]; + (*buf).byte2 = glyph[1]; + if (no_spc) { + wd -= XTextWidth16(fonts[fnum], buf, 1); + } + } else { + (*(buf + i)).byte1 = glyph[0]; + (*(buf + i)).byte2 = glyph[1]; + } + last_fnum = fnum; + i++; + string += ulen; + num_bytes -= ulen; + } + + XSetFont(display, gc, fonts[fnum]->fid); + res = XTextExtents16(fonts[fnum], buf, i, &dir_ret, &fnt_asc, &fnt_dsc, &sizes); + /* recover the dimensions - should verify that res == 0 first! */ + wd += sizes.width; /* accumulate the width */ + hs = sizes.ascent + sizes.descent; /* total height */ + if(hs > ht) ht = hs; /* new height exceeds previous height */ + if(yt > (-sizes.ascent)) yt = -sizes.ascent; /* delta y offset */ + /* return values */ + *ww = wd; + *hh = ht; + *xx = 0; + *yy = yt; +} + /*****************************************************************************/ /** returns the pixel width of a UTF-8 string **/ /*****************************************************************************/ -int -XUtf8TextWidth(XUtf8FontStruct *font_set, +int +XUtf8TextWidth(XUtf8FontStruct *font_set, const char *string, int num_bytes) { @@ -598,7 +742,7 @@ XUtf8TextWidth(XUtf8FontStruct *font_set, encodings = font_set->encodings; i = 0; fnum = 0; - + while(fnum < nb_font && !fonts[fnum]) fnum++; if (fnum >= nb_font) { /* there is no valid font for the X server */ @@ -619,23 +763,23 @@ XUtf8TextWidth(XUtf8FontStruct *font_set, i = 0; } - ulen = XFastConvertUtf8ToUcs((unsigned char*)string, num_bytes, &ucs); + ulen = XFastConvertUtf8ToUcs((unsigned char*)string, num_bytes, &ucs); - if (ulen < 1) ulen = 1; + if (ulen < 1) ulen = 1; no_spc = XUtf8IsNonSpacing(ucs); if (no_spc) { ucs = no_spc; } - /* - * find the first encoding which can be used to - * draw the glyph + /* + * find the first encoding which can be used to + * draw the glyph */ fnum = first; while (fnum < nb_font) { if (fonts[fnum] && ucs2fontmap(glyph, ucs, encodings[fnum]) >= 0) { - if (encodings[fnum] != 0 || + if (encodings[fnum] != 0 || (ucs >= ranges[fnum * 2] && ucs <= ranges[fnum * 2 + 1])) { break; @@ -718,14 +862,14 @@ XGetUtf8FontAndGlyph(XUtf8FontStruct *font_set, first = fnum; last_fnum = fnum; - /* - * find the first encoding which can be used to - * draw the glyph + /* + * find the first encoding which can be used to + * draw the glyph */ fnum = first; while (fnum < nb_font) { if (fonts[fnum] && ucs2fontmap(glyph, ucs, encodings[fnum]) >= 0) { - if (encodings[fnum] != 0 || + if (encodings[fnum] != 0 || (ucs >= ranges[fnum * 2] && ucs <= ranges[fnum * 2 + 1])) { break; @@ -778,7 +922,7 @@ XUtf8UcsWidth(XUtf8FontStruct *font_set, encodings = font_set->encodings; i = 0; fnum = 0; - + while(fnum < nb_font && !fonts[fnum]) fnum++; if (fnum >= nb_font) { /* there is no valid font for the X server */ @@ -790,13 +934,13 @@ XUtf8UcsWidth(XUtf8FontStruct *font_set, ucs = XUtf8IsNonSpacing(ucs); - /* - * find the first encoding which can be used to - * draw the glyph + /* + * find the first encoding which can be used to + * draw the glyph */ fnum = first; while (fnum < nb_font) { - if (fonts[fnum] && + if (fonts[fnum] && ucs2fontmap(glyph, ucs, encodings[fnum]) >= 0) { if (encodings[fnum] != 0 || (ucs >= ranges[fnum * 2] && ucs <= ranges[fnum * 2 + 1])) { @@ -843,10 +987,10 @@ XUtf8DrawImageString(Display *display, XGCValues xgcv; w = XUtf8TextWidth(font_set, string, num_bytes); - - XGetGCValues(display, gc, + + XGetGCValues(display, gc, GCFunction|GCForeground|GCBackground|GCFillStyle, &xgcv); - + function = xgcv.function; fill_style = xgcv.fill_style; foreground = xgcv.foreground; @@ -860,7 +1004,7 @@ XUtf8DrawImageString(Display *display, XChangeGC(display, gc, GCFunction|GCForeground|GCBackground|GCFillStyle, &xgcv); - XFillRectangle(display, d, gc, x, y - font_set->ascent, + XFillRectangle(display, d, gc, x, y - font_set->ascent, (unsigned)w, (unsigned)(font_set->ascent + font_set->descent)); xgcv.function = function; @@ -877,8 +1021,8 @@ XUtf8DrawImageString(Display *display, /*****************************************************************************/ /** free the XFontSet and others things created by XCreateUtf8FontSet **/ /*****************************************************************************/ -void -XFreeUtf8FontStruct(Display *dpy, +void +XFreeUtf8FontStruct(Display *dpy, XUtf8FontStruct *font_set) { int i; |
