add font
This commit is contained in:
parent
16e1192e4d
commit
55b2aaf973
6 changed files with 230 additions and 23 deletions
|
@ -3,10 +3,11 @@ exec_prefix=$(prefix)
|
||||||
libdir = $(exec_prefix)/lib
|
libdir = $(exec_prefix)/lib
|
||||||
|
|
||||||
targets = libotk.so libotk.a
|
targets = libotk.so libotk.a
|
||||||
sources = init.c display.c screeninfo.c rect.c gccache.c color.c
|
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
|
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
|
.PHONY: all install clean
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,6 @@ static void doCacheCleanup() {
|
||||||
static void allocate(OtkColor *self) {
|
static void allocate(OtkColor *self) {
|
||||||
XColor xcol;
|
XColor xcol;
|
||||||
|
|
||||||
assert(!self->allocated);
|
|
||||||
|
|
||||||
// allocate color from rgb values
|
// allocate color from rgb values
|
||||||
xcol.red = self->red | self->red << 8;
|
xcol.red = self->red | self->red << 8;
|
||||||
xcol.green = self->green | self->green << 8;
|
xcol.green = self->green | self->green << 8;
|
||||||
|
@ -92,7 +90,6 @@ static void allocate(OtkColor *self) {
|
||||||
}
|
}
|
||||||
|
|
||||||
self->pixel = xcol.pixel;
|
self->pixel = xcol.pixel;
|
||||||
self->allocated = True;
|
|
||||||
|
|
||||||
if (cleancache)
|
if (cleancache)
|
||||||
doCacheCleanup();
|
doCacheCleanup();
|
||||||
|
@ -108,11 +105,9 @@ PyObject *OtkColor_FromRGB(int r, int g, int b, int screen)
|
||||||
|
|
||||||
if (!colorcache) colorcache = PyDict_New();
|
if (!colorcache) colorcache = PyDict_New();
|
||||||
|
|
||||||
self->allocated = False;
|
|
||||||
self->red = r;
|
self->red = r;
|
||||||
self->green = g;
|
self->green = g;
|
||||||
self->blue = b;
|
self->blue = b;
|
||||||
self->pixel = 0;
|
|
||||||
self->screen = screen;
|
self->screen = screen;
|
||||||
|
|
||||||
// does this color already exist in the cache?
|
// 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
|
// add it to the cache
|
||||||
PyDict_SetItem(colorcache, (PyObject*)self, (PyObject*)self);
|
PyDict_SetItem(colorcache, (PyObject*)self, (PyObject*)self);
|
||||||
|
allocate(self);
|
||||||
return (PyObject*)self;
|
return (PyObject*)self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,11 +132,9 @@ PyObject *OtkColor_FromName(const char *name, int screen)
|
||||||
|
|
||||||
if (!colorcache) colorcache = PyDict_New();
|
if (!colorcache) colorcache = PyDict_New();
|
||||||
|
|
||||||
self->allocated = False;
|
|
||||||
self->red = -1;
|
self->red = -1;
|
||||||
self->green = -1;
|
self->green = -1;
|
||||||
self->blue = -1;
|
self->blue = -1;
|
||||||
self->pixel = 0;
|
|
||||||
self->screen = screen;
|
self->screen = screen;
|
||||||
|
|
||||||
parseColorName(self, name);
|
parseColorName(self, name);
|
||||||
|
@ -154,14 +148,8 @@ PyObject *OtkColor_FromName(const char *name, int screen)
|
||||||
|
|
||||||
// add it to the cache
|
// add it to the cache
|
||||||
PyDict_SetItem(colorcache, (PyObject*)self, (PyObject*)self);
|
PyDict_SetItem(colorcache, (PyObject*)self, (PyObject*)self);
|
||||||
return (PyObject*)self;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long OtkColor_Pixel(OtkColor *self)
|
|
||||||
{
|
|
||||||
if (!self->allocated)
|
|
||||||
allocate(self);
|
allocate(self);
|
||||||
return self->pixel;
|
return (PyObject*)self;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OtkColor_CleanupColorCache()
|
void OtkColor_CleanupColorCache()
|
||||||
|
|
|
@ -12,15 +12,12 @@ typedef struct OtkColor {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
int red, green, blue;
|
int red, green, blue;
|
||||||
int screen;
|
int screen;
|
||||||
Bool allocated;
|
|
||||||
unsigned long pixel;
|
unsigned long pixel;
|
||||||
} OtkColor;
|
} OtkColor;
|
||||||
|
|
||||||
PyObject *OtkColor_FromRGB(int r, int g, int b, int screen);
|
PyObject *OtkColor_FromRGB(int r, int g, int b, int screen);
|
||||||
PyObject *OtkColor_FromName(const char *name, int screen);
|
PyObject *OtkColor_FromName(const char *name, int screen);
|
||||||
|
|
||||||
unsigned long OtkColor_Pixel(OtkColor *self);
|
|
||||||
|
|
||||||
void OtkColor_CleanupColorCache();
|
void OtkColor_CleanupColorCache();
|
||||||
|
|
||||||
#endif // __color_h
|
#endif // __color_h
|
||||||
|
|
154
otk_c/font.c
Normal file
154
otk_c/font.c
Normal file
|
@ -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 */
|
||||||
|
};
|
64
otk_c/font.h
Normal file
64
otk_c/font.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// -*- mode: C; indent-tabs-mode: nil; -*-
|
||||||
|
#ifndef __font_h
|
||||||
|
#define __font_h
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#define _XFT_NO_COMPAT_ // no Xft 1 API
|
||||||
|
#include <X11/Xft/Xft.h>
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
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
|
|
@ -5,6 +5,7 @@
|
||||||
#include "screeninfo.h"
|
#include "screeninfo.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "gccache.h"
|
#include "gccache.h"
|
||||||
|
#include "font.h"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
@ -21,10 +22,12 @@ void initotk(char *display)
|
||||||
OtkDisplay_Type.ob_type = &PyType_Type;
|
OtkDisplay_Type.ob_type = &PyType_Type;
|
||||||
OtkScreenInfo_Type.ob_type = &PyType_Type;
|
OtkScreenInfo_Type.ob_type = &PyType_Type;
|
||||||
OtkColor_Type.ob_type = &PyType_Type;
|
OtkColor_Type.ob_type = &PyType_Type;
|
||||||
|
OtkFont_Type.ob_type = &PyType_Type;
|
||||||
|
|
||||||
Py_InitModule("otk", otk_methods);
|
Py_InitModule("otk", otk_methods);
|
||||||
|
|
||||||
OtkDisplay_Initialize(display);
|
OtkDisplay_Initialize(display);
|
||||||
assert(OBDisplay);
|
assert(OBDisplay);
|
||||||
OtkGCCache_Initialize();
|
OtkGCCache_Initialize();
|
||||||
|
OtkFont_Initialize();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue