Index: CMake/options.cmake
===================================================================
--- CMake/options.cmake	(revision 11746)
+++ CMake/options.cmake	(working copy)
@@ -329,8 +329,35 @@
 #######################################################################
 if(X11_Xft_FOUND)
    option(OPTION_USE_XFT "use lib Xft" ON)
+   option(OPTION_PANGO "use lib Pango" OFF)
 endif(X11_Xft_FOUND)
 
+#######################################################################
+if(X11_Xft_FOUND AND OPTION_PANGO)
+#this search list covers Debian, Ubuntu, FreeBSD, NetBSD, Darwin
+  list(APPEND PANGO_SEARCH_LIST /usr/include/pango-1.0 /usr/local/include/pango-1.0
+    /usr/pkg/include/pango-1.0 /sw/include/pango-1.0)
+  find_file(HAS_PANGO_H pango/pango.h ${PANGO_SEARCH_LIST})
+  find_file(HAS_PANGOXFT_H pango/pangoxft.h ${PANGO_SEARCH_LIST})
+  if(HAS_PANGO_H AND HAS_PANGOXFT_H)
+    list(APPEND PANGOLIB_SEARCH_LIST /usr/local/lib /sw/lib)
+    find_library(HAS_LIB_PANGO pango-1.0 ${PANGOLIB_SEARCH_LIST})
+    find_library(HAS_LIB_PANGOXFT pangoxft-1.0 ${PANGOLIB_SEARCH_LIST})
+    find_library(HAS_LIB_GOBJECT gobject-2.0 ${PANGOLIB_SEARCH_LIST})
+  endif(HAS_PANGO_H AND HAS_PANGOXFT_H)
+  if(HAS_LIB_PANGO AND HAS_LIB_PANGOXFT AND HAS_LIB_GOBJECT)
+    set(USE_PANGO TRUE)
+message(STATUS "USE_PANGO=" ${USE_PANGO})
+    #remove last 3 components of HAS_PANGO_H and put in PANGO_H_PREFIX
+    get_filename_component(PANGO_H_PREFIX ${HAS_PANGO_H} PATH)
+    get_filename_component(PANGO_H_PREFIX ${PANGO_H_PREFIX} PATH)
+    get_filename_component(PANGO_H_PREFIX ${PANGO_H_PREFIX} PATH)
+
+    get_filename_component(PANGOLIB_DIR ${HAS_LIB_PANGO} PATH)
+    include_directories(${PANGO_H_PREFIX}/pango-1.0 ${PANGO_H_PREFIX}/glib-2.0 ${PANGOLIB_DIR}/glib-2.0/include /usr/pkg/include/glib/glib-2.0 )
+  endif(HAS_LIB_PANGO AND HAS_LIB_PANGOXFT AND HAS_LIB_GOBJECT)
+endif(X11_Xft_FOUND AND OPTION_PANGO)
+
 if(OPTION_USE_XFT)
    set(USE_XFT X11_Xft_FOUND)
    list(APPEND FLTK_LDLIBS -lXft)
Index: configh.cmake.in
===================================================================
--- configh.cmake.in	(revision 11746)
+++ configh.cmake.in	(working copy)
@@ -92,6 +92,14 @@
 #cmakedefine01 USE_XFT
 
 /*
+* USE_PANGO:
+*
+* Use the pango library to draw UTF8 text.
+*/
+
+#cmakedefine USE_PANGO 1
+
+/*
  * HAVE_XDBE:
  *
  * Do we have the X double-buffer extension?
Index: src/CMakeLists.txt
===================================================================
--- src/CMakeLists.txt	(revision 11746)
+++ src/CMakeLists.txt	(working copy)
@@ -472,6 +472,10 @@
     list (APPEND OPTIONAL_LIBS ${X11_Xrender_LIB})
 endif (HAVE_XRENDER)
 
+if (USE_PANGO)
+  list (APPEND OPTIONAL_LIBS ${HAS_LIB_PANGO} ${HAS_LIB_PANGOXFT} ${HAS_LIB_GOBJECT})
+endif(USE_PANGO)
+
 if (USE_XFT)
     list (APPEND OPTIONAL_LIBS ${X11_Xft_LIB})
     if (LIB_fontconfig)
Index: src/drivers/Xlib/Fl_Font.H
===================================================================
--- src/drivers/Xlib/Fl_Font.H	(revision 11746)
+++ src/drivers/Xlib/Fl_Font.H	(working copy)
@@ -45,8 +45,12 @@
   Fl_Fontsize size; /**< font size */
 #ifndef FL_DOXYGEN // don't bother with platorm dependant details in the doc. 
 #  if USE_XFT
-  XftFont* font;
-  //const char* encoding;
+#    if USE_PANGO
+        int descent_;
+        int height_;
+#    else
+        XftFont* font;
+#    endif
   int angle;
   FL_EXPORT Fl_Font_Descriptor(const char* xfontname, Fl_Fontsize size, int angle);
 #  else
Index: src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
===================================================================
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H	(revision 11746)
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H	(working copy)
@@ -27,14 +27,31 @@
 
 #include <FL/Fl_Graphics_Driver.H>
 #include <FL/x.H>
