Index: FL/Fl_Graphics_Driver.H
===================================================================
--- FL/Fl_Graphics_Driver.H	(Revision 12618)
+++ FL/Fl_Graphics_Driver.H	(Arbeitskopie)
@@ -350,6 +350,7 @@
   /** Compute the width of Unicode character \p c if drawn with current font */
   virtual double width(unsigned int c) { char ch = (char)c; return width(&ch, 1); }
   virtual void 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& w);
   /** Return the current line height */
   virtual int height() { return size(); }
   /** Return the current line descent */
@@ -464,7 +465,9 @@
   virtual Fl_Fontsize size();
   virtual Fl_Fontsize size_unscaled()=0;
   virtual void text_extents(const char *str, int n, int &dx, int &dy, int &w, int &h);
+  virtual void text_extents(const char*, int n, int& dx, int& w);
   virtual void text_extents_unscaled(const char *str, int n, int &dx, int &dy, int &w, int &h)=0;
+  virtual void text_extents_unscaled(const char *str, int n, int &dx, int &w);
   virtual int height();
   virtual int descent();
   virtual int height_unscaled()=0;
Index: FL/Fl_Text_Display.H
===================================================================
--- FL/Fl_Text_Display.H	(Revision 12618)
+++ FL/Fl_Text_Display.H	(Arbeitskopie)
@@ -451,7 +451,7 @@
   void calc_last_char();
   
   int position_to_line( int pos, int* lineNum ) const;
-  double string_width(const char* string, int length, int style) const;
+  double string_width(const char* string, int length, int style, bool bounding = false) const;
   
   static void scroll_timer_cb(void*);
   
Index: FL/fl_draw.H
===================================================================
--- FL/fl_draw.H	(Revision 12618)
+++ FL/fl_draw.H	(Arbeitskopie)
@@ -601,6 +601,9 @@
 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);}
 
+inline void fl_text_extents(const char *t, int n, int& dx, int& w)
+  {fl_graphics_driver->text_extents(t, n, dx, w);}
+
 // font encoding:
 // Note: doxygen comments here to avoid duplication for os-sepecific cases
 /**
Index: src/Fl_Graphics_Driver.cxx
===================================================================
--- src/Fl_Graphics_Driver.cxx	(Revision 12618)
+++ src/Fl_Graphics_Driver.cxx	(Arbeitskopie)
@@ -61,6 +61,15 @@
   dy = descent();
 }
 
+
+/** see fl_text_extents() */
+void Fl_Graphics_Driver::text_extents(const char*t, int n, int& dx, int& w)
+{
+  int h, dy;
+  text_extents(t, n, dx, dy, w, h);
+}
+
+
 /** see fl_focus_rect() */
 void Fl_Graphics_Driver::focus_rect(int x, int y, int w, int h)
 {
@@ -456,6 +465,17 @@
   h /= scale_;
 }
 
+void Fl_Scalable_Graphics_Driver::text_extents_unscaled(const char *str, int n, int &dx, int &w) {
+  int h, dy;
+  text_extents_unscaled(str, n, dx, dy, w, h);
+}
+
+void Fl_Scalable_Graphics_Driver::text_extents(const char *str, int n, int &dx, int &w) {
+  text_extents_unscaled(str, n, dx, w);
+  dx /= scale_;
+  w /= scale_;
+}
+
 int Fl_Scalable_Graphics_Driver::height() {
   return int(height_unscaled()/scale_);
 }
