2002-11-26 16:01:28 +00:00
|
|
|
// XmbFontImp.cc for FbTk fluxbox toolkit
|
2003-04-26 18:58:30 +00:00
|
|
|
// Copyright (c) 2002-2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
|
2004-09-10 16:12:01 +00:00
|
|
|
//
|
2002-11-26 16:01:28 +00:00
|
|
|
// 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.
|
|
|
|
|
2004-11-17 16:39:30 +00:00
|
|
|
// $Id$
|
2002-11-26 16:01:28 +00:00
|
|
|
|
|
|
|
#include "XmbFontImp.hh"
|
|
|
|
|
|
|
|
#include "App.hh"
|
2003-04-26 18:58:30 +00:00
|
|
|
#include "StringUtil.hh"
|
2004-09-11 23:01:34 +00:00
|
|
|
#include "FbDrawable.hh"
|
2003-02-17 23:36:43 +00:00
|
|
|
|
2002-11-26 16:01:28 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif //HAVE_CONFIG_H
|
|
|
|
|
|
|
|
#ifdef HAVE_SETLOCALE
|
|
|
|
#include <locale.h>
|
|
|
|
#endif // HAVE_SETLOCALE
|
|
|
|
|
|
|
|
#ifndef _GNU_SOURCE
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#endif // _GNU_SOURCE
|
|
|
|
|
2004-08-31 15:26:40 +00:00
|
|
|
#ifdef HAVE_CSTDIO
|
|
|
|
#include <cstdio>
|
|
|
|
#else
|
|
|
|
#include <stdio.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_CSTDARG
|
|
|
|
#include <cstdarg>
|
|
|
|
#else
|
|
|
|
#include <stdarg.h>
|
|
|
|
#endif
|
2002-11-26 16:01:28 +00:00
|
|
|
#include <iostream>
|
2004-08-31 15:26:40 +00:00
|
|
|
#ifdef HAVE_CSTRING
|
|
|
|
#include <cstring>
|
|
|
|
#else
|
|
|
|
#include <string.h>
|
|
|
|
#endif
|
2002-12-02 19:31:05 +00:00
|
|
|
|
2002-11-26 16:01:28 +00:00
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
const char *getFontSize(const char *pattern, int *size) {
|
2002-12-01 13:42:15 +00:00
|
|
|
const char *p;
|
|
|
|
const char *p2=0;
|
|
|
|
int n=0;
|
|
|
|
|
|
|
|
for (p=pattern; 1; p++) {
|
|
|
|
if (!*p) {
|
|
|
|
if (p2!=0 && n>1 && n<72) {
|
|
|
|
*size = n; return p2+1;
|
|
|
|
} else {
|
|
|
|
*size = 16; return 0;
|
|
|
|
}
|
|
|
|
} else if (*p=='-') {
|
|
|
|
if (n>1 && n<72 && p2!=0) {
|
|
|
|
*size = n;
|
|
|
|
return p2+1;
|
|
|
|
}
|
|
|
|
p2=p; n=0;
|
|
|
|
} else if (*p>='0' && *p<='9' && p2!=0) {
|
|
|
|
n *= 10;
|
|
|
|
n += *p-'0';
|
|
|
|
} else {
|
|
|
|
p2=0; n=0;
|
|
|
|
}
|
|
|
|
}
|
2002-11-26 16:01:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *getFontElement(const char *pattern, char *buf, int bufsiz, ...) {
|
2002-12-01 13:42:15 +00:00
|
|
|
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 *)) != 0) {
|
2003-04-26 18:58:30 +00:00
|
|
|
p = FbTk::StringUtil::strcasestr(pattern, v);
|
2002-12-01 13:42:15 +00:00
|
|
|
if (p) {
|
2004-02-10 19:03:42 +00:00
|
|
|
strncpy(buf, p+1, bufsiz-2);
|
2002-12-01 13:42:15 +00:00
|
|
|
p2 = strchr(buf, '-');
|
|
|
|
if (p2) *p2=0;
|
|
|
|
va_end(va);
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
va_end(va);
|
2004-02-10 19:03:42 +00:00
|
|
|
strncpy(buf, "*", bufsiz);
|
2002-12-01 13:42:15 +00:00
|
|
|
return 0;
|
2002-11-26 16:01:28 +00:00
|
|
|
}
|
|
|
|
|
2004-08-28 18:10:19 +00:00
|
|
|
XFontSet createFontSet(const char *fontname, bool utf8mode) {
|
2002-12-01 13:42:15 +00:00
|
|
|
Display *display = FbTk::App::instance()->display();
|
|
|
|
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];
|
2004-10-04 12:43:52 +00:00
|
|
|
std::string orig_locale = "";
|
2002-11-26 16:01:28 +00:00
|
|
|
|
2004-08-28 18:10:19 +00:00
|
|
|
#ifdef HAVE_SETLOCALE
|
|
|
|
if (utf8mode) {
|
|
|
|
orig_locale = setlocale(LC_CTYPE, NULL);
|
|
|
|
setlocale(LC_CTYPE, "UTF-8");
|
|
|
|
}
|
|
|
|
#endif // HAVE_SETLOCALE
|
2002-12-01 13:42:15 +00:00
|
|
|
fs = XCreateFontSet(display,
|
|
|
|
fontname, &missing, &nmissing, &def);
|
2004-08-28 18:10:19 +00:00
|
|
|
|
|
|
|
if (fs && (! nmissing)) {
|
|
|
|
#ifdef HAVE_SETLOCALE
|
|
|
|
if (utf8mode)
|
2004-10-04 12:43:52 +00:00
|
|
|
setlocale(LC_CTYPE, orig_locale.c_str());
|
2004-08-28 18:10:19 +00:00
|
|
|
#endif // HAVE_SETLOCALE
|
|
|
|
return fs;
|
|
|
|
}
|
2002-11-26 16:01:28 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_SETLOCALE
|
2002-12-01 13:42:15 +00:00
|
|
|
if (! fs) {
|
|
|
|
if (nmissing) XFreeStringList(missing);
|
|
|
|
|
|
|
|
setlocale(LC_CTYPE, "C");
|
|
|
|
fs = XCreateFontSet(display, fontname,
|
|
|
|
&missing, &nmissing, &def);
|
2004-10-04 12:43:52 +00:00
|
|
|
setlocale(LC_CTYPE, orig_locale.c_str());
|
2002-12-01 13:42:15 +00:00
|
|
|
}
|
2002-11-26 16:01:28 +00:00
|
|
|
#endif // HAVE_SETLOCALE
|
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (fs) {
|
|
|
|
XFontStruct **fontstructs;
|
|
|
|
char **fontnames;
|
|
|
|
XFontsOfFontSet(fs, &fontstructs, &fontnames);
|
|
|
|
fontname = fontnames[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
getFontElement(fontname, weight, FONT_ELEMENT_SIZE,
|
2004-09-03 17:05:35 +00:00
|
|
|
"-medium-", "-bold-", "-demibold-", "-regular-", NULL);
|
2002-12-01 13:42:15 +00:00
|
|
|
getFontElement(fontname, slant, FONT_ELEMENT_SIZE,
|
2004-09-03 17:05:35 +00:00
|
|
|
"-r-", "-i-", "-o-", "-ri-", "-ro-", NULL);
|
2002-12-01 13:42:15 +00:00
|
|
|
getFontSize(fontname, &pixel_size);
|
|
|
|
|
2004-09-10 16:12:01 +00:00
|
|
|
if (! strcmp(weight, "*"))
|
2004-02-10 19:03:42 +00:00
|
|
|
strncpy(weight, "medium", FONT_ELEMENT_SIZE);
|
2004-09-10 16:12:01 +00:00
|
|
|
if (! strcmp(slant, "*"))
|
2004-02-10 19:03:42 +00:00
|
|
|
strncpy(slant, "r", FONT_ELEMENT_SIZE);
|
2004-09-10 16:12:01 +00:00
|
|
|
if (pixel_size < 3)
|
2002-12-01 13:42:15 +00:00
|
|
|
pixel_size = 3;
|
2004-09-10 16:12:01 +00:00
|
|
|
else if (pixel_size > 97)
|
2002-12-01 13:42:15 +00:00
|
|
|
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;
|
|
|
|
|
2004-08-28 18:10:19 +00:00
|
|
|
#ifdef HAVE_SETLOCALE
|
|
|
|
if (utf8mode)
|
2004-10-04 12:43:52 +00:00
|
|
|
setlocale(LC_CTYPE, orig_locale.c_str());
|
2004-08-28 18:10:19 +00:00
|
|
|
#endif // HAVE_SETLOCALE
|
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
return fs;
|
2002-11-26 16:01:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
namespace FbTk {
|
|
|
|
|
2004-11-17 16:39:30 +00:00
|
|
|
XmbFontImp::XmbFontImp(const char *filename, bool utf8):m_fontset(0), m_setextents(0), m_utf8mode(utf8) {
|
2002-12-01 13:42:15 +00:00
|
|
|
if (filename != 0)
|
|
|
|
load(filename);
|
2002-11-26 16:01:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
XmbFontImp::~XmbFontImp() {
|
2002-12-01 13:42:15 +00:00
|
|
|
if (m_fontset != 0)
|
|
|
|
XFreeFontSet(App::instance()->display(), m_fontset);
|
2002-11-26 16:01:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool XmbFontImp::load(const std::string &fontname) {
|
2002-12-01 13:42:15 +00:00
|
|
|
if (fontname.size() == 0)
|
|
|
|
return false;
|
2004-08-28 18:10:19 +00:00
|
|
|
|
|
|
|
XFontSet set = createFontSet(fontname.c_str(), m_utf8mode);
|
2002-12-01 13:42:15 +00:00
|
|
|
if (set == 0)
|
|
|
|
return false;
|
2004-08-28 18:10:19 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
if (m_fontset != 0)
|
|
|
|
XFreeFontSet(App::instance()->display(), m_fontset);
|
2004-08-28 18:10:19 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
m_fontset = set;
|
|
|
|
m_setextents = XExtentsOfFontSet(m_fontset);
|
|
|
|
|
2004-09-10 16:12:01 +00:00
|
|
|
return true;
|
2002-11-26 16:01:28 +00:00
|
|
|
}
|
|
|
|
|
2004-09-11 23:01:34 +00:00
|
|
|
void XmbFontImp::drawText(const FbDrawable &w, int screen, GC gc, const char *text,
|
2002-12-01 13:42:15 +00:00
|
|
|
size_t len, int x, int y) const {
|
2002-11-26 16:01:28 +00:00
|
|
|
|
2004-09-11 23:01:34 +00:00
|
|
|
if (m_fontset == 0)
|
2002-12-01 13:42:15 +00:00
|
|
|
return;
|
2004-09-10 16:12:01 +00:00
|
|
|
|
2002-11-26 16:01:28 +00:00
|
|
|
#ifdef X_HAVE_UTF8_STRING
|
2002-12-01 13:42:15 +00:00
|
|
|
if (m_utf8mode) {
|
2004-09-11 23:01:34 +00:00
|
|
|
Xutf8DrawString(w.display(), w.drawable(), m_fontset,
|
|
|
|
gc, x, y,
|
|
|
|
text, len);
|
2004-09-10 16:12:01 +00:00
|
|
|
} else
|
2002-11-26 16:01:28 +00:00
|
|
|
#endif //X_HAVE_UTF8_STRING
|
2004-09-10 16:12:01 +00:00
|
|
|
{
|
2004-09-11 23:01:34 +00:00
|
|
|
XmbDrawString(w.display(), w.drawable(), m_fontset,
|
2004-09-10 16:12:01 +00:00
|
|
|
gc, x, y,
|
|
|
|
text, len);
|
|
|
|
}
|
2002-11-26 16:01:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int XmbFontImp::textWidth(const char * const text, unsigned int len) const {
|
2002-12-01 13:42:15 +00:00
|
|
|
if (m_fontset == 0)
|
|
|
|
return 0;
|
2004-08-10 11:57:35 +00:00
|
|
|
|
2002-12-01 13:42:15 +00:00
|
|
|
XRectangle ink, logical;
|
2002-11-26 16:01:28 +00:00
|
|
|
#ifdef X_HAVE_UTF8_STRING
|
2002-12-01 13:42:15 +00:00
|
|
|
if (m_utf8mode) {
|
|
|
|
Xutf8TextExtents(m_fontset, text, len,
|
|
|
|
&ink, &logical);
|
2004-08-10 11:57:35 +00:00
|
|
|
if (logical.width != 0)
|
|
|
|
return logical.width;
|
|
|
|
}
|
2002-11-26 16:01:28 +00:00
|
|
|
#endif // X_HAVE_UTF8_STRING
|
|
|
|
|
2004-08-10 11:57:35 +00:00
|
|
|
XmbTextExtents(m_fontset, text, len,
|
|
|
|
&ink, &logical);
|
2002-12-01 13:42:15 +00:00
|
|
|
return logical.width;
|
2002-11-26 16:01:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int XmbFontImp::height() const {
|
2002-12-01 13:42:15 +00:00
|
|
|
if (m_fontset == 0)
|
|
|
|
return 0;
|
|
|
|
return m_setextents->max_ink_extent.height;
|
2002-11-26 16:01:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}; // end namespace FbTk
|
|
|
|
|