FLTK logo

[master] 368f180 - Fast pango (#201)

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] 368f180 - Fast pango (#201) "ManoloFLTK" Mar 13, 2021  
 
commit 368f18016c96a1516e9e72bc151e523ec94622a8
Author:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
AuthorDate: Sat Mar 13 19:21:25 2021 +0100
Commit:     GitHub <noreply@github.com>
CommitDate: Sat Mar 13 19:21:25 2021 +0100

    Fast pango (#201)
    
    * Cache single unicode character widths under Xft+Pango

 src/Fl_Text_Display.cxx                            |  1 -
 src/drivers/Xlib/Fl_Font.H                         |  1 +
 src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H         |  3 ++
 .../Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx      | 49 +++++++++++++++++++---
 4 files changed, 47 insertions(+), 7 deletions(-)

diff --git src/Fl_Text_Display.cxx src/Fl_Text_Display.cxx
index 66eaae6..a9cfcdf 100644
--- src/Fl_Text_Display.cxx
+++ src/Fl_Text_Display.cxx
@@ -472,7 +472,6 @@ void Fl_Text_Display::resize(int X, int Y, int W, int H) {
  */
 void Fl_Text_Display::recalc_display() {
   if (!buffer()) return;
-
   // did we have scrollbars initially?
   unsigned int hscrollbarvisible = mHScrollBar->visible();
   unsigned int vscrollbarvisible = mVScrollBar->visible();
diff --git src/drivers/Xlib/Fl_Font.H src/drivers/Xlib/Fl_Font.H
index 474d6ce..a148e2b 100644
--- src/drivers/Xlib/Fl_Font.H
+++ src/drivers/Xlib/Fl_Font.H
@@ -36,6 +36,7 @@ public:
 #    if USE_PANGO
         int descent_;
         int height_;
+        int **width;
 #    else
         XftFont* font;
 #    endif
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
index 7ee34a9..e4a3530 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
@@ -62,6 +62,9 @@ private:
   virtual void draw_fixed(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
   virtual void draw_fixed(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy);
   virtual void draw_fixed(Fl_RGB_Image *rgb, int XP, int YP, int WP, int HP, int cx, int cy);
+#if USE_PANGO
+  double do_width_unscaled_(const char *str, int n);
+#endif
 protected:
   virtual void draw_image_unscaled(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0);
   virtual void draw_image_unscaled(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3);
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
index a8039df..a755d88 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver_font_xft.cxx
@@ -1012,6 +1012,10 @@ float Fl_Xlib_Graphics_Driver::scale_bitmap_for_PostScript() {
 Fl_Xlib_Font_Descriptor::~Fl_Xlib_Font_Descriptor() {
   if (this == fl_graphics_driver->font_descriptor()) fl_graphics_driver->font_descriptor(NULL);
   //  XftFontClose(fl_display, font);
+#if USE_PANGO
+  if (width) for (int i = 0; i < 64; i++) delete[] width[i];
+  delete[] width;
+#endif
 }
 
 
@@ -1347,7 +1351,45 @@ void Fl_Xlib_Graphics_Driver::do_draw(int from_right, const char *str, int n, in
                           (y - y_correction  - lheight + desc) * PANGO_SCALE ); // 1.8
   }
 
+// cache the widths of single Unicode characters
+double Fl_Xlib_Graphics_Driver::width_unscaled(unsigned int utf32) {
+  unsigned r=0;
+  Fl_Xlib_Font_Descriptor *desc = NULL;
+  if (utf32 <= 0xFFFF) {
+    desc = (Fl_Xlib_Font_Descriptor*)font_descriptor();
+    r = (utf32 & 0xFC00) >> 10;
+    if (!desc->width) {
+      desc->width = (int**)new int*[64];
+      memset(desc->width, 0, 64*sizeof(int*));
+    }
+    if (!desc->width[r]) {
+      desc->width[r] = (int*)new int[0x0400];
+      for (int i = 0; i < 0x0400; i++) desc->width[r][i] = -1;
+    } else {
+      if ( desc->width[r][utf32&0x03FF] >= 0 ) { // already cached
+        return double(desc->width[r][utf32 & 0x03FF]);
+      }
+    }
+  }
+  char buf4[4];
+  int n = fl_utf8encode(utf32, buf4);
+  double width = do_width_unscaled_(buf4, n);
+  if (utf32 <= 0xFFFF) {
+    desc->width[r][utf32 & 0x03FF] = (int)width;
+  }
+  return width;
+}
+
 double Fl_Xlib_Graphics_Driver::width_unscaled(const char* str, int n) {
+  if (n == fl_utf8len(*str)) { // str contains a single unicode character
+    int l;
+    unsigned c = fl_utf8decode(str, str+n, &l);
+    return width_unscaled(c); // that character's width may have been cached
+  }
+  return do_width_unscaled_(str, n); // full width computation for multi-char strings
+}
+
+double Fl_Xlib_Graphics_Driver::do_width_unscaled_(const char* str, int n) {
   if (!n) return 0;
   if (!fl_display || size_ == 0) return -1;
   if (!playout_) context();
@@ -1373,12 +1415,6 @@ int Fl_Xlib_Graphics_Driver::height_unscaled() {
   else return -1;
 }
 
-double Fl_Xlib_Graphics_Driver::width_unscaled(unsigned int c) {
-  char buf4[4];
-  int n = fl_utf8encode(c, buf4);
-  return width_unscaled(buf4, n);
-}
-
 int Fl_Xlib_Graphics_Driver::descent_unscaled() {
   if (font_descriptor()) return ((Fl_Xlib_Font_Descriptor*)font_descriptor())->descent_;
   else return -1;
@@ -1458,6 +1494,7 @@ Fl_Xlib_Font_Descriptor::Fl_Xlib_Font_Descriptor(const char* name, Fl_Fontsize f
   angle = fangle;
   height_ = 0;
   descent_ = 0;
+  width = NULL;
 }
 
 #endif // USE_PANGO
Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.