add font
authorDana Jansens <danakj@orodu.net>
Sat, 21 Dec 2002 13:49:57 +0000 (13:49 +0000)
committerDana Jansens <danakj@orodu.net>
Sat, 21 Dec 2002 13:49:57 +0000 (13:49 +0000)
otk_c/Makefile
otk_c/color.c
otk_c/color.h
otk_c/font.c [new file with mode: 0644]
otk_c/font.h [new file with mode: 0644]
otk_c/init.c

index 2e0589d..397227e 100644 (file)
@@ -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
 
index 4ecca30..732f7b7 100644 (file)
@@ -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;
index 143429a..b8dff22 100644 (file)
@@ -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 (file)
index 0000000..7c9b4f5
--- /dev/null
@@ -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 (file)
index 0000000..637a215
--- /dev/null
@@ -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
index 5f576ac..a958c4f 100644 (file)
@@ -5,6 +5,7 @@
 #include "screeninfo.h"
 #include "color.h"
 #include "gccache.h"
+#include "font.h"
 
 #include <X11/Xlib.h>
 #include <Python.h>
@@ -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();
 }