aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/XftFontImp.cc
diff options
context:
space:
mode:
authorMathias Gumz <akira at fluxbox dot org>2013-06-18 15:43:28 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2013-06-18 15:43:28 (GMT)
commit118ea25f9d581de6fc2c57dde7b8737cbba6faf4 (patch)
treec1ade88f6cc1de44c3eab0d7190a57d80e44a236 /src/FbTk/XftFontImp.cc
parent1f24e6decdc1b34b46565f4e9b76a4b6fa91a063 (diff)
downloadfluxbox-118ea25f9d581de6fc2c57dde7b8737cbba6faf4.zip
fluxbox-118ea25f9d581de6fc2c57dde7b8737cbba6faf4.tar.bz2
Speedup overlong text detection
Detecting very long window titles is done via FbTk::TextUtils::doAlignment(). Instead of removing one char from the title at a time to see if it fits into a given 'max_width', we now use a binary-search like approach to get faster to the right value. This massively improves the speed for windows with (arbitrary) long window titles (see bug #1090, javascript document.title = new Array(4999).join("."); leads to massive waiting for fluxbox to detect that this window has a very long title). In addition to that Xft returns 'wrapped' shorts ('integer overflows') for long texts: XGlpyhInfo.xOff is declared as signed short, it's able to hold ~32k pixels. A monospace font with font-size 10 produces an integer overflow after 3276 chars / glyphs, thus rendering the check if (text_width < max_width) { /* ... */ } pointless and leading rendering the whole title. By calculating some kind of upper limit for a pseudo-wide glyph ("WW") and strictly cutting off the input string at that limit prevents this issue.
Diffstat (limited to 'src/FbTk/XftFontImp.cc')
-rw-r--r--src/FbTk/XftFontImp.cc17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/FbTk/XftFontImp.cc b/src/FbTk/XftFontImp.cc
index 15c8212..9e57349 100644
--- a/src/FbTk/XftFontImp.cc
+++ b/src/FbTk/XftFontImp.cc
@@ -23,7 +23,9 @@
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#ifdef HAVE_CONFIG_H 30#ifdef HAVE_CONFIG_H
29#include "config.h" 31#include "config.h"
@@ -32,7 +34,7 @@
32namespace FbTk { 34namespace FbTk {
33 35
34XftFontImp::XftFontImp(const char *name, bool utf8): 36XftFontImp::XftFontImp(const char *name, bool utf8):
35 m_utf8mode(utf8), m_name("") { 37 m_utf8mode(utf8), m_name(""), m_maxlength(0x8000) {
36 38
37 for (int r = ROT0; r <= ROT270; r++) { 39 for (int r = ROT0; r <= ROT270; r++) {
38 m_xftfonts[r] = 0; 40 m_xftfonts[r] = 0;
@@ -74,6 +76,15 @@ bool XftFontImp::load(const std::string &name) {
74 m_xftfonts_loaded[ROT0] = true; 76 m_xftfonts_loaded[ROT0] = true;
75 m_name = name; 77 m_name = name;
76 78
79 // XGlyphInfo (used by XftFontImp::textWidth() / XftTextExtents8() etc)
80 // holds only type 'short' or 'unsigned short'. any text bigger than that
81 // yields either some negative or some 'wrapped' values ('integer
82 // overflow'). to prevent something like this we detect the maximium
83 // number of glyphs by calculating the amount of 'WW' (pretending a 'wide'
84 // glyph) fitting into 32k pixels
85 unsigned int tw = textWidth("WW", 2);
86 m_maxlength = 0x8000 / tw;
87
77 return true; 88 return true;
78} 89}
79 90
@@ -160,6 +171,8 @@ unsigned int XftFontImp::textWidth(const char* text, unsigned int len) const {
160 171
161 XftFont *font = m_xftfonts[ROT0]; 172 XftFont *font = m_xftfonts[ROT0];
162 173
174 len = std::min(len, m_maxlength);
175
163 176
164#ifdef HAVE_XFT_UTF8_STRING 177#ifdef HAVE_XFT_UTF8_STRING
165 if (m_utf8mode) { 178 if (m_utf8mode) {