From 99c92a637392a988382559d0b162aed68ab83ba8 Mon Sep 17 00:00:00 2001 From: fluxgen Date: Mon, 25 Nov 2002 14:07:21 +0000 Subject: fixed rotated text on vertical tab in XFontImp and a rotate function in FontImp interface --- src/Font.cc | 25 ++++- src/Font.hh | 10 +- src/FontImp.hh | 4 +- src/Screen.cc | 18 +++- src/Tab.cc | 46 ++++----- src/Theme.cc | 13 +-- src/Theme.hh | 3 +- src/XFontImp.cc | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/XFontImp.hh | 38 ++++++- 9 files changed, 419 insertions(+), 52 deletions(-) diff --git a/src/Font.cc b/src/Font.cc index a3d3b29..8f683d9 100644 --- a/src/Font.cc +++ b/src/Font.cc @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -//$Id: Font.cc,v 1.21 2002/11/24 05:23:36 rathnor Exp $ +//$Id: Font.cc,v 1.22 2002/11/25 14:07:21 fluxgen Exp $ #include "Font.hh" @@ -69,7 +69,7 @@ bool Font::m_utf8mode = false; Font::Font(const char *name, bool antialias): m_fontimp(0), -m_antialias(false) { +m_antialias(false), m_rotated(false) { // MB_CUR_MAX returns the size of a char in the current locale if (MB_CUR_MAX > 1) // more than one byte, then we're multibyte @@ -115,7 +115,7 @@ Font::~Font() { void Font::setAntialias(bool flag) { bool loaded = m_fontimp->loaded(); #ifdef USE_XFT - if (flag && !isAntialias()) { + if (flag && !isAntialias() && !m_rotated) { m_fontimp.reset(new XftFontImp(m_fontstr.c_str(), m_utf8mode)); } else if (!flag && isAntialias()) #endif // USE_XFT @@ -164,4 +164,23 @@ void Font::drawText(Drawable w, int screen, GC gc, const char *text, size_t len, m_fontimp->drawText(w, screen, gc, text, len, x, y); } +void Font::rotate(float angle) { +#ifdef USE_XFT + // if we are rotated and we are changing to horiz text + // and we were antialiased before we rotated then change to XftFontImp + if (isRotated() && angle == 0 && isAntialias()) + m_fontimp.reset(new XftFontImp(m_fontstr.c_str(), m_utf8mode)); +#endif // USE_XFT + // change to a font imp that handles rotated fonts (i.e just XFontImp at the moment) + // if we're going to rotate this font + if (angle != 0 && isAntialias() && !isRotated()) { + m_fontimp.reset(new XFontImp(m_fontstr.c_str())); + } + + //Note: only XFontImp implements FontImp::rotate + m_fontimp->rotate(angle); + + m_rotated = (angle == 0 ? false : true); +} + }; diff --git a/src/Font.hh b/src/Font.hh index 93cbd87..a1fb62d 100644 --- a/src/Font.hh +++ b/src/Font.hh @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -//$Id: Font.hh,v 1.8 2002/10/19 14:00:37 fluxgen Exp $ +//$Id: Font.hh,v 1.9 2002/11/25 14:07:21 fluxgen Exp $ #ifndef FBTK_FONT_HH #define FBTK_FONT_HH @@ -62,8 +62,13 @@ public: unsigned int height() const; int ascent() const; int descent() const; + /** + Rotate font in any angle (currently only 90 degrees supported and just XFont implementation) + */ + void rotate(float angle); void drawText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y) const; - bool isAntialias() const { return m_antialias; } + bool isAntialias() const { return m_antialias; } + bool isRotated() const { return m_rotated; } private: std::auto_ptr m_fontimp; @@ -71,6 +76,7 @@ private: static bool m_multibyte; static bool m_utf8mode; bool m_antialias; + bool m_rotated; ///< wheter we're rotated or not }; }; //end namespace FbTk diff --git a/src/FontImp.hh b/src/FontImp.hh index f822b73..95f980a 100644 --- a/src/FontImp.hh +++ b/src/FontImp.hh @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: FontImp.hh,v 1.3 2002/10/19 13:57:48 fluxgen Exp $ +// $Id: FontImp.hh,v 1.4 2002/11/25 14:07:20 fluxgen Exp $ #ifndef FBTK_FONTIMP_HH #define FBTK_FONTIMP_HH @@ -35,6 +35,7 @@ namespace FbTk { /** FontImp, second part of the bridge pattern for fonts pure interface class. + @see Font */ class FontImp { public: @@ -46,6 +47,7 @@ public: virtual int descent() const = 0; virtual unsigned int height() const = 0; virtual bool loaded() const = 0; + virtual void rotate(float angle) { } // by default, no rotate support protected: FontImp() { } }; diff --git a/src/Screen.cc b/src/Screen.cc index 880e13c..1d885be 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.cc,v 1.83 2002/11/24 20:56:06 fluxgen Exp $ +// $Id: Screen.cc,v 1.84 2002/11/25 14:07:21 fluxgen Exp $ #include "Screen.hh" @@ -286,6 +286,13 @@ resource(rm, screenname, altscreenname) image_control, fluxbox->getStyleFilename(), getRootCommand().c_str()); theme->reconfigure(*resource.antialias); + // special case for tab rotated + if (*resource.tab_rotate_vertical && + ( *resource.tab_placement == Tab::PLEFT || *resource.tab_placement == Tab::PRIGHT)) { + theme->getWindowStyle().tab.font.rotate(90); + } else { + theme->getWindowStyle().tab.font.rotate(0); + } const char *s = i18n->getMessage( FBNLS::ScreenSet, FBNLS::ScreenPositionLength, @@ -504,7 +511,14 @@ void BScreen::reconfigure() { theme->setRootCommand(getRootCommand()); theme->load(Fluxbox::instance()->getStyleFilename()); theme->reconfigure(*resource.antialias); - + // special case for tab rotated + if (*resource.tab_rotate_vertical && + ( *resource.tab_placement == Tab::PLEFT || *resource.tab_placement == Tab::PRIGHT)) { + theme->getWindowStyle().tab.font.rotate(90); + } else { + theme->getWindowStyle().tab.font.rotate(0); + } + I18n *i18n = I18n::instance(); const char *s = i18n->getMessage( diff --git a/src/Tab.cc b/src/Tab.cc index 22d229f..c46d2c8 100644 --- a/src/Tab.cc +++ b/src/Tab.cc @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Tab.cc,v 1.41 2002/11/17 13:40:01 fluxgen Exp $ +// $Id: Tab.cc,v 1.42 2002/11/25 14:07:21 fluxgen Exp $ #include "Tab.hh" @@ -367,43 +367,30 @@ void Tab::draw(bool pressed) const { GC gc = ((m_win->isFocused()) ? m_win->getScreen()->getWindowStyle()->tab.l_text_focus_gc : m_win->getScreen()->getWindowStyle()->tab.l_text_unfocus_gc); - // Different routines for drawing rotated text - // TODO: rotated font - /*if ((m_win->getScreen()->getTabPlacement() == PLEFT || - m_win->getScreen()->getTabPlacement() == PRIGHT) && - (!m_win->isShaded() && m_win->getScreen()->isTabRotateVertical())) { - - tabtext_w = DrawUtil::XRotTextWidth(m_win->getScreen()->getWindowStyle()->tab.rot_font, - m_win->getTitle().c_str(), m_win->getTitle().size()); - tabtext_w += (m_win->frame.bevel_w * 4); - - DrawUtil::DrawRotString(m_display, m_tabwin, gc, - m_win->getScreen()->getWindowStyle()->tab.rot_font, - m_win->getScreen()->getWindowStyle()->tab.font.justify, - tabtext_w, m_size_w, m_size_h, - m_win->frame.bevel_w, m_win->getTitle().c_str()); - - } else { - */ int dx=0; Theme::WindowStyle *winstyle = m_win->getScreen()->getWindowStyle(); size_t dlen = m_win->getTitle().size(); size_t l = winstyle->tab.font.textWidth(m_win->getTitle().c_str(), dlen); + + size_t max_width = m_size_w; // special cases in rotated mode + if (winstyle->tab.font.isRotated()) + max_width = m_size_h; + if ( l > m_size_w) { for (; dlen >= 0; dlen--) { l = winstyle->tab.font.textWidth(m_win->getTitle().c_str(), dlen) + m_win->frame.bevel_w*4; - if (l < m_size_w || dlen == 0) + if (l < max_width || dlen == 0) break; } } switch (winstyle->tab.justify) { case DrawUtil::Font::RIGHT: - dx += m_size_w - l - m_win->frame.bevel_w*3; + dx += max_width - l - m_win->frame.bevel_w*3; break; case DrawUtil::Font::CENTER: - dx += (m_size_w - l) / 2; + dx += (max_width - l) / 2; break; case DrawUtil::Font::LEFT: dx = m_win->frame.bevel_w; @@ -411,14 +398,21 @@ void Tab::draw(bool pressed) const { default: break; } - - m_win->getScreen()->getWindowStyle()->tab.font.drawText( + + int dy = winstyle->tab.font.ascent() + m_win->frame.bevel_w; + // swap dx and dy if we're rotated + if (winstyle->tab.font.isRotated()) { + int tmp = dy; + dy = m_size_h - dx; // upside down + dx = tmp; + } + + winstyle->tab.font.drawText( m_tabwin, m_win->getScreen()->getScreenNumber(), gc, m_win->getTitle().c_str(), dlen, - dx, - m_win->getScreen()->getWindowStyle()->tab.font.ascent() + m_win->frame.bevel_w); + dx, dy); } diff --git a/src/Theme.cc b/src/Theme.cc index d0188cf..b924855 100644 --- a/src/Theme.cc +++ b/src/Theme.cc @@ -21,7 +21,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Theme.cc,v 1.34 2002/11/15 13:10:48 fluxgen Exp $ +// $Id: Theme.cc,v 1.35 2002/11/25 14:07:21 fluxgen Exp $ #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -471,17 +471,6 @@ void Theme::loadTabStyle() { loadFontFromDatabase(m_windowstyle.tab.font, "window.tab.font", "Window.Tab.Font"); - //TODO: fix rotated font - //--------- rotated font for left and right tabs - // TODO: add extra checking - /*if (XrmGetResource(m_database, "window.tab.font", "Window.Tab.Font", - &value_type, &value)) { - if (! (m_windowstyle.tab.rot_font = DrawUtil::XRotLoadFont(m_display, value.addr, 90.0)) ) - m_windowstyle.tab.rot_font = DrawUtil::XRotLoadFont(m_display, "fixed", 90); - } else - m_windowstyle.tab.rot_font = DrawUtil::XRotLoadFont(m_display, "fixed", 90); - */ - if (XrmGetResource(m_database, "window.tab.justify", "Window.Tab.Justify", &value_type, &value)) { if (strstr(value.addr, "right") || strstr(value.addr, "Right")) diff --git a/src/Theme.hh b/src/Theme.hh index adabc39..e7d4536 100644 --- a/src/Theme.hh +++ b/src/Theme.hh @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Theme.hh,v 1.17 2002/10/29 16:06:23 fluxgen Exp $ +// $Id: Theme.hh,v 1.18 2002/11/25 14:07:21 fluxgen Exp $ #ifndef THEME_HH #define THEME_HH @@ -82,7 +82,6 @@ public: FbTk::Color border_color; unsigned int border_width; unsigned int border_width_2x; - DrawUtil::XRotFontStruct *rot_font; } tab; } WindowStyle; diff --git a/src/XFontImp.cc b/src/XFontImp.cc index 9a57cc7..a263466 100644 --- a/src/XFontImp.cc +++ b/src/XFontImp.cc @@ -19,15 +19,18 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: XFontImp.cc,v 1.1 2002/10/13 22:22:14 fluxgen Exp $ +// $Id: XFontImp.cc,v 1.2 2002/11/25 14:07:21 fluxgen Exp $ #include "XFontImp.hh" #include "BaseDisplay.hh" +#include + #include using namespace std; -XFontImp::XFontImp(const char *fontname):m_fontstruct(0) { +XFontImp::XFontImp(const char *fontname):m_rotfont(0), m_fontstruct(0), +m_angle(0) { if (fontname != 0) load(fontname); } @@ -35,6 +38,17 @@ XFontImp::XFontImp(const char *fontname):m_fontstruct(0) { XFontImp::~XFontImp() { if (m_fontstruct != 0) XFreeFont(BaseDisplay::getXDisplay(), m_fontstruct); + if (m_rotfont != 0) + freeRotFont(); +} + +int XFontImp::ascent() const { + if (m_fontstruct == 0) + return 0; + if (m_rotfont != 0) + return m_rotfont->max_ascent; + + return m_fontstruct->ascent; } bool XFontImp::load(const std::string &fontname) { @@ -51,14 +65,26 @@ bool XFontImp::load(const std::string &fontname) { void XFontImp::drawText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y) const { if (m_fontstruct == 0) return; + // use roated font functions? + if (m_rotfont != 0) { + drawRotText(w, screen, gc, text, len, x, y); + return; + } + Display *disp = BaseDisplay::getXDisplay(); XSetFont(disp, gc, m_fontstruct->fid); XDrawString(disp, w, gc, x, y, text, len); } unsigned int XFontImp::textWidth(const char * const text, unsigned int size) const { + if (text == 0) + return 0; if (m_fontstruct == 0) return 0; + // check rotated font? + if (m_rotfont != 0) + return rotTextWidth(text, size); + return XTextWidth(m_fontstruct, text, size); } @@ -68,3 +94,287 @@ unsigned int XFontImp::height() const { return m_fontstruct->ascent + m_fontstruct->descent; } + +void XFontImp::rotate(float angle) { + //we must have a font loaded before we rotate + if (m_fontstruct == 0) + return; + if (m_rotfont != 0) + freeRotFont(); + // no need for rotating, use regular font + if (angle == 0) + return; + + //get positive angle + while (angle < 0) + angle += 360; + + char val; + XImage *I1, *I2; + // X system default vars + Display *dpy = BaseDisplay::instance()->getXDisplay(); + Window rootwin = DefaultRootWindow(dpy); + int screen = DefaultScreen(dpy); + + GC font_gc; + char text[3]; + int ichar, i, j, index, boxlen = 60; + int vert_w, vert_h, vert_len, bit_w, bit_h, bit_len; + int min_char, max_char; + unsigned char *vertdata, *bitdata; + int ascent, descent, lbearing, rbearing; + + // get nearest vertical or horizontal direction + int dir = (int)((angle+45.0)/90.0)%4; + + if (dir == 0) // no rotation + return; + + // create the depth 1 canvas bitmap + Pixmap canvas = XCreatePixmap(dpy, rootwin, boxlen, boxlen, 1); + + // create graphic context for our canvas + font_gc = XCreateGC(dpy, canvas, 0, 0); + + XSetBackground(dpy, font_gc, None); + + XSetFont(dpy, font_gc, m_fontstruct->fid); + + // allocate space for rotated font + m_rotfont = new(nothrow) XRotFontStruct; + + if (m_rotfont == 0) { + cerr<<"RotFont: out of memory"<min_char_or_byte2; + max_char = m_fontstruct->max_char_or_byte2; + + // we only want printable chars + if (min_char<32) + min_char = 32; + if (max_char>126) + max_char = 126; + + /* some overall font data ... */ + m_rotfont->dir = dir; + m_rotfont->min_char = min_char; + m_rotfont->max_char = max_char; + m_rotfont->max_ascent = m_fontstruct->max_bounds.ascent; + m_rotfont->max_descent = m_fontstruct->max_bounds.descent; + m_rotfont->height = m_rotfont->max_ascent + m_rotfont->max_descent; + + // font needs rotation + // loop through each character + for (ichar = min_char; ichar <= max_char; ichar++) { + index = ichar - m_fontstruct->min_char_or_byte2; + + // per char dimensions ... + ascent = m_rotfont->per_char[ichar-32].ascent = m_fontstruct->per_char[index].ascent; + descent = m_rotfont->per_char[ichar-32].descent = m_fontstruct->per_char[index].descent; + lbearing = m_rotfont->per_char[ichar-32].lbearing = m_fontstruct->per_char[index].lbearing; + rbearing = m_rotfont->per_char[ichar-32].rbearing = m_fontstruct->per_char[index].rbearing; + m_rotfont->per_char[ichar-32].width = m_fontstruct->per_char[index].width; + + // some space chars have zero body, but a bitmap can't have + if (!ascent && !descent) + ascent = m_rotfont->per_char[ichar-32].ascent = 1; + if (!lbearing && !rbearing) + rbearing = m_rotfont->per_char[ichar-32].rbearing = 1; + + // glyph width and height when vertical + vert_w = rbearing - lbearing; + vert_h = ascent + descent; + + // width in bytes + vert_len = (vert_w-1)/8+1; + + XSetForeground(dpy, font_gc, None); + XFillRectangle(dpy, canvas, font_gc, 0, 0, boxlen, boxlen); + + // draw the character centre top right on canvas + sprintf(text, "%c", ichar); + XSetForeground(dpy, font_gc, 1); + XDrawImageString(dpy, canvas, font_gc, boxlen/2 - lbearing, + boxlen/2 - descent, text, 1); + + // reserve memory for first XImage + vertdata = (unsigned char *) malloc((unsigned)(vert_len*vert_h)); + + /* create the XImage ... */ + I1 = XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap, + 0, (char *)vertdata, vert_w, vert_h, 8, 0); + + if (I1 == None) { + cerr<<"RotFont: Cant create ximage."<byte_order = I1->bitmap_bit_order = MSBFirst; + + /* extract character from canvas ... */ + XGetSubImage(dpy, canvas, boxlen/2, boxlen/2 - vert_h, + vert_w, vert_h, 1, XYPixmap, I1, 0, 0); + I1->format = XYBitmap; + + /* width, height of rotated character ... */ + if (dir == 2) { + bit_w = vert_w; + bit_h = vert_h; + } else { + bit_w = vert_h; + bit_h = vert_w; + } + + /* width in bytes ... */ + bit_len = (bit_w-1)/8 + 1; + + m_rotfont->per_char[ichar-32].glyph.bit_w = bit_w; + m_rotfont->per_char[ichar-32].glyph.bit_h = bit_h; + + /* reserve memory for the rotated image ... */ + bitdata = (unsigned char *)calloc((unsigned)(bit_h * bit_len), 1); + + /* create the image ... */ + I2 = XCreateImage(dpy, DefaultVisual(dpy, screen), 1, XYBitmap, 0, + (char *)bitdata, bit_w, bit_h, 8, 0); + + if (I2 == None) { + cerr<<"XFontImp: Cant create ximage!"<byte_order = I2->bitmap_bit_order = MSBFirst; + + /* map vertical data to rotated character ... */ + for (j = 0; j < bit_h; j++) { + for (i = 0; i < bit_w; i++) { + /* map bits ... */ + if (dir == 1) { + val = vertdata[i*vert_len + (vert_w-j-1)/8] & + (128>>((vert_w-j-1)%8)); + } else if (dir == 2) { + val = vertdata[(vert_h-j-1)*vert_len + + (vert_w-i-1)/8] & (128>>((vert_w-i-1)%8)); + } else { + val = vertdata[(vert_h-i-1)*vert_len + j/8] & + (128>>(j%8)); + } + if (val) { + bitdata[j*bit_len + i/8] = bitdata[j*bit_len + i/8] | + (128>>(i%8)); + } + } + } + + // create this character's bitmap + m_rotfont->per_char[ichar-32].glyph.bm = + XCreatePixmap(dpy, rootwin, bit_w, bit_h, 1); + + // put the image into the bitmap + XPutImage(dpy, m_rotfont->per_char[ichar-32].glyph.bm, + font_gc, I2, 0, 0, 0, 0, bit_w, bit_h); + + // free the image and data + XDestroyImage(I1); + XDestroyImage(I2); + } + + /* free pixmap and GC ... */ + XFreePixmap(dpy, canvas); + XFreeGC(dpy, font_gc); + +} + +void XFontImp::freeRotFont() { + if (m_rotfont == 0) + return; + // loop through each character and free its pixmap + for (int ichar = m_rotfont->min_char - 32; + ichar <= m_rotfont->max_char - 32; ++ichar) { + XFreePixmap(BaseDisplay::instance()->getXDisplay(), m_rotfont->per_char[ichar].glyph.bm); + } + + delete m_rotfont; + m_rotfont = 0; +} + +void XFontImp::drawRotText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y) const { + + Display *dpy = BaseDisplay::instance()->getXDisplay(); + static GC my_gc = 0; + int xp, yp, dir, ichar; + + if (text == NULL || len<1) + return; + + dir = m_rotfont->dir; + if (my_gc == 0) + my_gc = XCreateGC(dpy, w, 0, 0); + + XCopyGC(dpy, gc, GCForeground|GCBackground, my_gc); + + // vertical or upside down + + XSetFillStyle(dpy, my_gc, FillStippled); + + // loop through each character in texting + for (size_t i = 0; i= 0 && ichar<95) { + // suitable offset + if (dir == 1) { + xp = x-m_rotfont->per_char[ichar].ascent; + yp = y-m_rotfont->per_char[ichar].rbearing; + } else if (dir == 2) { + xp = x-m_rotfont->per_char[ichar].rbearing; + yp = y-m_rotfont->per_char[ichar].descent+1; + } else { + xp = x-m_rotfont->per_char[ichar].descent+1; + yp = y+m_rotfont->per_char[ichar].lbearing; + } + + // draw the glyph + XSetStipple(dpy, my_gc, m_rotfont->per_char[ichar].glyph.bm); + + XSetTSOrigin(dpy, my_gc, xp, yp); + + XFillRectangle(dpy, w, my_gc, xp, yp, + m_rotfont->per_char[ichar].glyph.bit_w, + m_rotfont->per_char[ichar].glyph.bit_h); + + // advance position + if (dir == 1) + y -= m_rotfont->per_char[ichar].width; + else if (dir == 2) + x -= m_rotfont->per_char[ichar].width; + else + y += m_rotfont->per_char[ichar].width; + } + } +} + + +unsigned int XFontImp::rotTextWidth(const char * const text, unsigned int size) const { + + if (text == 0) + return 0; + + unsigned int width = 0; + for (size_t i = 0; i= 0 && ichar < 95) + width += m_rotfont->per_char[ichar].width; + } + + return width; +} diff --git a/src/XFontImp.hh b/src/XFontImp.hh index 8ea7af1..b293fdd 100644 --- a/src/XFontImp.hh +++ b/src/XFontImp.hh @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: XFontImp.hh,v 1.3 2002/10/19 13:58:47 fluxgen Exp $ +// $Id: XFontImp.hh,v 1.4 2002/11/25 14:07:21 fluxgen Exp $ #ifndef XFONTIMP_HH #define XFONTIMP_HH @@ -33,12 +33,46 @@ public: bool load(const std::string &filename); unsigned int textWidth(const char * const text, unsigned int size) const; unsigned int height() const; - int ascent() const { return m_fontstruct ? m_fontstruct->ascent : 0; } + float angle() const { return m_angle; } + int ascent() const; int descent() const { return m_fontstruct ? m_fontstruct->descent : 0; } void drawText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y) const; bool loaded() const { return m_fontstruct != 0; } + void rotate(float angle); private: + void freeRotFont(); + void drawRotText(Drawable w, int screen, GC gc, const char *text, size_t len, int x, int y) const; + unsigned int rotTextWidth(const char * const text, unsigned int size) const; + struct BitmapStruct { + int bit_w; + int bit_h; + + Pixmap bm; + }; + + struct XRotCharStruct { + int ascent; + int descent; + int lbearing; + int rbearing; + int width; + + BitmapStruct glyph; + }; + + struct XRotFontStruct { + int dir; + int height; + int max_ascent; + int max_descent; + int max_char; + int min_char; + + XRotCharStruct per_char[95]; + }; + XRotFontStruct *m_rotfont; XFontStruct *m_fontstruct; + float m_angle; }; #endif // XFONTIMP_HH -- cgit v0.11.2