aboutsummaryrefslogtreecommitdiff
path: root/src/font.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/font.c')
-rw-r--r--src/font.c295
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);
+
+}
+