summaryrefslogtreecommitdiff
path: root/src/fl_font_x.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/fl_font_x.cxx')
-rw-r--r--src/fl_font_x.cxx189
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);
}
//