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
This commit is contained in:
Manolo Gouy
2011-02-18 13:39:48 +00:00
parent 2c129b4833
commit 199b32d921
11 changed files with 224 additions and 171 deletions
+35 -1
View File
@@ -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.
<br> 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
+7
View File
@@ -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);};
+6 -5
View File
@@ -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
+8
View File
@@ -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$".
//
+43 -23
View File
@@ -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);
+4 -2
View File
@@ -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$".
//
+35 -53
View File
@@ -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);
}
//
+21 -21
View File
@@ -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);
+12 -13
View File
@@ -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...
+52 -52
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -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 */