start on otk::ustring (unicode/utf8)
[mikachu/openbox.git] / otk_c / font.c
1 // -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #include "../config.h"
4 #include "font.h"
5 #include "display.h"
6 #include "color.h"
7
8 #include "../src/gettext.h"
9
10 static Bool xft_init = False;
11 static const char *fallback = "fixed";
12
13 void OtkFont_Initialize()
14 {
15   if (!XftInit(0)) {
16     printf(_("Couldn't initialize Xft version %d.%d.%d.\n\n"),
17            XFT_MAJOR, XFT_MINOR, XFT_REVISION);
18     exit(3);
19   }
20   printf(_("Using Xft %d.%d.%d.\n"), XFT_MAJOR, XFT_MINOR, XFT_REVISION);
21   xft_init = True;
22 }
23
24 PyObject *OtkFont_New(int screen, const char *fontstring, Bool shadow,
25                       unsigned char offset, unsigned char tint)
26 {
27   OtkFont *self = PyObject_New(OtkFont, &OtkFont_Type);
28
29   assert(xft_init);
30   assert(screen >= 0);
31   assert(fontstring);
32   
33   self->screen = screen;
34   self->shadow = shadow;
35   self->offset = offset;
36   self->tint   = tint;
37
38   if (!(self->xftfont = XftFontOpenName(OBDisplay->display, screen,
39                                         fontstring))) {
40     printf(_("Unable to load font: %s"), fontstring);
41     printf(_("Trying fallback font: %s\n"), fallback);
42     if (!(self->xftfont =
43           XftFontOpenName(OBDisplay->display, screen, fallback))) {
44       printf(_("Unable to load font: %s"), fallback);
45       printf(_("Aborting!.\n"));
46       
47       exit(3); // can't continue without a font
48     }
49   }
50
51   return (PyObject*)self;
52 }
53
54 int OtkFont_MeasureString(OtkFont *self, const char *string)//, Bool utf8)
55 {
56   XGlyphInfo info;
57
58 /*  if (utf8)*/
59     XftTextExtentsUtf8(OBDisplay->display, self->xftfont,
60                        (const FcChar8*)string, strlen(string), &info);
61 /*  else
62     XftTextExtents8(OBDisplay->display, self->xftfont,
63     (const FcChar8*)string, strlen(string), &info);*/
64
65   return info.xOff + (self->shadow ? self->offset : 0);
66 }
67
68 void OtkFont_DrawString(OtkFont *self, XftDraw *d, int x, int y,
69                         OtkColor *color, const char *string)//, Bool utf8)
70 {
71   assert(self);
72   assert(d);
73
74   if (self->shadow) {
75     XftColor c;
76     c.color.red = 0;
77     c.color.green = 0;
78     c.color.blue = 0;
79     c.color.alpha = self->tint | self->tint << 8; // transparent shadow
80     c.pixel = BlackPixel(OBDisplay->display, self->screen);
81
82 /*    if (utf8)*/
83       XftDrawStringUtf8(d, &c, self->xftfont, x + self->offset,
84                         self->xftfont->ascent + y + self->offset,
85                         (const FcChar8*)string, strlen(string));
86 /*    else
87       XftDrawString8(d, &c, self->xftfont, x + self->offset,
88                      self->xftfont->ascent + y + self->offset,
89                      (const FcChar8*)string, strlen(string));*/
90   }
91     
92   XftColor c;
93   c.color.red   = color->red   | color->red   << 8;
94   c.color.green = color->green | color->green << 8;
95   c.color.blue  = color->blue  | color->blue  << 8;
96   c.pixel = color->pixel;
97   c.color.alpha = 0xff | 0xff << 8; // no transparency in BColor yet
98
99 /*  if (utf8)*/
100     XftDrawStringUtf8(d, &c, self->xftfont, x, self->xftfont->ascent + y,
101                       (const FcChar8*)string, strlen(string));
102 /*  else
103     XftDrawString8(d, &c, self->xftfont, x, self->xftfont->ascent + y,
104     (const FcChar8*)string, strlen(string));*/
105 }
106
107
108
109
110 static PyObject *otkfont_measurestring(OtkFont* self, PyObject* args)
111 {
112   char *s;
113   
114   if (!PyArg_ParseTuple(args, "s", &s))
115     return NULL;
116   return PyInt_FromLong(OtkFont_MeasureString(self, s));
117 }
118
119 static PyMethodDef get_methods[] = {
120   {"measureString", (PyCFunction)otkfont_measurestring, METH_VARARGS,
121    "Measure the length of a string with a font."},
122   {NULL, NULL, 0, NULL}
123 };
124
125
126 static void otkfont_dealloc(OtkFont* self)
127 {
128   // this is always set. cuz if it failed.. the app would exit!
129   XftFontClose(OBDisplay->display, self->xftfont);
130   PyObject_Del((PyObject*)self);
131 }
132
133 static PyObject *otkfont_getattr(PyObject *obj, char *name)
134 {
135   return Py_FindMethod(get_methods, obj, name);
136 }
137
138 PyTypeObject OtkFont_Type = {
139   PyObject_HEAD_INIT(NULL)
140   0,
141   "OtkFont",
142   sizeof(OtkFont),
143   0,
144   (destructor)otkfont_dealloc,  /*tp_dealloc*/
145   0,                            /*tp_print*/
146   otkfont_getattr,              /*tp_getattr*/
147   0,                            /*tp_setattr*/
148   0,                            /*tp_compare*/
149   0,                            /*tp_repr*/
150   0,                            /*tp_as_number*/
151   0,                            /*tp_as_sequence*/
152   0,                            /*tp_as_mapping*/
153   0,                            /*tp_hash */
154 };