From 3d3985609cd6dddff78558a9c1b3429ed4e891f4 Mon Sep 17 00:00:00 2001 From: fluxgen Date: Thu, 21 Mar 2002 10:51:48 +0000 Subject: first --- src/Font.cc | 255 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Font.hh | 68 ++++++++++++++++ 2 files changed, 323 insertions(+) create mode 100644 src/Font.cc create mode 100644 src/Font.hh diff --git a/src/Font.cc b/src/Font.cc new file mode 100644 index 0000000..3d516dd --- /dev/null +++ b/src/Font.cc @@ -0,0 +1,255 @@ +// Font.cc +// Copyright (c) 2002 Henrik Kinnunen (fluxgen@linuxmail.org) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +//$Id: Font.cc,v 1.1 2002/03/21 10:51:48 fluxgen Exp $ +#include "Font.hh" +#include +#include //for debug msg +using namespace std; + +//use gnu extensions +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif //_GNU_SOURCE + +#ifdef HAVE_CONFIG_H +# include "../config.h" +#endif // HAVE_CONFIG_H + +namespace FbTk +{ + +bool Font::m_multibyte = false; //TODO: fix multibyte + +Font::Font(Display *display, const char *name):m_loaded(false), +m_display(display) { + m_font.fontstruct = 0; + m_font.set_extents = 0; + m_font.set = 0; + if (name!=0) { + load(name); + } + +} + +Font::~Font() { + freeFont(); +} + +bool Font::load(const char *name) { + if (m_multibyte) { + XFontSet set = createFontSet(m_display, name); + if (!set) + return false; + freeFont(); + + m_font.set = set; + m_font.set_extents = XExtentsOfFontSet(m_font.set); + + } else { + XFontStruct *font = XLoadQueryFont(m_display, name); + if (font==0) + return false; + freeFont(); //free old font + m_font.fontstruct = font; //set new font + } + + m_loaded = true; //mark the font loaded + + return true; +} + +bool Font::loadFromDatabase(XrmDatabase &database, const char *rname, const char *rclass) { + assert(rname); + assert(rclass); + + XrmValue value; + char *value_type; + + //this should probably be moved to a Database class so we can keep + //track of database init + + if (XrmGetResource(database, rname, rclass, &value_type, &value)) { + #ifdef DEBUG + cerr<<__FILE__<<"("<<__LINE__<<"): Load font:"<max_ink_extent.height; + if (getFontStruct()) + return getFontStruct()->ascent + getFontStruct()->descent; + return 0; +} + +XFontSet Font::createFontSet(Display *display, const char *fontname) { + XFontSet fs; + const int FONT_ELEMENT_SIZE=50; + char **missing, *def = "-"; + int nmissing, pixel_size = 0, buf_size = 0; + char weight[FONT_ELEMENT_SIZE], slant[FONT_ELEMENT_SIZE]; + + fs = XCreateFontSet(display, + fontname, &missing, &nmissing, &def); + if (fs && (! nmissing)) return fs; + +#ifdef HAVE_SETLOCALE + if (! fs) { + if (nmissing) XFreeStringList(missing); + + setlocale(LC_CTYPE, "C"); + fs = XCreateFontSet(m_display, fontname, + &missing, &nmissing, &def); + setlocale(LC_CTYPE, ""); + } +#endif // HAVE_SETLOCALE + + if (fs) { + XFontStruct **fontstructs; + char **fontnames; + XFontsOfFontSet(fs, &fontstructs, &fontnames); + fontname = fontnames[0]; + } + + getFontElement(fontname, weight, FONT_ELEMENT_SIZE, + "-medium-", "-bold-", "-demibold-", "-regular-", NULL); + getFontElement(fontname, slant, FONT_ELEMENT_SIZE, + "-r-", "-i-", "-o-", "-ri-", "-ro-", NULL); + getFontSize(fontname, &pixel_size); + + if (! strcmp(weight, "*")) + strncpy(weight, "medium", FONT_ELEMENT_SIZE); + if (! strcmp(slant, "*")) + strncpy(slant, "r", FONT_ELEMENT_SIZE); + if (pixel_size < 3) + pixel_size = 3; + else if (pixel_size > 97) + pixel_size = 97; + + buf_size = strlen(fontname) + (FONT_ELEMENT_SIZE * 2) + 64; + char *pattern2 = new char[buf_size]; + snprintf(pattern2, buf_size - 1, + "%s," + "-*-*-%s-%s-*-*-%d-*-*-*-*-*-*-*," + "-*-*-*-*-*-*-%d-*-*-*-*-*-*-*,*", + fontname, weight, slant, pixel_size, pixel_size); + fontname = pattern2; + + if (nmissing) + XFreeStringList(missing); + if (fs) + XFreeFontSet(display, fs); + + fs = XCreateFontSet(display, fontname, + &missing, &nmissing, &def); + delete [] pattern2; + + return fs; +} + +const char *Font::getFontElement(const char *pattern, char *buf, int bufsiz, ...) { + const char *p, *v; + char *p2; + va_list va; + + va_start(va, bufsiz); + buf[bufsiz-1] = 0; + buf[bufsiz-2] = '*'; + while((v = va_arg(va, char *)) != NULL) { + p = strcasestr(pattern, v); + if (p) { + strncpy(buf, p+1, bufsiz-2); + p2 = strchr(buf, '-'); + if (p2) *p2=0; + va_end(va); + return p; + } + } + va_end(va); + strncpy(buf, "*", bufsiz); + return NULL; +} + +const char *Font::getFontSize(const char *pattern, int *size) { + const char *p; + const char *p2=0; + int n=0; + + for (p=pattern; 1; p++) { + if (!*p) { + if (p2!=NULL && n>1 && n<72) { + *size = n; return p2+1; + } else { + *size = 16; return NULL; + } + } else if (*p=='-') { + if (n>1 && n<72 && p2!=NULL) { + *size = n; + return p2+1; + } + p2=p; n=0; + } else if (*p>='0' && *p<='9' && p2!=NULL) { + n *= 10; + n += *p-'0'; + } else { + p2=NULL; n=0; + } + } +} + +void Font::freeFont() { + //free memory + if (m_font.fontstruct!=0) + XFreeFont(m_display, m_font.fontstruct); + if (m_font.set) + XFreeFontSet(m_display, m_font.set); + + //clear struct + m_font.fontstruct = 0; + m_font.set = 0; + m_font.set_extents = 0; + + m_loaded = false; //mark the font not loaded +} + +}; diff --git a/src/Font.hh b/src/Font.hh new file mode 100644 index 0000000..04318ba --- /dev/null +++ b/src/Font.hh @@ -0,0 +1,68 @@ +// Font.cc +// Copyright (c) 2002 Henrik Kinnunen (fluxgen@linuxmail.org) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +//$Id: Font.hh,v 1.1 2002/03/21 10:51:48 fluxgen Exp $ + +#ifndef FBTK_FONT_HH +#define FBTK_FONT_HH + +#include +namespace FbTk +{ + +class Font +{ +public: + Font(Display *display, const char *name=0); + virtual ~Font(); + //manipulators + bool load(const char *name); + bool loadFromDatabase(XrmDatabase &database, const char *rname, const char *rclass); + //accessors + inline bool isLoaded() const { return m_loaded; } + inline XFontStruct *getFontStruct() const { return m_font.fontstruct; } + inline XFontSet &getFontSet() { return m_font.set; } + inline XFontSetExtents *getFontSetExtents() const { return m_font.set_extents; } + static inline bool multibyte() { return m_multibyte; } + unsigned int getTextWidth(const char *text, unsigned int size) const; + unsigned int getHeight() const; + Display *getDisplay() const { return m_display; } +private: + void freeFont(); + static XFontSet createFontSet(Display *display, const char *fontname); + static const char *getFontSize(const char *pattern, int *size); + static const char *getFontElement(const char *pattern, char *buf, int bufsiz, ...); + + struct FontType + { + XFontSet set; + XFontSetExtents *set_extents; + XFontStruct *fontstruct; + } m_font; + + bool m_loaded; + static bool m_multibyte; + Display *m_display; +}; + +}; //end namespace FbTk + +#endif //FBTK_FONT_HH -- cgit v0.11.2