Index: src/Fl_Text_Display.cxx
===================================================================
--- src/Fl_Text_Display.cxx	(Revision 12618)
+++ src/Fl_Text_Display.cxx	(Arbeitskopie)
@@ -2031,7 +2031,8 @@
         }
       } else {
         // draw a text segment
-        w = string_width( lineStr+startIndex, i-startIndex, style );
+        w = string_width( lineStr+startIndex, i-startIndex, style,
+                          (mode!=GET_WIDTH) && (style==charStyle));
         if (mode==DRAW_LINE)
           draw_string( style, startX, Y, startX+w, lineStr+startIndex, i-startIndex );
         if (mode==FIND_INDEX && startX+w>rightClip) {
@@ -2065,7 +2066,7 @@
       return lineStartPos + startIndex + ( rightClip-startX>w ? 1 : 0 );
     }
   } else {
-    w = string_width( lineStr+startIndex, i-startIndex, style );
+    w = string_width( lineStr+startIndex, i-startIndex, style, mode!=GET_WIDTH );
     if (mode==DRAW_LINE)
       draw_string( style, startX, Y, startX+w, lineStr+startIndex, i-startIndex );
     if (mode==FIND_INDEX) {
@@ -2473,7 +2474,7 @@
  \param style index into style table
  \return width of text segment in pixels
  */
-double Fl_Text_Display::string_width( const char *string, int length, int style ) const {
+double Fl_Text_Display::string_width( const char *string, int length, int style, bool bounding/* = false*/ ) const {
   IS_UTF8_ALIGNED(string)
 
   Fl_Font font;
@@ -2491,7 +2492,13 @@
     fsize = textsize();
   }
   fl_font( font, fsize );
-  return fl_width( string, length );
+  int W = fl_width( string, length );
+  if ( !bounding )
+    return W;
+  int dx, w;
+  fl_text_extents( string, length, dx, w );
+  w += dx;
+  return W > w ? W : w;
 }
 
 
Index: src/drivers/GDI/Fl_GDI_Graphics_Driver.H
===================================================================
--- src/drivers/GDI/Fl_GDI_Graphics_Driver.H	(Revision 12618)
+++ src/drivers/GDI/Fl_GDI_Graphics_Driver.H	(Arbeitskopie)
@@ -79,6 +79,7 @@
   virtual double width_unscaled(const char *str, int n);
   virtual double width_unscaled(unsigned int c);
   void text_extents_unscaled(const char*, int n, int& dx, int& dy, int& w, int& h);
+  void text_extents_unscaled(const char*, int n, int& dx, int& w);
   int height_unscaled();
   int descent_unscaled();
   Fl_Fontsize size_unscaled();
Index: src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx
===================================================================
--- src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx	(Revision 12618)
+++ src/drivers/GDI/Fl_GDI_Graphics_Driver_font.cxx	(Arbeitskopie)
@@ -584,6 +584,82 @@
   return;
 } // fl_text_extents
 
+
+// Function to determine the extent of the "inked" width of the glyphs in a string
+void Fl_GDI_Graphics_Driver::text_extents_unscaled(const char *c, int n, int &dx, int &w) {
+
+  dx = 0;
+  w = 0;
+  Fl_Font_Descriptor *fl_fontsize = font_descriptor();
+  if (!fl_fontsize) { // no valid font, nothing to measure
+    return;
+  }
+
+  static unsigned short *ext_buff = NULL; // UTF-16 converted version of input UTF-8 string
+  static WORD  *w_buff = NULL; // glyph indices array
+  static unsigned wc_len = 0;  // current string buffer dimensions
+  unsigned len = 0;
+  HWND hWnd = 0;
+  HDC gc2 = gc_; // local copy of current gc - make a copy in case we change it...
+
+  // The following code makes a best effort attempt to obtain a valid fl_gc.
+  // See description in fl_width() above for an explanation.
+  if (!gc2) { // We have no valid gc, try and obtain one
+    // Use our first fltk window, or fallback to using the screen via GetDC(NULL)
+    hWnd = Fl::first_window() ? fl_xid(Fl::first_window()) : NULL;
+    gc2 = GetDC(hWnd);
+  }
+  if (!gc2) { // no valid gc, attempt to use fallback measure
+    // just return fl_measure values
+    w = (int)width(c, n);
+    return;
+  }
+  // now convert the string to WCHAR and measure it
+  len = fl_utf8toUtf16(c, n, ext_buff, wc_len);
+  if(len >= wc_len) {
+    if(ext_buff) {delete [] ext_buff;}
+    if(w_buff) {delete [] w_buff;}
+    wc_len = len + 64;
+    ext_buff = new unsigned short[wc_len];
+    w_buff = new WORD[wc_len];
+    len = fl_utf8toUtf16(c, n, ext_buff, wc_len);
+  }
+  SelectObject(gc2, fl_fontsize->fid);
+
+  SIZE sizeRect;
+  if (!::GetTextExtentPoint32W(gc2, (WCHAR*)ext_buff, len, &sizeRect)) {
+    // just return fl_measure values
+    w = (int)width(c, n);
+    return;
+  }
+  // Note: this is an adapted version of code found in wxWidgets 'textmeasure.cpp'
+
+  // the result computed by GetTextExtentPoint32() may be too small as it
+  // accounts for under/overhang of the first/last character while we want
+  // just the bounding rect for this string so adjust the width as needed
+  if ( len > 0 ) {
+    ABC widthABC;
+    const WCHAR chFirst = ((WCHAR*)ext_buff)[0];
+    if (::GetCharABCWidthsW(gc2, chFirst, chFirst, &widthABC)) {
+      if (widthABC.abcA < 0)
+        sizeRect.cx -= widthABC.abcA;
+
+      if (len > 1) {
+        const WCHAR chLast = ((WCHAR*)ext_buff)[len - 1];
+        ::GetCharABCWidthsW(gc2, chLast, chLast, &widthABC);
+      }
+      //else: we already have the width of the last character
+
+      if (widthABC.abcC < 0)
+        sizeRect.cx -= widthABC.abcC;
+     }
+     //else: GetCharABCWidths() failed, not a TrueType font?
+  }
+
+  w = sizeRect.cx;
+  return; // normal exit
+} // fl_text_extents
+