-
+#if USE_PANGO
+#include <pango/pangoxft.h>
+#endif
 /**
  \brief The Xlib-specific graphics class.
  *
  This class is implemented only on the Xlib platform.
  */
 class FL_EXPORT Fl_Xlib_Graphics_Driver : public Fl_Graphics_Driver {
+#if USE_XFT
+  void drawUCS4(const void *str, int n, int x, int y);
+#endif
+#if USE_PANGO
+  friend class Fl;
+  PangoFontDescription *pfd_;
+  static PangoContext *pctxt_;
+  static PangoFontMap *pfmap_;
+  static PangoLayout *playout_;
 protected:
+  void do_draw(int from_right, const char *str, int n, int x, int y);
+  static PangoContext *context();
+  static void init_built_in_fonts();
+  static int set_fonts();
+#endif
+protected:
   static GC gc_;
   uchar **mask_bitmap_;
   uchar **mask_bitmap() {return mask_bitmap_;}
@@ -42,9 +59,13 @@
   int p_size;
   typedef struct {short x, y;} XPOINT;
   XPOINT *p;
+#if USE_XFT
+  static Window draw_window;
+  static struct _XftDraw* draw_;
+#endif
 public:
   Fl_Xlib_Graphics_Driver(void);
-  virtual ~Fl_Xlib_Graphics_Driver() { if (p) free(p); }
+  virtual ~Fl_Xlib_Graphics_Driver();
   virtual int has_feature(driver_feature mask) { return mask & NATIVE; }
   virtual void *gc() { return gc_; }
   virtual void gc(void *value);
Index: src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx
===================================================================
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx	(revision 11746)
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx	(working copy)
@@ -30,6 +30,9 @@
 
 extern XIC fl_xim_ic;
 extern char fl_is_over_the_spot;
+#if !USE_XFT
+extern char *fl_get_font_xfld(int fnum, int size);
+#endif
 
 
 /*
@@ -57,8 +60,20 @@
   mask_bitmap_ = NULL;
   p_size = 0;
   p = NULL;
+#if USE_PANGO
+  pfd_ = pango_font_description_new();
+  Fl_Graphics_Driver::font(0, 0);
+#endif
 }
 
+Fl_Xlib_Graphics_Driver::~Fl_Xlib_Graphics_Driver() {
+  if (p) free(p);
+#if USE_PANGO
+  pango_font_description_free(pfd_);
+#endif
+}
+
+
 void Fl_Xlib_Graphics_Driver::gc(void *value) {
   gc_ = (GC)value;
   fl_gc = gc_;
Index: src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
===================================================================
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx	(revision 11772)
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx	(working copy)
@@ -16,7 +16,8 @@
 //     http://www.fltk.org/str.php
 //
 
-// Select fonts from the FLTK font table.
+#ifndef FL_DOXYGEN
+
 #include "../../flstring.h"
 #include "Fl_Xlib_Graphics_Driver.H"
 #include <FL/Fl.H>
@@ -26,46 +27,107 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <math.h>
 
 #include <X11/Xft/Xft.h>
+#include <X11/Xft/XftCompat.h>
 
-// This function fills in the fltk font table with all the fonts that
-// are found on the X server.  It tries to place the fonts into families
-// and to sort them so the first 4 in a family are normal, bold, italic,
-// and bold italic.
+#define USE_OVERLAY 0
 
-// Bug: older versions calculated the value for *ap as a side effect of
-// making the name, and then forgot about it. To avoid having to change
-// the header files I decided to store this value in the last character
-// of the font name array.
-#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1
+#if USE_OVERLAY
+// Currently Xft does not work with colormapped visuals, so this probably
+// does not work unless you have a true-color overlay.
+extern bool fl_overlay;
+extern Colormap fl_overlay_colormap;
+extern XVisualInfo* fl_overlay_visual;
+#endif
 
-#define USE_OVERLAY 0
+Fl_XFont_On_Demand fl_xfont = 0;
 
-// turn a stored font name in "fltk format" into a pretty name:
-const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
-  Fl_Fontdesc *f = fl_fonts + fnum;
-  if (!f->fontname[0]) {
-    const char* p = f->name;
-    int type;
-    switch (p[0]) {
-    case 'B': type = FL_BOLD; break;
-    case 'I': type = FL_ITALIC; break;
-    case 'P': type = FL_BOLD | FL_ITALIC; break;
-    default:  type = 0; break;
-    }
+static void fl_xft_font(Fl_Xlib_Graphics_Driver *driver, Fl_Font fnum, Fl_Fontsize size, int angle);
 
-  // NOTE: This can cause duplications in fonts that already have Bold or Italic in
-  // their "name". Maybe we need to find a cleverer way?
-    strlcpy(f->fontname, p+1, ENDOFBUFFER);
-    if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER);
-    if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER);
-    f->fontname[ENDOFBUFFER] = (char)type;
-  }
-  if (ap) *ap = f->fontname[ENDOFBUFFER];
-  return f->fontname;
-}
+// For some reason Xft produces errors if you destroy a window whose id
+// still exists in an XftDraw structure. It would be nice if this is not
+// true, a lot of junk is needed to try to stop this:
 
+XftDraw* Fl_Xlib_Graphics_Driver::draw_ = 0;
+Window Fl_Xlib_Graphics_Driver::draw_window = (Window)0;
+#if USE_OVERLAY
+static XftDraw* draw_overlay;
+static Window draw_overlay_window;
+#endif
+
+
+#if ! USE_PANGO
+
+// The predefined fonts that FLTK has:
+static Fl_Fontdesc built_in_table[] = {
+#if 1
+  {" sans"},
+  {"Bsans"},
+  {"Isans"},
+  {"Psans"},
+  {" mono"},
+  {"Bmono"},
+  {"Imono"},
+  {"Pmono"},
+  {" serif"},
+  {"Bserif"},
+  {"Iserif"},
+  {"Pserif"},
+  {" symbol"},
+  {" screen"},
+  {"Bscreen"},
+  {" zapf dingbats"},
+#else
+  {" helvetica"},
+  {"Bhelvetica"},
+  {"Ihelvetica"},
+  {"Phelvetica"},
+  {" courier"},
+  {"Bcourier"},
+  {"Icourier"},
+  {"Pcourier"},
+  {" times"},
+  {"Btimes"},
+  {"Itimes"},
+  {"Ptimes"},
+  {" symbol"},
+  {" lucidatypewriter"},
+  {"Blucidatypewriter"},
+  {" zapf dingbats"},
+#endif
+};
+
+#else
+
+// The predefined fonts that FLTK has with Pango:
+static Fl_Fontdesc built_in_table[] = {
+  {" Sans"},
+  {" Sans Bold"},
+  {" Sans Italic"},
+  {" Sans Bold Italic"},
+  {" Monospace"},
+  {" Monospace Bold"},
+  {" Monospace Italic"},
+  {" Monospace Bold Italic"},
+  {" Serif"},
+  {" Serif Bold"},
+  {" Serif Italic"},
+  {" Serif Bold Italic"},
+  {" Sans"},
+  {" Monospace"},
+  {" Monospace Bold"},
+  {" Sans"},
+};
+
+#endif // USE_PANGO
+
+Fl_Fontdesc* fl_fonts = built_in_table;
+
+
+#if ! USE_PANGO
+
 ///////////////////////////////////////////////////////////
 #define LOCAL_RAW_NAME_MAX 256
 
@@ -349,49 +411,9 @@
   }
   return (Fl_Font)fl_free_font;
 } // ::set_fonts
-////////////////////////////////////////////////////////////////
 
-
-extern "C" {
-static int int_sort(const void *aa, const void *bb) {
-  return (*(int*)aa)-(*(int*)bb);
-}
-}
-
 ////////////////////////////////////////////////////////////////
 
-// Return all the point sizes supported by this font:
-// Suprisingly enough Xft works exactly like fltk does and returns
-// the same list. Except there is no way to tell if the font is scalable.
-int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
-  Fl_Fontdesc *s = fl_fonts+fnum;
-  if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
-
-  fl_open_display();
-  XftFontSet* fs = XftListFonts(fl_display, fl_screen,
-                                XFT_FAMILY, XftTypeString, s->name+1,
-				(void *)0,
-                                XFT_PIXEL_SIZE,
-				(void *)0);
-  static int* array = 0;
-  static int array_size = 0;
-  if (fs->nfont >= array_size) {
-    delete[] array;
-    array = new int[array_size = fs->nfont+1];
-  }
-  array[0] = 0; int j = 1; // claim all fonts are scalable
-  for (int i = 0; i < fs->nfont; i++) {
-    double v;
-    if (XftPatternGetDouble(fs->fonts[i], XFT_PIXEL_SIZE, 0, &v) == XftResultMatch) {
-      array[j++] = int(v);
-    }
-  }
-  qsort(array+1, j-1, sizeof(int), int_sort);
-  XftFontSetDestroy(fs);
-  sizep = array;
-  return j;
-}
-
 //
 // Draw fonts using Keith Packard's Xft library to provide anti-
 // aliased text. Yow!
@@ -428,86 +450,10 @@
 // itself. You should edit the ~/.xftconfig file to "fix" things, there
 // are several web pages of information on how to do this.
 //
-#ifndef FL_DOXYGEN
 
-#include <X11/Xft/Xft.h>
-
-#include <math.h>
-
-// The predefined fonts that FLTK has:
-static Fl_Fontdesc built_in_table[] = {
-#if 1
-{" sans"},
-{"Bsans"},
-{"Isans"},
-{"Psans"},
-{" mono"},
-{"Bmono"},
-{"Imono"},
-{"Pmono"},
-{" serif"},
-{"Bserif"},
-{"Iserif"},
-{"Pserif"},
-{" symbol"},
-{" screen"},
-{"Bscreen"},
-{" zapf dingbats"},
-#else
-{" helvetica"},
-{"Bhelvetica"},
-{"Ihelvetica"},
-{"Phelvetica"},
-{" courier"},
-{"Bcourier"},
-{"Icourier"},
-{"Pcourier"},
-{" times"},
-{"Btimes"},
-{"Itimes"},
-{"Ptimes"},
-{" symbol"},
-{" lucidatypewriter"},
-{"Blucidatypewriter"},
-{" zapf dingbats"},
-#endif
-};
-
-Fl_Fontdesc* fl_fonts = built_in_table;
-
-Fl_XFont_On_Demand fl_xfont;
-void *fl_xftfont = 0;
 //static const char* fl_encoding_ = "iso8859-1";
 static const char* fl_encoding_ = "iso10646-1";
 
-static void fl_xft_font(Fl_Xlib_Graphics_Driver *driver, Fl_Font fnum, Fl_Fontsize size, int angle) {
-  if (fnum==-1) { // special case to stop font caching
-    driver->Fl_Graphics_Driver::font(0, 0);
-    return;
-  }
-  Fl_Font_Descriptor* f = driver->font_descriptor();
-  if (fnum == driver->Fl_Graphics_Driver::font() && size == driver->size() && f && f->angle == angle)
-    return;
-  driver->Fl_Graphics_Driver::font(fnum, size);
-  Fl_Fontdesc *font = fl_fonts + fnum;
-  // search the fontsizes we have generated already
-  for (f = font->first; f; f = f->next) {
-    if (f->size == size && f->angle == angle)// && !strcasecmp(f->encoding, fl_encoding_))
-      break;
-  }
-  if (!f) {
-    f = new Fl_Font_Descriptor(font->name, size, angle);
-    f->next = font->first;
-    font->first = f;
-  }
-  driver->font_descriptor(f);
-#if XFT_MAJOR < 2
-  fl_xfont    = f->font->u.core.font;
-#else
-  fl_xfont    = NULL; // invalidate
-#endif // XFT_MAJOR < 2
-  fl_xftfont = (void*)f->font;
-}
 
 void Fl_Xlib_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) {
   fl_xft_font(this,fnum,size,0);
@@ -710,10 +656,6 @@
   font = fontopen(name, fsize, false, angle);
 }
 
-Fl_Font_Descriptor::~Fl_Font_Descriptor() {
-  if (this == fl_graphics_driver->font_descriptor()) fl_graphics_driver->font_descriptor(NULL);
-//  XftFontClose(fl_display, font);
-}
 
 /* decodes the input UTF-8 string into a series of wchar_t characters.
  n is set upon return to the number of characters.
@@ -766,10 +708,6 @@
   return i.xOff;
 }
 
-/*double fl_width(uchar c) {
-  return fl_graphics_driver->width((const char *)(&c), 1);
-}*/
-
 static double fl_xft_width(Fl_Font_Descriptor *desc, FcChar32 *str, int n) {
   if (!desc) return -1.0;
   XGlyphInfo i;
@@ -797,14 +735,277 @@
 } // fl_text_extents
 
 
+void Fl_Xlib_Graphics_Driver::draw(const char *str, int n, int x, int y) {
+  if ( !this->font_descriptor() ) {
+    this->font(FL_HELVETICA, FL_NORMAL_SIZE);
+  }
+#if USE_OVERLAY
+  XftDraw*& draw_ = fl_overlay ? draw_overlay : ::draw_;
+  if (fl_overlay) {
+    if (!draw_)
+      draw_ = XftDrawCreate(fl_display, draw_overlay_window = fl_window,
+			   fl_overlay_visual->visual, fl_overlay_colormap);
+    else //if (draw_overlay_window != fl_window)
+      XftDrawChange(draw_, draw_overlay_window = fl_window);
+  } else
+#endif
+  if (!draw_)
+    draw_ = XftDrawCreate(fl_display, draw_window = fl_window,
+			 fl_visual->visual, fl_colormap);
+  else //if (draw_window != fl_window)
+    XftDrawChange(draw_, draw_window = fl_window);
+
+  Region region = fl_clip_region();
+  if (region && XEmptyRegion(region)) return;
+  XftDrawSetClip(draw_, region);
+
+  // Use fltk's color allocator, copy the results to match what
+  // XftCollorAllocValue returns:
+  XftColor color;
+  color.pixel = fl_xpixel(Fl_Graphics_Driver::color());
+  uchar r,g,b; Fl::get_color(Fl_Graphics_Driver::color(), r,g,b);
+  color.color.red   = ((int)r)*0x101;
+  color.color.green = ((int)g)*0x101;
+  color.color.blue  = ((int)b)*0x101;
+  color.color.alpha = 0xffff;
+
+  const wchar_t *buffer = utf8reformat(str, n);
+#ifdef __CYGWIN__
+  XftDrawString16(draw_, &color, font_descriptor()->font, x, y, (XftChar16 *)buffer, n);
+#else
+  XftDrawString32(draw_, &color, font_descriptor()->font, x, y, (XftChar32 *)buffer, n);
+#endif
+}
+
+void Fl_Xlib_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) {
+  fl_xft_font(this, this->Fl_Graphics_Driver::font(), this->size(), angle);
+  this->draw(str, n, (int)x, (int)y);
+  fl_xft_font(this, this->Fl_Graphics_Driver::font(), this->size(), 0);
+}
+
+void Fl_Xlib_Graphics_Driver::drawUCS4(const void *str, int n, int x, int y) {
+#if USE_OVERLAY
+  XftDraw*& draw_ = fl_overlay ? draw_overlay : ::draw_;
+  if (fl_overlay) {
+    if (!draw_)
+      draw_ = XftDrawCreate(fl_display, draw_overlay_window = fl_window,
+			   fl_overlay_visual->visual, fl_overlay_colormap);
+    else //if (draw_overlay_window != fl_window)
+      XftDrawChange(draw_, draw_overlay_window = fl_window);
+  } else
+#endif
+  if (!draw_)
+    draw_ = XftDrawCreate(fl_display, draw_window = fl_window,
+			 fl_visual->visual, fl_colormap);
+  else //if (draw_window != fl_window)
+    XftDrawChange(draw_, draw_window = fl_window);
+
+  Region region = fl_clip_region();
+  if (region && XEmptyRegion(region)) return;
+  XftDrawSetClip(draw_, region);
+
+  // Use fltk's color allocator, copy the results to match what
+  // XftCollorAllocValue returns:
+  XftColor color;
+  color.pixel = fl_xpixel(this->color());
+  uchar r,g,b; Fl::get_color(this->color(), r,g,b);
+  color.color.red   = ((int)r)*0x101;
+  color.color.green = ((int)g)*0x101;
+  color.color.blue  = ((int)b)*0x101;
+  color.color.alpha = 0xffff;
+
+  XftDrawString32(draw_, &color, font_descriptor()->font, x, y, (FcChar32 *)str, n);
+}
+
+
+void Fl_Xlib_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) {
+
+#if defined(__GNUC__)
+// FIXME: warning Need to improve this XFT right to left draw function
+#endif /*__GNUC__*/
+
+// This actually draws LtoR, but aligned to R edge with the glyph order reversed...
+// but you can't just byte-rev a UTF-8 string, that isn't valid.
+// You can reverse a UCS4 string though...
+  int num_chars, wid, utf_len = strlen(c);
+  FcChar8 *u8 = (FcChar8 *)c;
+  FcBool valid = FcUtf8Len(u8, utf_len, &num_chars, &wid);
+  if (!valid)
+  {
+    // badly formed Utf-8 input string
+    return;
+  }
+  if (num_chars < n) n = num_chars; // limit drawing to usable characters in input array
+  FcChar32 *ucs_txt = new FcChar32[n+1];
+  FcChar32* pu;
+  int out, sz;
+  ucs_txt[n] = 0;
+  out = n-1;
+  while ((out >= 0) && (utf_len > 0))
+  {
+    pu = &ucs_txt[out];
+    sz = FcUtf8ToUcs4(u8, pu, utf_len);
+    utf_len = utf_len - sz;
+    u8 = u8 + sz;
+    out = out - 1;
+  }
+  // Now we have a UCS4 version of the input text, reversed, in ucs_txt
+  int offs = (int)fl_xft_width(font_descriptor(), ucs_txt, n);
+  drawUCS4(ucs_txt, n, (x-offs), y);
+
+  delete[] ucs_txt;
+}
+
+
+extern "C" {
+  static int int_sort(const void *aa, const void *bb) {
+    return (*(int*)aa)-(*(int*)bb);
+  }
+}
+
+////////////////////////////////////////////////////////////////
+
+// Return all the point sizes supported by this font:
+// Suprisingly enough Xft works exactly like fltk does and returns
+// the same list. Except there is no way to tell if the font is scalable.
+int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
+  Fl_Fontdesc *s = fl_fonts+fnum;
+  if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
+  
+  fl_open_display();
+  XftFontSet* fs = XftListFonts(fl_display, fl_screen,
+                                XFT_FAMILY, XftTypeString, s->name+1,
+                                (void *)0,
+                                XFT_PIXEL_SIZE,
+                                (void *)0);
+  static int* array = 0;
+  static int array_size = 0;
+  if (fs->nfont >= array_size) {
+    delete[] array;
+    array = new int[array_size = fs->nfont+1];
+  }
+  array[0] = 0; int j = 1; // claim all fonts are scalable
+  for (int i = 0; i < fs->nfont; i++) {
+    double v;
+    if (XftPatternGetDouble(fs->fonts[i], XFT_PIXEL_SIZE, 0, &v) == XftResultMatch) {
+      array[j++] = int(v);
+    }
+  }
+  qsort(array+1, j-1, sizeof(int), int_sort);
+  XftFontSetDestroy(fs);
+  sizep = array;
+  return j;
+}
+
+#endif // !USE_PANGO
+
+float Fl_Xlib_Graphics_Driver::scale_font_for_PostScript(Fl_Font_Descriptor *desc, int s) {
+  // 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 = height();
+  float ps_size = s * 1.15;
+  if (ps_size > max) ps_size = max;
+  return ps_size;
+}
+
+
+// This function fills in the fltk font table with all the fonts that
+// are found on the X server.  It tries to place the fonts into families
+// and to sort them so the first 4 in a family are normal, bold, italic,
+// and bold italic.
+
+// Bug: older versions calculated the value for *ap as a side effect of
+// making the name, and then forgot about it. To avoid having to change
+// the header files I decided to store this value in the last character
+// of the font name array.
+#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1
+
+
+// turn a stored font name in "fltk format" into a pretty name:
+const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
+  Fl_Fontdesc *f = fl_fonts + fnum;
+  if (!f->fontname[0]) {
+    const char* p = f->name;
+    int type;
+    switch (p[0]) {
+      case 'B': type = FL_BOLD; break;
+      case 'I': type = FL_ITALIC; break;
+      case 'P': type = FL_BOLD | FL_ITALIC; break;
+      default:  type = 0; break;
+    }
+    
+    // NOTE: This can cause duplications in fonts that already have Bold or Italic in
+    // their "name". Maybe we need to find a cleverer way?
+    strlcpy(f->fontname, p+1, ENDOFBUFFER);
+    if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER);
+    if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER);
+    f->fontname[ENDOFBUFFER] = (char)type;
+  }
+  if (ap) *ap = f->fontname[ENDOFBUFFER];
+  return f->fontname;
+}
+
+
+float Fl_Xlib_Graphics_Driver::scale_bitmap_for_PostScript() {
+  return 2;
+}
+
+Fl_Font_Descriptor::~Fl_Font_Descriptor() {
+  if (this == fl_graphics_driver->font_descriptor()) fl_graphics_driver->font_descriptor(NULL);
+  //  XftFontClose(fl_display, font);
+}
+
+
+void Fl_Xlib_Graphics_Driver::destroy_xft_draw(Window id) {
+  if (id == draw_window)
+    XftDrawChange(draw_, draw_window = fl_message_window);
+#if USE_OVERLAY
+  if (id == draw_overlay_window)
+    XftDrawChange(draw_overlay, draw_overlay_window = fl_message_window);
+#endif
+}
+
+void *fl_xftfont = 0; // always 0 under Pango
+static void fl_xft_font(Fl_Xlib_Graphics_Driver *driver, Fl_Font fnum, Fl_Fontsize size, int angle) {
+  if (fnum==-1) { // special case to stop font caching
+    driver->Fl_Graphics_Driver::font(0, 0);
+    return;
+  }
+  Fl_Font_Descriptor* f = driver->font_descriptor();
+  if (fnum == driver->Fl_Graphics_Driver::font() && size == driver->size() && f && f->angle == angle)
+    return;
+  driver->Fl_Graphics_Driver::font(fnum, size);
+  Fl_Fontdesc *font = fl_fonts + fnum;
+  // search the fontsizes we have generated already
+  for (f = font->first; f; f = f->next) {
+    if (f->size == size && f->angle == angle)// && !strcasecmp(f->encoding, fl_encoding_))
+      break;
+  }
+  if (!f) {
+    f = new Fl_Font_Descriptor(font->name, size, angle);
+    f->next = font->first;
+    font->first = f;
+  }
+  driver->font_descriptor(f);
+#if XFT_MAJOR < 2 && ! USE_PANGO
+  fl_xfont    = f->font->u.core.font;
+#else
+  fl_xfont    = NULL; // invalidate
+#endif // XFT_MAJOR < 2
+#if USE_PANGO
+  fl_xftfont = NULL;
+#else
+  fl_xftfont = (void*)f->font;
+#endif
+}
+
 /* This code is used (mainly 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 X-bitmap font, that could then be readily
  * used with GL.  But XFT-2 does not provide that ability, and there
  * is no easy method to use an XFT font directly with GL. So...
-*/
-
-#  if XFT_MAJOR > 1
+ */
+#  if XFT_MAJOR > 1 || USE_PANGO
 // This function attempts, on XFT2 systems, to find a suitable "core" Xfont
 // for GL or other bitmap font needs (we dont have an XglUseXftFont(...) function.)
 // There's probably a better way to do this. I can't believe it is this hard...
