From 55b2aaf973063796a668bc758232141c3d6f5cc9 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sat, 21 Dec 2002 13:49:57 +0000 Subject: [PATCH] add font --- otk_c/Makefile | 13 +++-- otk_c/color.c | 16 +---- otk_c/color.h | 3 - otk_c/font.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++ otk_c/font.h | 64 ++++++++++++++++++++ otk_c/init.c | 3 + 6 files changed, 230 insertions(+), 23 deletions(-) create mode 100644 otk_c/font.c create mode 100644 otk_c/font.h diff --git a/otk_c/Makefile b/otk_c/Makefile index 2e0589d6..397227ef 100644 --- a/otk_c/Makefile +++ b/otk_c/Makefile @@ -1,12 +1,13 @@ -prefix=/tmp/ob -exec_prefix=$(prefix) -libdir=$(exec_prefix)/lib +prefix = /tmp/ob +exec_prefix = $(prefix) +libdir = $(exec_prefix)/lib targets = libotk.so libotk.a -sources = init.c display.c screeninfo.c rect.c gccache.c color.c -headers = init.h display.h screeninfo.h rect.h gccache.h color.h +sources = init.c display.c screeninfo.c rect.c gccache.c color.c font.c +headers = init.h display.h screeninfo.h rect.h gccache.h color.h font.h -CFLAGS+=-g -I/usr/gwar/include/python2.2 -W -Wall +CFLAGS += -g -W -Wall -I/usr/gwar/include/python2.2 `pkg-config --cflags xft` +LDFLAGS += `pkg-config --libs xft` .PHONY: all install clean diff --git a/otk_c/color.c b/otk_c/color.c index 4ecca30c..732f7b7d 100644 --- a/otk_c/color.c +++ b/otk_c/color.c @@ -75,8 +75,6 @@ static void doCacheCleanup() { static void allocate(OtkColor *self) { XColor xcol; - assert(!self->allocated); - // allocate color from rgb values xcol.red = self->red | self->red << 8; xcol.green = self->green | self->green << 8; @@ -92,7 +90,6 @@ static void allocate(OtkColor *self) { } self->pixel = xcol.pixel; - self->allocated = True; if (cleancache) doCacheCleanup(); @@ -108,11 +105,9 @@ PyObject *OtkColor_FromRGB(int r, int g, int b, int screen) if (!colorcache) colorcache = PyDict_New(); - self->allocated = False; self->red = r; self->green = g; self->blue = b; - self->pixel = 0; self->screen = screen; // does this color already exist in the cache? @@ -124,6 +119,7 @@ PyObject *OtkColor_FromRGB(int r, int g, int b, int screen) // add it to the cache PyDict_SetItem(colorcache, (PyObject*)self, (PyObject*)self); + allocate(self); return (PyObject*)self; } @@ -136,11 +132,9 @@ PyObject *OtkColor_FromName(const char *name, int screen) if (!colorcache) colorcache = PyDict_New(); - self->allocated = False; self->red = -1; self->green = -1; self->blue = -1; - self->pixel = 0; self->screen = screen; parseColorName(self, name); @@ -154,16 +148,10 @@ PyObject *OtkColor_FromName(const char *name, int screen) // add it to the cache PyDict_SetItem(colorcache, (PyObject*)self, (PyObject*)self); + allocate(self); return (PyObject*)self; } -unsigned long OtkColor_Pixel(OtkColor *self) -{ - if (!self->allocated) - allocate(self); - return self->pixel; -} - void OtkColor_CleanupColorCache() { cleancache = True; diff --git a/otk_c/color.h b/otk_c/color.h index 143429a0..b8dff225 100644 --- a/otk_c/color.h +++ b/otk_c/color.h @@ -12,15 +12,12 @@ typedef struct OtkColor { PyObject_HEAD int red, green, blue; int screen; - Bool allocated; unsigned long pixel; } OtkColor; PyObject *OtkColor_FromRGB(int r, int g, int b, int screen); PyObject *OtkColor_FromName(const char *name, int screen); -unsigned long OtkColor_Pixel(OtkColor *self); - void OtkColor_CleanupColorCache(); #endif // __color_h diff --git a/otk_c/font.c b/otk_c/font.c new file mode 100644 index 00000000..7c9b4f5f --- /dev/null +++ b/otk_c/font.c @@ -0,0 +1,154 @@ +// -*- mode: C; indent-tabs-mode: nil; -*- + +#include "../config.h" +#include "font.h" +#include "display.h" +#include "color.h" + +#include "../src/gettext.h" + +static Bool xft_init = False; +static const char *fallback = "fixed"; + +void OtkFont_Initialize() +{ + if (!XftInit(0)) { + printf(_("Couldn't initialize Xft version %d.%d.%d.\n\n"), + XFT_MAJOR, XFT_MINOR, XFT_REVISION); + exit(3); + } + printf(_("Using Xft %d.%d.%d.\n"), XFT_MAJOR, XFT_MINOR, XFT_REVISION); + xft_init = True; +} + +PyObject *OtkFont_New(int screen, const char *fontstring, Bool shadow, + unsigned char offset, unsigned char tint) +{ + OtkFont *self = PyObject_New(OtkFont, &OtkFont_Type); + + assert(xft_init); + assert(screen >= 0); + assert(fontstring); + + self->screen = screen; + self->shadow = shadow; + self->offset = offset; + self->tint = tint; + + if (!(self->xftfont = XftFontOpenName(OBDisplay->display, screen, + fontstring))) { + printf(_("Unable to load font: %s"), fontstring); + printf(_("Trying fallback font: %s\n"), fallback); + if (!(self->xftfont = + XftFontOpenName(OBDisplay->display, screen, fallback))) { + printf(_("Unable to load font: %s"), fallback); + printf(_("Aborting!.\n")); + + exit(3); // can't continue without a font + } + } + + return (PyObject*)self; +} + +int OtkFont_MeasureString(OtkFont *self, const char *string)//, Bool utf8) +{ + XGlyphInfo info; + +/* if (utf8)*/ + XftTextExtentsUtf8(OBDisplay->display, self->xftfont, + (const FcChar8*)string, strlen(string), &info); +/* else + XftTextExtents8(OBDisplay->display, self->xftfont, + (const FcChar8*)string, strlen(string), &info);*/ + + return info.xOff + (self->shadow ? self->offset : 0); +} + +void OtkFont_DrawString(OtkFont *self, XftDraw *d, int x, int y, + OtkColor *color, const char *string)//, Bool utf8) +{ + assert(self); + assert(d); + + if (self->shadow) { + XftColor c; + c.color.red = 0; + c.color.green = 0; + c.color.blue = 0; + c.color.alpha = self->tint | self->tint << 8; // transparent shadow + c.pixel = BlackPixel(OBDisplay->display, self->screen); + +/* if (utf8)*/ + XftDrawStringUtf8(d, &c, self->xftfont, x + self->offset, + self->xftfont->ascent + y + self->offset, + (const FcChar8*)string, strlen(string)); +/* else + XftDrawString8(d, &c, self->xftfont, x + self->offset, + self->xftfont->ascent + y + self->offset, + (const FcChar8*)string, strlen(string));*/ + } + + XftColor c; + c.color.red = color->red | color->red << 8; + c.color.green = color->green | color->green << 8; + c.color.blue = color->blue | color->blue << 8; + c.pixel = color->pixel; + c.color.alpha = 0xff | 0xff << 8; // no transparency in BColor yet + +/* if (utf8)*/ + XftDrawStringUtf8(d, &c, self->xftfont, x, self->xftfont->ascent + y, + (const FcChar8*)string, strlen(string)); +/* else + XftDrawString8(d, &c, self->xftfont, x, self->xftfont->ascent + y, + (const FcChar8*)string, strlen(string));*/ +} + + + + +static PyObject *otkfont_measurestring(OtkFont* self, PyObject* args) +{ + char *s; + + if (!PyArg_ParseTuple(args, "s", &s)) + return NULL; + return PyInt_FromLong(OtkFont_MeasureString(self, s)); +} + +static PyMethodDef get_methods[] = { + {"measureString", (PyCFunction)otkfont_measurestring, METH_VARARGS, + "Measure the length of a string with a font."}, + {NULL, NULL, 0, NULL} +}; + + +static void otkfont_dealloc(OtkFont* self) +{ + // this is always set. cuz if it failed.. the app would exit! + XftFontClose(OBDisplay->display, self->xftfont); + PyObject_Del((PyObject*)self); +} + +static PyObject *otkfont_getattr(PyObject *obj, char *name) +{ + return Py_FindMethod(get_methods, obj, name); +} + +PyTypeObject Otkfont_Type = { + PyObject_HEAD_INIT(NULL) + 0, + "OtkFont", + sizeof(OtkFont), + 0, + (destructor)otkfont_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + otkfont_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ +}; diff --git a/otk_c/font.h b/otk_c/font.h new file mode 100644 index 00000000..637a215d --- /dev/null +++ b/otk_c/font.h @@ -0,0 +1,64 @@ +// -*- mode: C; indent-tabs-mode: nil; -*- +#ifndef __font_h +#define __font_h + +#include +#define _XFT_NO_COMPAT_ // no Xft 1 API +#include +#include + +extern PyTypeObject OtkFont_Type; + +struct OtkColor; +struct ScreenInfo; + +#define OTKFONTHEIGHT(font) (font->xftfont->height + \ + (font->shadow ? font->offset : 0)) +#define OTKFONTMAXCHARWIDTH(font) (font->xftfont->max_advance_width) + +typedef struct OtkFont { + PyObject_HEAD + int screen; + Bool shadow; + unsigned char offset; + unsigned char tint; + XftFont *xftfont; +} OtkFont; + +void OtkFont_Initialize(); + +PyObject *OtkFont_New(int screen, const char *fontstring, Bool shadow, + unsigned char offset, unsigned char tint); + +int OtkFont_MeasureString(OtkFont *self, const char *string);//, Bool utf8); + +//! Draws a string into an XftDraw object +/*! + Be Warned: If you use an XftDraw object and a color, or a font from + different screens, you WILL have unpredictable results! :) +*/ +void OtkFont_DrawString(OtkFont *self, XftDraw *d, int x, int y, + struct OtkColor *color, const char *string);//, Bool utf8); + +/* + bool createXftFont(void); + +public: + // loads an Xft font + BFont(int screen_num, const std::string &fontstring, bool shadow, + unsigned char offset, unsigned char tint); + virtual ~BFont(); + + inline const std::string &fontstring() const { return _fontstring; } + + unsigned int height() const; + unsigned int maxCharWidth() const; + + unsigned int measureString(const std::string &string, + bool utf8 = false) const; + +}; + +} +*/ +#endif // __font_h diff --git a/otk_c/init.c b/otk_c/init.c index 5f576ac3..a958c4fe 100644 --- a/otk_c/init.c +++ b/otk_c/init.c @@ -5,6 +5,7 @@ #include "screeninfo.h" #include "color.h" #include "gccache.h" +#include "font.h" #include #include @@ -21,10 +22,12 @@ void initotk(char *display) OtkDisplay_Type.ob_type = &PyType_Type; OtkScreenInfo_Type.ob_type = &PyType_Type; OtkColor_Type.ob_type = &PyType_Type; + OtkFont_Type.ob_type = &PyType_Type; Py_InitModule("otk", otk_methods); OtkDisplay_Initialize(display); assert(OBDisplay); OtkGCCache_Initialize(); + OtkFont_Initialize(); } -- 2.45.2