Author: ianmacarthur
Date: 2008-11-19 12:34:27 -0800 (Wed, 19 Nov 2008)
New Revision: 6529
Log:
STR 2076: experimental fl_text_extents patch applied. Please feedback comments.



Modified:
   branches/branch-1.3/FL/fl_draw.H
   branches/branch-1.3/src/fl_font.cxx
   branches/branch-1.3/src/fl_font_mac.cxx
   branches/branch-1.3/src/fl_font_win32.cxx
   branches/branch-1.3/src/fl_font_x.cxx
   branches/branch-1.3/src/fl_font_xft.cxx

Modified: branches/branch-1.3/FL/fl_draw.H
===================================================================
--- branches/branch-1.3/FL/fl_draw.H    2008-11-16 19:44:58 UTC (rev 6528)
+++ branches/branch-1.3/FL/fl_draw.H    2008-11-19 20:34:27 UTC (rev 6529)
@@ -194,12 +194,16 @@
   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.

Modified: branches/branch-1.3/src/fl_font.cxx
===================================================================
--- branches/branch-1.3/src/fl_font.cxx 2008-11-16 19:44:58 UTC (rev 6528)
+++ branches/branch-1.3/src/fl_font.cxx 2008-11-19 20:34:27 UTC (rev 6529)
@@ -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 @@
   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);

Modified: branches/branch-1.3/src/fl_font_mac.cxx
===================================================================
--- branches/branch-1.3/src/fl_font_mac.cxx     2008-11-16 19:44:58 UTC (rev 
6528)
+++ branches/branch-1.3/src/fl_font_mac.cxx     2008-11-19 20:34:27 UTC (rev 
6529)
@@ -268,6 +268,48 @@
   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) {

Modified: branches/branch-1.3/src/fl_font_win32.cxx
===================================================================
--- branches/branch-1.3/src/fl_font_win32.cxx   2008-11-16 19:44:58 UTC (rev 
6528)
+++ branches/branch-1.3/src/fl_font_win32.cxx   2008-11-19 20:34:27 UTC (rev 
6529)
@@ -37,19 +37,19 @@
   }
   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 @@
   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;

Modified: branches/branch-1.3/src/fl_font_x.cxx
===================================================================
--- branches/branch-1.3/src/fl_font_x.cxx       2008-11-16 19:44:58 UTC (rev 
6528)
+++ branches/branch-1.3/src/fl_font_x.cxx       2008-11-19 20:34:27 UTC (rev 
6529)
@@ -296,6 +296,16 @@
   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);

Modified: branches/branch-1.3/src/fl_font_xft.cxx
===================================================================
--- branches/branch-1.3/src/fl_font_xft.cxx     2008-11-16 19:44:58 UTC (rev 
6528)
+++ branches/branch-1.3/src/fl_font_xft.cxx     2008-11-19 20:34:27 UTC (rev 
6529)
@@ -338,6 +338,22 @@
   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 @@
 // 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 @@
   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
   }

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to