@@ -828,16 +1029,32 @@
   char slant = 'r';   // regular non-italic by default
   char xlfd[128];     // we will put our synthetic XLFD in here
   char *pc = strdup(fl_fonts[fnum].name); // what font were we asked for?
+#if USE_PANGO
+  char *p = pc;
+  while (*p) { *p = tolower(*p); p++; }
+  p = pc + strlen(pc) - 12;
+  if (memcmp(p, " bold italic\0", 13) == 0) {
+    *pc = 'P'; *p = 0;
+  }
+  p = pc + strlen(pc) - 5;
+  if (memcmp(p, " bold\0", 6) == 0) {
+    *pc = 'B'; *p = 0;
+  }
+  p = pc + strlen(pc) - 7;
+  if (memcmp(p, " italic\0", 8) == 0) {
+    *pc = 'I'; *p = 0;
+  }
+#endif // USE_PANGO
   const char *name = pc;    // keep a handle to the original name for freeing later
   // Parse the "fltk-name" of the font
   switch (*name++) {
-  case 'I': slant = 'i'; break;       // italic
-  case 'P': slant = 'i';              // bold-italic (falls-through)
-  case 'B': weight = wt_bold; break;  // bold
-  case ' ': break;                    // regular
-  default: name--;                    // no prefix, restore name
+    case 'I': slant = 'i'; break;       // italic
+    case 'P': slant = 'i';              // bold-italic (falls-through)
+    case 'B': weight = wt_bold; break;  // bold
+    case ' ': break;                    // regular
+    default: name--;                    // no prefix, restore name
   }
