diff options
author | Mathias Gumz <akira at fluxbox dot org> | 2010-09-08 18:17:21 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2010-09-08 18:17:21 (GMT) |
commit | 690d926ac444243611cd875fb84fabb4e6db2cf2 (patch) | |
tree | c8ef84056b295071f9a9207ffea5393c6cf4ad4d /src/FbTk | |
parent | 1e8fe2bc14856fa16508686a28a85e72cb0e422c (diff) | |
download | fluxbox-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.cc | 150 | ||||
-rw-r--r-- | src/FbTk/FbString.hh | 37 | ||||
-rw-r--r-- | src/FbTk/Font.cc | 34 | ||||
-rw-r--r-- | src/FbTk/Font.hh | 14 | ||||
-rw-r--r-- | src/FbTk/FontImp.hh | 4 | ||||
-rw-r--r-- | src/FbTk/ITypeAheadable.hh | 2 | ||||
-rw-r--r-- | src/FbTk/IntMenuItem.hh | 14 | ||||
-rw-r--r-- | src/FbTk/Menu.cc | 13 | ||||
-rw-r--r-- | src/FbTk/Menu.hh | 6 | ||||
-rw-r--r-- | src/FbTk/MenuItem.cc | 31 | ||||
-rw-r--r-- | src/FbTk/MenuItem.hh | 18 | ||||
-rw-r--r-- | src/FbTk/MultiButtonMenuItem.cc | 4 | ||||
-rw-r--r-- | src/FbTk/MultiButtonMenuItem.hh | 4 | ||||
-rw-r--r-- | src/FbTk/TextBox.cc | 63 | ||||
-rw-r--r-- | src/FbTk/TextBox.hh | 9 | ||||
-rw-r--r-- | src/FbTk/TextButton.cc | 33 | ||||
-rw-r--r-- | src/FbTk/TextButton.hh | 11 | ||||
-rw-r--r-- | src/FbTk/XFontImp.cc | 18 | ||||
-rw-r--r-- | src/FbTk/XFontImp.hh | 4 | ||||
-rw-r--r-- | src/FbTk/XftFontImp.cc | 55 | ||||
-rw-r--r-- | src/FbTk/XftFontImp.hh | 4 | ||||
-rw-r--r-- | src/FbTk/XmbFontImp.cc | 28 | ||||
-rw-r--r-- | src/FbTk/XmbFontImp.hh | 4 |
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; | |||
62 | using std::endl; | 62 | using std::endl; |
63 | #endif // DEBUG | 63 | #endif // DEBUG |
64 | 64 | ||
65 | namespace { | ||
66 | |||
67 | #ifdef HAVE_FRIBIDI | ||
68 | FbTk::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 | |||
65 | namespace FbTk { | 107 | namespace FbTk { |
66 | 108 | ||
109 | |||
110 | BiDiString::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 | |||
119 | const 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 | |||
131 | const 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 | |||
67 | namespace FbStringUtil { | 145 | namespace FbStringUtil { |
68 | 146 | ||
69 | enum ConvType { FB2X = 0, X2FB, LOCALE2FB, FB2LOCALE, CONVSIZE }; | 147 | enum 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 | */ |
217 | string 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 | */ |
148 | string 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 |
218 | string 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 | ||
224 | FbString XStrToFb(const string &src) { | 298 | FbString 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 | |||
254 | FbString 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 | ||
292 | StringConvertor::StringConvertor(EncodingTarget target): | ||
293 | #ifdef HAVE_ICONV | 328 | #ifdef HAVE_ICONV |
294 | m_iconv((iconv_t)(-1)) { | 329 | StringConvertor::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) {} | 336 | StringConvertor::StringConvertor(EncodingTarget target) { } |
302 | #endif | 337 | #endif |
303 | 338 | ||
304 | |||
305 | StringConvertor::~StringConvertor() { | 339 | StringConvertor::~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 | ||
332 | string StringConvertor::recode(const string &src) { | 366 | FbString 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 | ||
374 | void 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) |
37 | typedef std::string FbString; | 37 | typedef std::string FbString; |
38 | 38 | ||
39 | class BiDiString { | ||
40 | |||
41 | public: | ||
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 | |||
50 | private: | ||
51 | FbString m_logical; | ||
52 | #ifdef HAVE_FRIBIDI | ||
53 | mutable FbString m_visual; | ||
54 | mutable bool m_visual_dirty; | ||
55 | #endif | ||
56 | }; | ||
57 | |||
39 | namespace FbStringUtil { | 58 | namespace FbStringUtil { |
40 | 59 | ||
41 | void init(); | 60 | void init(); |
@@ -52,11 +71,6 @@ std::string FbStrToX(const FbString &src); | |||
52 | FbString LocaleStrToFb(const std::string &src); | 71 | FbString LocaleStrToFb(const std::string &src); |
53 | std::string FbStrToLocale(const FbString &src); | 72 | std::string FbStrToLocale(const FbString &src); |
54 | 73 | ||
55 | #ifdef HAVE_FRIBIDI | ||
56 | /// Make Bidi | ||
57 | FbString BidiLog2Vis (const FbString& src); | ||
58 | #endif | ||
59 | |||
60 | bool haveUTF8(); | 74 | bool 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 | ||
83 | private: | 91 | private: |
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 | ||
250 | unsigned int Font::textWidth(const FbString &text, unsigned int size) const { | 250 | unsigned 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 | ||
260 | unsigned int Font::height() const { | 254 | unsigned int Font::height() const { |
@@ -274,34 +268,28 @@ bool Font::validOrientation(FbTk::Orientation orient) { | |||
274 | } | 268 | } |
275 | 269 | ||
276 | void Font::drawText(const FbDrawable &w, int screen, GC gc, | 270 | void 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 { | |||
40 | public: | 40 | public: |
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 | ||
27 | namespace FbTk { | 28 | namespace 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 | ||
92 | private: | 84 | private: |
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 | ||
376 | void Menu::updateMenu() { | 376 | void 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 | ||
798 | void Menu::setLabel(const FbString &labelstr) { | 793 | void 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 { | |||
335 | unsigned int MenuItem::width(const FbTk::ThemeProxy<MenuTheme> &theme) const { | 330 | unsigned 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 | ||
352 | void MenuItem::showSubmenu() { | 347 | void 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; | |||
41 | class MenuItem : public FbTk::ITypeAheadable { | 41 | class MenuItem : public FbTk::ITypeAheadable { |
42 | public: | 42 | public: |
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 | ||
150 | private: | 150 | private: |
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 | ||
27 | namespace FbTk { | 27 | namespace FbTk { |
28 | 28 | ||
29 | MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbString &label): | 29 | MultiButtonMenuItem::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 | ||
36 | MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbString &label, Menu *submenu): | 36 | MultiButtonMenuItem::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 |
31 | class MultiButtonMenuItem: public FbTk::MenuItem { | 31 | class MultiButtonMenuItem: public FbTk::MenuItem { |
32 | public: | 32 | public: |
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 | ||
78 | void TextBox::setText(const std::string &text) { | 78 | void 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 | ||
130 | void TextBox::backspace() { | 130 | void 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 | ||
141 | void TextBox::deleteForward() { | 143 | void 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 | ||
148 | void TextBox::insertText(const std::string &val) { | 152 | void 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 | ||
156 | void TextBox::killToEnd() { | 162 | void 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 | ||
370 | void TextBox::adjustStartPos() { | 379 | void 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() { | |||
387 | unsigned int TextBox::findEmptySpaceLeft(){ | 398 | unsigned 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(){ | |||
406 | unsigned int TextBox::findEmptySpaceRight(){ | 417 | unsigned 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 | ||
30 | namespace FbTk { | 29 | namespace 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 | ||
29 | TextButton::TextButton(const FbTk::FbWindow &parent, | 29 | TextButton::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 | ||
84 | void TextButton::setText(const std::string &text) { | 84 | void 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 | ||
128 | unsigned int TextButton::textWidth() const { | 128 | unsigned int TextButton::textWidth() const { |
129 | return font().textWidth(text(), text().size()); | 129 | return font().textWidth(text()); |
130 | } | 130 | } |
131 | 131 | ||
132 | void TextButton::renderForeground(FbWindow &win, FbDrawable &drawable) { | 132 | void TextButton::renderForeground(FbWindow &win, FbDrawable &drawable) { |
@@ -135,15 +135,15 @@ void TextButton::renderForeground(FbWindow &win, FbDrawable &drawable) { | |||
135 | } | 135 | } |
136 | 136 | ||
137 | void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) { | 137 | void 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 | ||
169 | bool TextButton::textExceeds(int x_offset) { | 169 | bool 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 | ||
185 | void TextButton::exposeEvent(XExposeEvent &event) { | 184 | void 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 | ||
29 | namespace FbTk { | 28 | namespace FbTk { |
30 | 29 | ||
@@ -34,11 +33,11 @@ class Font; | |||
34 | class TextButton: public FbTk::Button, FbTk::FbWindowRenderer { | 33 | class TextButton: public FbTk::Button, FbTk::FbWindowRenderer { |
35 | public: | 34 | public: |
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 | ||
76 | private: | 75 | private: |
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 | ||
100 | void XFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) { | 100 | void 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 | ||
118 | unsigned int XFontImp::textWidth(const FbString &text, unsigned int size) const { | 117 | unsigned 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 | ||
80 | void XftFontImp::drawText(const FbDrawable &w, int screen, GC gc, const FbString &text, size_t len, int x, int y, FbTk::Orientation orient) { | 80 | void 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 | ||
169 | unsigned int XftFontImp::textWidth(const FbString &text, unsigned int len) const { | 153 | unsigned 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 | ||
192 | void XmbFontImp::drawText(const FbDrawable &d, int screen, GC main_gc, const FbString &text, | 192 | void 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 | ||
280 | unsigned int XmbFontImp::textWidth(const FbString &text, unsigned int len) const { | 276 | unsigned 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; } |