summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2016-01-26 20:17:47 +0000
committerMatthias Melcher <fltk@matthiasm.com>2016-01-26 20:17:47 +0000
commit5892993cbcf77e322f51475820d19f8307375df7 (patch)
tree314dd6627e5a44a6027febf8b2f9ea53fc8fdfb9 /src
parent12e85b882aedccfae4836dd8c72bd546e1be408e (diff)
Preliminary commit of porting Xlib drivers to the new naming scheme
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11053 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver.h (renamed from src/cfg_gfx/xlib.H)2
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx (renamed from src/cfg_gfx/xlib_arci.cxx)0
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx (renamed from src/cfg_gfx/xlib_color.cxx)0
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx (renamed from src/fl_set_fonts_x.cxx)335
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx (renamed from src/fl_font_xft.cxx)384
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx (renamed from src/cfg_gfx/xlib_line_style.cxx)2
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx (renamed from src/cfg_gfx/xlib_rect.cxx)2
-rw-r--r--src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx (renamed from src/cfg_gfx/xlib_vertex.cxx)2
-rw-r--r--src/fl_arci.cxx2
-rw-r--r--src/fl_color.cxx2
-rw-r--r--src/fl_font.cxx3
-rw-r--r--src/fl_font_x.cxx335
-rw-r--r--src/fl_line_style.cxx2
-rw-r--r--src/fl_rect.cxx27
-rw-r--r--src/fl_set_fonts.cxx2
-rw-r--r--src/fl_set_fonts_xft.cxx384
-rw-r--r--src/fl_vertex.cxx2
17 files changed, 731 insertions, 755 deletions
diff --git a/src/cfg_gfx/xlib.H b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.h
index 4ce00b426..255e5f16b 100644
--- a/src/cfg_gfx/xlib.H
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.h
@@ -18,7 +18,7 @@
//
/**
- \file xlib.H
+ \file Fl_Xlib_Graphics_Driver.h
\brief Definition of X11 Xlib graphics driver.
*/
diff --git a/src/cfg_gfx/xlib_arci.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx
index 118e683a1..118e683a1 100644
--- a/src/cfg_gfx/xlib_arci.cxx
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx
diff --git a/src/cfg_gfx/xlib_color.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx
index e7e9d0cf7..e7e9d0cf7 100644
--- a/src/cfg_gfx/xlib_color.cxx
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx
diff --git a/src/fl_set_fonts_x.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx
index 845f15a87..cec910f30 100644
--- a/src/fl_set_fonts_x.cxx
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx
@@ -339,3 +339,338 @@ int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
//
// End of "$Id$".
//
+//
+// "$Id$"
+//
+// Standard X11 font selection code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2011 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+#ifndef FL_DOXYGEN
+
+Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name) {
+ font = XCreateUtf8FontStruct(fl_display, name);
+ if (!font) {
+ Fl::warning("bad font: %s", name);
+ font = XCreateUtf8FontStruct(fl_display, "fixed");
+ }
+# if HAVE_GL
+ listbase = 0;
+ for (int u = 0; u < 64; u++) glok[u] = 0;
+# endif
+}
+
+Fl_XFont_On_Demand fl_xfont;
+
+Fl_Font_Descriptor::~Fl_Font_Descriptor() {
+# if HAVE_GL
+// Delete list created by gl_draw(). This is not done by this code
+// as it will link in GL unnecessarily. There should be some kind
+// of "free" routine pointer, or a subclass?
+// if (listbase) {
+// int base = font->min_char_or_byte2;
+// int size = font->max_char_or_byte2-base+1;
+// int base = 0; int size = 256;
+// glDeleteLists(listbase+base,size);
+// }
+# endif
+ if (this == fl_graphics_driver->font_descriptor()) {
+ fl_graphics_driver->font_descriptor(NULL);
+ fl_xfont = 0;
+ }
+ XFreeUtf8FontStruct(fl_display, font);
+}
+
+////////////////////////////////////////////////////////////////
+
+// WARNING: if you add to this table, you must redefine FL_FREE_FONT
+// in Enumerations.H & recompile!!
+static Fl_Fontdesc built_in_table[] = {
+{"-*-helvetica-medium-r-normal--*"},
+{"-*-helvetica-bold-r-normal--*"},
+{"-*-helvetica-medium-o-normal--*"},
+{"-*-helvetica-bold-o-normal--*"},
+{"-*-courier-medium-r-normal--*"},
+{"-*-courier-bold-r-normal--*"},
+{"-*-courier-medium-o-normal--*"},
+{"-*-courier-bold-o-normal--*"},
+{"-*-times-medium-r-normal--*"},
+{"-*-times-bold-r-normal--*"},
+{"-*-times-medium-i-normal--*"},
+{"-*-times-bold-i-normal--*"},
+{"-*-symbol-*"},
+{"-*-lucidatypewriter-medium-r-normal-sans-*"},
+{"-*-lucidatypewriter-bold-r-normal-sans-*"},
+{"-*-*zapf dingbats-*"}
+};
+
+Fl_Fontdesc* fl_fonts = built_in_table;
+
+#define MAXSIZE 32767
+
+// return dash number N, or pointer to ending null if none:
+const char* fl_font_word(const char* p, int n) {
+ while (*p) {if (*p=='-') {if (!--n) break;} p++;}
+ return p;
+}
+
+// return a pointer to a number we think is "point size":
+char* fl_find_fontsize(char* name) {
+ char* c = name;
+ // for standard x font names, try after 7th dash:
+ if (*c == '-') {
+ c = (char*)fl_font_word(c,7);
+ if (*c++ && isdigit(*c)) return c;
+ return 0; // malformed x font name?
+ }
+ char* r = 0;
+ // find last set of digits:
+ for (c++;* c; c++)
+ if (isdigit(*c) && !isdigit(*(c-1))) r = c;
+ return r;
+}
+
+//const char* fl_encoding = "iso8859-1";
+const char* fl_encoding = "iso10646-1";
+
+// return true if this matches fl_encoding:
+int fl_correct_encoding(const char* name) {
+ if (*name != '-') return 0;
+ const char* c = fl_font_word(name,13);
+ return (*c++ && !strcmp(c,fl_encoding));
+}
+
+static const char *find_best_font(const char *fname, int size) {
+ int cnt;
+ static char **list = NULL;
+// locate or create an Fl_Font_Descriptor 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 = list[0]; int ptsize = 0; // best one found so far
+ int matchedlength = 32767;
+ char namebuffer[1024]; // holds scalable font name
+ int found_encoding = 0;
+ int m = cnt; if (m<0) m = -m;
+ for (int n=0; n < m; 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 = (char*)fl_find_fontsize(thisname);
+ int thissize = c ? atoi(c) : MAXSIZE;
+ int thislength = strlen(thisname);
+ if (thissize == size && thislength < matchedlength) {
+ // exact match, use it:
+ name = thisname;
+ ptsize = size;
+ matchedlength = thislength;
+ } else if (!thissize && ptsize!=size) {
+ // whoa! A scalable font! Use unless exact match found:
+ int l = c-thisname;
+ memcpy(namebuffer,thisname,l);
+ l += sprintf(namebuffer+l,"%d",size);
+ while (*c == '0') c++;
+ strcpy(namebuffer+l,c);
+ name = namebuffer;
+ ptsize = size;
+ } else if (!ptsize || // no fonts yet
+ (thissize < ptsize && ptsize > size) || // current font too big
+ (thissize > ptsize && thissize <= size) // current too small
+ ) {
+ 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;
+// }
+// }
+// }
+//
+// // 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;}
+// 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;
+ const 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_Font_Descriptor for a given Fl_Fontdesc and size:
+static Fl_Font_Descriptor* 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_Font_Descriptor* f;
+ for (f = s->first; f; f = f->next)
+ if (f->size == size) return f;
+ fl_open_display();
+
+ name = put_font_size(s->name, size);
+ f = new Fl_Font_Descriptor(name);
+ f->size = size;
+ f->next = s->first;
+ s->first = f;
+ free(name);
+ return f;
+}
+
+
+////////////////////////////////////////////////////////////////
+// Public interface:
+
+void *fl_xftfont = 0;
+static GC font_gc;
+
+XFontStruct* Fl_XFont_On_Demand::value() {
+ return ptr;
+}
+
+void Fl_Xlib_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) {
+ if (fnum==-1) {
+ Fl_Graphics_Driver::font(0, 0);
+ return;
+ }
+ if (fnum == Fl_Graphics_Driver::font() && size == Fl_Graphics_Driver::size()) return;
+ Fl_Graphics_Driver::font(fnum, size);
+ Fl_Font_Descriptor* f = find(fnum, size);
+ if (f != this->font_descriptor()) {
+ this->font_descriptor(f);
+ fl_xfont = f->font->fonts[0];
+ font_gc = 0;
+ }
+}
+
+int Fl_Xlib_Graphics_Driver::height() {
+ if (font_descriptor()) return font_descriptor()->font->ascent + font_descriptor()->font->descent;
+ else return -1;
+}
+
+int Fl_Xlib_Graphics_Driver::descent() {
+ if (font_descriptor()) return font_descriptor()->font->descent;
+ else return -1;
+}
+
+double Fl_Xlib_Graphics_Driver::width(const char* c, int n) {
+ if (font_descriptor()) return (double) XUtf8TextWidth(font_descriptor()->font, c, n);
+ else return -1;
+}
+
+double Fl_Xlib_Graphics_Driver::width(unsigned int c) {
+ if (font_descriptor()) return (double) XUtf8UcsWidth(font_descriptor()->font, c);
+ else return -1;
+}
+
+void Fl_Xlib_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy, int &W, int &H) {
+ if (font_gc != fl_gc) {
+ if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE);
+ font_gc = fl_gc;
+ XSetFont(fl_display, fl_gc, font_descriptor()->font->fid);
+ }
+ int xx, yy, ww, hh;
+ xx = yy = ww = hh = 0;
+ if (fl_gc) XUtf8_measure_extents(fl_display, fl_window, font_descriptor()->font, fl_gc, &xx, &yy, &ww, &hh, c, n);
+
+ W = ww; H = hh; dx = xx; dy = yy;
+// This is the safe but mostly wrong thing we used to do...
+// W = 0; H = 0;
+// fl_measure(c, W, H, 0);
+// dx = 0;
+// dy = fl_descent() - H;
+}
+
+void Fl_Xlib_Graphics_Driver::draw(const char* c, int n, int x, int y) {
+ if (font_gc != fl_gc) {
+ if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE);
+ font_gc = fl_gc;
+ XSetFont(fl_display, fl_gc, font_descriptor()->font->fid);
+ }
+ if (fl_gc) XUtf8DrawString(fl_display, fl_window, font_descriptor()->font, fl_gc, x, y, c, n);
+}
+
+void Fl_Xlib_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) {
+ fprintf(stderr,"ROTATING TEXT NOT IMPLEMENTED\n");
+ this->draw(str, n, (int)x, (int)y);
+}
+
+void Fl_Xlib_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) {
+ if (font_gc != fl_gc) {
+ if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE);
+ font_gc = fl_gc;
+ }
+ if (fl_gc) XUtf8DrawRtlString(fl_display, fl_window, font_descriptor()->font, fl_gc, x, y, c, n);
+}
+#endif // FL_DOXYGEN
+//
+// End of "$Id$".
+//
diff --git a/src/fl_font_xft.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
index 67921699a..91ee460ce 100644
--- a/src/fl_font_xft.cxx
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
@@ -1,6 +1,390 @@
//
// "$Id$"
//
+// More font utilities for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2011 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+#include <X11/Xft/Xft.h>
+
+// This function fills in the fltk font table with all the fonts that
+// are found on the X server. It tries to place the fonts into families
+// and to sort them so the first 4 in a family are normal, bold, italic,
+// and bold italic.
+
+// Bug: older versions calculated the value for *ap as a side effect of
+// making the name, and then forgot about it. To avoid having to change
+// the header files I decided to store this value in the last character
+// of the font name array.
+#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1
+
+// turn a stored font name in "fltk format" into a pretty name:
+const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
+ Fl_Fontdesc *f = fl_fonts + fnum;
+ if (!f->fontname[0]) {
+ const char* p = f->name;
+ int type;
+ switch (p[0]) {
+ case 'B': type = FL_BOLD; break;
+ case 'I': type = FL_ITALIC; break;
+ case 'P': type = FL_BOLD | FL_ITALIC; break;
+ default: type = 0; break;
+ }
+
+ // NOTE: This can cause duplications in fonts that already have Bold or Italic in
+ // their "name". Maybe we need to find a cleverer way?
+ strlcpy(f->fontname, p+1, ENDOFBUFFER);
+ if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER);
+ if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER);
+ f->fontname[ENDOFBUFFER] = (char)type;
+ }
+ if (ap) *ap = f->fontname[ENDOFBUFFER];
+ return f->fontname;
+}
+
+///////////////////////////////////////////////////////////
+#define LOCAL_RAW_NAME_MAX 256
+
+extern "C" {
+// sort returned fontconfig font names
+static int name_sort(const void *aa, const void *bb) {
+ // What should we do here? Just do a string compare for now...
+ // NOTE: This yeilds some oddities - in particular a Blah Bold font will be
+ // listed before Blah...
+ // Also - the fontconfig listing returns some faces that are effectively duplicates
+ // as far as fltk is concerned, e.g. where there are ko or ja variants that we
+ // can't distinguish (since we are not yet fully UTF-*) - should we strip them here?
+ return fl_ascii_strcasecmp(*(char**)aa, *(char**)bb);
+} // end of name_sort
+} // end of extern C section
+
+
+// Read the "pretty" name we have derived from fontconfig then convert
+// it into the format fltk uses internally for Xft names...
+// This is just a mess - I should have tokenised the strings and gone from there,
+// but I really thought this would be easier!
+static void make_raw_name(char *raw, char *pretty)
+{
+ // Input name will be "Some Name:style = Bold Italic" or whatever
+ // The plan is this:
+ // - the first char in the "raw" name becomes either I, B, P or " " for
+ // italic, bold, bold italic or normal - this seems to be the fltk way...
+
+ char *style = strchr(pretty, ':');
+
+ if (style)
+ {
+ *style = 0; // Terminate "name" string
+ style ++; // point to start of style section
+ }
+
+ // It is still possible that the "pretty" name has multiple comma separated entries
+ // I've seen this often in CJK fonts, for example... Keep only the first one... This
+ // is not ideal, the CJK fonts often have the name in utf8 in several languages. What
+ // we ought to do is use fontconfig to query the available languages and pick one... But which?
+#if 0 // loop to keep the LAST name entry...
+ char *nm1 = pretty;
+ char *nm2 = strchr(nm1, ',');
+ while(nm2) {
+ nm1 = nm2 + 1;
+ nm2 = strchr(nm1, ',');
+ }
+ raw[0] = ' '; raw[1] = 0; // Default start of "raw name" text
+ strncat(raw, nm1, LOCAL_RAW_NAME_MAX-1); // only copy MAX-1 chars, we have already set cell 0
+ // Ensure raw is terminated, just in case the given name is infeasibly long...
+ raw[LOCAL_RAW_NAME_MAX-1] = 0;
+#else // keep the first remaining name entry
+ char *nm2 = strchr(pretty, ',');
+ if(nm2) *nm2 = 0; // terminate name after first entry
+ raw[0] = ' '; raw[1] = 0; // Default start of "raw name" text
+ strncat(raw, pretty, LOCAL_RAW_NAME_MAX-1); // only copy MAX-1 chars, we have already set cell 0
+ // Ensure raw is terminated, just in case the given name is infeasibly long...
+ raw[LOCAL_RAW_NAME_MAX-1] = 0;
+#endif
+ // At this point, the name is "marked" as regular...
+ if (style)
+ {
+#define PLAIN 0
+#define BOLD 1
+#define ITALIC 2
+#define BITALIC (BOLD | ITALIC)
+
+ int mods = PLAIN;
+ char *last = style + strlen(style) - 2;
+
+ // Now try and parse the style string - look for the "=" sign
+ style = strchr(style, '=');
+ while ((style) && (style < last))
+ {
+ int type;
+ while ((*style == '=') || (*style == ' ') || (*style == '\t') || (*style == ','))
+ {
+ style++; // Start of Style string
+ if ((style >= last) || (*style == 0)) continue;
+ }
+ type = toupper(style[0]);
+ switch (type)
+ {
+ // Things we might see: Regular Normal Bold Italic Oblique (??what??) Medium
+ // Roman Light Demi Sans SemiCondensed SuperBold Book... etc...
+ // Things we actually care about: Bold Italic Oblique SuperBold - Others???
+ case 'I':
+ if (strncasecmp(style, "Italic", 6) == 0)
+ {
+ mods |= ITALIC;
+ }
+ goto NEXT_STYLE;
+
+ case 'B':
+ if (strncasecmp(style, "Bold", 4) == 0)
+ {
+ mods |= BOLD;
+ }
+ goto NEXT_STYLE;
+
+ case 'O':
+ if (strncasecmp(style, "Oblique", 7) == 0)
+ {
+ mods |= ITALIC;
+ }
+ goto NEXT_STYLE;
+
+ case 'S':
+ if (strncasecmp(style, "SuperBold", 9) == 0)
+ {
+ mods |= BOLD;
+ }
+ goto NEXT_STYLE;
+
+ default: // find the next gap
+ goto NEXT_STYLE;
+ } // switch end
+NEXT_STYLE:
+ while ((*style != ' ') && (*style != '\t') && (*style != ','))
+ {
+ style++;
+ if ((style >= last) || (*style == 0)) goto STYLE_DONE;
+ }
+ }
+STYLE_DONE:
+ // Set the "modifier" character in the raw string
+ switch(mods)
+ {
+ case BOLD: raw[0] = 'B';
+ break;
+ case ITALIC: raw[0] = 'I';
+ break;
+ case BITALIC: raw[0] = 'P';
+ break;
+ default: raw[0] = ' ';
+ break;
+ }
+ }
+} // make_raw_name
+
+///////////////////////////////////////////////////////////
+
+static int fl_free_font = FL_FREE_FONT;
+
+// Uses the fontconfig lib to construct a list of all installed fonts.
+// I tried using XftListFonts for this, but the API is tricky - and when
+// I looked at the XftList* code, it calls the Fc* functions anyway, so...
+//
+// Also, for now I'm ignoring the "pattern_name" and just getting everything...
+// AND I don't try and skip the fonts we've already loaded in the defaults.
+// Blimey! What a hack!
+Fl_Font Fl::set_fonts(const char* pattern_name)
+{
+ FcFontSet *fnt_set; // Will hold the list of fonts we find
+ FcPattern *fnt_pattern; // Holds the generic "match all names" pattern
+ FcObjectSet *fnt_obj_set = 0; // Holds the generic "match all objects"
+
+ int j; // loop iterator variable
+ int font_count; // Total number of fonts found to process
+ char **full_list; // The list of font names we build
+
+ if (fl_free_font > FL_FREE_FONT) // already been here
+ return (Fl_Font)fl_free_font;
+
+ fl_open_display(); // Just in case...
+
+ // Make sure fontconfig is ready... is this necessary? The docs say it is
+ // safe to call it multiple times, so just go for it anyway!
+ if (!FcInit())
+ {
+ // What to do? Just return defaults...
+ return FL_FREE_FONT;
+ }
+
+ // Create a search pattern that will match every font name - I think this
+ // does the Right Thing, but am not certain...
+ //
+ // This could possibly be "enhanced" to pay attention to the requested
+ // "pattern_name"?
+ fnt_pattern = FcPatternCreate();
+ fnt_obj_set = FcObjectSetBuild(FC_FAMILY, FC_STYLE, (void *)0);
+
+ // Hopefully, this is a set of all the fonts...
+ fnt_set = FcFontList(0, fnt_pattern, fnt_obj_set);
+
+ // We don't need the fnt_pattern and fnt_obj_set any more, release them
+ FcPatternDestroy(fnt_pattern);
+ FcObjectSetDestroy(fnt_obj_set);
+
+ // Now, if we got any fonts, iterate through them...
+ if (fnt_set)
+ {
+ char *stop;
+ char *start;
+ char *first;
+
+ font_count = fnt_set->nfont; // How many fonts?
+
+ // Allocate array of char*'s to hold the name strings
+ full_list = (char **)malloc(sizeof(char *) * font_count);
+
+ // iterate through all the font patterns and get the names out...
+ for (j = 0; j < font_count; j++)
+ {
+ // NOTE: FcChar8 is a typedef of "unsigned char"...
+ FcChar8 *font; // String to hold the font's name
+
+ // Convert from fontconfig internal pattern to human readable name
+ // NOTE: This WILL malloc storage, so we need to free it later...
+ font = FcNameUnparse(fnt_set->fonts[j]);
+
+ // The returned strings look like this...
+ // Century Schoolbook:style=Bold Italic,fed kursiv,Fett Kursiv,...
+ // So the bit we want is up to the first comma - BUT some strings have
+ // more than one name, separated by, guess what?, a comma...
+ stop = start = first = 0;
+ stop = strchr((char *)font, ',');
+ start = strchr((char *)font, ':');
+ if ((stop) && (start) && (stop < start))
+ {
+ first = stop + 1; // discard first version of name
+ // find first comma *after* the end of the name
+ stop = strchr((char *)start, ',');
+ }
+ else
+ {
+ first = (char *)font; // name is just what was returned
+ }
+ // Truncate the name after the (english) modifiers description
+ // Matt: Actually, there is no guarantee that the *first* description is the English one.
+ // Matt: So we keep the entire description, just in case.
+ //if (stop)
+ //{
+ // *stop = 0; // Terminate the string at the first comma, if there is one
+ //}
+
+ // Copy the font description into our list
+ if (first == (char *)font)
+ { // The listed name is still OK
+ full_list[j] = (char *)font;
+ }
+ else
+ { // The listed name has been modified
+ full_list[j] = strdup(first);
+ // Free the font name storage
+ free (font);
+ }
+ // replace "style=Regular" so strcmp sorts it first
+ if (start) {
+ char *reg = strstr(full_list[j], "=Regular");
+ if (reg) reg[1]='.';
+ }
+ }
+
+ // Release the fnt_set - we don't need it any more
+ FcFontSetDestroy(fnt_set);
+
+ // Sort the list into alphabetic order
+ qsort(full_list, font_count, sizeof(*full_list), name_sort);
+
+ // Now let us add the names we got to fltk's font list...
+ for (j = 0; j < font_count; j++)
+ {
+ if (full_list[j])
+ {
+ char xft_name[LOCAL_RAW_NAME_MAX];
+ char *stored_name;
+ // Parse the strings into FLTK-XFT style..
+ make_raw_name(xft_name, full_list[j]);
+ // NOTE: This just adds on AFTER the default fonts - no attempt is made
+ // to identify already loaded fonts. Is this bad?
+ stored_name = strdup(xft_name);
+ Fl::set_font((Fl_Font)(j + FL_FREE_FONT), stored_name);
+ fl_free_font ++;
+
+ free(full_list[j]); // release that name from our internal array
+ }
+ }
+ // Now we are done with the list, release it fully
+ free(full_list);
+ }
+ return (Fl_Font)fl_free_font;
+} // ::set_fonts
+////////////////////////////////////////////////////////////////
+
+
+extern "C" {
+static int int_sort(const void *aa, const void *bb) {
+ return (*(int*)aa)-(*(int*)bb);
+}
+}
+
+////////////////////////////////////////////////////////////////
+
+// Return all the point sizes supported by this font:
+// Suprisingly enough Xft works exactly like fltk does and returns
+// the same list. Except there is no way to tell if the font is scalable.
+int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
+ Fl_Fontdesc *s = fl_fonts+fnum;
+ if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
+
+ fl_open_display();
+ XftFontSet* fs = XftListFonts(fl_display, fl_screen,
+ XFT_FAMILY, XftTypeString, s->name+1,
+ (void *)0,
+ XFT_PIXEL_SIZE,
+ (void *)0);
+ static int* array = 0;
+ static int array_size = 0;
+ if (fs->nfont >= array_size) {
+ delete[] array;
+ array = new int[array_size = fs->nfont+1];
+ }
+ array[0] = 0; int j = 1; // claim all fonts are scalable
+ for (int i = 0; i < fs->nfont; i++) {
+ double v;
+ if (XftPatternGetDouble(fs->fonts[i], XFT_PIXEL_SIZE, 0, &v) == XftResultMatch) {
+ array[j++] = int(v);
+ }
+ }
+ qsort(array+1, j-1, sizeof(int), int_sort);
+ XftFontSetDestroy(fs);
+ sizep = array;
+ return j;
+}
+
+//
+// End of "$Id$".
+//
+//
+// "$Id$"
+//
// Xft font code for the Fast Light Tool Kit (FLTK).
//
// Copyright 2001-2011 Bill Spitzak and others.
diff --git a/src/cfg_gfx/xlib_line_style.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx
index 55e759a61..a20ace778 100644
--- a/src/cfg_gfx/xlib_line_style.cxx
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx
@@ -24,7 +24,7 @@
\brief Line style drawing utility hiding different platforms.
*/
-#include "xlib.H"
+#include "Fl_Xlib_Graphics_Driver.h"
void Fl_Xlib_Graphics_Driver::line_style(int style, int width, char* dashes) {
diff --git a/src/cfg_gfx/xlib_rect.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx
index fc5ff1474..225b578d1 100644
--- a/src/cfg_gfx/xlib_rect.cxx
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx
@@ -27,7 +27,7 @@
*/
-#include "xlib.H"
+#include "Fl_Xlib_Graphics_Driver.h"
#ifndef SHRT_MAX
diff --git a/src/cfg_gfx/xlib_vertex.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx
index 9fe73a27c..4c559ad8c 100644
--- a/src/cfg_gfx/xlib_vertex.cxx
+++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx
@@ -25,7 +25,7 @@
simple 2D transformations, implemented for X11 Xlib.
*/
-#include "xlib.H"
+#include "Fl_Xlib_Graphics_Driver.h"
#include <FL/fl_draw.H>
#include <FL/x.H>
diff --git a/src/fl_arci.cxx b/src/fl_arci.cxx
index 7cc3c0690..11f6d4273 100644
--- a/src/fl_arci.cxx
+++ b/src/fl_arci.cxx
@@ -60,7 +60,7 @@
#ifdef FL_CFG_GFX_XLIB
-# include "cfg_gfx/xlib_arci.cxx"
+# include "drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx"
#endif
diff --git a/src/fl_color.cxx b/src/fl_color.cxx
index ddcb8a3ca..1bf3a19f6 100644
--- a/src/fl_color.cxx
+++ b/src/fl_color.cxx
@@ -52,7 +52,7 @@
#ifdef FL_CFG_GFX_XLIB
-# include "cfg_gfx/xlib_color.cxx"
+# include "drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx"
#endif
diff --git a/src/fl_font.cxx b/src/fl_font.cxx
index ca7e87560..02a6b8932 100644
--- a/src/fl_font.cxx
+++ b/src/fl_font.cxx
@@ -54,7 +54,8 @@
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: implement font handling specifics in its own file"
#else
-# include "fl_font_x.cxx"
+# include "drivers/Xlib/Fl_Xlib_Graphics_Driver_font_x.cxx"
+# include "drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx"
#endif // WIN32
#if defined(WIN32) || defined(__APPLE__)
diff --git a/src/fl_font_x.cxx b/src/fl_font_x.cxx
deleted file mode 100644
index cd2ac4e6a..000000000
--- a/src/fl_font_x.cxx
+++ /dev/null
@@ -1,335 +0,0 @@
-//
-// "$Id$"
-//
-// Standard X11 font selection code for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 1998-2011 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// http://www.fltk.org/COPYING.php
-//
-// Please report all bugs and problems on the following page:
-//
-// http://www.fltk.org/str.php
-//
-#ifndef FL_DOXYGEN
-
-Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name) {
- font = XCreateUtf8FontStruct(fl_display, name);
- if (!font) {
- Fl::warning("bad font: %s", name);
- font = XCreateUtf8FontStruct(fl_display, "fixed");
- }
-# if HAVE_GL
- listbase = 0;
- for (int u = 0; u < 64; u++) glok[u] = 0;
-# endif
-}
-
-Fl_XFont_On_Demand fl_xfont;
-
-Fl_Font_Descriptor::~Fl_Font_Descriptor() {
-# if HAVE_GL
-// Delete list created by gl_draw(). This is not done by this code
-// as it will link in GL unnecessarily. There should be some kind
-// of "free" routine pointer, or a subclass?
-// if (listbase) {
-// int base = font->min_char_or_byte2;
-// int size = font->max_char_or_byte2-base+1;
-// int base = 0; int size = 256;
-// glDeleteLists(listbase+base,size);
-// }
-# endif
- if (this == fl_graphics_driver->font_descriptor()) {
- fl_graphics_driver->font_descriptor(NULL);
- fl_xfont = 0;
- }
- XFreeUtf8FontStruct(fl_display, font);
-}
-
-////////////////////////////////////////////////////////////////
-
-// WARNING: if you add to this table, you must redefine FL_FREE_FONT
-// in Enumerations.H & recompile!!
-static Fl_Fontdesc built_in_table[] = {
-{"-*-helvetica-medium-r-normal--*"},
-{"-*-helvetica-bold-r-normal--*"},
-{"-*-helvetica-medium-o-normal--*"},
-{"-*-helvetica-bold-o-normal--*"},
-{"-*-courier-medium-r-normal--*"},
-{"-*-courier-bold-r-normal--*"},
-{"-*-courier-medium-o-normal--*"},
-{"-*-courier-bold-o-normal--*"},
-{"-*-times-medium-r-normal--*"},
-{"-*-times-bold-r-normal--*"},
-{"-*-times-medium-i-normal--*"},
-{"-*-times-bold-i-normal--*"},
-{"-*-symbol-*"},
-{"-*-lucidatypewriter-medium-r-normal-sans-*"},
-{"-*-lucidatypewriter-bold-r-normal-sans-*"},
-{"-*-*zapf dingbats-*"}
-};
-
-Fl_Fontdesc* fl_fonts = built_in_table;
-
-#define MAXSIZE 32767
-
-// return dash number N, or pointer to ending null if none:
-const char* fl_font_word(const char* p, int n) {
- while (*p) {if (*p=='-') {if (!--n) break;} p++;}
- return p;
-}
-
-// return a pointer to a number we think is "point size":
-char* fl_find_fontsize(char* name) {
- char* c = name;
- // for standard x font names, try after 7th dash:
- if (*c == '-') {
- c = (char*)fl_font_word(c,7);
- if (*c++ && isdigit(*c)) return c;
- return 0; // malformed x font name?
- }
- char* r = 0;
- // find last set of digits:
- for (c++;* c; c++)
- if (isdigit(*c) && !isdigit(*(c-1))) r = c;
- return r;
-}
-
-//const char* fl_encoding = "iso8859-1";
-const char* fl_encoding = "iso10646-1";
-
-// return true if this matches fl_encoding:
-int fl_correct_encoding(const char* name) {
- if (*name != '-') return 0;
- const char* c = fl_font_word(name,13);
- return (*c++ && !strcmp(c,fl_encoding));
-}
-
-static const char *find_best_font(const char *fname, int size) {
- int cnt;
- static char **list = NULL;
-// locate or create an Fl_Font_Descriptor 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 = list[0]; int ptsize = 0; // best one found so far
- int matchedlength = 32767;
- char namebuffer[1024]; // holds scalable font name
- int found_encoding = 0;
- int m = cnt; if (m<0) m = -m;
- for (int n=0; n < m; 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 = (char*)fl_find_fontsize(thisname);
- int thissize = c ? atoi(c) : MAXSIZE;
- int thislength = strlen(thisname);
- if (thissize == size && thislength < matchedlength) {
- // exact match, use it:
- name = thisname;
- ptsize = size;
- matchedlength = thislength;
- } else if (!thissize && ptsize!=size) {
- // whoa! A scalable font! Use unless exact match found:
- int l = c-thisname;
- memcpy(namebuffer,thisname,l);
- l += sprintf(namebuffer+l,"%d",size);
- while (*c == '0') c++;
- strcpy(namebuffer+l,c);
- name = namebuffer;
- ptsize = size;
- } else if (!ptsize || // no fonts yet
- (thissize < ptsize && ptsize > size) || // current font too big
- (thissize > ptsize && thissize <= size) // current too small
- ) {
- 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;
-// }
-// }
-// }
-//
-// // 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;}
-// 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;
- const 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_Font_Descriptor for a given Fl_Fontdesc and size:
-static Fl_Font_Descriptor* 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_Font_Descriptor* f;
- for (f = s->first; f; f = f->next)
- if (f->size == size) return f;
- fl_open_display();
-
- name = put_font_size(s->name, size);
- f = new Fl_Font_Descriptor(name);
- f->size = size;
- f->next = s->first;
- s->first = f;
- free(name);
- return f;
-}
-
-
-////////////////////////////////////////////////////////////////
-// Public interface:
-
-void *fl_xftfont = 0;
-static GC font_gc;
-
-XFontStruct* Fl_XFont_On_Demand::value() {
- return ptr;
-}
-
-void Fl_Xlib_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) {
- if (fnum==-1) {
- Fl_Graphics_Driver::font(0, 0);
- return;
- }
- if (fnum == Fl_Graphics_Driver::font() && size == Fl_Graphics_Driver::size()) return;
- Fl_Graphics_Driver::font(fnum, size);
- Fl_Font_Descriptor* f = find(fnum, size);
- if (f != this->font_descriptor()) {
- this->font_descriptor(f);
- fl_xfont = f->font->fonts[0];
- font_gc = 0;
- }
-}
-
-int Fl_Xlib_Graphics_Driver::height() {
- if (font_descriptor()) return font_descriptor()->font->ascent + font_descriptor()->font->descent;
- else return -1;
-}
-
-int Fl_Xlib_Graphics_Driver::descent() {
- if (font_descriptor()) return font_descriptor()->font->descent;
- else return -1;
-}
-
-double Fl_Xlib_Graphics_Driver::width(const char* c, int n) {
- if (font_descriptor()) return (double) XUtf8TextWidth(font_descriptor()->font, c, n);
- else return -1;
-}
-
-double Fl_Xlib_Graphics_Driver::width(unsigned int c) {
- if (font_descriptor()) return (double) XUtf8UcsWidth(font_descriptor()->font, c);
- else return -1;
-}
-
-void Fl_Xlib_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy, int &W, int &H) {
- if (font_gc != fl_gc) {
- if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE);
- font_gc = fl_gc;
- XSetFont(fl_display, fl_gc, font_descriptor()->font->fid);
- }
- int xx, yy, ww, hh;
- xx = yy = ww = hh = 0;
- if (fl_gc) XUtf8_measure_extents(fl_display, fl_window, font_descriptor()->font, fl_gc, &xx, &yy, &ww, &hh, c, n);
-
- W = ww; H = hh; dx = xx; dy = yy;
-// This is the safe but mostly wrong thing we used to do...
-// W = 0; H = 0;
-// fl_measure(c, W, H, 0);
-// dx = 0;
-// dy = fl_descent() - H;
-}
-
-void Fl_Xlib_Graphics_Driver::draw(const char* c, int n, int x, int y) {
- if (font_gc != fl_gc) {
- if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE);
- font_gc = fl_gc;
- XSetFont(fl_display, fl_gc, font_descriptor()->font->fid);
- }
- if (fl_gc) XUtf8DrawString(fl_display, fl_window, font_descriptor()->font, fl_gc, x, y, c, n);
-}
-
-void Fl_Xlib_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) {
- fprintf(stderr,"ROTATING TEXT NOT IMPLEMENTED\n");
- this->draw(str, n, (int)x, (int)y);
-}
-
-void Fl_Xlib_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) {
- if (font_gc != fl_gc) {
- if (!font_descriptor()) this->font(FL_HELVETICA, FL_NORMAL_SIZE);
- font_gc = fl_gc;
- }
- if (fl_gc) XUtf8DrawRtlString(fl_display, fl_window, font_descriptor()->font, fl_gc, x, y, c, n);
-}
-#endif // FL_DOXYGEN
-//
-// End of "$Id$".
-//
diff --git a/src/fl_line_style.cxx b/src/fl_line_style.cxx
index e07add50b..83a373394 100644
--- a/src/fl_line_style.cxx
+++ b/src/fl_line_style.cxx
@@ -60,7 +60,7 @@ int fl_line_width_ = 0;
#ifdef FL_CFG_GFX_XLIB
-# include "cfg_gfx/xlib_line_style.cxx"
+# include "drivers/Xlib/Fl_Xlib_Graphics_Driver_line_style.cxx"
#endif
diff --git a/src/fl_rect.cxx b/src/fl_rect.cxx
index 0676bb8f6..39af2e20c 100644
--- a/src/fl_rect.cxx
+++ b/src/fl_rect.cxx
@@ -65,31 +65,6 @@ Fl_Region Fl_Graphics_Driver::clip_region() {
-////////////////////////////////////////////////////////////////
-
-/*
- Matt: I wrote individual methods for every class. They are virtual, so the
- correct function is called, depending on the active driver.
-
- By having individual methods, multiple drivers can co-exist, for example
- Quartz, OpenGL, and a printer driver.
-
- The individual implementations should eventually go into files that are
- included into this file, based on the configuration, for example:
-
- src/cfg_gfx/quartz_rect.cxx
- src/cfg_gfx/gdi_rect.cxx
- src/cfg_gfx/xlib_rect.cxx
-
- Porting the graphics system to a new platform then requires to copy one of
- these files and implement the virtual functions. point() is the only function
- that *must* be implemented when deriving from 'Fl_Minimal_Graphics_Driver"
- (which is still to be written)
- */
-
-////////////////////////////////////////////////////////////////
-
-
#ifdef FL_CFG_GFX_QUARTZ
# include "cfg_gfx/quartz_rect.cxx"
@@ -112,7 +87,7 @@ Fl_Region Fl_Graphics_Driver::clip_region() {
#ifdef FL_CFG_GFX_XLIB
-# include "cfg_gfx/xlib_rect.cxx"
+# include "drivers/Xlib/Fl_Xlib_Graphics_Driver_rect.cxx"
#endif
diff --git a/src/fl_set_fonts.cxx b/src/fl_set_fonts.cxx
index 2673a78fd..ab92dc664 100644
--- a/src/fl_set_fonts.cxx
+++ b/src/fl_set_fonts.cxx
@@ -31,7 +31,7 @@
#elif defined(FL_PORTING)
# pragma message "FL_PORTING: implement changes in font in its own file"
#else
-# include "fl_set_fonts_x.cxx"
+// now included for fl_font.cxx, but will be its own source code module in drivers/Xlib/Fl_Xlib_Graphics_Driver_font..."
#endif // WIN32
//
diff --git a/src/fl_set_fonts_xft.cxx b/src/fl_set_fonts_xft.cxx
deleted file mode 100644
index 13374ee7f..000000000
--- a/src/fl_set_fonts_xft.cxx
+++ /dev/null
@@ -1,384 +0,0 @@
-//
-// "$Id$"
-//
-// More font utilities for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 1998-2011 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// http://www.fltk.org/COPYING.php
-//
-// Please report all bugs and problems on the following page:
-//
-// http://www.fltk.org/str.php
-//
-
-#include <X11/Xft/Xft.h>
-
-// This function fills in the fltk font table with all the fonts that
-// are found on the X server. It tries to place the fonts into families
-// and to sort them so the first 4 in a family are normal, bold, italic,
-// and bold italic.
-
-// Bug: older versions calculated the value for *ap as a side effect of
-// making the name, and then forgot about it. To avoid having to change
-// the header files I decided to store this value in the last character
-// of the font name array.
-#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1
-
-// turn a stored font name in "fltk format" into a pretty name:
-const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
- Fl_Fontdesc *f = fl_fonts + fnum;
- if (!f->fontname[0]) {
- const char* p = f->name;
- int type;
- switch (p[0]) {
- case 'B': type = FL_BOLD; break;
- case 'I': type = FL_ITALIC; break;
- case 'P': type = FL_BOLD | FL_ITALIC; break;
- default: type = 0; break;
- }
-
- // NOTE: This can cause duplications in fonts that already have Bold or Italic in
- // their "name". Maybe we need to find a cleverer way?
- strlcpy(f->fontname, p+1, ENDOFBUFFER);
- if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER);
- if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER);
- f->fontname[ENDOFBUFFER] = (char)type;
- }
- if (ap) *ap = f->fontname[ENDOFBUFFER];
- return f->fontname;
-}
-
-///////////////////////////////////////////////////////////
-#define LOCAL_RAW_NAME_MAX 256
-
-extern "C" {
-// sort returned fontconfig font names
-static int name_sort(const void *aa, const void *bb) {
- // What should we do here? Just do a string compare for now...
- // NOTE: This yeilds some oddities - in particular a Blah Bold font will be
- // listed before Blah...
- // Also - the fontconfig listing returns some faces that are effectively duplicates
- // as far as fltk is concerned, e.g. where there are ko or ja variants that we
- // can't distinguish (since we are not yet fully UTF-*) - should we strip them here?
- return fl_ascii_strcasecmp(*(char**)aa, *(char**)bb);
-} // end of name_sort
-} // end of extern C section
-
-
-// Read the "pretty" name we have derived from fontconfig then convert
-// it into the format fltk uses internally for Xft names...
-// This is just a mess - I should have tokenised the strings and gone from there,
-// but I really thought this would be easier!
-static void make_raw_name(char *raw, char *pretty)
-{
- // Input name will be "Some Name:style = Bold Italic" or whatever
- // The plan is this:
- // - the first char in the "raw" name becomes either I, B, P or " " for
- // italic, bold, bold italic or normal - this seems to be the fltk way...
-
- char *style = strchr(pretty, ':');
-
- if (style)
- {
- *style = 0; // Terminate "name" string
- style ++; // point to start of style section
- }
-
- // It is still possible that the "pretty" name has multiple comma separated entries
- // I've seen this often in CJK fonts, for example... Keep only the first one... This
- // is not ideal, the CJK fonts often have the name in utf8 in several languages. What
- // we ought to do is use fontconfig to query the available languages and pick one... But which?
-#if 0 // loop to keep the LAST name entry...
- char *nm1 = pretty;
- char *nm2 = strchr(nm1, ',');
- while(nm2) {
- nm1 = nm2 + 1;
- nm2 = strchr(nm1, ',');
- }
- raw[0] = ' '; raw[1] = 0; // Default start of "raw name" text
- strncat(raw, nm1, LOCAL_RAW_NAME_MAX-1); // only copy MAX-1 chars, we have already set cell 0
- // Ensure raw is terminated, just in case the given name is infeasibly long...
- raw[LOCAL_RAW_NAME_MAX-1] = 0;
-#else // keep the first remaining name entry
- char *nm2 = strchr(pretty, ',');
- if(nm2) *nm2 = 0; // terminate name after first entry
- raw[0] = ' '; raw[1] = 0; // Default start of "raw name" text
- strncat(raw, pretty, LOCAL_RAW_NAME_MAX-1); // only copy MAX-1 chars, we have already set cell 0
- // Ensure raw is terminated, just in case the given name is infeasibly long...
- raw[LOCAL_RAW_NAME_MAX-1] = 0;
-#endif
- // At this point, the name is "marked" as regular...
- if (style)
- {
-#define PLAIN 0
-#define BOLD 1
-#define ITALIC 2
-#define BITALIC (BOLD | ITALIC)
-
- int mods = PLAIN;
- char *last = style + strlen(style) - 2;
-
- // Now try and parse the style string - look for the "=" sign
- style = strchr(style, '=');
- while ((style) && (style < last))
- {
- int type;
- while ((*style == '=') || (*style == ' ') || (*style == '\t') || (*style == ','))
- {
- style++; // Start of Style string
- if ((style >= last) || (*style == 0)) continue;
- }
- type = toupper(style[0]);
- switch (type)
- {
- // Things we might see: Regular Normal Bold Italic Oblique (??what??) Medium
- // Roman Light Demi Sans SemiCondensed SuperBold Book... etc...
- // Things we actually care about: Bold Italic Oblique SuperBold - Others???
- case 'I':
- if (strncasecmp(style, "Italic", 6) == 0)
- {
- mods |= ITALIC;
- }
- goto NEXT_STYLE;
-
- case 'B':
- if (strncasecmp(style, "Bold", 4) == 0)
- {
- mods |= BOLD;
- }
- goto NEXT_STYLE;
-
- case 'O':
- if (strncasecmp(style, "Oblique", 7) == 0)
- {
- mods |= ITALIC;
- }
- goto NEXT_STYLE;
-
- case 'S':
- if (strncasecmp(style, "SuperBold", 9) == 0)
- {
- mods |= BOLD;
- }
- goto NEXT_STYLE;
-
- default: // find the next gap
- goto NEXT_STYLE;
- } // switch end
-NEXT_STYLE:
- while ((*style != ' ') && (*style != '\t') && (*style != ','))
- {
- style++;
- if ((style >= last) || (*style == 0)) goto STYLE_DONE;
- }
- }
-STYLE_DONE:
- // Set the "modifier" character in the raw string
- switch(mods)
- {
- case BOLD: raw[0] = 'B';
- break;
- case ITALIC: raw[0] = 'I';
- break;
- case BITALIC: raw[0] = 'P';
- break;
- default: raw[0] = ' ';
- break;
- }
- }
-} // make_raw_name
-
-///////////////////////////////////////////////////////////
-
-static int fl_free_font = FL_FREE_FONT;
-
-// Uses the fontconfig lib to construct a list of all installed fonts.
-// I tried using XftListFonts for this, but the API is tricky - and when
-// I looked at the XftList* code, it calls the Fc* functions anyway, so...
-//
-// Also, for now I'm ignoring the "pattern_name" and just getting everything...
-// AND I don't try and skip the fonts we've already loaded in the defaults.
-// Blimey! What a hack!
-Fl_Font Fl::set_fonts(const char* pattern_name)
-{
- FcFontSet *fnt_set; // Will hold the list of fonts we find
- FcPattern *fnt_pattern; // Holds the generic "match all names" pattern
- FcObjectSet *fnt_obj_set = 0; // Holds the generic "match all objects"
-
- int j; // loop iterator variable
- int font_count; // Total number of fonts found to process
- char **full_list; // The list of font names we build
-
- if (fl_free_font > FL_FREE_FONT) // already been here
- return (Fl_Font)fl_free_font;
-
- fl_open_display(); // Just in case...
-
- // Make sure fontconfig is ready... is this necessary? The docs say it is
- // safe to call it multiple times, so just go for it anyway!
- if (!FcInit())
- {
- // What to do? Just return defaults...
- return FL_FREE_FONT;
- }
-
- // Create a search pattern that will match every font name - I think this
- // does the Right Thing, but am not certain...
- //
- // This could possibly be "enhanced" to pay attention to the requested
- // "pattern_name"?
- fnt_pattern = FcPatternCreate();
- fnt_obj_set = FcObjectSetBuild(FC_FAMILY, FC_STYLE, (void *)0);
-
- // Hopefully, this is a set of all the fonts...
- fnt_set = FcFontList(0, fnt_pattern, fnt_obj_set);
-
- // We don't need the fnt_pattern and fnt_obj_set any more, release them
- FcPatternDestroy(fnt_pattern);
- FcObjectSetDestroy(fnt_obj_set);
-
- // Now, if we got any fonts, iterate through them...
- if (fnt_set)
- {
- char *stop;
- char *start;
- char *first;
-
- font_count = fnt_set->nfont; // How many fonts?
-
- // Allocate array of char*'s to hold the name strings
- full_list = (char **)malloc(sizeof(char *) * font_count);
-
- // iterate through all the font patterns and get the names out...
- for (j = 0; j < font_count; j++)
- {
- // NOTE: FcChar8 is a typedef of "unsigned char"...
- FcChar8 *font; // String to hold the font's name
-
- // Convert from fontconfig internal pattern to human readable name
- // NOTE: This WILL malloc storage, so we need to free it later...
- font = FcNameUnparse(fnt_set->fonts[j]);
-
- // The returned strings look like this...
- // Century Schoolbook:style=Bold Italic,fed kursiv,Fett Kursiv,...
- // So the bit we want is up to the first comma - BUT some strings have
- // more than one name, separated by, guess what?, a comma...
- stop = start = first = 0;
- stop = strchr((char *)font, ',');
- start = strchr((char *)font, ':');
- if ((stop) && (start) && (stop < start))
- {
- first = stop + 1; // discard first version of name
- // find first comma *after* the end of the name
- stop = strchr((char *)start, ',');
- }
- else
- {
- first = (char *)font; // name is just what was returned
- }
- // Truncate the name after the (english) modifiers description
- // Matt: Actually, there is no guarantee that the *first* description is the English one.
- // Matt: So we keep the entire description, just in case.
- //if (stop)
- //{
- // *stop = 0; // Terminate the string at the first comma, if there is one
- //}
-
- // Copy the font description into our list
- if (first == (char *)font)
- { // The listed name is still OK
- full_list[j] = (char *)font;
- }
- else
- { // The listed name has been modified
- full_list[j] = strdup(first);
- // Free the font name storage
- free (font);
- }
- // replace "style=Regular" so strcmp sorts it first
- if (start) {
- char *reg = strstr(full_list[j], "=Regular");
- if (reg) reg[1]='.';
- }
- }
-
- // Release the fnt_set - we don't need it any more
- FcFontSetDestroy(fnt_set);
-
- // Sort the list into alphabetic order
- qsort(full_list, font_count, sizeof(*full_list), name_sort);
-
- // Now let us add the names we got to fltk's font list...
- for (j = 0; j < font_count; j++)
- {
- if (full_list[j])
- {
- char xft_name[LOCAL_RAW_NAME_MAX];
- char *stored_name;
- // Parse the strings into FLTK-XFT style..
- make_raw_name(xft_name, full_list[j]);
- // NOTE: This just adds on AFTER the default fonts - no attempt is made
- // to identify already loaded fonts. Is this bad?
- stored_name = strdup(xft_name);
- Fl::set_font((Fl_Font)(j + FL_FREE_FONT), stored_name);
- fl_free_font ++;
-
- free(full_list[j]); // release that name from our internal array
- }
- }
- // Now we are done with the list, release it fully
- free(full_list);
- }
- return (Fl_Font)fl_free_font;
-} // ::set_fonts
-////////////////////////////////////////////////////////////////
-
-
-extern "C" {
-static int int_sort(const void *aa, const void *bb) {
- return (*(int*)aa)-(*(int*)bb);
-}
-}
-
-////////////////////////////////////////////////////////////////
-
-// Return all the point sizes supported by this font:
-// Suprisingly enough Xft works exactly like fltk does and returns
-// the same list. Except there is no way to tell if the font is scalable.
-int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
- Fl_Fontdesc *s = fl_fonts+fnum;
- if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
-
- fl_open_display();
- XftFontSet* fs = XftListFonts(fl_display, fl_screen,
- XFT_FAMILY, XftTypeString, s->name+1,
- (void *)0,
- XFT_PIXEL_SIZE,
- (void *)0);
- static int* array = 0;
- static int array_size = 0;
- if (fs->nfont >= array_size) {
- delete[] array;
- array = new int[array_size = fs->nfont+1];
- }
- array[0] = 0; int j = 1; // claim all fonts are scalable
- for (int i = 0; i < fs->nfont; i++) {
- double v;
- if (XftPatternGetDouble(fs->fonts[i], XFT_PIXEL_SIZE, 0, &v) == XftResultMatch) {
- array[j++] = int(v);
- }
- }
- qsort(array+1, j-1, sizeof(int), int_sort);
- XftFontSetDestroy(fs);
- sizep = array;
- return j;
-}
-
-//
-// End of "$Id$".
-//
diff --git a/src/fl_vertex.cxx b/src/fl_vertex.cxx
index 16f0a501f..d891794c0 100644
--- a/src/fl_vertex.cxx
+++ b/src/fl_vertex.cxx
@@ -170,7 +170,7 @@ void Fl_Graphics_Driver::fixloop() { // remove equal points from closed path
#ifdef FL_CFG_GFX_XLIB
-# include "cfg_gfx/xlib_vertex.cxx"
+# include "drivers/Xlib/Fl_Xlib_Graphics_Driver_vertex.cxx"
#endif