-
+  
   // first, we do a query with no prefered size, to see if the font exists at all
   snprintf(xlfd, 128, "-*-%s-%s-%c-*--*-*-*-*-*-*-*-*", name, weight, slant); // make up xlfd style name
   xgl_font = XLoadQueryFont(fl_display, xlfd);
@@ -846,13 +1063,14 @@
     snprintf(xlfd, 128, "-*-%s-%s-%c-*--*-%d-*-*-*-*-*-*", name, weight, slant, (size*10));
     xgl_font = XLoadQueryFont(fl_display, xlfd); // attempt to load the font at the right size
   }
-//puts(xlfd);
-
+  //puts(xlfd);
+  
   // try alternative names
   if (!xgl_font) {
     if (!strcmp(name, "sans")) {
       name = "helvetica";
-    } else if (!strcmp(name, "mono")) {
+      if (slant == 'i') slant = 'o';
+    } else if (!strcmp(name, "mono") || !strcmp(name, "monospace")) {
       name = "courier";
     } else if (!strcmp(name, "serif")) {
       name = "times";
@@ -865,7 +1083,7 @@
     xgl_font = XLoadQueryFont(fl_display, xlfd);
   }
   free(pc); // release our copy of the font name
-
+  
   // if we have nothing loaded, try a generic proportional font
   if(!xgl_font) {
     snprintf(xlfd, 128, "-*-helvetica-*-%c-*--*-%d-*-*-*-*-*-*", slant, (size*10));
@@ -876,18 +1094,19 @@
     snprintf(xlfd, 128, "-*-courier-medium-%c-*--*-%d-*-*-*-*-*-*", slant, (size*10));
     xgl_font = XLoadQueryFont(fl_display, xlfd);
   }
-//printf("glf: %d\n%s\n%s\n", size, xlfd, fl_fonts[fl_font_].name);
-//if(xgl_font) puts("ok");
-
+  //printf("glf: %d\n%s\n%s\n", size, xlfd, fl_fonts[fl_font_].name);
+  //if(xgl_font) puts("ok");
+  
   // Last chance fallback - this usually loads something...
   if (!xgl_font) xgl_font = XLoadQueryFont(fl_display, "fixed");
-
+  
   return xgl_font;
 } // end of load_xfont_for_xft2
 #  endif
 
