diff options
| author | Ian MacArthur <imacarthur@gmail.com> | 2008-11-19 20:34:27 +0000 |
|---|---|---|
| committer | Ian MacArthur <imacarthur@gmail.com> | 2008-11-19 20:34:27 +0000 |
| commit | 865f3d8e61f5fe7a582f1233b90bd2ef8260c827 (patch) | |
| tree | 09421807f61cff4476a26387880c9bcef15e0e27 /src | |
| parent | 9c7af9b2cf586dd9aaf0b11793514f458d09afed (diff) | |
STR 2076: experimental fl_text_extents patch applied. Please feedback comments.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6529 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
| -rw-r--r-- | src/fl_font.cxx | 19 | ||||
| -rw-r--r-- | src/fl_font_mac.cxx | 42 | ||||
| -rw-r--r-- | src/fl_font_win32.cxx | 82 | ||||
| -rw-r--r-- | src/fl_font_x.cxx | 10 | ||||
| -rw-r--r-- | src/fl_font_xft.cxx | 26 |
5 files changed, 164 insertions, 15 deletions
diff --git a/src/fl_font.cxx b/src/fl_font.cxx index bb65303b7..20bdc198b 100644 --- a/src/fl_font.cxx +++ b/src/fl_font.cxx @@ -25,6 +25,17 @@ // http://www.fltk.org/str.php // +#ifdef WIN32 +# define WIN32_LEAN_AND_MEAN +/* We require Windows 2000 features such as GetGlyphIndices */ +# if !defined(WINVER) || (WINVER < 0x0500) +# define WINVER 0x0500 +# endif +# if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) +# define _WIN32_WINNT 0x0500 +# endif +#endif + // Select fonts from the FLTK font table. #include "flstring.h" #include <FL/Fl.H> @@ -55,6 +66,14 @@ void fl_draw(const char* str, int x, int y) { fl_draw(str, strlen(str), x, y); } +void fl_text_extents(const char *c, int &dx, int &dy, int &w, int &h) { + if (c) return fl_text_extents(c, strlen(c), dx, dy, w, h); + // else + w = 0; h = 0; + dx = 0; dy = 0; +} // fl_text_extents + + #if !USE_XFT && !__APPLE__ void fl_draw(const char* str, int l, float x, float y) { fl_draw(str, l, (int)x, (int)y); diff --git a/src/fl_font_mac.cxx b/src/fl_font_mac.cxx index c5d04c6ed..15791f0e1 100644 --- a/src/fl_font_mac.cxx +++ b/src/fl_font_mac.cxx @@ -268,6 +268,48 @@ double fl_width(unsigned int wc) { return fl_width((const UniChar*)(&wc), 1); } +// text extent calculation +void fl_text_extents(const UniChar* txt, int n, int &dx, int &dy, int &w, int &h) { + if (!fl_fontsize) { + check_default_font(); // avoid a crash! + if (!fl_fontsize) + w = 8.0 * n; // user must select a font first! + h = 8.0; + return; + } + OSStatus err; + ATSUTextLayout layout; + ByteCount iSize; + ATSUAttributeTag iTag; + ATSUAttributeValuePtr iValuePtr; + +// Here's my ATSU text measuring attempt... This seems to do the Right Thing + // now collect our ATSU resources and measure our text string + layout = fl_fontsize->layout; + // activate the current GC + iSize = sizeof(CGContextRef); + iTag = kATSUCGContextTag; + iValuePtr = &fl_gc; + ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr); + // now measure the bounding box + err = ATSUSetTextPointerLocation(layout, txt, kATSUFromTextBeginning, n, n); + Rect bbox; + err = ATSUMeasureTextImage(layout, kATSUFromTextBeginning, n, 0, 0, &bbox); + w = bbox.right - bbox.left; + h = bbox.bottom - bbox.top; + dx = bbox.left; + dy = -bbox.bottom; +//printf("r: %d l: %d t: %d b: %d w: %d h: %d\n", bbox.right, bbox.left, bbox.top, bbox.bottom, w, h); + return; +} // fl_text_extents + +void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { + int wc_len = n; + UniChar *uniStr = mac_Utf8_to_Utf16(c, n, &wc_len); + fl_text_extents(uniStr, wc_len, dx, dy, w, h); +} // fl_text_extents + + void fl_draw(const char *str, int n, float x, float y); void fl_draw(const char* str, int n, int x, int y) { diff --git a/src/fl_font_win32.cxx b/src/fl_font_win32.cxx index f55389126..eda3d7878 100644 --- a/src/fl_font_win32.cxx +++ b/src/fl_font_win32.cxx @@ -37,19 +37,19 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize size) { } fid = CreateFont( -size, // negative makes it use "char size" - 0, // logical average character width - 0, // angle of escapement - 0, // base-line orientation angle + 0, // logical average character width + 0, // angle of escapement + 0, // base-line orientation angle weight, italic, - FALSE, // underline attribute flag - FALSE, // strikeout attribute flag - DEFAULT_CHARSET, // character set identifier - OUT_DEFAULT_PRECIS, // output precision - CLIP_DEFAULT_PRECIS,// clipping precision - DEFAULT_QUALITY, // output quality - DEFAULT_PITCH, // pitch and family - name // pointer to typeface name string + FALSE, // underline attribute flag + FALSE, // strikeout attribute flag + DEFAULT_CHARSET, // character set identifier + OUT_DEFAULT_PRECIS, // output precision + CLIP_DEFAULT_PRECIS,// clipping precision + DEFAULT_QUALITY, // output quality + DEFAULT_PITCH, // pitch and family + name // pointer to typeface name string ); if (!fl_gc) fl_GetDC(0); SelectObject(fl_gc, fid); @@ -191,6 +191,66 @@ double fl_width(unsigned int c) { return (double) fl_fontsize->width[r][c & 0x03FF]; } +static unsigned short *ext_buff = NULL; // UTF-16 converted string +static unsigned wc_len = 0; // current string buffer dimension +static WORD *gi = NULL; // glyph indices array +void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { + if (!fl_fontsize) { + w = 0; h = 0; + dx = dy = 0; + return; + } + static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } }; + GLYPHMETRICS metrics; + int maxw = 0, maxh = 0, dh; + int minx = 0, miny = -999999; + // now convert the string to WCHAR and measure it + unsigned len = fl_utf8toUtf16(c, n, ext_buff, wc_len); + if(len >= wc_len) { + if(ext_buff) {delete [] ext_buff;} + if(gi) {delete [] gi;} + wc_len = len + 64; + ext_buff = new unsigned short[wc_len]; + gi = new WORD[wc_len]; + len = fl_utf8toUtf16(c, n, ext_buff, wc_len); + } + SelectObject(fl_gc, fl_fontsize->fid); + + if (GetGlyphIndicesW(fl_gc, (WCHAR*)ext_buff, len, gi, 0) == GDI_ERROR) { + // some error occured here - just return fl_measure values? + goto exit_error; + } + + // now we have the glyph array we measure each glyph in turn... + for(unsigned idx = 0; idx < len; idx++){ + if (GetGlyphOutlineW (fl_gc, gi[idx], GGO_METRICS | GGO_GLYPH_INDEX, + &metrics, 0, NULL, &matrix) == GDI_ERROR) { + goto exit_error; + } + maxw += metrics.gmCellIncX; + if(idx == 0) minx = metrics.gmptGlyphOrigin.x; + dh = metrics.gmBlackBoxY - metrics.gmptGlyphOrigin.y; + if(dh > maxh) maxh = dh; + if(miny < metrics.gmptGlyphOrigin.y) miny = metrics.gmptGlyphOrigin.y; + } + + // for the last cell, we only want the bounding X-extent, not the glyphs increment step + maxw = maxw - metrics.gmCellIncX + metrics.gmBlackBoxX + metrics.gmptGlyphOrigin.x; + w = maxw - minx; + h = maxh + miny; + dx = minx; + dy = -miny; + return; // normal exit + +exit_error: + // some error here - just return fl_measure values + w = (int)fl_width(c, n); + h = fl_height(); + dx = 0; + dy = fl_descent() - h; + return; +} // fl_text_extents + void fl_draw(const char* str, int n, int x, int y) { int i = 0; int lx = 0; diff --git a/src/fl_font_x.cxx b/src/fl_font_x.cxx index 04b3738d8..aeabe6765 100644 --- a/src/fl_font_x.cxx +++ b/src/fl_font_x.cxx @@ -296,6 +296,16 @@ double fl_width(unsigned int c) { else return -1; } + +void fl_text_extents(const char *c, int n, int &dx, int &dy, int &W, int &H) { +#warning fl_text_extents is only a test stub in Xlib build at present + w = 0; h = 0; + fl_measure(c, &w, &h, 0); + dx = 0; + dy = fl_descent() - h; +} // fl_text_extents + + void fl_draw(const char* c, int n, int x, int y) { if (font_gc != fl_gc) { if (!fl_xfont) fl_font(FL_HELVETICA, 14); diff --git a/src/fl_font_xft.cxx b/src/fl_font_xft.cxx index 6d73de6b4..970db3ccd 100644 --- a/src/fl_font_xft.cxx +++ b/src/fl_font_xft.cxx @@ -338,6 +338,22 @@ double fl_width(unsigned int c) { return fl_width((FcChar32 *)(&c), 1); } +void fl_text_extents(const char *c, int n, int &dx, int &dy, int &w, int &h) { + if (!current_font) { + w = h = 0; + dx = dy = 0; + return; + } + XGlyphInfo gi; + XftTextExtentsUtf8(fl_display, current_font, (XftChar8 *)c, n, &gi); + + w = gi.width; + h = gi.height; + dx = -gi.x; + dy = -gi.y; +} // fl_text_extents + + #if HAVE_GL /* This code is used by opengl to get a bitmapped font. The original XFT-1 code * used XFT's "core" fonts methods to load an XFT font that was actually a @@ -358,12 +374,14 @@ double fl_width(unsigned int c) { // If this code fails to load the requested font, it falls back through a // series of tried 'n tested alternatives, ultimately resorting to what the // original fltk code did. -// NOTE: -// On my test boxes (FC6, FC7) this works well for the fltk "built-in" font names. +// NOTE: On my test boxes (FC6, FC7, FC8, ubuntu8.04) this works well for the +// fltk "built-in" font names. static XFontStruct* load_xfont_for_xft2(void) { XFontStruct* xgl_font = 0; int size = fl_size_; - char *weight = "medium"; // no specifc weight requested - accept any + const char *wt_med = "medium"; + const char *wt_bold = "bold"; + char *weight = (char *)wt_med; // no specifc weight requested - accept any char slant = 'r'; // regular non-italic by default char xlfd[128]; // we will put our synthetic XLFD in here char *pc = strdup(fl_fonts[fl_font_].name); // what font were we asked for? @@ -372,7 +390,7 @@ static XFontStruct* load_xfont_for_xft2(void) { switch (*name++) { case 'I': slant = 'i'; break; // italic case 'P': slant = 'i'; // bold-italic (falls-through) - case 'B': weight = "bold"; break; // bold + case 'B': weight = (char*)wt_bold; break; // bold case ' ': break; // regular default: name--; // no prefix, restore name } |
