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
This commit is contained in:
parent
9c7af9b2cf
commit
865f3d8e61
10
FL/fl_draw.H
10
FL/fl_draw.H
@ -194,12 +194,16 @@ inline int fl_height(int, int size) {return size;}
|
||||
draw the text at so it looks centered vertically in that box.
|
||||
*/
|
||||
FL_EXPORT int fl_descent();
|
||||
/** Return the pixel width of a nul-terminated string */
|
||||
/** Return the typographical width of a nul-terminated string */
|
||||
FL_EXPORT double fl_width(const char* txt);
|
||||
/** Return the pixel width of a sequence of \a n characters */
|
||||
/** Return the typographical width of a sequence of \a n characters */
|
||||
FL_EXPORT double fl_width(const char* txt, int n);
|
||||
/** Return the pixed width of a single character */
|
||||
/** Return the typographical width of a single character */
|
||||
FL_EXPORT double fl_width(Fl_Unichar);
|
||||
/** Determine the minimum pixel dimensions of a nul-terminated string */
|
||||
FL_EXPORT void fl_text_extents(const char*, int& dx, int& dy, int& w, int& h); // NO fltk symbol expansion
|
||||
/** Determine the minimum pixel dimensions of a sequence of \a n characters */
|
||||
FL_EXPORT void fl_text_extents(const char*, int n, int& dx, int& dy, int& w, int& h);
|
||||
|
||||
/**
|
||||
Draw a nul-terminated string starting at the given location.
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user