aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/TextButton.cc
diff options
context:
space:
mode:
authorMathias Gumz <akira at fluxbox dot org>2012-10-02 12:24:47 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2012-10-03 08:27:16 (GMT)
commit7b6ab828c7e5453a2720462156d165707935c9ef (patch)
tree3b641791b20b1994935e149fd7461decb11bef8c /src/FbTk/TextButton.cc
parent032a23d1e790c5224194562a837cc80fc157ce9b (diff)
downloadfluxbox-7b6ab828c7e5453a2720462156d165707935c9ef.zip
fluxbox-7b6ab828c7e5453a2720462156d165707935c9ef.tar.bz2
Improved vertical alignment of text in FbTk::TextButton
The old formula for vertical align text inside FbTk::TextButton ('height/2 + font_ascent/2 - 1') produced not always good looking results, escpecially when different fonts are involved (eg, ClockTool and WorkspaceName have different fonts and font-sizes). '(height - font_ascent) / 2 - 1' produces better results. Additional changes: * added ASCII-Art to document the involved entities when calculating the baseline * rewritten tests/testFont.cc to accept multiples texts and multiple fonts * removed some internal parts of FbTk::Font from the public interface
Diffstat (limited to 'src/FbTk/TextButton.cc')
-rw-r--r--src/FbTk/TextButton.cc78
1 files changed, 52 insertions, 26 deletions
diff --git a/src/FbTk/TextButton.cc b/src/FbTk/TextButton.cc
index c31e3d6..33a2b44 100644
--- a/src/FbTk/TextButton.cc
+++ b/src/FbTk/TextButton.cc
@@ -23,6 +23,7 @@
23#include "TextUtils.hh" 23#include "TextUtils.hh"
24#include "Font.hh" 24#include "Font.hh"
25#include "GContext.hh" 25#include "GContext.hh"
26#include <cstdio>
26 27
27namespace FbTk { 28namespace FbTk {
28 29
@@ -62,16 +63,18 @@ void TextButton::setJustify(FbTk::Justify just) {
62} 63}
63 64
64bool TextButton::setOrientation(FbTk::Orientation orient) { 65bool TextButton::setOrientation(FbTk::Orientation orient) {
66
65 if (orient == m_orientation 67 if (orient == m_orientation
66 || !m_font->validOrientation(orient)) 68 || !m_font->validOrientation(orient))
67 return false; 69 return false;
70
68 invalidateBackground(); 71 invalidateBackground();
69 72
70 if (((m_orientation == FbTk::ROT0 || m_orientation == FbTk::ROT180) && 73 if (((m_orientation == FbTk::ROT0 || m_orientation == FbTk::ROT180) &&
71 (orient == FbTk::ROT90 || orient == FbTk::ROT270)) || 74 (orient == FbTk::ROT90 || orient == FbTk::ROT270)) ||
72 ((m_orientation == FbTk::ROT90 || m_orientation == FbTk::ROT270) && 75 ((m_orientation == FbTk::ROT90 || m_orientation == FbTk::ROT270) &&
73 (orient == FbTk::ROT0 || orient == FbTk::ROT180))) { 76 (orient == FbTk::ROT0 || orient == FbTk::ROT180))) {
74 // flip width and height 77
75 m_orientation = orient; 78 m_orientation = orient;
76 resize(height(), width()); 79 resize(height(), width());
77 } else { 80 } else {
@@ -112,8 +115,7 @@ void TextButton::setTextPadding(unsigned int padding) {
112 115
113/// clear window and redraw text 116/// clear window and redraw text
114void TextButton::clear() { 117void TextButton::clear() {
115 TextButton::clearArea(0, 0, 118 TextButton::clearArea(0, 0, width(), height());
116 width(), height());
117} 119}
118 120
119void TextButton::clearArea(int x, int y, 121void TextButton::clearArea(int x, int y,
@@ -135,34 +137,58 @@ void TextButton::renderForeground(FbWindow &win, FbDrawable &drawable) {
135} 137}
136 138
137void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) { 139void TextButton::drawText(int x_offset, int y_offset, FbDrawable *drawable) {
140
141 if (drawable == 0)
142 drawable = this;
143
138 const FbString& visual = text().visual(); 144 const FbString& visual = text().visual();
139 unsigned int textlen = visual.size(); 145 unsigned int textlen = visual.size();
140 unsigned int textw = width(); 146 unsigned int button_width = width();
141 unsigned int texth = height(); 147 unsigned int button_height = height();
142 translateSize(m_orientation, textw, texth); 148
149 translateSize(m_orientation, button_width, button_height);
143 150
144 int align_x = FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding, 151 // horizontal alignment, cut off text if needed
152 int align_x = FbTk::doAlignment(button_width - x_offset - m_left_padding - m_right_padding,
145 bevel(), justify(), font(), 153 bevel(), justify(), font(),
146 visual.data(), visual.size(), 154 visual.data(), visual.size(),
147 textlen); // return new text len 155 textlen); // return new text len
148 156
149 // center text by default 157 //
150 int center_pos = texth/2 + font().ascent()/2 - 1; 158 // we center the text vertically. to do this we have to nudge the
151 159 // baseline a little bit down so the "middle" of the glyph is placed
152 int textx = align_x + x_offset + m_left_padding; 160 // on the middle of the button. we "assume", that ascent/2 is roughly
153 int texty = center_pos + y_offset; 161 // the middle of the glyph. example:
154 162 //
155 if (drawable == 0) 163 // +== ascent <--------->== +=====================
156 drawable = this; 164 // | | | |
165 // | | ggggg | | ascent <--------->
166 // | | g gg | | | |
167 // | baseline < glyph | | | ggggg |
168 // | | g | -- middle of button -- | | g gg |
169 // | descent < ggggg | | baseline < glyph |
170 // | height |_________| | | g |
171 // | | descent < ggggg |
172 // | | height |_________|
173 // | |
174 // +======================= +=====================
175 //
176 // ascent = 4
177 // button_height = 11
178 // baseline = (11 + 4) / 2 - 1 = 6
179 //
180
181 int baseline_x = align_x + x_offset + m_left_padding;
182 int baseline_y = ((button_height + font().ascent()) / 2) - 1 + y_offset;
183
184 // TODO: remove debug output fprintf(stderr, "%d | %d %d %d\n", height(), font().height(), font().ascent(), font().descent());
157 185
158 // give it ROT0 style coords 186 // give it ROT0 style coords
159 translateCoords(m_orientation, textx, texty, textw, texth); 187 translateCoords(m_orientation, baseline_x, baseline_y, button_width, button_height);
160 188
161 font().drawText(*drawable, 189 font().drawText(*drawable, screenNumber(), gc(),
162 screenNumber(), 190 visual.c_str(), textlen,
163 gc(), // graphic context 191 baseline_x, baseline_y, m_orientation);
164 visual.c_str(), textlen, // string and string size
165 textx, texty, m_orientation); // position
166} 192}
167 193
168 194
@@ -170,15 +196,15 @@ bool TextButton::textExceeds(int x_offset) {
170 196
171 const FbString& visual = text().visual(); 197 const FbString& visual = text().visual();
172 unsigned int textlen = visual.size(); 198 unsigned int textlen = visual.size();
173 unsigned int textw = width(); 199 unsigned int button_width = width();
174 unsigned int texth = height(); 200 unsigned int button_height = height();
175 translateSize(m_orientation, textw, texth); 201 translateSize(m_orientation, button_width, button_height);
176 202
177 FbTk::doAlignment(textw - x_offset - m_left_padding - m_right_padding, 203 FbTk::doAlignment(button_width - x_offset - m_left_padding - m_right_padding,
178 bevel(), justify(), font(), visual.data(), visual.size(), 204 bevel(), justify(), font(), visual.data(), visual.size(),
179 textlen); // return new text len 205 textlen); // return new text len
180 206
181 return visual.size()>textlen; 207 return visual.size() > textlen;
182} 208}
183 209
184void TextButton::exposeEvent(XExposeEvent &event) { 210void TextButton::exposeEvent(XExposeEvent &event) {