+
 static XFontStruct* fl_xxfont(Fl_Graphics_Driver *driver) {
-#  if XFT_MAJOR > 1
+#  if XFT_MAJOR > 1 || USE_PANGO
   // kludge! XFT 2 and later does not provide core fonts for us to use with GL
   // try to load a bitmap X font instead
   static XFontStruct* xgl_font = 0;
@@ -905,7 +1124,7 @@
 #  else // XFT-1 provides a means to load a "core" font directly
   if (driver->font_descriptor()->font->core) {
     return driver->font_descriptor()->font->u.core.font; // is the current font a "core" font? If so, use it.
-    }
+  }
   static XftFont* xftfont;
   if (xftfont) XftFontClose (fl_display, xftfont);
   xftfont = fontopen(fl_fonts[driver->font()].name, driver->size(), true, 0); // else request XFT to load a suitable "core" font instead.
@@ -918,168 +1137,228 @@
   return ptr;
 }
 
-#if USE_OVERLAY
-// Currently Xft does not work with colormapped visuals, so this probably
-// does not work unless you have a true-color overlay.
-extern bool fl_overlay;
-extern Colormap fl_overlay_colormap;
-extern XVisualInfo* fl_overlay_visual;
+#if USE_PANGO
+
+#include <pango/pangoxft.h>
+#include <pango/pango.h>
+#if ! PANGO_VERSION_CHECK(1,8,0)
+#error "Requires Pango 1.8 or higher"
 #endif
 
