From 199b32d9213584e232aee11d2a4d16a26f1d508d Mon Sep 17 00:00:00 2001 From: Manolo Gouy Date: Fri, 18 Feb 2011 13:39:48 +0000 Subject: [PATCH] Added virtual width(), height(), descent() and text_extents() functions to the Fl_Graphics_Driver class to prepare for the future definition of graphics drivers that fully deal with text measurement. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@8442 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- FL/Fl_Device.H | 36 ++++++++++++++- FL/Fl_PostScript.H | 7 +++ FL/fl_draw.H | 11 +++-- src/Fl_Device.cxx | 8 ++++ src/Fl_PostScript.cxx | 66 +++++++++++++++++---------- src/fl_font.cxx | 6 ++- src/fl_font_mac.cxx | 88 ++++++++++++++--------------------- src/fl_font_win32.cxx | 42 ++++++++--------- src/fl_font_x.cxx | 25 +++++----- src/fl_font_xft.cxx | 104 +++++++++++++++++++++--------------------- src/gl_draw.cxx | 2 +- 11 files changed, 224 insertions(+), 171 deletions(-) diff --git a/FL/Fl_Device.H b/FL/Fl_Device.H index 6569a8720..c973f73db 100644 --- a/FL/Fl_Device.H +++ b/FL/Fl_Device.H @@ -107,7 +107,7 @@ public: /** \brief A virtual class subclassed for each graphics driver FLTK uses. * - The protected virtual methods of this class are those that a graphics driver should implement to + The virtual methods of this class are those that a graphics driver should implement to support all of FLTK drawing functions.
The public API for drawing operations is functionally presented in \ref drawing and as function lists in the \ref fl_drawings and \ref fl_attributes modules. @@ -156,6 +156,9 @@ protected: friend void fl_line(int x, int y, int x1, int y1); friend void fl_line(int x, int y, int x1, int y1, int x2, int y2); friend void fl_draw(const char *str, int n, int x, int y); +#ifdef __APPLE__ + friend void fl_draw(const char *str, int n, float x, float y); +#endif friend void fl_draw(int angle, const char *str, int n, int x, int y); friend void fl_rtl_draw(const char *str, int n, int x, int y); friend void fl_font(Fl_Font face, Fl_Fontsize size); @@ -234,6 +237,9 @@ protected: virtual void line(int x, int y, int x1, int y1, int x2, int y2); /** \brief see fl_draw(const char *str, int n, int x, int y). */ virtual void draw(const char *str, int n, int x, int y) = 0; +#ifdef __APPLE__ + virtual void draw(const char *str, int n, float x, float y) = 0; +#endif /** \brief see fl_draw(int angle, const char *str, int n, int x, int y). */ virtual void draw(int angle, const char *str, int n, int x, int y) = 0; /** \brief see fl_rtl_draw(const char *str, int n, int x, int y). */ @@ -357,6 +363,16 @@ public: Fl_Font font() {return font_; } /** \brief see fl_size(). */ Fl_Fontsize size() {return size_; } + /** \brief see fl_width(const char *str, int n). */ + virtual double width(const char *str, int n) = 0; + /** \brief see fl_width(unsigned int n). */ + virtual inline double width(unsigned int c) { char ch = (char)c; return width(&ch, 1); } + /** \brief see fl_text_extents(const char*, int n, int& dx, int& dy, int& w, int& h). */ + virtual void text_extents(const char*, int n, int& dx, int& dy, int& w, int& h); + /** \brief see fl_height(). */ + virtual int height() = 0; + /** \brief see fl_descent(). */ + virtual int descent() = 0; /** \brief see fl_color(void). */ Fl_Color color() {return color_;} /** Returns a pointer to the current Fl_Font_Descriptor for the graphics driver */ @@ -381,6 +397,9 @@ public: void color(Fl_Color c); void color(uchar r, uchar g, uchar b); void draw(const char* str, int n, int x, int y); +#ifdef __APPLE__ + void draw(const char *str, int n, float x, float y); +#endif void draw(int angle, const char *str, int n, int x, int y); void rtl_draw(const char* str, int n, int x, int y); void font(Fl_Font face, Fl_Fontsize size); @@ -391,6 +410,11 @@ public: void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3); void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0); void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1); + double width(const char *str, int n); + double width(unsigned int c); + void text_extents(const char*, int n, int& dx, int& dy, int& w, int& h); + int height(); + int descent(); }; #endif #if defined(WIN32) || defined(FL_DOXYGEN) @@ -417,6 +441,11 @@ public: void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3); void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0); void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1); + double width(const char *str, int n); + double width(unsigned int c); + void text_extents(const char*, int n, int& dx, int& dy, int& w, int& h); + int height(); + int descent(); }; #endif #if !(defined(__APPLE__) || defined(WIN32)) @@ -443,6 +472,11 @@ public: void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3); void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0); void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1); + double width(const char *str, int n); + double width(unsigned int c); + void text_extents(const char*, int n, int& dx, int& dy, int& w, int& h); + int height(); + int descent(); }; #endif diff --git a/FL/Fl_PostScript.H b/FL/Fl_PostScript.H index 56b05234e..b03b67c06 100644 --- a/FL/Fl_PostScript.H +++ b/FL/Fl_PostScript.H @@ -116,6 +116,9 @@ class Clip { /* int alpha_mask(const uchar * data, int w, int h, int D, int LD=0); */ void draw(const char* s, int n, int x, int y) {transformed_draw(s,n,x,y); }; +#ifdef __APPLE__ + void draw(const char* s, int n, float x, float y) {transformed_draw(s,n,x,y); }; +#endif void draw(int angle, const char *str, int n, int x, int y); void rtl_draw(const char* s, int n, int x, int y); void transformed_draw(const char* s, int n, double x, double y); //precise text placing @@ -180,6 +183,10 @@ class Clip { void transformed_vertex(double x, double y); void font(int face, int size); + double width(const char *, int); + void text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h); + int height(); + int descent(); void draw_image(const uchar* d, int x,int y,int w,int h, int delta=3, int ldelta=0){draw_scaled_image(d,x,y,w,h,w,h,delta,ldelta);}; void draw_image_mono(const uchar* d, int x,int y,int w,int h, int delta=1, int ld=0){draw_scaled_image_mono(d,x,y,w,h,w,h,delta,ld);}; diff --git a/FL/fl_draw.H b/FL/fl_draw.H index a9651846d..1211c44a7 100644 --- a/FL/fl_draw.H +++ b/FL/fl_draw.H @@ -495,21 +495,21 @@ inline Fl_Fontsize fl_size() {return fl_graphics_driver->size();} Returns the recommended minimum line spacing for the current font. You can also use the value of \p size passed to fl_font() */ -FL_EXPORT int fl_height(); // using "size" should work ok +inline int fl_height() {return fl_graphics_driver->height();} FL_EXPORT int fl_height(int font, int size); /** Returns the recommended distance above the bottom of a fl_height() tall box to draw the text at so it looks centered vertically in that box. */ -FL_EXPORT int fl_descent(); +inline int fl_descent() {return fl_graphics_driver->descent();} /** Return the typographical width of a nul-terminated string */ FL_EXPORT double fl_width(const char* txt); /** Return the typographical width of a sequence of \p n characters */ -FL_EXPORT double fl_width(const char* txt, int n); +inline double fl_width(const char* txt, int n) {return fl_graphics_driver->width(txt, n);} /** Return the typographical width of a single character : \note if a valid fl_gc is NOT found then it uses the first window gc, or the screen gc if no fltk window is available when called. */ -FL_EXPORT double fl_width(unsigned int); +inline double fl_width(unsigned int c) {return fl_graphics_driver->width(c);} /** Determine the minimum pixel dimensions of a nul-terminated string. Usage: given a string "txt" drawn using fl_draw(txt, x, y) you would determine @@ -522,7 +522,8 @@ FL_EXPORT void fl_text_extents(const char*, int& dx, int& dy, int& w, int& h); / /** Determine the minimum pixel dimensions of a sequence of \p n characters. \see fl_text_extents(const char*, int& dx, int& dy, int& w, int& h) */ -FL_EXPORT void fl_text_extents(const char*, int n, int& dx, int& dy, int& w, int& h); +inline void fl_text_extents(const char *t, int n, int& dx, int& dy, int& w, int& h) + {fl_graphics_driver->text_extents(t, n, dx, dy, w, h);} // font encoding: // Note: doxygen comments here to avoid duplication for os-sepecific cases diff --git a/src/Fl_Device.cxx b/src/Fl_Device.cxx index acc94ca65..2b98bdf39 100644 --- a/src/Fl_Device.cxx +++ b/src/Fl_Device.cxx @@ -64,6 +64,14 @@ Fl_Graphics_Driver::Fl_Graphics_Driver() { font_descriptor_ = NULL; }; +void Fl_Graphics_Driver::text_extents(const char*t, int n, int& dx, int& dy, int& w, int& h) +{ + w = (int)width(t, n); + h = - height(); + dx = dy = 0; +} + + // // End of "$Id$". // diff --git a/src/Fl_PostScript.cxx b/src/Fl_PostScript.cxx index bbbaa490a..bbad835d7 100644 --- a/src/Fl_PostScript.cxx +++ b/src/Fl_PostScript.cxx @@ -944,7 +944,7 @@ void Fl_PostScript_Graphics_Driver::font(int f, int s) { fprintf(output, "/%s SF\n" , _fontNames[f]); #if defined(USE_X11) #if USE_XFT - // Xft font height is sometimes larger than the size required (see STR 2566). + // Xft font height is sometimes larger than the required size (see STR 2566). // Increase the PostScript font size by 15% without exceeding the display font height int max = desc->font->height; ps_size = s * 1.15; @@ -963,6 +963,23 @@ void Fl_PostScript_Graphics_Driver::font(int f, int s) { } } +double Fl_PostScript_Graphics_Driver::width(const char *s, int n) { + return Fl_Display_Device::display_device()->driver()->width(s, n); +} + +int Fl_PostScript_Graphics_Driver::height() { + return Fl_Display_Device::display_device()->driver()->height(); +} + +int Fl_PostScript_Graphics_Driver::descent() { + return Fl_Display_Device::display_device()->driver()->descent(); +} + +void Fl_PostScript_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { + return Fl_Display_Device::display_device()->driver()->text_extents(c, n, dx, dy, w, h); +} + + void Fl_PostScript_Graphics_Driver::color(Fl_Color c) { Fl::get_color(c, cr_, cg_, cb_); color(cr_, cg_, cb_); @@ -1022,45 +1039,48 @@ static uchar *calc_mask(uchar *img, int w, int h, Fl_Color bg) } // write to PostScript a bitmap image of a UTF8 string -static void transformed_draw_extra(const char* str, int n, double x, double y, int w, FILE *output) { +static void transformed_draw_extra( + const char* str, int n, double x, double y, int w, FILE *output, Fl_Graphics_Driver *driver) { // scale for bitmask computation #if defined(USE_X11) && !USE_XFT - const float scale = 1; // don't scale because we can't expect to have scalable fonts + float scale = 1; // don't scale because we can't expect to have scalable fonts #else - const float scale = 3; + float scale = 3; #endif - Fl_Fontsize old_size = fl_size(); - Fl_Font fontnum = fl_font(); - w = (int)(w *scale + 0.5); - int h = (int)(fl_height() * scale); + Fl_Fontsize old_size = driver->size(); + Fl_Font fontnum = driver->font(); + int w_scaled = (int)(w * (scale + 0.5)); + int h = (int)(driver->height() * scale); // create an offscreen image of the string - Fl_Color text_color = fl_color(); + Fl_Color text_color = driver->color(); Fl_Color bg_color = fl_contrast(FL_WHITE, text_color); - Fl_Offscreen off = fl_create_offscreen(w+2, (int)(h+3*scale) ); + Fl_Offscreen off = fl_create_offscreen(w_scaled, (int)(h+3*scale) ); fl_begin_offscreen(off); fl_color(bg_color); // color offscreen background with a shade contrasting with the text color - fl_rectf(0, 0, w+2, (int)(h+3*scale) ); + fl_rectf(0, 0, w_scaled, (int)(h+3*scale) ); fl_color(text_color); #if defined(USE_X11) && !USE_XFT // force seeing this font as new so it's applied to the offscreen graphics context fl_graphics_driver->font_descriptor(NULL); - fl_graphics_driver->Fl_Graphics_Driver::font(fontnum, 0); + fl_font(fontnum, 0); #endif fl_font(fontnum, (Fl_Fontsize)(scale * old_size) ); fl_draw(str, n, 1, (int)(h * 0.8) ); // draw string in offscreen + int w2 = (int)fl_width(str, n); // read (most of) the offscreen image - uchar *img = fl_read_image(NULL, 1, 1, w, h, 0); + uchar *img = fl_read_image(NULL, 1, 1, w2, h, 0); fl_end_offscreen(); - fl_font(fontnum, old_size); + driver->font(fontnum, old_size); fl_delete_offscreen(off); // compute the mask of what is not the background - uchar *mask = calc_mask(img, w, h, bg_color); + uchar *mask = calc_mask(img, w2, h, bg_color); delete[] img; // write the string image to PostScript as a scaled bitmask - fprintf(output, "%g %g %g %g %d %d MI\n", x, y - h*0.77/scale, w/scale, h/scale, w, h); + scale = w2 / float(w); + fprintf(output, "%g %g %g %g %d %d MI\n", x, y - h*0.77/scale, w2/scale, h/scale, w2, h); uchar *di; - int wmask = (w+7)/8; + int wmask = (w2+7)/8; for (int j = h - 1; j >= 0; j--){ di = mask + j * wmask; for (int i = 0; i < wmask; i++){ @@ -1101,13 +1121,13 @@ void Fl_PostScript_Graphics_Driver::transformed_draw(const char* str, int n, dou int len, code; if (!n || !str || !*str) return; // compute display width of string - int width = (int)fl_width(str, n); - if (width == 0) return; - if (fl_font() >= FL_FREE_FONT) { - transformed_draw_extra(str, n, x, y, width, output); + int w = (int)width(str, n); + if (w == 0) return; + if (Fl_Graphics_Driver::font() >= FL_FREE_FONT) { + transformed_draw_extra(str, n, x, y, w, output, this); return; } - fprintf(output, "%d <", width); + fprintf(output, "%d <", w); // transforms UTF8 encoding to our custom PostScript encoding as follows: // extract each unicode character // if unicode <= 0x17F, unicode and PostScript codes are identical @@ -1129,7 +1149,7 @@ void Fl_PostScript_Graphics_Driver::transformed_draw(const char* str, int n, dou } else { // unhandled character: draw all string as bitmap image fprintf(output, "> pop pop\n"); // close and ignore the opened hex string - transformed_draw_extra(str, n, x, y, width, output); + transformed_draw_extra(str, n, x, y, w, output, this); return; } fprintf(output, "%4.4X", utf); diff --git a/src/fl_font.cxx b/src/fl_font.cxx index 2a6833adf..53a639efd 100644 --- a/src/fl_font.cxx +++ b/src/fl_font.cxx @@ -81,11 +81,13 @@ void fl_text_extents(const char *c, int &dx, int &dy, int &w, int &h) { } // fl_text_extents -#ifndef __APPLE__ void fl_draw(const char* str, int l, float x, float y) { +#ifdef __APPLE__ + fl_graphics_driver->draw(str, l, x, y); +#else fl_draw(str, l, (int)x, (int)y); -} #endif +} // // End of "$Id$". // diff --git a/src/fl_font_mac.cxx b/src/fl_font_mac.cxx index 602b8495d..f915143c5 100644 --- a/src/fl_font_mac.cxx +++ b/src/fl_font_mac.cxx @@ -30,9 +30,6 @@ /* from fl_utf.c */ extern unsigned fl_utf8toUtf16(const char* src, unsigned srclen, unsigned short* dst, unsigned dstlen); -// if no font has been selected yet by the user, get one. -#define check_default_font() {if (!fl_fontsize) fl_font(FL_HELVETICA, FL_NORMAL_SIZE);} - static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 }; #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 static CFMutableDictionaryRef attributes = NULL; @@ -251,26 +248,22 @@ void Fl_Quartz_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { this->font_descriptor( find(fnum, size) ); } -int fl_height() { - Fl_Font_Descriptor *fl_fontsize = fl_graphics_driver->font_descriptor(); - check_default_font(); - if (fl_fontsize) return fl_fontsize->ascent+fl_fontsize->descent; - else return -1; +int Fl_Quartz_Graphics_Driver::height() { + if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE); + Fl_Font_Descriptor *fl_fontsize = font_descriptor(); + return fl_fontsize->ascent + fl_fontsize->descent; } -int fl_descent() { - Fl_Font_Descriptor *fl_fontsize = fl_graphics_driver->font_descriptor(); - check_default_font(); - if (fl_fontsize) - return fl_fontsize->descent+1; - else return -1; +int Fl_Quartz_Graphics_Driver::descent() { + if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE); + Fl_Font_Descriptor *fl_fontsize = font_descriptor(); + return fl_fontsize->descent+1; } #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 // returns width of a pair of UniChar's in the surrogate range -static CGFloat surrogate_width(const UniChar *txt) +static CGFloat surrogate_width(const UniChar *txt, Fl_Font_Descriptor *fl_fontsize) { - Fl_Font_Descriptor *fl_fontsize = fl_graphics_driver->font_descriptor(); CFStringRef str = CFStringCreateWithCharactersNoCopy(NULL, txt, 2, kCFAllocatorNull); CTFontRef font2 = CTFontCreateForString(fl_fontsize->fontref, str, CFRangeMake(0,2)); CFRelease(str); @@ -284,14 +277,7 @@ static CGFloat surrogate_width(const UniChar *txt) } #endif -static double fl_width(const UniChar* txt, int n) { - Fl_Font_Descriptor *fl_fontsize = fl_graphics_driver->font_descriptor(); - check_default_font(); - if (!fl_fontsize) { - check_default_font(); // avoid a crash! - if (!fl_fontsize) - return 8*n; // user must select a font first! - } +static double fl_mac_width(const UniChar* txt, int n, Fl_Font_Descriptor *fl_fontsize) { #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 if (fl_mac_os_version >= 0x1050) { double retval = 0; @@ -300,7 +286,7 @@ if (fl_mac_os_version >= 0x1050) { for (i = 0; i < n; i++) { // loop over txt uni = txt[i]; if (uni >= 0xD800 && uni <= 0xDBFF) { // handles the surrogate range - retval += surrogate_width(txt + i); + retval += surrogate_width(txt + i, fl_fontsize); i++; // because a pair of UniChar's represent a single character continue; } @@ -370,27 +356,23 @@ if (fl_mac_os_version >= 0x1050) { return 0; } -double fl_width(const char* txt, int n) { +double Fl_Quartz_Graphics_Driver::width(const char* txt, int n) { int wc_len = n; UniChar *uniStr = mac_Utf8_to_Utf16(txt, n, &wc_len); - return fl_width(uniStr, wc_len); + if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE); + return fl_mac_width(uniStr, wc_len, font_descriptor()); } -double fl_width(unsigned int wc) { +double Fl_Quartz_Graphics_Driver::width(unsigned int wc) { const UniChar uc = wc; - return fl_width(&uc, 1); + if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE); + return fl_mac_width(&uc, 1, font_descriptor()); } // text extent calculation -void fl_text_extents(const char *str8, int n, int &dx, int &dy, int &w, int &h) { - Fl_Font_Descriptor *fl_fontsize = fl_graphics_driver->font_descriptor(); - if (!fl_fontsize) { - check_default_font(); // avoid a crash! - if (!fl_fontsize) - w = int(8.0 * n); // user must select a font first! - h = int(8.0); - return; - } +void Fl_Quartz_Graphics_Driver::text_extents(const char *str8, int n, int &dx, int &dy, int &w, int &h) { + if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE); + Fl_Font_Descriptor *fl_fontsize = font_descriptor(); #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 if (fl_mac_os_version >= 0x1050) { CFStringRef str16 = CFStringCreateWithBytes(NULL, (const UInt8*)str8, n, kCFStringEncodingUTF8, false); @@ -443,14 +425,6 @@ else { return; } // fl_text_extents - -void fl_draw(const char *str, int n, float x, float y); - -void Fl_Quartz_Graphics_Driver::draw(const char* str, int n, int x, int y) { - fl_draw(str, n, (float)x-0.0f, (float)y+0.5f); -} - - #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 static CGColorRef flcolortocgcolor(Fl_Color i) { @@ -465,11 +439,7 @@ static CGColorRef flcolortocgcolor(Fl_Color i) } #endif - -void fl_draw(const char *str, int n, float x, float y) { - Fl_Font_Descriptor *fl_fontsize = fl_graphics_driver->font_descriptor(); - // avoid a crash if no font has been selected by user yet ! - check_default_font(); +static void fl_mac_draw(const char *str, int n, float x, float y, Fl_Font_Descriptor *fl_fontsize) { // convert to UTF-16 first UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n); #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 @@ -512,16 +482,28 @@ void fl_draw(const char *str, int n, float x, float y) { #endif } +void Fl_Quartz_Graphics_Driver::draw(const char *str, int n, float x, float y) { + // avoid a crash if no font has been selected by user yet ! + if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE); + fl_mac_draw(str, n, x, y, font_descriptor()); +} + +void Fl_Quartz_Graphics_Driver::draw(const char* str, int n, int x, int y) { + // avoid a crash if no font has been selected by user yet ! + if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE); + fl_mac_draw(str, n, (float)x-0.0f, (float)y+0.5f, font_descriptor()); +} + void Fl_Quartz_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) { CGContextSaveGState(fl_gc); CGContextTranslateCTM(fl_gc, x, y); CGContextRotateCTM(fl_gc, - angle*(M_PI/180) ); - fl_draw(str, n, (float)0., (float)0.); + draw(str, n, 0, 0); CGContextRestoreGState(fl_gc); } void Fl_Quartz_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { - draw(c, n, int(x - fl_width(c, n)), y); + draw(c, n, int(x - width(c, n)), y); } // diff --git a/src/fl_font_win32.cxx b/src/fl_font_win32.cxx index 361de323d..90c6a08b4 100644 --- a/src/fl_font_win32.cxx +++ b/src/fl_font_win32.cxx @@ -146,14 +146,14 @@ void Fl_GDI_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { fl_font(this, fnum, size, 0); } -int fl_height() { - Fl_Font_Descriptor *fl_fontsize = fl_graphics_driver->font_descriptor(); +int Fl_GDI_Graphics_Driver::height() { + Fl_Font_Descriptor *fl_fontsize = font_descriptor(); if (fl_fontsize) return (fl_fontsize->metr.tmAscent + fl_fontsize->metr.tmDescent); else return -1; } -int fl_descent() { - Fl_Font_Descriptor *fl_fontsize = fl_graphics_driver->font_descriptor(); +int Fl_GDI_Graphics_Driver::descent() { + Fl_Font_Descriptor *fl_fontsize = font_descriptor(); if (fl_fontsize) return fl_fontsize->metr.tmDescent; else return -1; } @@ -163,9 +163,9 @@ static xchar *wstr = NULL; static int wstr_len = 0; -double fl_width(const char* c, int n) { +double Fl_GDI_Graphics_Driver::width(const char* c, int n) { int i = 0; - if (!fl_graphics_driver->font_descriptor()) return -1.0; + if (!font_descriptor()) return -1.0; double w = 0.0; char *end = (char *)&c[n]; while (i < n) { @@ -176,14 +176,14 @@ double fl_width(const char* c, int n) { // if (l < 1) l = 1; i += l; if (!fl_nonspacing(ucs)) { - w += fl_width(ucs); + w += width(ucs); } } return w; } -double fl_width(unsigned int c) { - Fl_Font_Descriptor *fl_fontsize = fl_graphics_driver->font_descriptor(); +double Fl_GDI_Graphics_Driver::width(unsigned int c) { + Fl_Font_Descriptor *fl_fontsize = font_descriptor(); unsigned int r; r = (c & 0xFC00) >> 10; if (!fl_fontsize->width[r]) { @@ -255,8 +255,8 @@ static unsigned short *ext_buff = NULL; // UTF-16 converted version of input UTF static unsigned wc_len = 0; // current string buffer dimension static WORD *gi = NULL; // glyph indices array // Function to determine the extent of the "inked" area of the glyphs in a string -void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { - Fl_Font_Descriptor *fl_fontsize = fl_graphics_driver->font_descriptor(); +void Fl_GDI_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { + Fl_Font_Descriptor *fl_fontsize = font_descriptor(); if (!fl_fontsize) { w = 0; h = 0; dx = dy = 0; @@ -326,10 +326,10 @@ void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { exit_error: // some error here - just return fl_measure values - w = (int)fl_width(c, n); - h = fl_height(); + w = (int)width(c, n); + h = height(); dx = 0; - dy = fl_descent() - h; + dy = descent() - h; EXTENTS_UPDATE(dx, dy, w, h); return; } // fl_text_extents @@ -339,10 +339,10 @@ void Fl_GDI_Graphics_Driver::draw(const char* str, int n, int x, int y) { int lx = 0; char *end = (char *)&str[n]; COLORREF oldColor = SetTextColor(fl_gc, fl_RGB()); - SelectObject(fl_gc, fl_graphics_driver->font_descriptor()->fid); + SelectObject(fl_gc, font_descriptor()->fid); while (i < n) { unsigned int u; - unsigned int u1; + unsigned int u1; unsigned short ucs; // int l = fl_utf2ucs((const unsigned char*)str + i, n - i, &u); int l; @@ -351,7 +351,7 @@ void Fl_GDI_Graphics_Driver::draw(const char* str, int n, int x, int y) { x -= lx; u = u1; } else { - lx = (int) fl_width(u); + lx = (int) width(u); } ucs = u; if (l < 1) l = 1; @@ -367,7 +367,7 @@ void Fl_GDI_Graphics_Driver::draw(int angle, const char* str, int n, int x, int int i = 0, i2=0; char *end = (char *)&str[n]; COLORREF oldColor = SetTextColor(fl_gc, fl_RGB()); - SelectObject(fl_gc, fl_graphics_driver->font_descriptor()->fid); + SelectObject(fl_gc, font_descriptor()->fid); //unsigned short ucs[n]; //only GCC, but not MSVC unsigned short* ucs = new unsigned short[n]; while (i < n) { @@ -395,12 +395,12 @@ void Fl_GDI_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { } COLORREF oldColor = SetTextColor(fl_gc, fl_RGB()); - SelectObject(fl_gc, fl_graphics_driver->font_descriptor()->fid); + SelectObject(fl_gc, font_descriptor()->fid); #ifdef RTL_CHAR_BY_CHAR int i = 0; int lx = 0; while (i < wn) { // output char by char is very bad for Arabic but coherent with fl_width() - lx = (int) fl_width(wstr[i]); + lx = (int) width(wstr[i]); x -= lx; TextOutW(fl_gc, x, y, (WCHAR*)wstr + i, 1); if (fl_nonspacing(wstr[i])) { @@ -410,7 +410,7 @@ void Fl_GDI_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { } #else UINT old_align = SetTextAlign(fl_gc, TA_RIGHT | TA_RTLREADING); - TextOutW(fl_gc, x, y - fl_height() + fl_descent(), (WCHAR*)wstr, wn); + TextOutW(fl_gc, x, y - height() + descent(), (WCHAR*)wstr, wn); SetTextAlign(fl_gc, old_align); #endif SetTextColor(fl_gc, oldColor); diff --git a/src/fl_font_x.cxx b/src/fl_font_x.cxx index 8b09af235..46f7eeefd 100644 --- a/src/fl_font_x.cxx +++ b/src/fl_font_x.cxx @@ -278,36 +278,35 @@ void Fl_Xlib_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { } } -#define current_font (fl_graphics_driver->font_descriptor()->font) -int fl_height() { - if (fl_graphics_driver->font_descriptor()) return current_font->ascent + current_font->descent; +int Fl_Xlib_Graphics_Driver::height() { + if (font_descriptor()) return font_descriptor()->font->ascent + font_descriptor()->font->descent; else return -1; } -int fl_descent() { - if (fl_graphics_driver->font_descriptor()) return current_font->descent; +int Fl_Xlib_Graphics_Driver::descent() { + if (font_descriptor()) return font_descriptor()->font->descent; else return -1; } -double fl_width(const char* c, int n) { - if (fl_graphics_driver->font_descriptor()) return (double) XUtf8TextWidth(current_font, c, n); +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_width(unsigned int c) { - if (fl_graphics_driver->font_descriptor()) return (double) XUtf8UcsWidth(current_font, c); +double Fl_Xlib_Graphics_Driver::width(unsigned int c) { + if (font_descriptor()) return (double) XUtf8UcsWidth(font_descriptor()->font, c); else return -1; } -void fl_text_extents(const char *c, int n, int &dx, int &dy, int &W, int &H) { +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 (!fl_graphics_driver->font_descriptor()) fl_font(FL_HELVETICA, FL_NORMAL_SIZE); + if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE); font_gc = fl_gc; - XSetFont(fl_display, fl_gc, current_font->fid); + 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, current_font, fl_gc, &xx, &yy, &ww, &hh, c, n); + 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... diff --git a/src/fl_font_xft.cxx b/src/fl_font_xft.cxx index 552fd96c2..b01829a11 100644 --- a/src/fl_font_xft.cxx +++ b/src/fl_font_xft.cxx @@ -108,14 +108,12 @@ static Fl_Fontdesc built_in_table[] = { Fl_Fontdesc* fl_fonts = built_in_table; -#define current_font (fl_graphics_driver->font_descriptor()->font) - Fl_XFont_On_Demand fl_xfont; void *fl_xftfont = 0; //const char* fl_encoding_ = "iso8859-1"; const char* fl_encoding_ = "iso10646-1"; -static void fl_font(Fl_Xlib_Graphics_Driver *driver, Fl_Font fnum, Fl_Fontsize size, int angle) { +static void fl_xft_font(Fl_Xlib_Graphics_Driver *driver, Fl_Font fnum, Fl_Fontsize size, int angle) { if (fnum==-1) { // special case to stop font caching driver->Fl_Graphics_Driver::font(0, 0); return; @@ -145,10 +143,10 @@ static void fl_font(Fl_Xlib_Graphics_Driver *driver, Fl_Font fnum, Fl_Fontsize s } void Fl_Xlib_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { - fl_font(this,fnum,size,0); + fl_xft_font(this,fnum,size,0); } -static XftFont* fontopen(const char* name, bool core, int angle) { +static XftFont* fontopen(const char* name, Fl_Fontsize size, bool core, int angle) { // Check: does it look like we have been passed an old-school XLFD fontname? bool is_xlfd = false; int hyphen_count = 0; @@ -225,7 +223,7 @@ static XftFont* fontopen(const char* name, bool core, int angle) { // Construct a match pattern for the font we want... XftPatternAddInteger(fnt_pat, XFT_WEIGHT, weight); XftPatternAddInteger(fnt_pat, XFT_SLANT, slant); - XftPatternAddDouble (fnt_pat, XFT_PIXEL_SIZE, (double)fl_graphics_driver->size()); + XftPatternAddDouble (fnt_pat, XFT_PIXEL_SIZE, (double)size); XftPatternAddString (fnt_pat, XFT_ENCODING, fl_encoding_); // rotate font if angle!=0 @@ -285,7 +283,7 @@ static XftFont* fontopen(const char* name, bool core, int angle) { // last chance, just open any font in the right size the_font = XftFontOpen (fl_display, fl_screen, XFT_FAMILY, XftTypeString, "sans", - XFT_SIZE, XftTypeDouble, (double)fl_graphics_driver->size(), + XFT_SIZE, XftTypeDouble, (double)size, NULL); XftPatternDestroy(fnt_pat); if (!the_font) { @@ -342,7 +340,7 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize fsize, int #if HAVE_GL listbase = 0; #endif // HAVE_GL - font = fontopen(name, false, angle); + font = fontopen(name, fsize, false, angle); } Fl_Font_Descriptor::~Fl_Font_Descriptor() { @@ -373,57 +371,57 @@ static const wchar_t *utf8reformat(const char *str, int& n) return buffer; } -static void utf8extents(const char *str, int n, XGlyphInfo *extents) +static void utf8extents(Fl_Font_Descriptor *desc, const char *str, int n, XGlyphInfo *extents) { memset(extents, 0, sizeof(XGlyphInfo)); const wchar_t *buffer = utf8reformat(str, n); #ifdef __CYGWIN__ - XftTextExtents16(fl_display, current_font, (XftChar16 *)buffer, n, extents); + XftTextExtents16(fl_display, desc->font, (XftChar16 *)buffer, n, extents); #else - XftTextExtents32(fl_display, current_font, (XftChar32 *)buffer, n, extents); + XftTextExtents32(fl_display, desc->font, (XftChar32 *)buffer, n, extents); #endif } -int fl_height() { - if (fl_graphics_driver->font_descriptor()) return current_font->ascent + current_font->descent; +int Fl_Xlib_Graphics_Driver::height() { + if (font_descriptor()) return font_descriptor()->font->ascent + font_descriptor()->font->descent; else return -1; } -int fl_descent() { - if (fl_graphics_driver->font_descriptor()) return current_font->descent; +int Fl_Xlib_Graphics_Driver::descent() { + if (font_descriptor()) return font_descriptor()->font->descent; else return -1; } -double fl_width(const char *str, int n) { - if (!fl_graphics_driver->font_descriptor()) return -1.0; +double Fl_Xlib_Graphics_Driver::width(const char* str, int n) { + if (!font_descriptor()) return -1.0; XGlyphInfo i; - utf8extents(str, n, &i); + utf8extents(font_descriptor(), str, n, &i); return i.xOff; } -double fl_width(uchar c) { - return fl_width((const char *)(&c), 1); -} +/*double fl_width(uchar c) { + return fl_graphics_driver->width((const char *)(&c), 1); +}*/ -double fl_width(FcChar32 *str, int n) { - if (!fl_graphics_driver->font_descriptor()) return -1.0; +static double fl_xft_width(Fl_Font_Descriptor *desc, FcChar32 *str, int n) { + if (!desc) return -1.0; XGlyphInfo i; - XftTextExtents32(fl_display, current_font, str, n, &i); + XftTextExtents32(fl_display, desc->font, str, n, &i); return i.xOff; } -double fl_width(unsigned int c) { - return fl_width((FcChar32 *)(&c), 1); +double Fl_Xlib_Graphics_Driver::width(unsigned int c) { + return fl_xft_width(font_descriptor(), (FcChar32 *)(&c), 1); } -void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { - if (!fl_graphics_driver->font_descriptor()) { +void Fl_Xlib_Graphics_Driver::text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { + if (!font_descriptor()) { w = h = 0; dx = dy = 0; return; } XGlyphInfo gi; - utf8extents(c, n, &gi); + utf8extents(font_descriptor(), c, n, &gi); w = gi.width; h = gi.height; @@ -453,10 +451,10 @@ void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { // original fltk code did. // NOTE: On my test boxes (FC6, FC7, FC8, ubuntu8.04, 9.04, 9.10) this works // well for the fltk "built-in" font names. -static XFontStruct* load_xfont_for_xft2(void) { +static XFontStruct* load_xfont_for_xft2(Fl_Graphics_Driver *driver) { XFontStruct* xgl_font = 0; - int size = fl_graphics_driver->size(); - int fnum = fl_graphics_driver->font(); + int size = driver->size(); + int fnum = driver->font(); const char *wt_med = "medium"; const char *wt_bold = "bold"; const char *weight = wt_med; // no specifc weight requested - accept any @@ -521,7 +519,7 @@ static XFontStruct* load_xfont_for_xft2(void) { } // end of load_xfont_for_xft2 # endif -XFontStruct* fl_xxfont() { +static XFontStruct* fl_xxfont(Fl_Graphics_Driver *driver) { # if XFT_MAJOR > 1 // kludge! XFT 2 and later does not provide core fonts for us to use with GL // try to load a bitmap X font instead @@ -529,25 +527,27 @@ XFontStruct* fl_xxfont() { static int glsize = 0; static int glfont = -1; // Do we need to load a new font? - if ((!xgl_font) || (glsize != fl_graphics_driver->size()) || (glfont != fl_graphics_driver->font())) { + if ((!xgl_font) || (glsize != driver->size()) || (glfont != driver->font())) { // create a dummy XLFD for some font of the appropriate size... if (xgl_font) XFreeFont(fl_display, xgl_font); // font already loaded, free it - this *might* be a Bad Idea - glsize = fl_graphics_driver->size(); // record current font size - glfont = fl_graphics_driver->font(); // and face - xgl_font = load_xfont_for_xft2(); + glsize = driver->size(); // record current font size + glfont = driver->font(); // and face + xgl_font = load_xfont_for_xft2(driver); } return xgl_font; # else // XFT-1 provides a means to load a "core" font directly - if (current_font->core) return current_font->u.core.font; // is the current font a "core" font? If so, use it. + if (driver->font_descriptor()->font->core) { + return driver->font_descriptor()->font->u.core.font; // is the current font a "core" font? If so, use it. + } static XftFont* xftfont; if (xftfont) XftFontClose (fl_display, xftfont); - xftfont = fontopen(fl_fonts[fl_graphics_driver->font()].name, true); // else request XFT to load a suitable "core" font instead. + xftfont = fontopen(fl_fonts[driver->font()].name, driver->size(), true, 0); // else request XFT to load a suitable "core" font instead. return xftfont->u.core.font; # endif // XFT_MAJOR > 1 } XFontStruct* Fl_XFont_On_Demand::value() { - if (!ptr) ptr = fl_xxfont(); + if (!ptr) ptr = fl_xxfont(fl_graphics_driver); return ptr; } @@ -606,8 +606,8 @@ void Fl_Xlib_Graphics_Driver::draw(const char *str, int n, int x, int y) { // Use fltk's color allocator, copy the results to match what // XftCollorAllocValue returns: XftColor color; - color.pixel = fl_xpixel(fl_graphics_driver->color()); - uchar r,g,b; Fl::get_color(fl_graphics_driver->color(), r,g,b); + color.pixel = fl_xpixel(Fl_Graphics_Driver::color()); + uchar r,g,b; Fl::get_color(Fl_Graphics_Driver::color(), r,g,b); color.color.red = ((int)r)*0x101; color.color.green = ((int)g)*0x101; color.color.blue = ((int)b)*0x101; @@ -615,19 +615,19 @@ void Fl_Xlib_Graphics_Driver::draw(const char *str, int n, int x, int y) { const wchar_t *buffer = utf8reformat(str, n); #ifdef __CYGWIN__ - XftDrawString16(draw_, &color, current_font, x, y, (XftChar16 *)buffer, n); + XftDrawString16(draw_, &color, font_descriptor()->font, x, y, (XftChar16 *)buffer, n); #else - XftDrawString32(draw_, &color, current_font, x, y, (XftChar32 *)buffer, n); + XftDrawString32(draw_, &color, font_descriptor()->font, x, y, (XftChar32 *)buffer, n); #endif } void Fl_Xlib_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) { - fl_font(this, this->Fl_Graphics_Driver::font(), this->size(), angle); + fl_xft_font(this, this->Fl_Graphics_Driver::font(), this->size(), angle); this->draw(str, n, (int)x, (int)y); - this->font(this->Fl_Graphics_Driver::font(), this->size()); + fl_xft_font(this, this->Fl_Graphics_Driver::font(), this->size(), 0); } -static void fl_drawUCS4(const FcChar32 *str, int n, int x, int y) { +static void fl_drawUCS4(Fl_Graphics_Driver *driver, const FcChar32 *str, int n, int x, int y) { #if USE_OVERLAY XftDraw*& draw_ = fl_overlay ? draw_overlay : ::draw_; if (fl_overlay) { @@ -651,14 +651,14 @@ static void fl_drawUCS4(const FcChar32 *str, int n, int x, int y) { // Use fltk's color allocator, copy the results to match what // XftCollorAllocValue returns: XftColor color; - color.pixel = fl_xpixel(fl_graphics_driver->color()); - uchar r,g,b; Fl::get_color(fl_graphics_driver->color(), r,g,b); + color.pixel = fl_xpixel(driver->color()); + uchar r,g,b; Fl::get_color(driver->color(), r,g,b); color.color.red = ((int)r)*0x101; color.color.green = ((int)g)*0x101; color.color.blue = ((int)b)*0x101; color.color.alpha = 0xffff; - XftDrawString32(draw_, &color, current_font, x, y, (FcChar32 *)str, n); + XftDrawString32(draw_, &color, driver->font_descriptor()->font, x, y, (FcChar32 *)str, n); } @@ -694,8 +694,8 @@ void Fl_Xlib_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { out = out - 1; } // Now we have a UCS4 version of the input text, reversed, in ucs_txt - int offs = (int)fl_width(ucs_txt, n); - fl_drawUCS4(ucs_txt, n, (x-offs), y); + int offs = (int)fl_xft_width(font_descriptor(), ucs_txt, n); + fl_drawUCS4(this, ucs_txt, n, (x-offs), y); delete[] ucs_txt; } diff --git a/src/gl_draw.cxx b/src/gl_draw.cxx index 913b47389..a15a15123 100644 --- a/src/gl_draw.cxx +++ b/src/gl_draw.cxx @@ -45,7 +45,7 @@ #endif #if USE_XFT -extern XFontStruct* fl_xxfont(); +//extern XFontStruct* fl_xxfont(); #endif // USE_XFT /** Returns the current font's height */