|
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 ] | |