diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | src/Container.cc | 8 | ||||
-rw-r--r-- | src/FbTk/Text.hh | 10 | ||||
-rw-r--r-- | src/FbTk/XFontImp.cc | 180 | ||||
-rw-r--r-- | src/FbTk/XFontImp.hh | 41 | ||||
-rw-r--r-- | src/FbWinFrame.cc | 15 |
6 files changed, 119 insertions, 140 deletions
@@ -1,5 +1,10 @@ | |||
1 | (Format: Year/Month/Day) | 1 | (Format: Year/Month/Day) |
2 | Changes for 0.9.16: | 2 | Changes for 0.9.16: |
3 | *06/04/04: | ||
4 | * Rotated X Fonts again, plus minor external tab alignment fixes (Simon) | ||
5 | - Still need to do XmbFonts. Most people probably load those | ||
6 | instead of XFont these days. Will need yet another approach... | ||
7 | FbTk/XFontImp.hh/cc FbTk/Text.hh FbWinFrame.cc Container.cc | ||
3 | *06/04/02: | 8 | *06/04/02: |
4 | * size_t fixes. (Thanks Semushin Slava aka php-coder) | 9 | * size_t fixes. (Thanks Semushin Slava aka php-coder) |
5 | *06/03/27: | 10 | *06/03/27: |
diff --git a/src/Container.cc b/src/Container.cc index 6f811ef..db3e401 100644 --- a/src/Container.cc +++ b/src/Container.cc | |||
@@ -382,6 +382,7 @@ void Container::repositionItems() { | |||
382 | unsigned int total_width; | 382 | unsigned int total_width; |
383 | unsigned int cur_width; | 383 | unsigned int cur_width; |
384 | unsigned int height; | 384 | unsigned int height; |
385 | |||
385 | // unrotate | 386 | // unrotate |
386 | if (m_orientation == FbTk::ROT0 || m_orientation == FbTk::ROT180) { | 387 | if (m_orientation == FbTk::ROT0 || m_orientation == FbTk::ROT180) { |
387 | total_width = cur_width = width(); | 388 | total_width = cur_width = width(); |
@@ -438,11 +439,6 @@ void Container::repositionItems() { | |||
438 | next_x = total_width - max_width_per_client - borderW; | 439 | next_x = total_width - max_width_per_client - borderW; |
439 | } | 440 | } |
440 | 441 | ||
441 | // when rot270, our borderwidth adjustment actually needs to be at the | ||
442 | // other end (i.e. top), so this puts it there | ||
443 | if (m_orientation == FbTk::ROT270) | ||
444 | next_x += 2*borderW; | ||
445 | |||
446 | int tmpx, tmpy; | 442 | int tmpx, tmpy; |
447 | unsigned int tmpw, tmph; | 443 | unsigned int tmpw, tmph; |
448 | for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) { | 444 | for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) { |
@@ -460,7 +456,7 @@ void Container::repositionItems() { | |||
460 | tmph = height; | 456 | tmph = height; |
461 | 457 | ||
462 | FbTk::translateCoords(m_orientation, tmpx, tmpy, total_width, height); | 458 | FbTk::translateCoords(m_orientation, tmpx, tmpy, total_width, height); |
463 | FbTk::translatePosition(m_orientation, tmpx, tmpy, tmpw, tmph); | 459 | FbTk::translatePosition(m_orientation, tmpx, tmpy, tmpw, tmph, borderW); |
464 | FbTk::translateSize(m_orientation, tmpw, tmph); | 460 | FbTk::translateSize(m_orientation, tmpw, tmph); |
465 | 461 | ||
466 | // resize each clients including border in size | 462 | // resize each clients including border in size |
diff --git a/src/FbTk/Text.hh b/src/FbTk/Text.hh index f04642d..ceb0f19 100644 --- a/src/FbTk/Text.hh +++ b/src/FbTk/Text.hh | |||
@@ -77,7 +77,7 @@ inline void translateCoords(Orientation orient, int &x, int &y, unsigned int w, | |||
77 | 77 | ||
78 | // When positioning an X11 box inside another area, we need to | 78 | // When positioning an X11 box inside another area, we need to |
79 | // relocate the x,y coordinates | 79 | // relocate the x,y coordinates |
80 | inline void translatePosition(Orientation orient, int &x, int &y, unsigned int w, unsigned int h) { | 80 | inline void translatePosition(Orientation orient, int &x, int &y, unsigned int w, unsigned int h, unsigned int bw) { |
81 | 81 | ||
82 | int orig_x = x; | 82 | int orig_x = x; |
83 | int orig_y = y; | 83 | int orig_y = y; |
@@ -86,14 +86,14 @@ inline void translatePosition(Orientation orient, int &x, int &y, unsigned int w | |||
86 | case ROT0: | 86 | case ROT0: |
87 | break; | 87 | break; |
88 | case ROT90: | 88 | case ROT90: |
89 | x -= h; | 89 | x -= h + 2*bw; |
90 | break; | 90 | break; |
91 | case ROT180: | 91 | case ROT180: |
92 | x -= w; | 92 | x -= w + 2*bw; |
93 | y -= h; | 93 | y -= h + 2*bw; |
94 | break; | 94 | break; |
95 | case ROT270: | 95 | case ROT270: |
96 | y -= w; | 96 | y -= w + 2*bw; |
97 | break; | 97 | break; |
98 | } | 98 | } |
99 | 99 | ||
diff --git a/src/FbTk/XFontImp.cc b/src/FbTk/XFontImp.cc index eeb0830..1bf54a7 100644 --- a/src/FbTk/XFontImp.cc +++ b/src/FbTk/XFontImp.cc | |||
@@ -40,8 +40,10 @@ using namespace std; | |||
40 | 40 | ||
41 | namespace FbTk { | 41 | namespace FbTk { |
42 | 42 | ||
43 | XFontImp::XFontImp(const char *fontname):m_rotfont(0), m_fontstruct(0), | 43 | XFontImp::XFontImp(const char *fontname):m_fontstruct(0) { |
44 | m_angle(0), m_rotate(true) { | 44 | for (int i = ROT0; i <= ROT270; ++i) |
45 | m_rotfonts[i] = 0; | ||
46 | |||
45 | if (fontname != 0) | 47 | if (fontname != 0) |
46 | load(fontname); | 48 | load(fontname); |
47 | } | 49 | } |
@@ -49,20 +51,21 @@ XFontImp::XFontImp(const char *fontname):m_rotfont(0), m_fontstruct(0), | |||
49 | XFontImp::~XFontImp() { | 51 | XFontImp::~XFontImp() { |
50 | if (m_fontstruct != 0) | 52 | if (m_fontstruct != 0) |
51 | XFreeFont(App::instance()->display(), m_fontstruct); | 53 | XFreeFont(App::instance()->display(), m_fontstruct); |
52 | if (m_rotfont != 0) | 54 | |
53 | freeRotFont(); | 55 | for (int i = ROT0; i <= ROT270; ++i) |
56 | if (m_rotfonts[i] != 0) | ||
57 | freeRotFont(m_rotfonts[i]); | ||
54 | } | 58 | } |
55 | 59 | ||
56 | int XFontImp::ascent() const { | 60 | int XFontImp::ascent() const { |
57 | if (m_fontstruct == 0) | 61 | if (m_fontstruct == 0) |
58 | return 0; | 62 | return 0; |
59 | if (m_rotfont != 0) | ||
60 | return m_rotfont->max_ascent; | ||
61 | 63 | ||
62 | return m_fontstruct->ascent; | 64 | return m_fontstruct->ascent; |
63 | } | 65 | } |
64 | 66 | ||
65 | bool XFontImp::load(const std::string &fontname) { | 67 | bool XFontImp::load(const std::string &fontname) { |
68 | |||
66 | XFontStruct *font = XLoadQueryFont(App::instance()->display(), fontname.c_str()); | 69 | XFontStruct *font = XLoadQueryFont(App::instance()->display(), fontname.c_str()); |
67 | if (font == 0) | 70 | if (font == 0) |
68 | return false; | 71 | return false; |
@@ -71,10 +74,9 @@ bool XFontImp::load(const std::string &fontname) { | |||
71 | 74 | ||
72 | m_fontstruct = font; //set new font | 75 | m_fontstruct = font; //set new font |
73 | 76 | ||
74 | if (m_rotfont != 0) { | 77 | for (int i = ROT0; i <= ROT270; ++i) |
75 | freeRotFont(); // free old rotated font | 78 | if (m_rotfonts[i] != 0) |
76 | rotate(m_angle); // allocate new rotated font and rotate it to old angle | 79 | freeRotFont(m_rotfonts[i]); |
77 | } | ||
78 | 80 | ||
79 | return true; | 81 | return true; |
80 | } | 82 | } |
@@ -84,8 +86,8 @@ void XFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *text | |||
84 | return; | 86 | return; |
85 | 87 | ||
86 | // use roated font functions? | 88 | // use roated font functions? |
87 | if (m_rotfont != 0 && m_rotate) { | 89 | if (orient != ROT0 && m_rotfonts[orient] != 0) { |
88 | drawRotText(w.drawable(), screen, gc, text, len, x, y); | 90 | drawRotText(w.drawable(), screen, gc, text, len, x, y, orient); |
89 | return; | 91 | return; |
90 | } | 92 | } |
91 | 93 | ||
@@ -97,10 +99,6 @@ unsigned int XFontImp::textWidth(const char * const text, unsigned int size) con | |||
97 | if (text == 0 || m_fontstruct == 0) | 99 | if (text == 0 || m_fontstruct == 0) |
98 | return 0; | 100 | return 0; |
99 | 101 | ||
100 | // check rotated font? | ||
101 | if (m_rotfont != 0) | ||
102 | return rotTextWidth(text, size); | ||
103 | |||
104 | return XTextWidth(m_fontstruct, text, size); | 102 | return XTextWidth(m_fontstruct, text, size); |
105 | } | 103 | } |
106 | 104 | ||
@@ -111,28 +109,13 @@ unsigned int XFontImp::height() const { | |||
111 | return m_fontstruct->ascent + m_fontstruct->descent; | 109 | return m_fontstruct->ascent + m_fontstruct->descent; |
112 | } | 110 | } |
113 | 111 | ||
114 | void XFontImp::rotate(int angle) { | 112 | void XFontImp::rotate(FbTk::Orientation orient) { |
115 | //we must have a font loaded before we rotate | 113 | //we must have a font loaded before we rotate |
116 | if (m_fontstruct == 0 || m_fontstruct->per_char == 0) | 114 | if (m_fontstruct == 0 || m_fontstruct->per_char == 0 || orient == ROT0) |
117 | return; | 115 | return; |
118 | 116 | ||
119 | if (m_rotfont != 0) | ||
120 | freeRotFont(); | ||
121 | |||
122 | // no need for rotating, use regular font | ||
123 | if (angle == 0) { | ||
124 | m_angle = 0; | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | _FB_USES_NLS; | 117 | _FB_USES_NLS; |
129 | 118 | ||
130 | //get positive angle | ||
131 | while (angle < 0) | ||
132 | angle += 360; | ||
133 | |||
134 | m_angle = angle; | ||
135 | |||
136 | // X system default vars | 119 | // X system default vars |
137 | Display *dpy = App::instance()->display(); | 120 | Display *dpy = App::instance()->display(); |
138 | Window rootwin = DefaultRootWindow(dpy); | 121 | Window rootwin = DefaultRootWindow(dpy); |
@@ -145,12 +128,6 @@ void XFontImp::rotate(int angle) { | |||
145 | unsigned char *vertdata, *bitdata; | 128 | unsigned char *vertdata, *bitdata; |
146 | int ascent, descent, lbearing, rbearing; | 129 | int ascent, descent, lbearing, rbearing; |
147 | 130 | ||
148 | // get nearest vertical or horizontal direction | ||
149 | int dir = (int)((angle+45.0)/90.0)%4; | ||
150 | |||
151 | if (dir == 0) // no rotation | ||
152 | return; | ||
153 | |||
154 | // create the depth 1 canvas bitmap | 131 | // create the depth 1 canvas bitmap |
155 | FbTk::FbPixmap canvas(rootwin, boxlen, boxlen, 1); | 132 | FbTk::FbPixmap canvas(rootwin, boxlen, boxlen, 1); |
156 | 133 | ||
@@ -160,9 +137,10 @@ void XFontImp::rotate(int angle) { | |||
160 | font_gc.setFont(m_fontstruct->fid); | 137 | font_gc.setFont(m_fontstruct->fid); |
161 | 138 | ||
162 | // allocate space for rotated font | 139 | // allocate space for rotated font |
163 | m_rotfont = new(nothrow) XRotFontStruct; | 140 | m_rotfonts[orient] = new(nothrow) XRotFontStruct; |
141 | XRotFontStruct *rotfont = m_rotfonts[orient]; | ||
164 | 142 | ||
165 | if (m_rotfont == 0) { | 143 | if (rotfont == 0) { |
166 | cerr<<"RotFont: "<<_FBTKTEXT(Error, OutOfMemory, "Out of memory", "Something couldn't allocate memory")<<endl; | 144 | cerr<<"RotFont: "<<_FBTKTEXT(Error, OutOfMemory, "Out of memory", "Something couldn't allocate memory")<<endl; |
167 | return; | 145 | return; |
168 | } | 146 | } |
@@ -178,12 +156,11 @@ void XFontImp::rotate(int angle) { | |||
178 | max_char = 126; | 156 | max_char = 126; |
179 | 157 | ||
180 | /* some overall font data ... */ | 158 | /* some overall font data ... */ |
181 | m_rotfont->dir = dir; | 159 | rotfont->min_char = min_char; |
182 | m_rotfont->min_char = min_char; | 160 | rotfont->max_char = max_char; |
183 | m_rotfont->max_char = max_char; | 161 | rotfont->max_ascent = m_fontstruct->max_bounds.ascent; |
184 | m_rotfont->max_ascent = m_fontstruct->max_bounds.ascent; | 162 | rotfont->max_descent = m_fontstruct->max_bounds.descent; |
185 | m_rotfont->max_descent = m_fontstruct->max_bounds.descent; | 163 | rotfont->height = rotfont->max_ascent + rotfont->max_descent; |
186 | m_rotfont->height = m_rotfont->max_ascent + m_rotfont->max_descent; | ||
187 | 164 | ||
188 | // font needs rotation | 165 | // font needs rotation |
189 | // loop through each character | 166 | // loop through each character |
@@ -191,17 +168,17 @@ void XFontImp::rotate(int angle) { | |||
191 | index = ichar - m_fontstruct->min_char_or_byte2; | 168 | index = ichar - m_fontstruct->min_char_or_byte2; |
192 | 169 | ||
193 | // per char dimensions ... | 170 | // per char dimensions ... |
194 | ascent = m_rotfont->per_char[ichar-32].ascent = m_fontstruct->per_char[index].ascent; | 171 | ascent = rotfont->per_char[ichar-32].ascent = m_fontstruct->per_char[index].ascent; |
195 | descent = m_rotfont->per_char[ichar-32].descent = m_fontstruct->per_char[index].descent; | 172 | descent = rotfont->per_char[ichar-32].descent = m_fontstruct->per_char[index].descent; |
196 | lbearing = m_rotfont->per_char[ichar-32].lbearing = m_fontstruct->per_char[index].lbearing; | 173 | lbearing = rotfont->per_char[ichar-32].lbearing = m_fontstruct->per_char[index].lbearing; |
197 | rbearing = m_rotfont->per_char[ichar-32].rbearing = m_fontstruct->per_char[index].rbearing; | 174 | rbearing = rotfont->per_char[ichar-32].rbearing = m_fontstruct->per_char[index].rbearing; |
198 | m_rotfont->per_char[ichar-32].width = m_fontstruct->per_char[index].width; | 175 | rotfont->per_char[ichar-32].width = m_fontstruct->per_char[index].width; |
199 | 176 | ||
200 | // some space chars have zero body, but a bitmap can't have | 177 | // some space chars have zero body, but a bitmap can't have |
201 | if (!ascent && !descent) | 178 | if (!ascent && !descent) |
202 | ascent = m_rotfont->per_char[ichar-32].ascent = 1; | 179 | ascent = rotfont->per_char[ichar-32].ascent = 1; |
203 | if (!lbearing && !rbearing) | 180 | if (!lbearing && !rbearing) |
204 | rbearing = m_rotfont->per_char[ichar-32].rbearing = 1; | 181 | rbearing = rotfont->per_char[ichar-32].rbearing = 1; |
205 | 182 | ||
206 | // glyph width and height when vertical | 183 | // glyph width and height when vertical |
207 | vert_w = rbearing - lbearing; | 184 | vert_w = rbearing - lbearing; |
@@ -235,8 +212,8 @@ void XFontImp::rotate(int angle) { | |||
235 | "XCreateImage failed for some reason") | 212 | "XCreateImage failed for some reason") |
236 | << "." << endl; | 213 | << "." << endl; |
237 | free(vertdata); | 214 | free(vertdata); |
238 | delete m_rotfont; | 215 | delete rotfont; |
239 | m_rotfont = 0; | 216 | m_rotfonts[orient] = 0; |
240 | return; | 217 | return; |
241 | } | 218 | } |
242 | 219 | ||
@@ -250,7 +227,7 @@ void XFontImp::rotate(int angle) { | |||
250 | I1->format = XYBitmap; | 227 | I1->format = XYBitmap; |
251 | 228 | ||
252 | // width, height of rotated character | 229 | // width, height of rotated character |
253 | if (dir == 2) { | 230 | if (orient == ROT180) { |
254 | bit_w = vert_w; | 231 | bit_w = vert_w; |
255 | bit_h = vert_h; | 232 | bit_h = vert_h; |
256 | } else { | 233 | } else { |
@@ -261,8 +238,8 @@ void XFontImp::rotate(int angle) { | |||
261 | // width in bytes | 238 | // width in bytes |
262 | bit_len = (bit_w-1)/8 + 1; | 239 | bit_len = (bit_w-1)/8 + 1; |
263 | 240 | ||
264 | m_rotfont->per_char[ichar-32].glyph.bit_w = bit_w; | 241 | rotfont->per_char[ichar-32].glyph.bit_w = bit_w; |
265 | m_rotfont->per_char[ichar-32].glyph.bit_h = bit_h; | 242 | rotfont->per_char[ichar-32].glyph.bit_h = bit_h; |
266 | 243 | ||
267 | // reserve memory for the rotated image | 244 | // reserve memory for the rotated image |
268 | bitdata = (unsigned char *)calloc((unsigned)(bit_h * bit_len), 1); | 245 | bitdata = (unsigned char *)calloc((unsigned)(bit_h * bit_len), 1); |
@@ -277,8 +254,8 @@ void XFontImp::rotate(int angle) { | |||
277 | "XCreateImage failed for some reason") | 254 | "XCreateImage failed for some reason") |
278 | << "." << endl; | 255 | << "." << endl; |
279 | free(bitdata); | 256 | free(bitdata); |
280 | delete m_rotfont; | 257 | delete rotfont; |
281 | m_rotfont = 0; | 258 | m_rotfonts[orient] = 0; |
282 | return; | 259 | return; |
283 | } | 260 | } |
284 | 261 | ||
@@ -288,10 +265,10 @@ void XFontImp::rotate(int angle) { | |||
288 | for (j = 0; j < bit_h; j++) { | 265 | for (j = 0; j < bit_h; j++) { |
289 | for (i = 0; i < bit_w; i++) { | 266 | for (i = 0; i < bit_w; i++) { |
290 | char val = 0; | 267 | char val = 0; |
291 | if (dir == 1) { | 268 | if (orient == ROT270) { |
292 | val = vertdata[i*vert_len + (vert_w-j-1)/8] & | 269 | val = vertdata[i*vert_len + (vert_w-j-1)/8] & |
293 | (128>>((vert_w-j-1)%8)); | 270 | (128>>((vert_w-j-1)%8)); |
294 | } else if (dir == 2) { | 271 | } else if (orient == ROT180) { |
295 | val = vertdata[(vert_h-j-1)*vert_len + | 272 | val = vertdata[(vert_h-j-1)*vert_len + |
296 | (vert_w-i-1)/8] & (128>>((vert_w-i-1)%8)); | 273 | (vert_w-i-1)/8] & (128>>((vert_w-i-1)%8)); |
297 | } else { | 274 | } else { |
@@ -306,11 +283,11 @@ void XFontImp::rotate(int angle) { | |||
306 | } | 283 | } |
307 | 284 | ||
308 | // create this character's bitmap | 285 | // create this character's bitmap |
309 | m_rotfont->per_char[ichar-32].glyph.bm = | 286 | rotfont->per_char[ichar-32].glyph.bm = |
310 | XCreatePixmap(dpy, rootwin, bit_w, bit_h, 1); | 287 | XCreatePixmap(dpy, rootwin, bit_w, bit_h, 1); |
311 | 288 | ||
312 | // put the image into the bitmap | 289 | // put the image into the bitmap |
313 | XPutImage(dpy, m_rotfont->per_char[ichar-32].glyph.bm, | 290 | XPutImage(dpy, rotfont->per_char[ichar-32].glyph.bm, |
314 | font_gc.gc(), I2, 0, 0, 0, 0, bit_w, bit_h); | 291 | font_gc.gc(), I2, 0, 0, 0, 0, bit_w, bit_h); |
315 | 292 | ||
316 | // free the image and data | 293 | // free the image and data |
@@ -320,29 +297,28 @@ void XFontImp::rotate(int angle) { | |||
320 | 297 | ||
321 | } | 298 | } |
322 | 299 | ||
323 | void XFontImp::freeRotFont() { | 300 | void XFontImp::freeRotFont(XRotFontStruct *rotfont) { |
324 | if (m_rotfont == 0) | ||
325 | return; | ||
326 | // loop through each character and free its pixmap | 301 | // loop through each character and free its pixmap |
327 | for (int ichar = m_rotfont->min_char - 32; | 302 | for (int ichar = rotfont->min_char - 32; |
328 | ichar <= m_rotfont->max_char - 32; ++ichar) { | 303 | ichar <= rotfont->max_char - 32; ++ichar) { |
329 | XFreePixmap(App::instance()->display(), m_rotfont->per_char[ichar].glyph.bm); | 304 | XFreePixmap(App::instance()->display(), rotfont->per_char[ichar].glyph.bm); |
330 | } | 305 | } |
331 | 306 | ||
332 | delete m_rotfont; | 307 | delete rotfont; |
333 | m_rotfont = 0; | 308 | rotfont = 0; |
334 | } | 309 | } |
335 | 310 | ||
336 | void XFontImp::drawRotText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y) const { | 311 | void XFontImp::drawRotText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const { |
337 | 312 | ||
338 | Display *dpy = App::instance()->display(); | 313 | Display *dpy = App::instance()->display(); |
339 | static GC my_gc = 0; | 314 | static GC my_gc = 0; |
340 | int xp, yp, dir, ichar; | 315 | int xp, yp, ichar; |
316 | |||
317 | XRotFontStruct *rotfont = m_rotfonts[orient]; | ||
341 | 318 | ||
342 | if (text == NULL || len<1) | 319 | if (text == NULL || len<1) |
343 | return; | 320 | return; |
344 | 321 | ||
345 | dir = m_rotfont->dir; | ||
346 | if (my_gc == 0) | 322 | if (my_gc == 0) |
347 | my_gc = XCreateGC(dpy, w, 0, 0); | 323 | my_gc = XCreateGC(dpy, w, 0, 0); |
348 | 324 | ||
@@ -359,52 +335,44 @@ void XFontImp::drawRotText(Drawable w, int screen, GC gc, const char *text, size | |||
359 | // make sure it's a printing character | 335 | // make sure it's a printing character |
360 | if (ichar >= 0 && ichar<95) { | 336 | if (ichar >= 0 && ichar<95) { |
361 | // suitable offset | 337 | // suitable offset |
362 | if (dir == 1) { | 338 | if (orient == ROT270) { |
363 | xp = x-m_rotfont->per_char[ichar].ascent; | 339 | xp = x-rotfont->per_char[ichar].ascent; |
364 | yp = y-m_rotfont->per_char[ichar].rbearing; | 340 | yp = y-rotfont->per_char[ichar].rbearing; |
365 | } else if (dir == 2) { | 341 | } else if (orient == ROT180) { |
366 | xp = x-m_rotfont->per_char[ichar].rbearing; | 342 | xp = x-rotfont->per_char[ichar].rbearing; |
367 | yp = y-m_rotfont->per_char[ichar].descent+1; | 343 | yp = y-rotfont->per_char[ichar].descent+1; |
368 | } else { | 344 | } else { // ROT90 |
369 | xp = x-m_rotfont->per_char[ichar].descent+1; | 345 | xp = x-rotfont->per_char[ichar].descent; |
370 | yp = y+m_rotfont->per_char[ichar].lbearing; | 346 | yp = y+rotfont->per_char[ichar].lbearing; |
371 | } | 347 | } |
372 | 348 | ||
373 | // draw the glyph | 349 | // draw the glyph |
374 | XSetStipple(dpy, my_gc, m_rotfont->per_char[ichar].glyph.bm); | 350 | XSetStipple(dpy, my_gc, rotfont->per_char[ichar].glyph.bm); |
375 | 351 | ||
376 | XSetTSOrigin(dpy, my_gc, xp, yp); | 352 | XSetTSOrigin(dpy, my_gc, xp, yp); |
377 | 353 | ||
378 | XFillRectangle(dpy, w, my_gc, xp, yp, | 354 | XFillRectangle(dpy, w, my_gc, xp, yp, |
379 | m_rotfont->per_char[ichar].glyph.bit_w, | 355 | rotfont->per_char[ichar].glyph.bit_w, |
380 | m_rotfont->per_char[ichar].glyph.bit_h); | 356 | rotfont->per_char[ichar].glyph.bit_h); |
381 | 357 | ||
382 | // advance position | 358 | // advance position |
383 | if (dir == 1) | 359 | if (orient == ROT270) |
384 | y -= m_rotfont->per_char[ichar].width; | 360 | y -= rotfont->per_char[ichar].width; |
385 | else if (dir == 2) | 361 | else if (orient == ROT180) |
386 | x -= m_rotfont->per_char[ichar].width; | 362 | x -= rotfont->per_char[ichar].width; |
387 | else | 363 | else |
388 | y += m_rotfont->per_char[ichar].width; | 364 | y += rotfont->per_char[ichar].width; |
389 | } | 365 | } |
390 | } | 366 | } |
391 | } | 367 | } |
392 | 368 | ||
393 | 369 | ||
394 | unsigned int XFontImp::rotTextWidth(const char * const text, unsigned int size) const { | 370 | bool XFontImp::validOrientation(FbTk::Orientation orient) { |
395 | 371 | if (orient == ROT0 || m_rotfonts[orient]) | |
396 | if (text == 0) | 372 | return true; |
397 | return 0; | ||
398 | |||
399 | unsigned int width = 0; | ||
400 | for (size_t i = 0; i<size; i++) { | ||
401 | int ichar = text[i] - 32; | ||
402 | // make sure it's a printing character | ||
403 | if (ichar >= 0 && ichar < 95) | ||
404 | width += m_rotfont->per_char[ichar].width; | ||
405 | } | ||
406 | 373 | ||
407 | return width; | 374 | rotate(orient); |
375 | return m_rotfonts[orient] != 0; | ||
408 | } | 376 | } |
409 | 377 | ||
410 | }; | 378 | }; |
diff --git a/src/FbTk/XFontImp.hh b/src/FbTk/XFontImp.hh index 6b5a34b..0312fb5 100644 --- a/src/FbTk/XFontImp.hh +++ b/src/FbTk/XFontImp.hh | |||
@@ -38,50 +38,49 @@ public: | |||
38 | bool load(const std::string &filename); | 38 | bool load(const std::string &filename); |
39 | unsigned int textWidth(const char * const text, unsigned int size) const; | 39 | unsigned int textWidth(const char * const text, unsigned int size) const; |
40 | unsigned int height() const; | 40 | unsigned int height() const; |
41 | int angle() const { return m_angle; } | ||
42 | int ascent() const; | 41 | int ascent() const; |
43 | int descent() const { return m_fontstruct ? m_fontstruct->descent : 0; } | 42 | int descent() const { return m_fontstruct ? m_fontstruct->descent : 0; } |
44 | void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const; | 43 | void drawText(const FbDrawable &w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const; |
45 | 44 | ||
45 | bool validOrientation(FbTk::Orientation orient); | ||
46 | |||
46 | bool loaded() const { return m_fontstruct != 0; } | 47 | bool loaded() const { return m_fontstruct != 0; } |
47 | void rotate(int angle); | 48 | |
48 | /// enable/disable rotation witout alloc/dealloc rotfont structures | ||
49 | void setRotate(bool val) { m_rotate = val; } | ||
50 | private: | 49 | private: |
51 | void freeRotFont(); | ||
52 | void drawRotText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y) const; | ||
53 | unsigned int rotTextWidth(const char * const text, unsigned int size) const; | ||
54 | struct BitmapStruct { | 50 | struct BitmapStruct { |
55 | int bit_w; | 51 | int bit_w; |
56 | int bit_h; | 52 | int bit_h; |
57 | 53 | ||
58 | Pixmap bm; | 54 | Pixmap bm; |
59 | }; | 55 | }; |
60 | |||
61 | struct XRotCharStruct { | 56 | struct XRotCharStruct { |
62 | int ascent; | 57 | int ascent; |
63 | int descent; | 58 | int descent; |
64 | int lbearing; | 59 | int lbearing; |
65 | int rbearing; | 60 | int rbearing; |
66 | int width; | 61 | int width; |
67 | 62 | ||
68 | BitmapStruct glyph; | 63 | BitmapStruct glyph; |
69 | }; | 64 | }; |
70 | 65 | ||
71 | struct XRotFontStruct { | 66 | struct XRotFontStruct { |
72 | int dir; | 67 | int height; |
73 | int height; | 68 | int max_ascent; |
74 | int max_ascent; | 69 | int max_descent; |
75 | int max_descent; | 70 | int max_char; |
76 | int max_char; | ||
77 | int min_char; | 71 | int min_char; |
78 | 72 | ||
79 | XRotCharStruct per_char[95]; | 73 | XRotCharStruct per_char[95]; |
80 | }; | 74 | }; |
81 | XRotFontStruct *m_rotfont; ///< rotated font structure | 75 | |
76 | void rotate(FbTk::Orientation orient); | ||
77 | |||
78 | void freeRotFont(XRotFontStruct * rotfont); | ||
79 | void drawRotText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y, FbTk::Orientation orient) const; | ||
80 | |||
81 | XRotFontStruct *m_rotfonts[4]; ///< rotated font structure (only 3 used) | ||
82 | XFontStruct *m_fontstruct; ///< X font structure | 82 | XFontStruct *m_fontstruct; ///< X font structure |
83 | int m_angle; ///< the rotated angle | 83 | |
84 | bool m_rotate; ///< used to disable/enable rotation temprarly without reallocating m_rotfont | ||
85 | }; | 84 | }; |
86 | 85 | ||
87 | } // end namespace FbTk | 86 | } // end namespace FbTk |
diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc index 0e33b5a..18bae9a 100644 --- a/src/FbWinFrame.cc +++ b/src/FbWinFrame.cc | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <algorithm> | 42 | #include <algorithm> |
43 | #include <X11/X.h> | 43 | #include <X11/X.h> |
44 | 44 | ||
45 | #include <iostream> | ||
45 | using namespace std; // mem_fun | 46 | using namespace std; // mem_fun |
46 | 47 | ||
47 | FbWinFrame::FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl, | 48 | FbWinFrame::FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl, |
@@ -334,6 +335,7 @@ void FbWinFrame::alignTabs() { | |||
334 | if (m_tabmode != EXTERNAL) | 335 | if (m_tabmode != EXTERNAL) |
335 | return; | 336 | return; |
336 | 337 | ||
338 | |||
337 | FbTk::Orientation orig_orient = m_tab_container.orientation(); | 339 | FbTk::Orientation orig_orient = m_tab_container.orientation(); |
338 | unsigned int orig_tabwidth = m_tab_container.maxWidthPerClient(); | 340 | unsigned int orig_tabwidth = m_tab_container.maxWidthPerClient(); |
339 | 341 | ||
@@ -374,14 +376,14 @@ void FbWinFrame::alignTabs() { | |||
374 | if (orig_orient != FbTk::ROT90) m_tab_container.hide(); | 376 | if (orig_orient != FbTk::ROT90) m_tab_container.hide(); |
375 | m_tab_container.setOrientation(FbTk::ROT90); | 377 | m_tab_container.setOrientation(FbTk::ROT90); |
376 | m_tab_container.setAlignment(Container::LEFT); | 378 | m_tab_container.setAlignment(Container::LEFT); |
377 | tabx = x() + width(); | 379 | tabx = x() + width() + m_window.borderWidth(); |
378 | taby = y(); | 380 | taby = y(); |
379 | break; | 381 | break; |
380 | case RIGHTBOTTOM: | 382 | case RIGHTBOTTOM: |
381 | if (orig_orient != FbTk::ROT90) m_tab_container.hide(); | 383 | if (orig_orient != FbTk::ROT90) m_tab_container.hide(); |
382 | m_tab_container.setOrientation(FbTk::ROT90); | 384 | m_tab_container.setOrientation(FbTk::ROT90); |
383 | m_tab_container.setAlignment(Container::RIGHT); | 385 | m_tab_container.setAlignment(Container::RIGHT); |
384 | tabx = x() + width(); | 386 | tabx = x() + width() + m_window.borderWidth(); |
385 | taby = y() + height() - m_tab_container.height(); | 387 | taby = y() + height() - m_tab_container.height(); |
386 | break; | 388 | break; |
387 | case BOTTOMLEFT: | 389 | case BOTTOMLEFT: |
@@ -1106,6 +1108,15 @@ void FbWinFrame::reconfigureTitlebar() { | |||
1106 | if (m_tabmode == INTERNAL) | 1108 | if (m_tabmode == INTERNAL) |
1107 | m_tab_container.moveResize(next_x, m_bevel, | 1109 | m_tab_container.moveResize(next_x, m_bevel, |
1108 | space_left, button_size); | 1110 | space_left, button_size); |
1111 | else { | ||
1112 | if (m_use_tabs) { | ||
1113 | if (m_tab_container.orientation() == FbTk::ROT0) { | ||
1114 | m_tab_container.resize(m_tab_container.width(), button_size); | ||
1115 | } else { | ||
1116 | m_tab_container.resize(button_size, m_tab_container.height()); | ||
1117 | } | ||
1118 | } | ||
1119 | } | ||
1109 | 1120 | ||
1110 | next_x += m_label.width() + m_bevel; | 1121 | next_x += m_label.width() + m_bevel; |
1111 | 1122 | ||