diff options
Diffstat (limited to 'src/FbTk/XftFontImp.cc')
-rw-r--r-- | src/FbTk/XftFontImp.cc | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/src/FbTk/XftFontImp.cc b/src/FbTk/XftFontImp.cc index 6568457..fa34404 100644 --- a/src/FbTk/XftFontImp.cc +++ b/src/FbTk/XftFontImp.cc | |||
@@ -23,12 +23,14 @@ | |||
23 | #include "App.hh" | 23 | #include "App.hh" |
24 | #include "FbDrawable.hh" | 24 | #include "FbDrawable.hh" |
25 | 25 | ||
26 | #include <math.h> | 26 | #include <cmath> |
27 | #include <cstdio> | ||
28 | #include <algorithm> | ||
27 | 29 | ||
28 | namespace FbTk { | 30 | namespace FbTk { |
29 | 31 | ||
30 | XftFontImp::XftFontImp(const char *name, bool utf8): | 32 | XftFontImp::XftFontImp(const char *name, bool utf8): |
31 | m_utf8mode(utf8), m_name("") { | 33 | m_utf8mode(utf8), m_name(""), m_maxlength(0x8000) { |
32 | 34 | ||
33 | for (int r = ROT0; r <= ROT270; r++) { | 35 | for (int r = ROT0; r <= ROT270; r++) { |
34 | m_xftfonts[r] = 0; | 36 | m_xftfonts[r] = 0; |
@@ -56,12 +58,12 @@ bool XftFontImp::load(const std::string &name) { | |||
56 | if (newxftfont == 0) | 58 | if (newxftfont == 0) |
57 | return false; | 59 | return false; |
58 | } | 60 | } |
59 | 61 | ||
60 | // destroy all old fonts and set new | 62 | // destroy all old fonts and set new |
61 | for (int r = ROT0; r <= ROT270; r++) { | 63 | for (int r = ROT0; r <= ROT270; r++) { |
62 | m_xftfonts_loaded[r] = false; | 64 | m_xftfonts_loaded[r] = false; |
63 | if (m_xftfonts[r] != 0) { | 65 | if (m_xftfonts[r] != 0) { |
64 | XftFontClose(App::instance()->display(), m_xftfonts[r]); | 66 | XftFontClose(disp, m_xftfonts[r]); |
65 | m_xftfonts[r] = 0; | 67 | m_xftfonts[r] = 0; |
66 | } | 68 | } |
67 | } | 69 | } |
@@ -70,6 +72,15 @@ bool XftFontImp::load(const std::string &name) { | |||
70 | m_xftfonts_loaded[ROT0] = true; | 72 | m_xftfonts_loaded[ROT0] = true; |
71 | m_name = name; | 73 | m_name = name; |
72 | 74 | ||
75 | // XGlyphInfo (used by XftFontImp::textWidth() / XftTextExtents8() etc) | ||
76 | // holds only type 'short' or 'unsigned short'. any text bigger than that | ||
77 | // yields either some negative or some 'wrapped' values ('integer | ||
78 | // overflow'). to prevent something like this we detect the maximium | ||
79 | // number of glyphs by calculating the amount of 'WW' (pretending a 'wide' | ||
80 | // glyph) fitting into 32k pixels | ||
81 | unsigned int tw = textWidth("WW", 2); | ||
82 | m_maxlength = 0x8000 / tw; | ||
83 | |||
73 | return true; | 84 | return true; |
74 | } | 85 | } |
75 | 86 | ||
@@ -156,15 +167,15 @@ unsigned int XftFontImp::textWidth(const char* text, unsigned int len) const { | |||
156 | 167 | ||
157 | XftFont *font = m_xftfonts[ROT0]; | 168 | XftFont *font = m_xftfonts[ROT0]; |
158 | 169 | ||
170 | len = std::min(len, m_maxlength); | ||
171 | |||
159 | 172 | ||
160 | #ifdef HAVE_XFT_UTF8_STRING | 173 | #ifdef HAVE_XFT_UTF8_STRING |
161 | if (m_utf8mode) { | 174 | if (m_utf8mode) { |
162 | XftTextExtentsUtf8(disp, | 175 | XftTextExtentsUtf8(disp, font, (XftChar8 *)text, len, &ginfo); |
163 | font, | 176 | if (ginfo.xOff != 0) { |
164 | (XftChar8 *)text, len, | ||
165 | &ginfo); | ||
166 | if (ginfo.xOff != 0) | ||
167 | return ginfo.xOff; | 177 | return ginfo.xOff; |
178 | } | ||
168 | 179 | ||
169 | // the utf8 failed, try normal extents | 180 | // the utf8 failed, try normal extents |
170 | } | 181 | } |