-// For some reason Xft produces errors if you destroy a window whose id
-// still exists in an XftDraw structure. It would be nice if this is not
-// true, a lot of junk is needed to try to stop this:
+PangoFontMap *Fl_Xlib_Graphics_Driver::pfmap_ = 0;
+PangoContext *Fl_Xlib_Graphics_Driver::pctxt_ = 0;
+PangoLayout *Fl_Xlib_Graphics_Driver::playout_ = 0;
 
-static XftDraw* draw_;
-static Window draw_window;
-#if USE_OVERLAY
-static XftDraw* draw_overlay;
-static Window draw_overlay_window;
+PangoContext *Fl_Xlib_Graphics_Driver::context() {
+  if (fl_display && !pctxt_) {
+    pfmap_ = pango_xft_get_font_map(fl_display, fl_screen); // 1.2
+#if PANGO_VERSION_CHECK(1,22,0)
+    pctxt_ = pango_font_map_create_context(pfmap_); // 1.22
+#else
+    pctxt_ = pango_xft_get_context(fl_display, fl_screen); // deprecated since 1.22
 #endif
+    playout_ = pango_layout_new(pctxt_);
+  }
+  return pctxt_;
+}
 
-void Fl_Xlib_Graphics_Driver::destroy_xft_draw(Window id) {
-  if (id == draw_window)
-    XftDrawChange(draw_, draw_window = fl_message_window);
-#if USE_OVERLAY
-  if (id == draw_overlay_window)
-    XftDrawChange(draw_overlay, draw_overlay_window = fl_message_window);
-#endif
+void Fl_Xlib_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) {
+  if (!size) return;
+  if (this->Fl_Graphics_Driver::font() == fnum && this->size() == size) return;
+  fl_xft_font(this, fnum, size, 0);
+  init_built_in_fonts();
+  if (pfd_) pango_font_description_free(pfd_);
+  pfd_ = pango_font_description_from_string(Fl::get_font_name(fnum));
+  pango_font_description_set_absolute_size(pfd_, size*PANGO_SCALE); // 1.8
+  if (!pctxt_) context();
+  Fl_Font_Descriptor *fd = font_descriptor();
+  if (!fd->height_) {
+    PangoFont *pfont = pango_font_map_load_font(pfmap_, pctxt_, pfd_);
+    PangoRectangle ink_rect, logical_rect;
+    pango_font_get_glyph_extents(pfont, /*PangoGlyph glyph*/'p', &ink_rect, &logical_rect);
+    fd->descent_ = PANGO_DESCENT(logical_rect)/PANGO_SCALE;
+    fd->height_ = logical_rect.height/PANGO_SCALE;
+  }
 }
 
 void Fl_Xlib_Graphics_Driver::draw(const char *str, int n, int x, int y) {
-  if ( !this->font_descriptor() ) {
-    this->font(FL_HELVETICA, FL_NORMAL_SIZE);
-  }
-#if USE_OVERLAY
-  XftDraw*& draw_ = fl_overlay ? draw_overlay : ::draw_;
-  if (fl_overlay) {
-    if (!draw_)
-      draw_ = XftDrawCreate(fl_display, draw_overlay_window = fl_window,
-			   fl_overlay_visual->visual, fl_overlay_colormap);
-    else //if (draw_overlay_window != fl_window)
-      XftDrawChange(draw_, draw_overlay_window = fl_window);
-  } else
-#endif
-  if (!draw_)
-    draw_ = XftDrawCreate(fl_display, draw_window = fl_window,
-			 fl_visual->visual, fl_colormap);
-  else //if (draw_window != fl_window)
-    XftDrawChange(draw_, draw_window = fl_window);
+  do_draw(0, str, n, x, y);
+}
 
