aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk
diff options
context:
space:
mode:
authorMathias Gumz <akira at fluxbox dot org>2010-09-08 18:17:21 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2010-09-08 18:17:21 (GMT)
commit690d926ac444243611cd875fb84fabb4e6db2cf2 (patch)
treec8ef84056b295071f9a9207ffea5393c6cf4ad4d /src/FbTk
parent1e8fe2bc14856fa16508686a28a85e72cb0e422c (diff)
downloadfluxbox-690d926ac444243611cd875fb84fabb4e6db2cf2.zip
fluxbox-690d926ac444243611cd875fb84fabb4e6db2cf2.tar.bz2
introduced FbTk::BidiString
a 'BidiString' holds both the logical content and the visual reordered version of the content of a string. this helps to reduce the number of calls to reorder the string before drawing it (as introduced in the patch from Ken Bloom) and to be more consistent in menus and textboxes (drawing cursors and underlining text).
Diffstat (limited to 'src/FbTk')
-rw-r--r--src/FbTk/FbString.cc150
-rw-r--r--src/FbTk/FbString.hh37
-rw-r--r--src/FbTk/Font.cc34
-rw-r--r--src/FbTk/Font.hh14
-rw-r--r--src/FbTk/FontImp.hh4
-rw-r--r--src/FbTk/ITypeAheadable.hh2
-rw-r--r--src/FbTk/IntMenuItem.hh14
-rw-r--r--src/FbTk/Menu.cc13
-rw-r--r--src/FbTk/Menu.hh6
-rw-r--r--src/FbTk/MenuItem.cc31
-rw-r--r--src/FbTk/MenuItem.hh18
-rw-r--r--src/FbTk/MultiButtonMenuItem.cc4
-rw-r--r--src/FbTk/MultiButtonMenuItem.hh4
-rw-r--r--src/FbTk/TextBox.cc63
-rw-r--r--src/FbTk/TextBox.hh9
-rw-r--r--src/FbTk/TextButton.cc33
-rw-r--r--src/FbTk/TextButton.hh11
-rw-r--r--src/FbTk/XFontImp.cc18
-rw-r--r--src/FbTk/XFontImp.hh4
-rw-r--r--src/FbTk/XftFontImp.cc55
-rw-r--r--src/FbTk/XftFontImp.hh4
-rw-r--r--src/FbTk/XmbFontImp.cc28
-rw-r--r--src/FbTk/XmbFontImp.hh4
23 files changed, 284 insertions, 276 deletions
diff --git a/src/FbTk/FbString.cc b/src/FbTk/FbString.cc
index 2190a76..79b773a 100644
--- a/src/FbTk/FbString.cc
+++ b/src/FbTk/FbString.cc
@@ -62,8 +62,86 @@ using std::cerr;
62using std::endl; 62using std::endl;
63#endif // DEBUG 63#endif // DEBUG
64 64
65namespace {
66
67#ifdef HAVE_FRIBIDI
68FbTk::FbString makeVisualFromLogical(const FbTk::FbString& src) {
69
70 FriBidiCharType base = FRIBIDI_TYPE_N;
71
72 // reuse allocated memory for reencoding / reordering
73 static std::vector<FriBidiChar> us;
74 static std::vector<FriBidiChar> out_us;
75 static FbTk::FbString result;
76
77 const size_t S = src.size() + 1;
78 const size_t S4 = S * 4;
79
80 if (us.capacity() < S)
81 us.reserve(S);
82 if (out_us.capacity() < S)
83 out_us.reserve(S);
84 if (result.capacity() < S4)
85 result.reserve(S4);
86
87 us.resize(S);
88 FriBidiStrIndex len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8,
89 const_cast<char*>(src.c_str()), S - 1,
90 &us[0]);
91
92 out_us.resize(S);
93 fribidi_log2vis(&us[0], len, &base, &out_us[0], NULL, NULL, NULL);
94
95 result.resize(S4);
96 len = fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, &out_us[0], len, &result[0]);
97 result.resize(len); // trim to currently used chars
98
99 return result;
100}
101
102#endif
103
104} // end of anonymous namespace
105
106
65namespace FbTk { 107namespace FbTk {
66 108
109
110BiDiString::BiDiString(const FbString& logical)
111#ifdef HAVE_FRIBIDI
112 : m_visual_dirty(false)
113#endif
114{
115 if (!logical.empty())
116 setLogical(logical);
117}
118
119const FbString& BiDiString::setLogical(const FbString& logical) {
120 m_logical = logical;
121#if HAVE_FRIBIDI
122 if (m_logical.empty()) {
123 m_visual_dirty = false;
124 m_visual.clear();
125 } else {
126 m_visual_dirty = true;
127 }
128#endif
129}
130
131const FbString& BiDiString::visual() const {
132#if HAVE_FRIBIDI
133 if (m_visual_dirty) {
134 m_visual = ::makeVisualFromLogical(logical());
135 }
136 m_visual_dirty = false;
137 return m_visual;
138#else
139 return m_logical;
140#endif
141}
142
143
144
67namespace FbStringUtil { 145namespace FbStringUtil {
68 146
69enum ConvType { FB2X = 0, X2FB, LOCALE2FB, FB2LOCALE, CONVSIZE }; 147enum ConvType { FB2X = 0, X2FB, LOCALE2FB, FB2LOCALE, CONVSIZE };
@@ -128,7 +206,6 @@ void shutdown() {
128 206
129 207
130 208
131#ifdef HAVE_ICONV
132/** 209/**
133 Recodes the text from one encoding to another 210 Recodes the text from one encoding to another
134 assuming cd is correct 211 assuming cd is correct
@@ -137,7 +214,9 @@ void shutdown() {
137 @param size number of BYTES to convert 214 @param size number of BYTES to convert
138 @return the recoded string, or 0 on failure 215 @return the recoded string, or 0 on failure
139*/ 216*/
217string recode(iconv_t cd, const string &in) {
140 218
219#ifdef HAVE_ICONV
141/** 220/**
142 --NOTE-- 221 --NOTE--
143 In the "C" locale, this will strip any high-bit characters 222 In the "C" locale, this will strip any high-bit characters
@@ -145,8 +224,6 @@ void shutdown() {
145 then you need to set your locale to something UTF-8, OR something 224 then you need to set your locale to something UTF-8, OR something
146 ISO8859-1. 225 ISO8859-1.
147*/ 226*/
148string recode(iconv_t cd,
149 const string &in) {
150 227
151 // If empty message, yes this can happen, return 228 // If empty message, yes this can happen, return
152 if (in.empty()) 229 if (in.empty())
@@ -163,18 +240,18 @@ string recode(iconv_t cd,
163 size_t inbytesleft = insize; 240 size_t inbytesleft = insize;
164 size_t outbytesleft = outsize; 241 size_t outbytesleft = outsize;
165 242
243#ifdef HAVE_CONST_ICONV
244 const char* in_ptr = in.data();
245#else
166 char * in_ptr = const_cast<char *>(in.data()); 246 char * in_ptr = const_cast<char *>(in.data());
247#endif
167 size_t result = (size_t)(-1); 248 size_t result = (size_t)(-1);
168 bool again = true; 249 bool again = true;
169 250
170 while (again) { 251 while (again) {
171 again = false; 252 again = false;
172 253
173#ifdef HAVE_CONST_ICONV
174 result = iconv(cd, (const char**)(&in_ptr), &inbytesleft, &out_ptr, &outbytesleft);
175#else
176 result = iconv(cd, &in_ptr, &inbytesleft, &out_ptr, &outbytesleft); 254 result = iconv(cd, &in_ptr, &inbytesleft, &out_ptr, &outbytesleft);
177#endif // HAVE_CONST_ICONV
178 255
179 if (result == (size_t)(-1)) { 256 if (result == (size_t)(-1)) {
180 switch(errno) { 257 switch(errno) {
@@ -213,13 +290,10 @@ string recode(iconv_t cd,
213 free(out); 290 free(out);
214 291
215 return ret; 292 return ret;
216}
217#else 293#else
218string recode(int cd,
219 const string &str) {
220 return str; 294 return str;
221}
222#endif // HAVE_ICONV 295#endif // HAVE_ICONV
296}
223 297
224FbString XStrToFb(const string &src) { 298FbString XStrToFb(const string &src) {
225 return recode(iconv_convs[X2FB], src); 299 return recode(iconv_convs[X2FB], src);
@@ -249,59 +323,19 @@ bool haveUTF8() {
249} 323}
250 324
251 325
252#ifdef HAVE_FRIBIDI
253
254FbString BidiLog2Vis (const FbString& src) {
255
256 FriBidiCharType base = FRIBIDI_TYPE_N;
257
258 // reuse allocated memory for reencoding / reordering
259 static std::vector<FriBidiChar> us;
260 static std::vector<FriBidiChar> out_us;
261 static FbString result;
262
263 const size_t S = src.size() + 1;
264 const size_t S4 = S * 4;
265
266 if (us.capacity() < S)
267 us.reserve(S);
268 if (out_us.capacity() < S)
269 out_us.reserve(S);
270 if (result.capacity() < S4)
271 result.reserve(S4);
272
273 us.resize(S);
274 FriBidiStrIndex len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8,
275 const_cast<char*>(src.c_str()), S - 1,
276 &us[0]);
277
278 out_us.resize(S);
279 fribidi_log2vis(&us[0], len, &base, &out_us[0], NULL, NULL, NULL);
280
281 result.resize(S4);
282 len = fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, &out_us[0], len, &result[0]);
283 result.resize(len); // trim to currently used chars
284
285 return result;
286}
287
288#endif
289
290} // end namespace StringUtil 326} // end namespace StringUtil
291 327
292StringConvertor::StringConvertor(EncodingTarget target):
293#ifdef HAVE_ICONV 328#ifdef HAVE_ICONV
294 m_iconv((iconv_t)(-1)) { 329StringConvertor::StringConvertor(EncodingTarget target) : m_iconv((iconv_t)(-1)) {
295 if (target == ToLocaleStr) 330 if (target == ToLocaleStr)
296 m_destencoding = FbStringUtil::locale_codeset; 331 m_destencoding = FbStringUtil::locale_codeset;
297 else 332 else
298 m_destencoding = "UTF-8"; 333 m_destencoding = "UTF-8";
299} 334}
300#else 335#else
301 m_iconv(-1) {} 336StringConvertor::StringConvertor(EncodingTarget target) { }
302#endif 337#endif
303 338
304
305StringConvertor::~StringConvertor() { 339StringConvertor::~StringConvertor() {
306#ifdef HAVE_ICONV 340#ifdef HAVE_ICONV
307 if (m_iconv != ((iconv_t)-1)) 341 if (m_iconv != ((iconv_t)-1))
@@ -329,7 +363,7 @@ bool StringConvertor::setSource(const string &encoding) {
329#endif 363#endif
330} 364}
331 365
332string StringConvertor::recode(const string &src) { 366FbString StringConvertor::recode(const string &src) {
333#ifdef HAVE_ICONV 367#ifdef HAVE_ICONV
334 return FbStringUtil::recode(m_iconv, src); 368 return FbStringUtil::recode(m_iconv, src);
335#else 369#else
@@ -337,5 +371,13 @@ string StringConvertor::recode(const string &src) {
337#endif 371#endif
338} 372}
339 373
374void StringConvertor::reset() {
375#ifdef HAVE_ICONV
376 if (m_iconv != ((iconv_t)-1))
377 iconv_close(m_iconv);
378 m_iconv = ((iconv_t)(-1));
379#endif
380}
381
340 382
341} // end namespace FbTk 383} // end namespace FbTk
diff --git a/src/FbTk/FbString.hh b/src/FbTk/FbString.hh
index e1a5dc5..55798e5 100644
--- a/src/FbTk/FbString.hh
+++ b/src/FbTk/FbString.hh
@@ -36,6 +36,25 @@ namespace FbTk {
36// (or just plain whatever for now if no utf-8 available) 36// (or just plain whatever for now if no utf-8 available)
37typedef std::string FbString; 37typedef std::string FbString;
38 38
39class BiDiString {
40
41public:
42
43 BiDiString(const FbString& logical = FbString());
44
45 const FbString& logical() const { return m_logical; }
46 const FbString& visual() const;
47
48 const FbString& setLogical(const FbString& logical);
49
50private:
51 FbString m_logical;
52#ifdef HAVE_FRIBIDI
53 mutable FbString m_visual;
54 mutable bool m_visual_dirty;
55#endif
56};
57
39namespace FbStringUtil { 58namespace FbStringUtil {
40 59
41void init(); 60void init();
@@ -52,11 +71,6 @@ std::string FbStrToX(const FbString &src);
52FbString LocaleStrToFb(const std::string &src); 71FbString LocaleStrToFb(const std::string &src);
53std::string FbStrToLocale(const FbString &src); 72std::string FbStrToLocale(const FbString &src);
54 73
55#ifdef HAVE_FRIBIDI
56/// Make Bidi
57FbString BidiLog2Vis (const FbString& src);
58#endif
59
60bool haveUTF8(); 74bool haveUTF8();
61 75
62} // namespace FbStringUtil 76} // namespace FbStringUtil
@@ -70,23 +84,14 @@ public:
70 ~StringConvertor(); 84 ~StringConvertor();
71 85
72 bool setSource(const std::string &encoding); 86 bool setSource(const std::string &encoding);
73 void reset() { 87 void reset();
74#ifdef HAVE_ICONV
75 if (m_iconv != ((iconv_t)-1))
76 iconv_close(m_iconv);
77 m_iconv = ((iconv_t)(-1));
78#endif
79 }
80 88
81 std::string recode(const std::string &src); 89 FbString recode(const FbString &src);
82 90
83private: 91private:
84#ifdef HAVE_ICONV 92#ifdef HAVE_ICONV
85 iconv_t m_iconv; 93 iconv_t m_iconv;
86#else
87 int m_iconv;
88#endif 94#endif
89
90 std::string m_destencoding; 95 std::string m_destencoding;
91}; 96};
92 97
diff --git a/src/FbTk/Font.cc b/src/FbTk/Font.cc
index 28341a7..ea0fbde 100644
--- a/src/FbTk/Font.cc
+++ b/src/FbTk/Font.cc
@@ -247,14 +247,8 @@ bool Font::load(const string &name) {
247 return false; 247 return false;
248} 248}
249 249
250unsigned int Font::textWidth(const FbString &text, unsigned int size) const { 250unsigned int Font::textWidth(const char* text, unsigned int size) const {
251#ifdef HAVE_FRIBIDI 251 return m_fontimp->textWidth(text, size);
252 const FbString visualOrder(FbTk::FbStringUtil::BidiLog2Vis(text));
253#else
254 const FbString &visualOrder = text;
255#endif
256
257 return m_fontimp->textWidth(visualOrder, size);
258} 252}
259 253
260unsigned int Font::height() const { 254unsigned int Font::height() const {
@@ -274,34 +268,28 @@ bool Font::validOrientation(FbTk::Orientation orient) {
274} 268}
275 269
276void Font::drawText(const FbDrawable &w, int screen, GC gc, 270void Font::drawText(const FbDrawable &w, int screen, GC gc,
277 const FbString &text, size_t len, int x, int y, 271 const char* text, size_t len, int x, int y,
278 Orientation orient) const { 272 Orientation orient) const {
279 if (text.empty() || len == 0)
280 return;
281
282#ifdef HAVE_FRIBIDI
283 const FbString visualOrder(FbTk::FbStringUtil::BidiLog2Vis(text));
284#else
285 const FbString &visualOrder = text;
286#endif
287 273
274 if (!text || !*text || len == 0)
275 return;
288 276
289 // draw "effects" first 277 // draw "effects" first
290 if (m_shadow) { 278 if (m_shadow) {
291 FbTk::GContext shadow_gc(w); 279 FbTk::GContext shadow_gc(w);
292 shadow_gc.setForeground(m_shadow_color); 280 shadow_gc.setForeground(m_shadow_color);
293 m_fontimp->drawText(w, screen, shadow_gc.gc(), visualOrder, len, 281 m_fontimp->drawText(w, screen, shadow_gc.gc(), text, len,
294 x + m_shadow_offx, y + m_shadow_offy, orient); 282 x + m_shadow_offx, y + m_shadow_offy, orient);
295 } else if (m_halo) { 283 } else if (m_halo) {
296 FbTk::GContext halo_gc(w); 284 FbTk::GContext halo_gc(w);
297 halo_gc.setForeground(m_halo_color); 285 halo_gc.setForeground(m_halo_color);
298 m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x + 1, y + 1, orient); 286 m_fontimp->drawText(w, screen, halo_gc.gc(), text, len, x + 1, y + 1, orient);
299 m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x - 1, y + 1, orient); 287 m_fontimp->drawText(w, screen, halo_gc.gc(), text, len, x - 1, y + 1, orient);
300 m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x - 1, y - 1, orient); 288 m_fontimp->drawText(w, screen, halo_gc.gc(), text, len, x - 1, y - 1, orient);
301 m_fontimp->drawText(w, screen, halo_gc.gc(), visualOrder, len, x + 1, y - 1, orient); 289 m_fontimp->drawText(w, screen, halo_gc.gc(), text, len, x + 1, y - 1, orient);
302 } 290 }
303 291
304 m_fontimp->drawText(w, screen, gc, visualOrder, len, x, y, orient); 292 m_fontimp->drawText(w, screen, gc, text, len, x, y, orient);
305 293
306 294
307} 295}
diff --git a/src/FbTk/Font.hh b/src/FbTk/Font.hh
index 28bbf22..fb399d9 100644
--- a/src/FbTk/Font.hh
+++ b/src/FbTk/Font.hh
@@ -75,7 +75,11 @@ public:
75 @param size length of text in bytes 75 @param size length of text in bytes
76 @return size of text in pixels 76 @return size of text in pixels
77 */ 77 */
78 unsigned int textWidth(const FbString &text, unsigned int size) const; 78 unsigned int textWidth(const char* text, unsigned int size) const;
79 unsigned int textWidth(const BiDiString &text) const {
80 return textWidth(text.visual().c_str(), text.visual().size());
81 }
82
79 unsigned int height() const; 83 unsigned int height() const;
80 int ascent() const; 84 int ascent() const;
81 int descent() const; 85 int descent() const;
@@ -99,8 +103,14 @@ public:
99 @param rotate if the text should be drawn rotated (if it's rotated before) 103 @param rotate if the text should be drawn rotated (if it's rotated before)
100 */ 104 */
101 void drawText(const FbDrawable &w, int screen, GC gc, 105 void drawText(const FbDrawable &w, int screen, GC gc,
102 const FbString &text, size_t len, 106 const char* text, size_t len,
103 int x, int y, FbTk::Orientation orient = ROT0) const; 107 int x, int y, FbTk::Orientation orient = ROT0) const;
108 void drawText(const FbDrawable &w, int screen, GC gc,
109 const BiDiString &text,
110 int x, int y, FbTk::Orientation orient = ROT0) const {
111 drawText(w, screen, gc, text.visual().c_str(), text.visual().size(), x, y, orient);
112 }
113
104 114
105 bool hasShadow() const { return m_shadow; } 115 bool hasShadow() const { return m_shadow; }
106 bool hasHalo() const { return m_halo; } 116 bool hasHalo() const { return m_halo; }
diff --git a/src/FbTk/FontImp.hh b/src/FbTk/FontImp.hh
index 4d7eb16..0578d1a 100644
--- a/src/FbTk/FontImp.hh
+++ b/src/FbTk/FontImp.hh
@@ -40,8 +40,8 @@ class FontImp {
40public: 40public:
41 virtual ~FontImp() { } 41 virtual ~FontImp() { }
42 virtual bool load(const std::string &name) = 0; 42 virtual bool load(const std::string &name) = 0;
43 virtual void drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) = 0; 43 virtual void drawText(const FbDrawable &w, int screen, GC gc, const char* text, size_t len, int x, int y, FbTk::Orientation orient) = 0;
44 virtual unsigned int textWidth(const FbString &text, unsigned int size) const = 0; 44 virtual unsigned int textWidth(const char* text, unsigned int len) const = 0;
45 virtual bool validOrientation(FbTk::Orientation orient) { return orient == ROT0; } 45 virtual bool validOrientation(FbTk::Orientation orient) { return orient == ROT0; }
46 virtual int ascent() const = 0; 46 virtual int ascent() const = 0;
47 virtual int descent() const = 0; 47 virtual int descent() const = 0;
diff --git a/src/FbTk/ITypeAheadable.hh b/src/FbTk/ITypeAheadable.hh
index 1b0bd03..ebcb935 100644
--- a/src/FbTk/ITypeAheadable.hh
+++ b/src/FbTk/ITypeAheadable.hh
@@ -22,7 +22,7 @@
22#ifndef FBTK_ITYPEAHEADABLE_HH 22#ifndef FBTK_ITYPEAHEADABLE_HH
23#define FBTK_ITYPEAHEADABLE_HH 23#define FBTK_ITYPEAHEADABLE_HH
24 24
25#include <string> 25#include "FbString.hh"
26 26
27#ifdef HAVE_CCTYPE 27#ifdef HAVE_CCTYPE
28 #include <cctype> 28 #include <cctype>
diff --git a/src/FbTk/IntMenuItem.hh b/src/FbTk/IntMenuItem.hh
index 9d2d2ba..2df3f14 100644
--- a/src/FbTk/IntMenuItem.hh
+++ b/src/FbTk/IntMenuItem.hh
@@ -23,6 +23,7 @@
23#define FBTK_INTMENUITEM_HH 23#define FBTK_INTMENUITEM_HH
24 24
25#include "MenuItem.hh" 25#include "MenuItem.hh"
26#include "StringUtil.hh"
26 27
27namespace FbTk { 28namespace FbTk {
28 29
@@ -39,15 +40,6 @@ public:
39 setCloseOnClick(false); 40 setCloseOnClick(false);
40 } 41 }
41 42
42 /* Utility, but doesn't get found in anonymous namespace? */
43 std::string appendIntValue(const std::string &label, int value) {
44 char *buff = new char[label.size() + 16];
45 sprintf(buff, "%s: %d", label.c_str(), value);
46 std::string ret(buff);
47 delete [] buff;
48 return ret;
49 }
50
51 void click(int button, int time, unsigned int mods) { 43 void click(int button, int time, unsigned int mods) {
52 static int last_time = -201; 44 static int last_time = -201;
53 int inc_val = 1; 45 int inc_val = 1;
@@ -86,11 +78,11 @@ public:
86 } 78 }
87 79
88 void updateLabel() { 80 void updateLabel() {
89 setLabel(appendIntValue(m_org_label, m_res)); 81 setLabel(m_org_label.logical() + ": " + FbTk::StringUtil::number2String(m_res));
90 } 82 }
91 83
92private: 84private:
93 std::string m_org_label; ///< original label 85 FbTk::BiDiString m_org_label; ///< original label
94 const int m_max; ///< maximum value the integer can have 86 const int m_max; ///< maximum value the integer can have
95 const int m_min; ///< minimum value the integer can have 87 const int m_min; ///< minimum value the integer can have
96 Accessor<int> &m_res; ///< resource item to be changed 88 Accessor<int> &m_res; ///< resource item to be changed
diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc
index ded5dab..811964c 100644
--- a/src/FbTk/Menu.cc
+++ b/src/FbTk/Menu.cc
@@ -375,8 +375,7 @@ void Menu::enableTitle() {
375 375
376void Menu::updateMenu() { 376void Menu::updateMenu() {
377 if (m_title_vis) { 377 if (m_title_vis) {
378 menu.item_w = theme()->titleFont().textWidth(menu.label, 378 menu.item_w = theme()->titleFont().textWidth(menu.label);
379 menu.label.size());
380 menu.item_w += (theme()->bevelWidth() * 2); 379 menu.item_w += (theme()->bevelWidth() * 2);
381 } else 380 } else
382 menu.item_w = 1; 381 menu.item_w = 1;
@@ -669,8 +668,7 @@ void Menu::redrawTitle(FbDrawable &drawable) {
669 668
670 const FbTk::Font &font = theme()->titleFont(); 669 const FbTk::Font &font = theme()->titleFont();
671 int dx = theme()->bevelWidth(); 670 int dx = theme()->bevelWidth();
672 size_t len = menu.label.size(); 671 unsigned int l = font.textWidth(menu.label) + theme()->bevelWidth()*2;
673 unsigned int l = font.textWidth(menu.label, len) + theme()->bevelWidth()*2;
674 672
675 switch (theme()->titleFontJustify()) { 673 switch (theme()->titleFontJustify()) {
676 case FbTk::RIGHT: 674 case FbTk::RIGHT:
@@ -686,10 +684,7 @@ void Menu::redrawTitle(FbDrawable &drawable) {
686 684
687 // difference between height based on font, and style-set height 685 // difference between height based on font, and style-set height
688 int height_offset = theme()->titleHeight() - (font.height() + 2*theme()->bevelWidth()); 686 int height_offset = theme()->titleHeight() - (font.height() + 2*theme()->bevelWidth());
689 font.drawText(drawable, // drawable 687 font.drawText(drawable, screenNumber(), theme()->titleTextGC().gc(), menu.label,
690 screenNumber(),
691 theme()->titleTextGC().gc(), // graphic context
692 menu.label, len, // text string with length
693 dx, font.ascent() + theme()->bevelWidth() + height_offset/2); // position 688 dx, font.ascent() + theme()->bevelWidth() + height_offset/2); // position
694} 689}
695 690
@@ -795,7 +790,7 @@ int Menu::drawItem(FbDrawable &drawable, unsigned int index,
795 return item_y; 790 return item_y;
796} 791}
797 792
798void Menu::setLabel(const FbString &labelstr) { 793void Menu::setLabel(const FbTk::BiDiString &labelstr) {
799 //make sure we don't send 0 to std::string 794 //make sure we don't send 0 to std::string
800 menu.label = labelstr; 795 menu.label = labelstr;
801 reconfigure(); 796 reconfigure();
diff --git a/src/FbTk/Menu.hh b/src/FbTk/Menu.hh
index 09bdd8c..a7bb982 100644
--- a/src/FbTk/Menu.hh
+++ b/src/FbTk/Menu.hh
@@ -108,7 +108,7 @@ public:
108 void grabInputFocus(); 108 void grabInputFocus();
109 virtual void reconfigure(); 109 virtual void reconfigure();
110 /// set label string 110 /// set label string
111 void setLabel(const FbString &labelstr); 111 void setLabel(const FbTk::BiDiString &labelstr);
112 /// move menu to x,y 112 /// move menu to x,y
113 virtual void move(int x, int y); 113 virtual void move(int x, int y);
114 virtual void updateMenu(); 114 virtual void updateMenu();
@@ -136,7 +136,7 @@ public:
136 const FbWindow &fbwindow() const { return menu.window; } 136 const FbWindow &fbwindow() const { return menu.window; }
137 FbWindow &titleWindow() { return menu.title; } 137 FbWindow &titleWindow() { return menu.title; }
138 FbWindow &frameWindow() { return menu.frame; } 138 FbWindow &frameWindow() { return menu.frame; }
139 const std::string &label() const { return menu.label; } 139 const FbTk::BiDiString &label() const { return menu.label; }
140 int x() const { return menu.window.x(); } 140 int x() const { return menu.window.x(); }
141 int y() const { return menu.window.y(); } 141 int y() const { return menu.window.y(); }
142 unsigned int width() const { return menu.window.width(); } 142 unsigned int width() const { return menu.window.width(); }
@@ -225,7 +225,7 @@ private:
225 Pixmap frame_pixmap, title_pixmap, hilite_pixmap; 225 Pixmap frame_pixmap, title_pixmap, hilite_pixmap;
226 FbTk::FbWindow window, frame, title; 226 FbTk::FbWindow window, frame, title;
227 227
228 std::string label; 228 FbTk::BiDiString label;
229 int x_move, y_move, sublevels, persub, minsub, grab_x, grab_y; 229 int x_move, y_move, sublevels, persub, minsub, grab_x, grab_y;
230 230
231 unsigned int frame_h, item_w; 231 unsigned int frame_h, item_w;
diff --git a/src/FbTk/MenuItem.cc b/src/FbTk/MenuItem.cc
index f995666..c1357fb 100644
--- a/src/FbTk/MenuItem.cc
+++ b/src/FbTk/MenuItem.cc
@@ -52,14 +52,14 @@ void MenuItem::drawLine(FbDrawable &draw,
52 int font_top = (height - theme->frameFont().height())/2; 52 int font_top = (height - theme->frameFont().height())/2;
53 int underline_height = font_top + theme->frameFont().ascent() + 2; 53 int underline_height = font_top + theme->frameFont().ascent() + 2;
54 int bottom = height - bevelW - 1; 54 int bottom = height - bevelW - 1;
55 55
56 text_y += bottom > underline_height ? underline_height : bottom; 56 text_y += bottom > underline_height ? underline_height : bottom;
57 int text_w = theme->frameFont().textWidth(m_label, m_label.size());
58 57
59 // width of the searchstring 58 int text_w = theme->frameFont().textWidth(label());
60 size = size > m_label.length() ? m_label.length() : size; 59
61 std::string search_string = m_label.substr(0,size); 60 const FbString& visual = m_label.visual();
62 int search_string_w = theme->frameFont().textWidth(search_string, size); 61 BiDiString search_string(FbString(visual, 0, size > visual.size() ? visual.size() : size));
62 int search_string_w = theme->frameFont().textWidth(search_string);
63 63
64 // pay attention to the text justification 64 // pay attention to the text justification
65 switch(theme->frameFontJustify()) { 65 switch(theme->frameFontJustify()) {
@@ -144,7 +144,7 @@ void MenuItem::draw(FbDrawable &draw,
144 } 144 }
145 } 145 }
146 146
147 if (label().empty()) 147 if (label().logical().empty())
148 return; 148 return;
149 149
150 // text is background 150 // text is background
@@ -156,8 +156,7 @@ void MenuItem::draw(FbDrawable &draw,
156 // Text 156 // Text
157 // 157 //
158 int text_y = y, text_x = x; 158 int text_y = y, text_x = x;
159 159 int text_w = theme->frameFont().textWidth(label());
160 int text_w = theme->frameFont().textWidth(label(), label().size());
161 160
162 int height_offset = theme->itemHeight() - (theme->frameFont().height() + 2*theme->bevelWidth()); 161 int height_offset = theme->itemHeight() - (theme->frameFont().height() + 2*theme->bevelWidth());
163 text_y = y + theme->bevelWidth() + theme->frameFont().ascent() + height_offset/2; 162 text_y = y + theme->bevelWidth() + theme->frameFont().ascent() + height_offset/2;
@@ -175,11 +174,7 @@ void MenuItem::draw(FbDrawable &draw,
175 break; 174 break;
176 } 175 }
177 176
178 theme->frameFont().drawText(draw, // drawable 177 theme->frameFont().drawText(draw, theme->screenNum(), tgc.gc(), label(), text_x, text_y);
179 theme->screenNum(),
180 tgc.gc(),
181 label().c_str(), label().size(), // text string and lenght
182 text_x, text_y); // position
183 } 178 }
184 179
185 GC gc = (highlight) ? theme->hiliteTextGC().gc() : 180 GC gc = (highlight) ? theme->hiliteTextGC().gc() :
@@ -335,7 +330,7 @@ unsigned int MenuItem::height(const FbTk::ThemeProxy<MenuTheme> &theme) const {
335unsigned int MenuItem::width(const FbTk::ThemeProxy<MenuTheme> &theme) const { 330unsigned int MenuItem::width(const FbTk::ThemeProxy<MenuTheme> &theme) const {
336 // textwidth + bevel width on each side of the text 331 // textwidth + bevel width on each side of the text
337 const unsigned int icon_width = height(theme); 332 const unsigned int icon_width = height(theme);
338 const unsigned int normal = theme->frameFont().textWidth(label(), label().size()) + 333 const unsigned int normal = theme->frameFont().textWidth(label()) +
339 2 * (theme->bevelWidth() + icon_width); 334 2 * (theme->bevelWidth() + icon_width);
340 return m_icon.get() == 0 ? normal : normal + icon_width; 335 return m_icon.get() == 0 ? normal : normal + icon_width;
341} 336}
@@ -349,9 +344,9 @@ void MenuItem::updateTheme(const FbTk::ThemeProxy<MenuTheme> &theme) {
349 344
350} 345}
351 346
352void MenuItem::showSubmenu() { 347void MenuItem::showSubmenu() {
353 if (submenu() != 0) 348 if (submenu() != 0)
354 submenu()->show(); 349 submenu()->show();
355} 350}
356 351
357} // end namespace FbTk 352} // end namespace FbTk
diff --git a/src/FbTk/MenuItem.hh b/src/FbTk/MenuItem.hh
index 9150849..2149559 100644
--- a/src/FbTk/MenuItem.hh
+++ b/src/FbTk/MenuItem.hh
@@ -41,7 +41,7 @@ template <class T> class ThemeProxy;
41class MenuItem : public FbTk::ITypeAheadable { 41class MenuItem : public FbTk::ITypeAheadable {
42public: 42public:
43 MenuItem() 43 MenuItem()
44 : m_label(""), 44 : m_label(BiDiString("")),
45 m_menu(0), 45 m_menu(0),
46 m_submenu(0), 46 m_submenu(0),
47 m_enabled(true), 47 m_enabled(true),
@@ -49,7 +49,7 @@ public:
49 m_close_on_click(true), 49 m_close_on_click(true),
50 m_toggle_item(false) 50 m_toggle_item(false)
51 { } 51 { }
52 explicit MenuItem(const FbString &label) 52 explicit MenuItem(const BiDiString &label)
53 : m_label(label), 53 : m_label(label),
54 m_menu(0), 54 m_menu(0),
55 m_submenu(0), 55 m_submenu(0),
@@ -59,7 +59,7 @@ public:
59 m_toggle_item(false) 59 m_toggle_item(false)
60 { } 60 { }
61 61
62 MenuItem(const FbString &label, Menu &host_menu) 62 MenuItem(const BiDiString &label, Menu &host_menu)
63 : m_label(label), 63 : m_label(label),
64 m_menu(&host_menu), 64 m_menu(&host_menu),
65 m_submenu(0), 65 m_submenu(0),
@@ -69,7 +69,7 @@ public:
69 m_toggle_item(false) 69 m_toggle_item(false)
70 { } 70 { }
71 /// create a menu item with a specific command to be executed on click 71 /// create a menu item with a specific command to be executed on click
72 MenuItem(const FbString &label, RefCount<Command<void> > &cmd, Menu *menu = 0) 72 MenuItem(const BiDiString &label, RefCount<Command<void> > &cmd, Menu *menu = 0)
73 : m_label(label), 73 : m_label(label),
74 m_menu(menu), 74 m_menu(menu),
75 m_submenu(0), 75 m_submenu(0),
@@ -80,7 +80,7 @@ public:
80 m_toggle_item(false) 80 m_toggle_item(false)
81 { } 81 { }
82 82
83 MenuItem(const FbString &label, Menu *submenu, Menu *host_menu = 0) 83 MenuItem(const BiDiString &label, Menu *submenu, Menu *host_menu = 0)
84 : m_label(label), 84 : m_label(label),
85 m_menu(host_menu), 85 m_menu(host_menu),
86 m_submenu(submenu), 86 m_submenu(submenu),
@@ -94,7 +94,7 @@ public:
94 void setCommand(RefCount<Command<void> > &cmd) { m_command = cmd; } 94 void setCommand(RefCount<Command<void> > &cmd) { m_command = cmd; }
95 virtual void setSelected(bool selected) { m_selected = selected; } 95 virtual void setSelected(bool selected) { m_selected = selected; }
96 virtual void setEnabled(bool enabled) { m_enabled = enabled; } 96 virtual void setEnabled(bool enabled) { m_enabled = enabled; }
97 virtual void setLabel(const FbString &label) { m_label = label; } 97 virtual void setLabel(const BiDiString &label) { m_label = label; }
98 virtual void setToggleItem(bool val) { m_toggle_item = val; } 98 virtual void setToggleItem(bool val) { m_toggle_item = val; }
99 void setCloseOnClick(bool val) { m_close_on_click = val; } 99 void setCloseOnClick(bool val) { m_close_on_click = val; }
100 void setIcon(const std::string &filename, int screen_num); 100 void setIcon(const std::string &filename, int screen_num);
@@ -103,7 +103,7 @@ public:
103 @name accessors 103 @name accessors
104 */ 104 */
105 //@{ 105 //@{
106 virtual const std::string &label() const { return m_label; } 106 virtual const FbTk::BiDiString& label() const { return m_label; }
107 virtual const PixmapWithMask *icon() const { 107 virtual const PixmapWithMask *icon() const {
108 return m_icon.get() ? m_icon->pixmap.get() : 0; 108 return m_icon.get() ? m_icon->pixmap.get() : 0;
109 } 109 }
@@ -115,7 +115,7 @@ public:
115 // iType functions 115 // iType functions
116 virtual void setIndex(int index) { m_index = index; } 116 virtual void setIndex(int index) { m_index = index; }
117 virtual int getIndex() { return m_index; } 117 virtual int getIndex() { return m_index; }
118 const std::string &iTypeString() const { return m_label; } 118 const FbString &iTypeString() const { return m_label.visual(); }
119 virtual void drawLine(FbDrawable &draw, 119 virtual void drawLine(FbDrawable &draw,
120 const FbTk::ThemeProxy<MenuTheme> &theme, 120 const FbTk::ThemeProxy<MenuTheme> &theme,
121 size_t size, 121 size_t size,
@@ -148,7 +148,7 @@ public:
148 Menu *menu() { return m_menu; } 148 Menu *menu() { return m_menu; }
149 149
150private: 150private:
151 FbString m_label; ///< label of this item 151 BiDiString m_label; ///< label of this item
152 Menu *m_menu; ///< the menu we live in 152 Menu *m_menu; ///< the menu we live in
153 Menu *m_submenu; ///< a submenu, 0 if we don't have one 153 Menu *m_submenu; ///< a submenu, 0 if we don't have one
154 RefCount<Command<void> > m_command; ///< command to be executed 154 RefCount<Command<void> > m_command; ///< command to be executed
diff --git a/src/FbTk/MultiButtonMenuItem.cc b/src/FbTk/MultiButtonMenuItem.cc
index 6fd8fee..ed67c83 100644
--- a/src/FbTk/MultiButtonMenuItem.cc
+++ b/src/FbTk/MultiButtonMenuItem.cc
@@ -26,14 +26,14 @@
26 26
27namespace FbTk { 27namespace FbTk {
28 28
29MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbString &label): 29MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbTk::BiDiString &label):
30 MenuItem(label), 30 MenuItem(label),
31 m_button_exe(0), 31 m_button_exe(0),
32 m_buttons(buttons) { 32 m_buttons(buttons) {
33 init(buttons); 33 init(buttons);
34} 34}
35 35
36MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbString &label, Menu *submenu): 36MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbTk::BiDiString &label, Menu *submenu):
37 MenuItem(label, submenu), 37 MenuItem(label, submenu),
38 m_button_exe(0), 38 m_button_exe(0),
39 m_buttons(buttons) { 39 m_buttons(buttons) {
diff --git a/src/FbTk/MultiButtonMenuItem.hh b/src/FbTk/MultiButtonMenuItem.hh
index 5d67bdf..0a9c5e6 100644
--- a/src/FbTk/MultiButtonMenuItem.hh
+++ b/src/FbTk/MultiButtonMenuItem.hh
@@ -30,8 +30,8 @@ namespace FbTk {
30/// Handles commands for the specified numbers of buttons 30/// Handles commands for the specified numbers of buttons
31class MultiButtonMenuItem: public FbTk::MenuItem { 31class MultiButtonMenuItem: public FbTk::MenuItem {
32public: 32public:
33 MultiButtonMenuItem(int buttons, const FbString &label); 33 MultiButtonMenuItem(int buttons, const FbTk::BiDiString& label);
34 MultiButtonMenuItem(int buttons, const FbString &label, Menu *submenu); 34 MultiButtonMenuItem(int buttons, const FbTk::BiDiString& label, Menu *submenu);
35 virtual ~MultiButtonMenuItem(); 35 virtual ~MultiButtonMenuItem();
36 /// sets command to specified button 36 /// sets command to specified button
37 void setCommand(int button, FbTk::RefCount<FbTk::Command<void> > &cmd); 37 void setCommand(int button, FbTk::RefCount<FbTk::Command<void> > &cmd);
diff --git a/src/FbTk/TextBox.cc b/src/FbTk/TextBox.cc
index 87e18e8..74771a6 100644
--- a/src/FbTk/TextBox.cc
+++ b/src/FbTk/TextBox.cc
@@ -75,7 +75,7 @@ TextBox::~TextBox() {
75 75
76} 76}
77 77
78void TextBox::setText(const std::string &text) { 78void TextBox::setText(const FbTk::BiDiString &text) {
79 m_text = text; 79 m_text = text;
80 m_start_pos = 0; 80 m_start_pos = 0;
81 cursorEnd(); 81 cursorEnd();
@@ -129,7 +129,9 @@ void TextBox::cursorBackward() {
129 129
130void TextBox::backspace() { 130void TextBox::backspace() {
131 if (m_start_pos || cursorPosition()) { 131 if (m_start_pos || cursorPosition()) {
132 m_text.erase(m_start_pos + cursorPosition() - 1, 1); 132 FbString t = text();
133 t.erase(m_start_pos + cursorPosition() - 1, 1);
134 m_text.setLogical(t);
133 if (cursorPosition()) 135 if (cursorPosition())
134 setCursorPosition(cursorPosition() - 1); 136 setCursorPosition(cursorPosition() - 1);
135 else 137 else
@@ -140,23 +142,28 @@ void TextBox::backspace() {
140 142
141void TextBox::deleteForward() { 143void TextBox::deleteForward() {
142 if (m_start_pos + m_cursor_pos < m_end_pos) { 144 if (m_start_pos + m_cursor_pos < m_end_pos) {
143 m_text.erase(m_start_pos + m_cursor_pos, 1); 145 FbString t = text();
146 t.erase(m_start_pos + m_cursor_pos, 1);
147 m_text.setLogical(t);
144 adjustEndPos(); 148 adjustEndPos();
145 } 149 }
146} 150}
147 151
148void TextBox::insertText(const std::string &val) { 152void TextBox::insertText(const std::string &val) {
149 m_text.insert(m_start_pos + cursorPosition(), val); 153 FbString t = text();
154 t.insert(m_start_pos + cursorPosition(), val);
155 m_text.setLogical(t);
150 m_cursor_pos += val.size(); 156 m_cursor_pos += val.size();
151 m_end_pos += val.size(); 157 m_end_pos += val.size();
152 158
153 adjustPos(); 159 adjustPos();
154} 160}
155 161
156void TextBox::killToEnd() { 162void TextBox::killToEnd() {
157 if (cursorPosition() >= 0 && cursorPosition() < static_cast<signed>(text().size())) { 163 if (cursorPosition() >= 0 && cursorPosition() < static_cast<signed>(text().size())) {
158 m_text.erase(cursorPosition()); 164 FbString t = text();
159 setText(m_text); 165 t.erase(cursorPosition());
166 setText(t);
160 } 167 }
161} 168}
162 169
@@ -168,13 +175,13 @@ void TextBox::clear() {
168 setGC(DefaultGC(FbTk::App::instance()->display(), screenNumber())); 175 setGC(DefaultGC(FbTk::App::instance()->display(), screenNumber()));
169 176
170 font().drawText(*this, screenNumber(), 177 font().drawText(*this, screenNumber(),
171 gc(), 178 gc(),
172 text().c_str() + m_start_pos, 179 m_text.visual().c_str() + m_start_pos,
173 m_end_pos - m_start_pos, 180 m_end_pos - m_start_pos,
174 0, center_pos); // pos 181 0, center_pos); // pos
175 182
176 // draw cursor position 183 // draw cursor position
177 int cursor_pos = font().textWidth(text().c_str() + m_start_pos, m_cursor_pos) + 1; 184 int cursor_pos = font().textWidth(m_text.visual().c_str() + m_start_pos, m_cursor_pos) + 1;
178 drawLine(gc(), cursor_pos, center_pos, cursor_pos, center_pos - font().height()); 185 drawLine(gc(), cursor_pos, center_pos, cursor_pos, center_pos - font().height());
179} 186}
180 187
@@ -202,9 +209,7 @@ void TextBox::buttonPressEvent(XButtonEvent &event) {
202 int tmp = 0; 209 int tmp = 0;
203 for(i = m_start_pos; i <= m_end_pos; i++) { 210 for(i = m_start_pos; i <= m_end_pos; i++) {
204 tmp = abs(static_cast<int> 211 tmp = abs(static_cast<int>
205 (event.x - font(). 212 (event.x - font().textWidth(m_text.visual().c_str() + m_start_pos, i - m_start_pos)));
206 textWidth(m_text.c_str() + m_start_pos,
207 i - m_start_pos)));
208 213
209 if (tmp < delta) { 214 if (tmp < delta) {
210 delta = tmp; 215 delta = tmp;
@@ -244,7 +249,7 @@ void TextBox::keyPressEvent(XKeyEvent &event) {
244 } 249 }
245 break; 250 break;
246 case XK_Right: 251 case XK_Right:
247 if (m_text.size() && m_cursor_pos < m_text.size()){ 252 if (!m_text.logical().empty() && m_cursor_pos < m_text.logical().size()){
248 unsigned int pos = findEmptySpaceRight(); 253 unsigned int pos = findEmptySpaceRight();
249 if (pos > m_start_pos) 254 if (pos > m_start_pos)
250 pos -= m_start_pos; 255 pos -= m_start_pos;
@@ -264,7 +269,9 @@ void TextBox::keyPressEvent(XKeyEvent &event) {
264 269
265 case XK_BackSpace: { 270 case XK_BackSpace: {
266 unsigned int pos = findEmptySpaceLeft(); 271 unsigned int pos = findEmptySpaceLeft();
267 m_text.erase(pos, m_cursor_pos - pos + m_start_pos); 272 FbString t = text();
273 t.erase(pos, m_cursor_pos - pos + m_start_pos);
274 m_text.setLogical(t);
268 275
269 if (pos < m_start_pos){ 276 if (pos < m_start_pos){
270 m_start_pos = pos; 277 m_start_pos = pos;
@@ -278,10 +285,12 @@ void TextBox::keyPressEvent(XKeyEvent &event) {
278 } 285 }
279 break; 286 break;
280 case XK_Delete: { 287 case XK_Delete: {
281 if (!m_text.size() || m_cursor_pos >= m_text.size()) 288 if (text().empty() || m_cursor_pos >= text().size())
282 break; 289 break;
283 unsigned int pos = findEmptySpaceRight(); 290 unsigned int pos = findEmptySpaceRight();
284 m_text.erase(m_cursor_pos + m_start_pos, pos - (m_cursor_pos + m_start_pos)); 291 FbString t = text();
292 t.erase(m_cursor_pos + m_start_pos, pos - (m_cursor_pos + m_start_pos));
293 m_text.setLogical(t);
285 adjustPos(); 294 adjustPos();
286 } 295 }
287 break; 296 break;
@@ -368,15 +377,17 @@ void TextBox::adjustEndPos() {
368} 377}
369 378
370void TextBox::adjustStartPos() { 379void TextBox::adjustStartPos() {
371 380
372 int text_width = font().textWidth(text(), m_end_pos); 381 const char* visual = m_text.visual().c_str();
382
383 int text_width = font().textWidth(visual, m_end_pos);
373 if (text_width < static_cast<signed>(width())) 384 if (text_width < static_cast<signed>(width()))
374 return; 385 return;
375 386
376 int start_pos = 0; 387 int start_pos = 0;
377 while (text_width > static_cast<signed>(width())) { 388 while (text_width > static_cast<signed>(width())) {
378 start_pos++; 389 start_pos++;
379 text_width = font().textWidth(text().c_str() + start_pos, m_end_pos - start_pos); 390 text_width = font().textWidth(visual + start_pos, m_end_pos - start_pos);
380 } 391 }
381 392
382 // adjust cursorPosition() according relative to change to m_start_pos 393 // adjust cursorPosition() according relative to change to m_start_pos
@@ -387,12 +398,12 @@ void TextBox::adjustStartPos() {
387unsigned int TextBox::findEmptySpaceLeft(){ 398unsigned int TextBox::findEmptySpaceLeft(){
388 399
389 // found the first left space symbol 400 // found the first left space symbol
390 int pos = m_text.rfind(' ', (m_start_pos + m_cursor_pos) > 0 ? 401 int pos = text().rfind(' ', (m_start_pos + m_cursor_pos) > 0 ?
391 m_start_pos + m_cursor_pos - 1 : 0); 402 m_start_pos + m_cursor_pos - 1 : 0);
392 403
393 // do we have one more space symbol near? 404 // do we have one more space symbol near?
394 int next_pos = -1; 405 int next_pos = -1;
395 while (pos > 0 && (next_pos = m_text.rfind(' ', pos - 1)) > -1){ 406 while (pos > 0 && (next_pos = text().rfind(' ', pos - 1)) > -1){
396 if (next_pos + 1 < pos) 407 if (next_pos + 1 < pos)
397 break; 408 break;
398 pos = next_pos; 409 pos = next_pos;
@@ -406,18 +417,18 @@ unsigned int TextBox::findEmptySpaceLeft(){
406unsigned int TextBox::findEmptySpaceRight(){ 417unsigned int TextBox::findEmptySpaceRight(){
407 418
408 // found the first right space symbol 419 // found the first right space symbol
409 int pos = m_text.find(' ', m_start_pos + m_cursor_pos); 420 int pos = text().find(' ', m_start_pos + m_cursor_pos);
410 421
411 // do we have one more space symbol near? 422 // do we have one more space symbol near?
412 int next_pos = -1; 423 int next_pos = -1;
413 while (pos > -1 && pos < static_cast<signed>(m_text.size()) && (next_pos = m_text.find(' ', pos + 1)) > -1 ){ 424 while (pos > -1 && pos < static_cast<signed>(text().size()) && (next_pos = text().find(' ', pos + 1)) > -1 ){
414 425
415 if (next_pos - 1 > pos) 426 if (next_pos - 1 > pos)
416 break; 427 break;
417 pos = next_pos; 428 pos = next_pos;
418 } 429 }
419 if (pos < 0) 430 if (pos < 0)
420 pos = m_text.size() - 1; 431 pos = text().size() - 1;
421 432
422 return pos + 1; // (+1) - sets cursor at the right. 433 return pos + 1; // (+1) - sets cursor at the right.
423 434
diff --git a/src/FbTk/TextBox.hh b/src/FbTk/TextBox.hh
index d313dca..7b42bd1 100644
--- a/src/FbTk/TextBox.hh
+++ b/src/FbTk/TextBox.hh
@@ -24,8 +24,7 @@
24 24
25#include "FbWindow.hh" 25#include "FbWindow.hh"
26#include "EventHandler.hh" 26#include "EventHandler.hh"
27 27#include "FbString.hh"
28#include <string>
29 28
30namespace FbTk { 29namespace FbTk {
31 30
@@ -37,7 +36,7 @@ public:
37 TextBox(const FbWindow &parent, const Font &font, const std::string &text); 36 TextBox(const FbWindow &parent, const Font &font, const std::string &text);
38 virtual ~TextBox(); 37 virtual ~TextBox();
39 38
40 void setText(const std::string &text); 39 void setText(const FbTk::BiDiString &text);
41 void setFont(const Font &font); 40 void setFont(const Font &font);
42 void setGC(GC gc); 41 void setGC(GC gc);
43 void setCursorPosition(int cursor); 42 void setCursorPosition(int cursor);
@@ -60,7 +59,7 @@ public:
60 void buttonPressEvent(XButtonEvent &event); 59 void buttonPressEvent(XButtonEvent &event);
61 void keyPressEvent(XKeyEvent &event); 60 void keyPressEvent(XKeyEvent &event);
62 61
63 const std::string &text() const { return m_text; } 62 const FbString &text() const { return m_text.logical(); }
64 const Font &font() const { return *m_font; } 63 const Font &font() const { return *m_font; }
65 GC gc() const { return m_gc; } 64 GC gc() const { return m_gc; }
66 int cursorPosition() const { return m_cursor_pos; } 65 int cursorPosition() const { return m_cursor_pos; }
@@ -76,7 +75,7 @@ private:
76 void adjustPos(); 75 void adjustPos();
77 76
78 const FbTk::Font *m_font; 77 const FbTk::Font *m_font;
79 std::string m_text; 78 BiDiString m_text;
80 GC m_gc; 79 GC m_gc;
81 std::string::size_type m_cursor_pos, m_start_pos, m_end_pos; 80 std::string::size_type m_cursor_pos, m_start_pos, m_end_pos;
82}; 81};
diff --git a/src/FbTk/TextButton.cc b/src/FbTk/TextButton.cc
index 04aa367..c31e3d6 100644
--- a/src/FbTk/TextButton.cc
+++ b/src/FbTk/TextButton.cc
@@ -28,7 +28,7 @@ namespace FbTk {
28 28
29TextButton::TextButton(const FbTk::FbWindow &parent, 29TextButton::TextButton(const FbTk::FbWindow &parent,
30 FbTk::Font &font, 30 FbTk::Font &font,
31 const std::string &text): 31 const FbTk::BiDiString &text):
32 FbTk::Button(parent, 0, 0, 10, 10), 32 FbTk::Button(parent, 0, 0, 10, 10),
33 m_font(&font), 33 m_font(&font),
34 m_text(text), 34 m_text(text),
@@ -81,8 +81,8 @@ bool TextButton::setOrientation(FbTk::Orientation orient) {
81 return true; 81 return true;
82} 82}
83 83
84void TextButton::setText(const std::string &text) { 84void TextButton::setText(const FbTk::BiDiString &text) {
85 if (m_text != text) { 85 if (m_text.logical() != text.logical()) {
86 m_text = text; 86 m_text = text;
87 updateBackground(false); 87 updateBackground(false);
88 clear(); 88 clear();
@@ -126,7 +126,7 @@ void TextButton::clearArea(int x, int y,
126 126
127 127
128unsigned int TextButton::textWidth() const { 128unsigned int TextButton::textWidth() const {
129 return font().textWidth(text(), text().size()); 129 return font().textWidth(text());
130} 130}
131 131
132void TextButton::renderForeground(FbWindow &win, FbDrawable &drawable) { 132void TextButton::renderForeground(FbWindow &win, FbDrawable &drawable) {
@@ -135,15 +135,15 @@ void TextButton::renderForeground(FbWindow &win, FbDrawable &drawable) {
135} 135}
136 136
137void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) { 137void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
138 unsigned int textlen = text().size(); 138 const FbString& visual = text().visual();
139 // do text alignment 139 unsigned int textlen = visual.size();
140 140 unsigned int textw = width();
141 unsigned int textw = width(), texth = height(); 141 unsigned int texth = height();
142 translateSize(m_orientation, textw, texth); 142 translateSize(m_orientation, textw, texth);
143 143
144 int align_x = FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding, 144 int align_x = FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding,
145 bevel(), justify(), font(), 145 bevel(), justify(), font(),
146 text().data(), text().size(), 146 visual.data(), visual.size(),
147 textlen); // return new text len 147 textlen); // return new text len
148 148
149 // center text by default 149 // center text by default
@@ -161,25 +161,24 @@ void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
161 font().drawText(*drawable, 161 font().drawText(*drawable,
162 screenNumber(), 162 screenNumber(),
163 gc(), // graphic context 163 gc(), // graphic context
164 text(), textlen, // string and string size 164 visual.c_str(), textlen, // string and string size
165 textx, texty, m_orientation); // position 165 textx, texty, m_orientation); // position
166} 166}
167 167
168 168
169bool TextButton::textExceeds(int x_offset) { 169bool TextButton::textExceeds(int x_offset) {
170
171 unsigned int textlen = text().size();
172 // do text alignment
173 170
174 unsigned int textw = width(), texth = height(); 171 const FbString& visual = text().visual();
172 unsigned int textlen = visual.size();
173 unsigned int textw = width();
174 unsigned int texth = height();
175 translateSize(m_orientation, textw, texth); 175 translateSize(m_orientation, textw, texth);
176 176
177 FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding, 177 FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding,
178 bevel(), justify(), font(), text().data(), text().size(), 178 bevel(), justify(), font(), visual.data(), visual.size(),
179 textlen); // return new text len 179 textlen); // return new text len
180 180
181 return text().size()>textlen; 181 return visual.size()>textlen;
182
183} 182}
184 183
185void TextButton::exposeEvent(XExposeEvent &event) { 184void TextButton::exposeEvent(XExposeEvent &event) {
diff --git a/src/FbTk/TextButton.hh b/src/FbTk/TextButton.hh
index 6ddcd8f..a1c8b0e 100644
--- a/src/FbTk/TextButton.hh
+++ b/src/FbTk/TextButton.hh
@@ -23,8 +23,7 @@
23#define FBTK_TEXTBUTTON_HH 23#define FBTK_TEXTBUTTON_HH
24 24
25#include "Button.hh" 25#include "Button.hh"
26 26#include "FbString.hh"
27#include <string>
28 27
29namespace FbTk { 28namespace FbTk {
30 29
@@ -34,11 +33,11 @@ class Font;
34class TextButton: public FbTk::Button, FbTk::FbWindowRenderer { 33class TextButton: public FbTk::Button, FbTk::FbWindowRenderer {
35public: 34public:
36 TextButton(const FbTk::FbWindow &parent, 35 TextButton(const FbTk::FbWindow &parent,
37 FbTk::Font &font, const std::string &text); 36 FbTk::Font &font, const FbTk::BiDiString &text);
38 37
39 void setJustify(FbTk::Justify just); 38 void setJustify(FbTk::Justify just);
40 bool setOrientation(FbTk::Orientation orient); 39 bool setOrientation(FbTk::Orientation orient);
41 void setText(const std::string &text); 40 void setText(const FbTk::BiDiString &text);
42 void setFont(FbTk::Font &font); 41 void setFont(FbTk::Font &font);
43 void setTextPadding(unsigned int padding); 42 void setTextPadding(unsigned int padding);
44 void setTextPaddingLeft(unsigned int leftpadding); 43 void setTextPaddingLeft(unsigned int leftpadding);
@@ -60,7 +59,7 @@ public:
60 void renderForeground(FbDrawable &drawable); 59 void renderForeground(FbDrawable &drawable);
61 60
62 FbTk::Justify justify() const { return m_justify; } 61 FbTk::Justify justify() const { return m_justify; }
63 const std::string &text() const { return m_text; } 62 const BiDiString &text() const { return m_text; }
64 FbTk::Font &font() const { return *m_font; } 63 FbTk::Font &font() const { return *m_font; }
65 FbTk::Orientation orientation() const { return m_orientation; } 64 FbTk::Orientation orientation() const { return m_orientation; }
66 unsigned int textWidth() const; 65 unsigned int textWidth() const;
@@ -75,7 +74,7 @@ protected:
75 74
76private: 75private:
77 FbTk::Font *m_font; 76 FbTk::Font *m_font;
78 std::string m_text; 77 BiDiString m_text;
79 FbTk::Justify m_justify; 78 FbTk::Justify m_justify;
80 FbTk::Orientation m_orientation; 79 FbTk::Orientation m_orientation;
81 80
diff --git a/src/FbTk/XFontImp.cc b/src/FbTk/XFontImp.cc
index 257a2a0..fa88593 100644
--- a/src/FbTk/XFontImp.cc
+++ b/src/FbTk/XFontImp.cc
@@ -97,8 +97,9 @@ bool XFontImp::load(const string &fontname) {
97 return true; 97 return true;
98} 98}
99 99
100void XFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) { 100void XFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char* text, size_t len, int x, int y, FbTk::Orientation orient) {
101 if (m_fontstruct == 0) 101
102 if (!text || !*text || m_fontstruct == 0)
102 return; 103 return;
103 104
104 // use roated font functions? 105 // use roated font functions?
@@ -107,21 +108,18 @@ void XFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString &
107 return; 108 return;
108 } 109 }
109 110
110 string localestr = text; 111 std::string localestr = FbStringUtil::FbStrToLocale(FbString(text, 0, len));
111 localestr.erase(len, string::npos);
112 localestr = FbStringUtil::FbStrToLocale(localestr);
113 112
114 XSetFont(w.display(), gc, m_fontstruct->fid); 113 XSetFont(w.display(), gc, m_fontstruct->fid);
115 XDrawString(w.display(), w.drawable(), gc, x, y, localestr.data(), localestr.size()); 114 XDrawString(w.display(), w.drawable(), gc, x, y, localestr.data(), localestr.size());
116} 115}
117 116
118unsigned int XFontImp::textWidth(const FbString &text, unsigned int size) const { 117unsigned int XFontImp::textWidth(const char* text, unsigned int size) const {
119 if (text.empty() || m_fontstruct == 0) 118
119 if (!text || !*text || m_fontstruct == 0)
120 return 0; 120 return 0;
121 121
122 string localestr = text; 122 std::string localestr = FbStringUtil::FbStrToLocale(FbString(text, size));
123 localestr.erase(size, string::npos);
124 localestr = FbStringUtil::FbStrToLocale(localestr);
125 123
126 return XTextWidth(m_fontstruct, localestr.data(), localestr.size()); 124 return XTextWidth(m_fontstruct, localestr.data(), localestr.size());
127} 125}
diff --git a/src/FbTk/XFontImp.hh b/src/FbTk/XFontImp.hh
index 3ba027c..ccebbb7 100644
--- a/src/FbTk/XFontImp.hh
+++ b/src/FbTk/XFontImp.hh
@@ -32,11 +32,11 @@ public:
32 explicit XFontImp(const char *filename = 0); 32 explicit XFontImp(const char *filename = 0);
33 ~XFontImp(); 33 ~XFontImp();
34 bool load(const std::string &filename); 34 bool load(const std::string &filename);
35 unsigned int textWidth(const FbString &text, unsigned int size) const; 35 unsigned int textWidth(const char* text, unsigned int len) const;
36 unsigned int height() const; 36 unsigned int height() const;
37 int ascent() const; 37 int ascent() const;
38 int descent() const { return m_fontstruct ? m_fontstruct->descent : 0; } 38 int descent() const { return m_fontstruct ? m_fontstruct->descent : 0; }
39 void drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient); 39 void drawText(const FbDrawable &w, int screen, GC gc, const char* text, size_t len, int x, int y, FbTk::Orientation orient);
40 40
41 bool validOrientation(FbTk::Orientation orient); 41 bool validOrientation(FbTk::Orientation orient);
42 42
diff --git a/src/FbTk/XftFontImp.cc b/src/FbTk/XftFontImp.cc
index 80eb2c4..15c8212 100644
--- a/src/FbTk/XftFontImp.cc
+++ b/src/FbTk/XftFontImp.cc
@@ -77,7 +77,10 @@ bool XftFontImp::load(const std::string &name) {
77 return true; 77 return true;
78} 78}
79 79
80void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) { 80void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char* text, size_t len, int x, int y, FbTk::Orientation orient) {
81
82 if (!text || !*text)
83 return;
81 84
82 if (!validOrientation(orient)) 85 if (!validOrientation(orient))
83 return; 86 return;
@@ -98,12 +101,11 @@ void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString
98 break; 101 break;
99 } 102 }
100 103
101 XftFont *font = m_xftfonts[orient]; 104 Visual* def_visual = DefaultVisual(w.display(), screen);
105 Colormap def_colmap = DefaultColormap(w.display(), screen);
102 106
103 XftDraw *draw = XftDrawCreate(w.display(), 107 XftFont *font = m_xftfonts[orient];
104 w.drawable(), 108 XftDraw *draw = XftDrawCreate(w.display(), w.drawable(), def_visual, def_colmap);
105 DefaultVisual(w.display(), screen),
106 DefaultColormap(w.display(), screen));
107 109
108 XGCValues gc_val; 110 XGCValues gc_val;
109 111
@@ -114,7 +116,7 @@ void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString
114 // get red, green, blue values 116 // get red, green, blue values
115 XColor xcol; 117 XColor xcol;
116 xcol.pixel = gc_val.foreground; 118 xcol.pixel = gc_val.foreground;
117 XQueryColor(w.display(), DefaultColormap(w.display(), screen), &xcol); 119 XQueryColor(w.display(), def_colmap, &xcol);
118 120
119 // convert xcolor to XftColor 121 // convert xcolor to XftColor
120 XRenderColor rendcol; 122 XRenderColor rendcol;
@@ -123,10 +125,7 @@ void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString
123 rendcol.blue = xcol.blue; 125 rendcol.blue = xcol.blue;
124 rendcol.alpha = 0xFFFF; 126 rendcol.alpha = 0xFFFF;
125 XftColor xftcolor; 127 XftColor xftcolor;
126 XftColorAllocValue(w.display(), 128 XftColorAllocValue(w.display(), def_visual, def_colmap, &rendcol, &xftcolor);
127 DefaultVisual(w.display(), screen),
128 DefaultColormap(w.display(), screen),
129 &rendcol, &xftcolor);
130 129
131 // draw string 130 // draw string
132#ifdef HAVE_XFT_UTF8_STRING 131#ifdef HAVE_XFT_UTF8_STRING
@@ -134,39 +133,25 @@ void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString
134 // check the string size, 133 // check the string size,
135 // if the size is zero we use the XftDrawString8 function instead. 134 // if the size is zero we use the XftDrawString8 function instead.
136 XGlyphInfo ginfo; 135 XGlyphInfo ginfo;
137 XftTextExtentsUtf8(w.display(), 136 XftTextExtentsUtf8(w.display(), m_xftfonts[ROT0], (XftChar8 *)text, len, &ginfo);
138 m_xftfonts[ROT0],
139 (XftChar8 *)text.data(), len,
140 &ginfo);
141 if (ginfo.xOff != 0) { 137 if (ginfo.xOff != 0) {
142 XftDrawStringUtf8(draw, 138 XftDrawStringUtf8(draw, &xftcolor, font, x, y, (XftChar8 *)text, len);
143 &xftcolor, 139 XftColorFree(w.display(), def_visual, def_colmap, &xftcolor);
144 font,
145 x, y,
146 (XftChar8 *)(text.data()), len);
147 XftColorFree(w.display(),
148 DefaultVisual(w.display(), screen),
149 DefaultColormap(w.display(), screen), &xftcolor);
150 XftDrawDestroy(draw); 140 XftDrawDestroy(draw);
151 return; 141 return;
152 } 142 }
153 } 143 }
154#endif // HAVE_XFT_UTF8_STRING 144#endif // HAVE_XFT_UTF8_STRING
155 145
156 XftDrawString8(draw, 146 XftDrawString8(draw, &xftcolor, font, x, y, (XftChar8 *)text, len);
157 &xftcolor,
158 font,
159 x, y,
160 (XftChar8 *)(text.data()), len);
161 147
162 148
163 XftColorFree(w.display(), 149 XftColorFree(w.display(), def_visual, def_colmap, &xftcolor);
164 DefaultVisual(w.display(), screen),
165 DefaultColormap(w.display(), screen), &xftcolor);
166 XftDrawDestroy(draw); 150 XftDrawDestroy(draw);
167} 151}
168 152
169unsigned int XftFontImp::textWidth(const FbString &text, unsigned int len) const { 153unsigned int XftFontImp::textWidth(const char* text, unsigned int len) const {
154
170 if (m_xftfonts[ROT0] == 0) 155 if (m_xftfonts[ROT0] == 0)
171 return 0; 156 return 0;
172 157
@@ -180,7 +165,7 @@ unsigned int XftFontImp::textWidth(const FbString &text, unsigned int len) const
180 if (m_utf8mode) { 165 if (m_utf8mode) {
181 XftTextExtentsUtf8(disp, 166 XftTextExtentsUtf8(disp,
182 font, 167 font,
183 (XftChar8 *)text.data(), len, 168 (XftChar8 *)text, len,
184 &ginfo); 169 &ginfo);
185 if (ginfo.xOff != 0) 170 if (ginfo.xOff != 0)
186 return ginfo.xOff; 171 return ginfo.xOff;
@@ -189,9 +174,7 @@ unsigned int XftFontImp::textWidth(const FbString &text, unsigned int len) const
189 } 174 }
190#endif //HAVE_XFT_UTF8_STRING 175#endif //HAVE_XFT_UTF8_STRING
191 176
192 std::string localestr = text; 177 std::string localestr = FbStringUtil::FbStrToLocale(FbString(text, len));
193 localestr.erase(len, std::string::npos);
194 localestr = FbStringUtil::FbStrToLocale(localestr);
195 178
196 XftTextExtents8(disp, 179 XftTextExtents8(disp,
197 font, 180 font,
diff --git a/src/FbTk/XftFontImp.hh b/src/FbTk/XftFontImp.hh
index 3d2dc55..fd24762 100644
--- a/src/FbTk/XftFontImp.hh
+++ b/src/FbTk/XftFontImp.hh
@@ -34,8 +34,8 @@ public:
34 XftFontImp(const char *fontname, bool utf8); 34 XftFontImp(const char *fontname, bool utf8);
35 ~XftFontImp(); 35 ~XftFontImp();
36 bool load(const std::string &name); 36 bool load(const std::string &name);
37 void drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y , FbTk::Orientation orient); 37 void drawText(const FbDrawable &w, int screen, GC gc, const char* text, size_t len, int x, int y , FbTk::Orientation orient);
38 unsigned int textWidth(const FbString &text, unsigned int len) const; 38 unsigned int textWidth(const char* text, unsigned int len) const;
39 unsigned int height() const; 39 unsigned int height() const;
40 int ascent() const { return m_xftfonts[0] ? m_xftfonts[0]->ascent : 0; } 40 int ascent() const { return m_xftfonts[0] ? m_xftfonts[0]->ascent : 0; }
41 int descent() const { return m_xftfonts[0] ? m_xftfonts[0]->descent : 0; } 41 int descent() const { return m_xftfonts[0] ? m_xftfonts[0]->descent : 0; }
diff --git a/src/FbTk/XmbFontImp.cc b/src/FbTk/XmbFontImp.cc
index 3ce913d..7613a40 100644
--- a/src/FbTk/XmbFontImp.cc
+++ b/src/FbTk/XmbFontImp.cc
@@ -189,10 +189,10 @@ bool XmbFontImp::load(const string &fontname) {
189 return true; 189 return true;
190} 190}
191 191
192void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const FbString &text, 192void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const char* text,
193 size_t len, int x, int y, FbTk::Orientation orient) { 193 size_t len, int x, int y, FbTk::Orientation orient) {
194 194
195 if (m_fontset == 0) 195 if (!text || !*text || m_fontset == 0)
196 return; 196 return;
197 197
198 if (orient == ROT0) { 198 if (orient == ROT0) {
@@ -200,13 +200,11 @@ void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const FbS
200 if (m_utf8mode) { 200 if (m_utf8mode) {
201 Xutf8DrawString(d.display(), d.drawable(), m_fontset, 201 Xutf8DrawString(d.display(), d.drawable(), m_fontset,
202 main_gc, x, y, 202 main_gc, x, y,
203 text.data(), len); 203 text, len);
204 } else 204 } else
205#endif //X_HAVE_UTF8_STRING 205#endif //X_HAVE_UTF8_STRING
206 { 206 {
207 string localestr = text; 207 std::string localestr = FbStringUtil::FbStrToLocale(FbString(text, 0, len));
208 localestr.erase(len, string::npos);
209 localestr = FbStringUtil::FbStrToLocale(localestr);
210 XmbDrawString(d.display(), d.drawable(), m_fontset, 208 XmbDrawString(d.display(), d.drawable(), m_fontset,
211 main_gc, x, y, 209 main_gc, x, y,
212 localestr.data(), localestr.size()); 210 localestr.data(), localestr.size());
@@ -239,13 +237,11 @@ void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const FbS
239 if (m_utf8mode) { 237 if (m_utf8mode) {
240 Xutf8DrawString(dpy, canvas.drawable(), m_fontset, 238 Xutf8DrawString(dpy, canvas.drawable(), m_fontset,
241 font_gc.gc(), xpos, ypos, 239 font_gc.gc(), xpos, ypos,
242 text.data(), len); 240 text, len);
243 } else 241 } else
244#endif //X_HAVE_UTF8_STRING 242#endif //X_HAVE_UTF8_STRING
245 { 243 {
246 string localestr = text; 244 std::string localestr = FbStringUtil::FbStrToLocale(FbString(text, 0, len));
247 localestr.erase(len, string::npos);
248 localestr = FbStringUtil::FbStrToLocale(localestr);
249 XmbDrawString(dpy, canvas.drawable(), m_fontset, 245 XmbDrawString(dpy, canvas.drawable(), m_fontset,
250 font_gc.gc(), xpos, ypos, 246 font_gc.gc(), xpos, ypos,
251 localestr.data(), localestr.size()); 247 localestr.data(), localestr.size());
@@ -277,25 +273,21 @@ void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const FbS
277 273
278} 274}
279 275
280unsigned int XmbFontImp::textWidth(const FbString &text, unsigned int len) const { 276unsigned int XmbFontImp::textWidth(const char* text, unsigned int len) const {
277
281 if (m_fontset == 0) 278 if (m_fontset == 0)
282 return 0; 279 return 0;
283 280
284 XRectangle ink, logical; 281 XRectangle ink, logical;
285#ifdef X_HAVE_UTF8_STRING 282#ifdef X_HAVE_UTF8_STRING
286 if (m_utf8mode) { 283 if (m_utf8mode) {
287 Xutf8TextExtents(m_fontset, text.data(), len, 284 Xutf8TextExtents(m_fontset, text, len, &ink, &logical);
288 &ink, &logical);
289 if (logical.width != 0) 285 if (logical.width != 0)
290 return logical.width; 286 return logical.width;
291 } 287 }
292#endif // X_HAVE_UTF8_STRING 288#endif // X_HAVE_UTF8_STRING
293 289
294 string localestr = text; 290 std::string localestr = FbStringUtil::FbStrToLocale(FbString(text, len));
295 if (len > localestr.length())
296 len = localestr.length();
297 localestr.erase(len, string::npos);
298 localestr = FbStringUtil::FbStrToLocale(localestr);
299 XmbTextExtents(m_fontset, localestr.data(), localestr.size(), 291 XmbTextExtents(m_fontset, localestr.data(), localestr.size(),
300 &ink, &logical); 292 &ink, &logical);
301 return logical.width; 293 return logical.width;
diff --git a/src/FbTk/XmbFontImp.hh b/src/FbTk/XmbFontImp.hh
index e2f916a..d3e586a 100644
--- a/src/FbTk/XmbFontImp.hh
+++ b/src/FbTk/XmbFontImp.hh
@@ -32,8 +32,8 @@ public:
32 XmbFontImp(const char *fontname, bool utf8); 32 XmbFontImp(const char *fontname, bool utf8);
33 ~XmbFontImp(); 33 ~XmbFontImp();
34 bool load(const std::string &name); 34 bool load(const std::string &name);
35 virtual void drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient); 35 virtual void drawText(const FbDrawable &w, int screen, GC gc, const char* text, size_t len, int x, int y, FbTk::Orientation orient);
36 unsigned int textWidth(const FbString &text, unsigned int len) const; 36 unsigned int textWidth(const char* text, unsigned int len) const;
37 unsigned int height() const; 37 unsigned int height() const;
38 int ascent() const { return m_setextents ? -m_setextents->max_ink_extent.y : 0; } 38 int ascent() const { return m_setextents ? -m_setextents->max_ink_extent.y : 0; }
39 int descent() const { return m_setextents ? m_setextents->max_ink_extent.height + m_setextents->max_ink_extent.y : 0; } 39 int descent() const { return m_setextents ? m_setextents->max_ink_extent.height + m_setextents->max_ink_extent.y : 0; }