diff options
Diffstat (limited to 'src/font.c')
-rw-r--r-- | src/font.c | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/src/font.c b/src/font.c new file mode 100644 index 0000000..8ebf19a --- /dev/null +++ b/src/font.c @@ -0,0 +1,295 @@ +/**************************************************************************** + * Functions to load fonts. + * Copyright (C) 2004 Joe Wingbermuehle + ****************************************************************************/ + +#include "jwm.h" +#include "font.h" +#include "main.h" +#include "error.h" +#include "color.h" +#include "misc.h" + +static const char *DEFAULT_FONT = "-*-courier-*-r-*-*-14-*-*-*-*-*-*-*"; + +static char *fontNames[FONT_COUNT]; + +#ifdef USE_XFT +static XftFont *fonts[FONT_COUNT]; +#else +static XFontStruct *fonts[FONT_COUNT]; +static GC fontGC; +#endif + +/**************************************************************************** + ****************************************************************************/ +void InitializeFonts() { + + int x; + + for(x = 0; x < FONT_COUNT; x++) { + fonts[x] = NULL; + fontNames[x] = NULL; + } + +} + +/**************************************************************************** + ****************************************************************************/ +void StartupFonts() { + +#ifndef USE_XFT + XGCValues gcValues; + unsigned long gcMask; +#endif + int x; + + /* Inherit unset fonts from the tray for tray items. */ + if(!fontNames[FONT_TASK]) { + fontNames[FONT_TASK] = CopyString(fontNames[FONT_TRAY]); + } + if(!fontNames[FONT_TRAYBUTTON]) { + fontNames[FONT_TRAYBUTTON] = CopyString(fontNames[FONT_TRAY]); + } + if(!fontNames[FONT_CLOCK]) { + fontNames[FONT_CLOCK] = CopyString(fontNames[FONT_TRAY]); + } + +#ifdef USE_XFT + + for(x = 0; x < FONT_COUNT; x++) { + if(fontNames[x]) { + fonts[x] = JXftFontOpenName(display, rootScreen, fontNames[x]); + if(!fonts[x]) { + fonts[x] = JXftFontOpenXlfd(display, rootScreen, fontNames[x]); + } + if(!fonts[x]) { + Warning("could not load font: %s", fontNames[x]); + } + } + if(!fonts[x]) { + fonts[x] = JXftFontOpenXlfd(display, rootScreen, DEFAULT_FONT); + } + if(!fonts[x]) { + FatalError("could not load the default font: %s", DEFAULT_FONT); + } + } + +#else + + for(x = 0; x < FONT_COUNT; x++) { + if(fontNames[x]) { + fonts[x] = JXLoadQueryFont(display, fontNames[x]); + if(!fonts[x] && fontNames[x]) { + Warning("could not load font: %s", fontNames[x]); + } + } + if(!fonts[x]) { + fonts[x] = JXLoadQueryFont(display, DEFAULT_FONT); + } + if(!fonts[x]) { + FatalError("could not load the default font: %s", DEFAULT_FONT); + } + } + + gcMask = GCGraphicsExposures; + gcValues.graphics_exposures = False; + fontGC = JXCreateGC(display, rootWindow, gcMask, &gcValues); + +#endif + +} + +/**************************************************************************** + ****************************************************************************/ +void ShutdownFonts() { + + int x; + + for(x = 0; x < FONT_COUNT; x++) { + if(fonts[x]) { +#ifdef USE_XFT + JXftFontClose(display, fonts[x]); +#else + JXFreeFont(display, fonts[x]); +#endif + fonts[x] = NULL; + } + } + +#ifndef USE_XFT + + JXFreeGC(display, fontGC); + +#endif + + +} + +/**************************************************************************** + ****************************************************************************/ +void DestroyFonts() { + + int x; + + for(x = 0; x < FONT_COUNT; x++) { + if(fontNames[x]) { + Release(fontNames[x]); + fontNames[x] = NULL; + } + } + +} + +/**************************************************************************** + ****************************************************************************/ +int GetStringWidth(FontType type, const char *str) { +#ifdef USE_XFT + + XGlyphInfo extents; + unsigned int length; + + Assert(str); + Assert(fonts[type]); + + length = strlen(str); + + JXftTextExtentsUtf8(display, fonts[type], (const unsigned char*)str, + length, &extents); + + return extents.width; + +#else + + Assert(str); + Assert(fonts[type]); + + return XTextWidth(fonts[type], str, strlen(str)); + +#endif +} + +/**************************************************************************** + ****************************************************************************/ +int GetStringHeight(FontType type) { + + Assert(fonts[type]); + + return fonts[type]->ascent + fonts[type]->descent; + +} + +/**************************************************************************** + ****************************************************************************/ +void SetFont(FontType type, const char *value) { + + if(!value) { + Warning("empty Font tag"); + return; + } + + if(fontNames[type]) { + Release(fontNames[type]); + } + + fontNames[type] = CopyString(value); + +} + +/**************************************************************************** + ****************************************************************************/ +void RenderString(Drawable d, FontType font, ColorType color, + int x, int y, int width, Region region, const char *str) { + +#ifdef USE_XFT + XftDraw *xd; +#endif + + XRectangle rect; + Region renderRegion; + int len; + char *output; + +#ifdef USE_FRIBIDI + + FriBidiChar *temp; + FriBidiCharType type = FRIBIDI_TYPE_ON; + int unicodeLength; + +#endif + + if(!str) { + return; + } + + len = strlen(str); + if(len == 0) { + return; + } + + /* Get the bounds for the string based on the specified width. */ + rect.x = x; + rect.y = y; + rect.width = Min(GetStringWidth(font, str), width) + 2; + rect.height = GetStringHeight(font); + + /* Create a region to use. */ + renderRegion = XCreateRegion(); + + /* Combine the width bounds with the region to use. */ + XUnionRectWithRegion(&rect, renderRegion, renderRegion); + + /* Combine the provided region with the region to use. */ + if(region) { + XIntersectRegion(region, renderRegion, renderRegion); + } + + /* Apply the bidi algorithm if requested. */ + +#ifdef USE_FRIBIDI + + temp = AllocateStack((len + 1) * sizeof(FriBidiChar)); + unicodeLength = fribidi_utf8_to_unicode((char*)str, len, temp); + + fribidi_log2vis(temp, unicodeLength, &type, temp, NULL, NULL, NULL); + + fribidi_unicode_to_utf8(temp, len, (char*)temp); + output = (char*)temp; + +#else + + output = (char*)str; + +#endif + + /* Display the string. */ + +#ifdef USE_XFT + + xd = XftDrawCreate(display, d, rootVisual, rootColormap); + XftDrawSetClip(xd, renderRegion); + JXftDrawStringUtf8(xd, GetXftColor(color), fonts[font], + x, y + fonts[font]->ascent, (const unsigned char*)output, len); + XftDrawDestroy(xd); + +#else + + JXSetForeground(display, fontGC, colors[color]); + XSetRegion(display, fontGC, renderRegion); + JXSetFont(display, fontGC, fonts[font]->fid); + JXDrawString(display, d, fontGC, x, y + fonts[font]->ascent, output, len); + +#endif + + /* Free any memory used for UTF conversion. */ + +#ifdef USE_FRIBIDI + + ReleaseStack(output); + +#endif + + XDestroyRegion(renderRegion); + +} + |