diff options
Diffstat (limited to 'src/fl_font_x.cxx')
| -rw-r--r-- | src/fl_font_x.cxx | 189 |
1 files changed, 121 insertions, 68 deletions
diff --git a/src/fl_font_x.cxx b/src/fl_font_x.cxx index b6beab8b4..ea044aed0 100644 --- a/src/fl_font_x.cxx +++ b/src/fl_font_x.cxx @@ -26,13 +26,14 @@ // Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name) { - font = XLoadQueryFont(fl_display, name); + font = XCreateUtf8FontStruct(fl_display, name); if (!font) { Fl::warning("bad font: %s", name); - font = XLoadQueryFont(fl_display, "fixed"); // if fixed fails we crash + font = XCreateUtf8FontStruct(fl_display, "fixed"); } # if HAVE_GL listbase = 0; + for (int u = 0; u < 64; u++) glok[u] = 0; # endif } @@ -51,7 +52,7 @@ Fl_Font_Descriptor::~Fl_Font_Descriptor() { // } # endif if (this == fl_fontsize) fl_fontsize = 0; - XFreeFont(fl_display, font); + XFreeUtf8FontStruct(fl_display, font); } //////////////////////////////////////////////////////////////// @@ -112,39 +113,29 @@ int fl_correct_encoding(const char* name) { return (*c++ && !strcmp(c,fl_encoding)); } -// locate or create an Fl_Font_Descriptor for a given Fl_Fontdesc and size: -static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) { - Fl_Fontdesc* s = fl_fonts+fnum; - if (!s->name) s = fl_fonts; // use font 0 if still undefined - Fl_Font_Descriptor* f; - for (f = s->first; f; f = f->next) - if (f->minsize <= size && f->maxsize >= size) return f; - fl_open_display(); - if (!s->xlist) { - s->xlist = XListFonts(fl_display, s->name, 100, &(s->n)); - if (!s->xlist) { // use fixed if no matching font... - s->first = new Fl_Font_Descriptor("fixed"); - s->first->minsize = 0; - s->first->maxsize = 32767; - return s->first; - } - } +static char *find_best_font(const char *fname, int size) { + int cnt; + static char **list = NULL; +// locate or create an Fl_FontSize for a given Fl_Fontdesc and size: + if (list) XFreeFontNames(list); + list = XListFonts(fl_display, fname, 100, &cnt); + if (!list) return "fixed"; + // search for largest <= font size: - char* name = s->xlist[0]; int ptsize = 0; // best one found so far + char* name = list[0]; int ptsize = 0; // best one found so far int matchedlength = 32767; - char namebuffer[1024]; // holds scalable font name + char namebuffer[1024]; // holds scalable font name int found_encoding = 0; - int m = s->n; if (m<0) m = -m; + int m = cnt; if (m<0) m = -m; for (int n=0; n < m; n++) { - - char* thisname = s->xlist[n]; + char* thisname = list[n]; if (fl_correct_encoding(thisname)) { if (!found_encoding) ptsize = 0; // force it to choose this found_encoding = 1; } else { if (found_encoding) continue; } - char* c = fl_find_fontsize(thisname); + char* c = (char*)fl_find_fontsize(thisname); int thissize = c ? atoi(c) : MAXSIZE; int thislength = strlen(thisname); if (thissize == size && thislength < matchedlength) { @@ -165,37 +156,107 @@ static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) { thissize < ptsize && ptsize > size || // current font too big thissize > ptsize && thissize <= size // current too small ) { - name = thisname; ptsize = thissize; + name = thisname; + ptsize = thissize; matchedlength = thislength; } } - if (ptsize != size) { // see if we already found this unscalable font: - for (f = s->first; f; f = f->next) { - if (f->minsize <= ptsize && f->maxsize >= ptsize) { - if (f->minsize > size) f->minsize = size; - if (f->maxsize < size) f->maxsize = size; - return f; - } - } - } +// if (ptsize != size) { // see if we already found this unscalable font: +// for (f = s->first; f; f = f->next) { +// if (f->minsize <= ptsize && f->maxsize >= ptsize) { +// if (f->minsize > size) f->minsize = size; +// if (f->maxsize < size) f->maxsize = size; +// return f; +// } +// } +// } +// +// // okay, we definately have some name, make the font: +// f = new Fl_FontSize(name); +// if (ptsize < size) {f->minsize = ptsize; f->maxsize = size;} +// else {f->minsize = size; f->maxsize = ptsize;} +// f->next = s->first; +// s->first = f; +// return f; + + return name; +} + +static char *put_font_size(const char *n, int size) +{ + int i = 0; + char *buf; + const char *ptr; + char *f; + char *name; + int nbf = 1; + name = strdup(n); + while (name[i]) { + if (name[i] == ',') {nbf++; name[i] = '\0';} + i++; + } + + buf = (char*) malloc(nbf * 256); + buf[0] = '\0'; + ptr = name; + i = 0; + while (ptr && nbf > 0) { + f = find_best_font(ptr, size); + while (*f) { + buf[i] = *f; + f++; i++; + } + nbf--; + while (*ptr) ptr++; + if (nbf) { + ptr++; + buf[i] = ','; + i++; + } + while(isspace(*ptr)) ptr++; + } + buf[i] = '\0'; + free(name); + return buf; +} + + +char *fl_get_font_xfld(int fnum, int size) { + Fl_Fontdesc* s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // use font 0 if still undefined + fl_open_display(); + return put_font_size(s->name, size); +} + +// locate or create an Fl_FontSize for a given Fl_Fontdesc and size: +static Fl_FontSize* find(int fnum, int size) { + char *name; + Fl_Fontdesc* s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // use font 0 if still undefined + Fl_FontSize* f; + for (f = s->first; f; f = f->next) + if (f->minsize <= size && f->maxsize >= size) return f; + fl_open_display(); - // okay, we definately have some name, make the font: - f = new Fl_Font_Descriptor(name); - if (ptsize < size) {f->minsize = ptsize; f->maxsize = size;} - else {f->minsize = size; f->maxsize = ptsize;} + name = put_font_size(s->name, size); + f = new Fl_FontSize(name); + f->minsize = size; + f->maxsize = size; f->next = s->first; s->first = f; + free(name); return f; - } + //////////////////////////////////////////////////////////////// // Public interface: Fl_Font fl_font_ = 0; Fl_Fontsize fl_size_ = 0; -XFontStruct* fl_xfont = 0; +//XFontStruct* fl_xfont = 0; +XUtf8FontStruct* fl_xfont; void *fl_xftfont = 0; static GC font_gc; @@ -225,43 +286,35 @@ int fl_descent() { } double fl_width(const char* c, int n) { - if (!fl_xfont) return -1.0; - XCharStruct* p = fl_xfont->per_char; - if (!p) return n*fl_xfont->min_bounds.width; - int a = fl_xfont->min_char_or_byte2; - int b = fl_xfont->max_char_or_byte2 - a; - int w = 0; - while (n--) { - int x = *(uchar*)c++ - a; - if (x >= 0 && x <= b) w += p[x].width; - else w += fl_xfont->min_bounds.width; - } - return w; + if (fl_xfont) return (double) XUtf8TextWidth(fl_xfont, c, n); + else return -1; } -double fl_width(uchar c) { - if (!fl_xfont) return -1; - XCharStruct* p = fl_xfont->per_char; - if (p) { - int a = fl_xfont->min_char_or_byte2; - int b = fl_xfont->max_char_or_byte2 - a; - int x = c-a; - if (x >= 0 && x <= b) return p[x].width; - } - return fl_xfont->min_bounds.width; +double fl_width(unsigned int c) { + if (fl_xfont) return (double) XUtf8UcsWidth(fl_xfont, c); + else return -1; } -void fl_draw(const char* str, int n, int x, int y) { +void fl_draw(const char* c, int n, int x, int y) { if (font_gc != fl_gc) { if (!fl_xfont) fl_font(FL_HELVETICA, 14); font_gc = fl_gc; XSetFont(fl_display, fl_gc, fl_xfont->fid); } - XDrawString(fl_display, fl_window, fl_gc, x, y, str, n); +// XDrawString(fl_display, fl_window, fl_gc, x, y, c, n); + XUtf8DrawString(fl_display, fl_window, fl_xfont, fl_gc, x, y, c, n); } -void fl_draw(const char* str, int n, float x, float y) { - fl_draw(str, n, (int)x, (int)y); +//void fl_draw(const char* str, int n, float x, float y) { +// fl_draw(str, n, (int)x, (int)y); +//} + +void fl_rtl_draw(const char* c, int n, int x, int y) { + if (font_gc != fl_gc) { + if (!fl_xfont) fl_font(FL_HELVETICA, 12); + font_gc = fl_gc; + } + XUtf8DrawRtlString(fl_display, fl_window, fl_xfont, fl_gc, x, y, c, n); } // |