-  Region region = fl_clip_region();
+void Fl_Xlib_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) {
+  PangoMatrix mat = PANGO_MATRIX_INIT; // 1.6
+  pango_matrix_translate(&mat, x, y); // 1.6
+  pango_matrix_rotate(&mat, angle); // 1.6
+  pango_context_set_matrix(pctxt_, &mat); // 1.6
+  do_draw(0, str, n, 0, 0);
+  pango_context_set_matrix(pctxt_, NULL); // 1.6
+}
+
+void Fl_Xlib_Graphics_Driver::rtl_draw(const char* str, int n, int x, int y) {
+  do_draw(1, str, n, x, y);
+}
+
+void Fl_Xlib_Graphics_Driver::do_draw(int from_right, const char *str, int n, int x, int y) {
+  if (!fl_display || n == 0) return;
+  Region region = clip_region();
   if (region && XEmptyRegion(region)) return;
-  XftDrawSetClip(draw_, region);
-
-  // Use fltk's color allocator, copy the results to match what
-  // XftCollorAllocValue returns:
+  if (!playout_) context();
+  
+  char *str2 = NULL;
+  const char *tmpv = (const char *)memchr(str, '\n', n);
+  if (tmpv == str + n - 1) { // ignore final '\n'
+    if (--n == 0) return;
+    tmpv = NULL;
+  }
+  pango_layout_set_font_description(playout_, pfd_);
+  if (tmpv) { // replace newlines by spaces in a copy of str
+    str2 = (char*)malloc(n);
+    memcpy(str2, str, n);
+    do {
+      str2[tmpv - str] = ' ';
+      if (tmpv >= str + n - 1) break;
+      tmpv = (const char *)memchr(tmpv + 1, '\n', n - (tmpv - str + 1));
+    }
+    while (tmpv);
+    str = str2;
+  }
+  const char *old = 0;
+  if (!str2) old = pango_layout_get_text(playout_);
+  if (!old || strlen(old) != n || memcmp(str, old, n)) // do not re-set text if equal to text already in layout
+        pango_layout_set_text(playout_, str, n);
+  if (str2) free(str2);
+  
   XftColor color;
-  color.pixel = fl_xpixel(Fl_Graphics_Driver::color());
-  uchar r,g,b; Fl::get_color(Fl_Graphics_Driver::color(), r,g,b);
+  Fl_Color c = this->color();
+  color.pixel = fl_xpixel(c);
+  uchar r,g,b; Fl::get_color(c, r,g,b);
   color.color.red   = ((int)r)*0x101;
   color.color.green = ((int)g)*0x101;
   color.color.blue  = ((int)b)*0x101;
   color.color.alpha = 0xffff;
+  if (from_right) {
+    int width, height;
+    pango_layout_get_pixel_size(playout_, &width, &height);
+    x -= width;
+  }
+  if (!draw_)
+    draw_ = XftDrawCreate(fl_display, draw_window = fl_window, fl_visual->visual, fl_colormap);
+  else
+    XftDrawChange(draw_, draw_window = fl_window);
+  XftDrawSetClip(draw_, region);
+  pango_xft_render_layout(draw_, &color, playout_, x*PANGO_SCALE, (y-height()+descent())*PANGO_SCALE ); // 1.8
+}
 
-  const wchar_t *buffer = utf8reformat(str, n);
-#ifdef __CYGWIN__
-  XftDrawString16(draw_, &color, font_descriptor()->font, x, y, (XftChar16 *)buffer, n);
-#else
-  XftDrawString32(draw_, &color, font_descriptor()->font, x, y, (XftChar32 *)buffer, n);
-#endif
+double Fl_Xlib_Graphics_Driver::width(const char* str, int n) {
+  if (!n) return 0;
+  if (!fl_display || fl_size() == 0) return -1;
+  if (!playout_) context();
+  int width, height;
+  pango_layout_set_font_description(playout_, pfd_);
+  pango_layout_set_text(playout_, str, n);
+  pango_layout_get_pixel_size(playout_, &width, &height);
+  return (double)width;
 }
 
-void Fl_Xlib_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) {
-  fl_xft_font(this, this->Fl_Graphics_Driver::font(), this->size(), angle);
-  this->draw(str, n, (int)x, (int)y);
-  fl_xft_font(this, this->Fl_Graphics_Driver::font(), this->size(), 0);
+void Fl_Xlib_Graphics_Driver::text_extents(const char *str, int n, int &dx, int &dy, int &w, int &h) {
+  if (!playout_) context();
+  pango_layout_set_font_description(playout_, pfd_);
+  pango_layout_set_text(playout_, str, n);
+  PangoRectangle ink_rect, logical_rect;
+  pango_layout_get_pixel_extents(playout_, &ink_rect, &logical_rect);
+  dx = ink_rect.x;
+  dy = ink_rect.y - height() + descent();
+  w = ink_rect.width;
+  h = ink_rect.height;
 }
 
-static void fl_drawUCS4(Fl_Graphics_Driver *driver, const FcChar32 *str, int n, int x, int y) {
-#if USE_OVERLAY
-  XftDraw*& draw_ = fl_overlay ? draw_overlay : ::draw_;
-  if (fl_overlay) {
-    if (!draw_)
-      draw_ = XftDrawCreate(fl_display, draw_overlay_window = fl_window,
-			   fl_overlay_visual->visual, fl_overlay_colormap);
-    else //if (draw_overlay_window != fl_window)
-      XftDrawChange(draw_, draw_overlay_window = fl_window);
-  } else
-#endif
-  if (!draw_)
-    draw_ = XftDrawCreate(fl_display, draw_window = fl_window,
-			 fl_visual->visual, fl_colormap);
-  else //if (draw_window != fl_window)
-    XftDrawChange(draw_, draw_window = fl_window);
+int Fl_Xlib_Graphics_Driver::height() {
+  return font_descriptor()->height_;
+}
 
-  Region region = fl_clip_region();
-  if (region && XEmptyRegion(region)) return;
-  XftDrawSetClip(draw_, region);
+double Fl_Xlib_Graphics_Driver::width(unsigned int c) {
+  char buf4[4];
+  int n = fl_utf8encode(c, buf4);
+  return width(buf4, n);
+}
 
-  // Use fltk's color allocator, copy the results to match what
-  // XftCollorAllocValue returns:
-  XftColor color;
-  color.pixel = fl_xpixel(driver->color());
-  uchar r,g,b; Fl::get_color(driver->color(), r,g,b);
-  color.color.red   = ((int)r)*0x101;
-  color.color.green = ((int)g)*0x101;
-  color.color.blue  = ((int)b)*0x101;
-  color.color.alpha = 0xffff;
+int Fl_Xlib_Graphics_Driver::descent() {
+  return font_descriptor()->descent_;
+}
 
-  XftDrawString32(draw_, &color, driver->font_descriptor()->font, x, y, (FcChar32 *)str, n);
+Fl_Font Fl::set_fonts(const char* pattern_name)
+{
+  return Fl_Xlib_Graphics_Driver::set_fonts();
 }
 
+typedef int (*sort_f_type)(const void *aa, const void *bb);
 
-void Fl_Xlib_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) {
+static int font_sort(Fl_Fontdesc *fa, Fl_Fontdesc *fb) {
+  return strcmp(fa->name, fb->name);
+}
 
-#if defined(__GNUC__)
-// FIXME: warning Need to improve this XFT right to left draw function
-#endif /*__GNUC__*/
+int Fl_Xlib_Graphics_Driver::set_fonts()
+{
+  fl_open_display();
+  int n_families, count = 0;
+  PangoFontFamily **families;
+  context();
+  init_built_in_fonts();
+  pango_font_map_list_families(pfmap_, &families, &n_families);
+  for (int fam = 0; fam < n_families; fam++) {
+    PangoFontFace **faces;
+    int n_faces;
+    const char *fam_name = pango_font_family_get_name (families[fam]);
+    int l = strlen(fam_name);
+    pango_font_family_list_faces(families[fam], &faces, &n_faces);
+    for (int j = 0; j < n_faces; j++) {
+      const char *p =  pango_font_face_get_face_name(faces[j]);
+      if (strcmp(p, "Regular") == 0) p = NULL;
+      int lq = l+2;
+      if (p) lq += strlen(p) + 1;
+      char *q = new char[lq];
+      sprintf(q, " %s", fam_name);
+      if (p) sprintf(q + strlen(q), " %s", p);
+      // at this point, q contains " family-name[ face-name-except-Regular]"
+      Fl::set_font((Fl_Font)(count++ + FL_FREE_FONT), q);
+    }
+    /*g_*/free(faces); // glib source code shows that g_free is equivalent to free
+  }
+  /*g_*/free(families);
+  // Sort the list into alphabetic order
+  qsort(fl_fonts + FL_FREE_FONT, count, sizeof(Fl_Fontdesc), (sort_f_type)font_sort);
+  return FL_FREE_FONT + count;
+}
 
-// This actually draws LtoR, but aligned to R edge with the glyph order reversed...
-// but you can't just byte-rev a UTF-8 string, that isn't valid.
-// You can reverse a UCS4 string though...
-  int num_chars, wid, utf_len = strlen(c);
-  FcChar8 *u8 = (FcChar8 *)c;
-  FcBool valid = FcUtf8Len(u8, utf_len, &num_chars, &wid);
-  if (!valid)
-  {
-    // badly formed Utf-8 input string
-    return;
+
+void Fl_Xlib_Graphics_Driver::init_built_in_fonts() {
+  static int i = 0;
+  while (i < FL_FREE_FONT) {
+    Fl::set_font((Fl_Font)i, built_in_table[i].name);
+    i++;
   }
-  if (num_chars < n) n = num_chars; // limit drawing to usable characters in input array
-  FcChar32 *ucs_txt = new FcChar32[n+1];
-  FcChar32* pu;
-  int out, sz;
-  ucs_txt[n] = 0;
-  out = n-1;
-  while ((out >= 0) && (utf_len > 0))
-  {
-    pu = &ucs_txt[out];
-    sz = FcUtf8ToUcs4(u8, pu, utf_len);
-    utf_len = utf_len - sz;
-    u8 = u8 + sz;
-    out = out - 1;
-  }
-  // Now we have a UCS4 version of the input text, reversed, in ucs_txt
-  int offs = (int)fl_xft_width(font_descriptor(), ucs_txt, n);
-  fl_drawUCS4(this, ucs_txt, n, (x-offs), y);
-
-  delete[] ucs_txt;
 }
 
-float Fl_Xlib_Graphics_Driver::scale_font_for_PostScript(Fl_Font_Descriptor *desc, int s) {
-  // 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;
-  float ps_size = s * 1.15;
-  if (ps_size > max) ps_size = max;
-  return ps_size;
+
+int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
+  static int array[1] = {0};
+  sizep = array;
+  return 1;
 }
 
-float Fl_Xlib_Graphics_Driver::scale_bitmap_for_PostScript() {
-  return 2;
+Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize fsize, int fangle) {
+  fl_open_display();
+  size = fsize;
+  angle = fangle;
+#if HAVE_GL
+  listbase = 0;
+#endif // HAVE_GL
+  height_ = 0;
+  descent_ = 0;
 }
 
+#endif // USE_PANGO
+
 #endif // FL_DOXYGEN
 
 //
