better font layout
authorDana Jansens <danakj@orodu.net>
Wed, 4 Jun 2003 21:30:17 +0000 (21:30 +0000)
committerDana Jansens <danakj@orodu.net>
Wed, 4 Jun 2003 21:30:17 +0000 (21:30 +0000)
12 files changed:
glft/font.c
glft/glft.h
glft/render.c
render2/font.c
render2/font.h
render2/paint.c
render2/planar.c
render2/planar.h
render2/texture.c
render2/texture.h
render2/theme.c
render2/theme.h

index ba7bbd25ecb6b1582f60603825d10d1b1c29e366..2d641ab658bbac53b23021c50af7bd618bd9e584 100644 (file)
@@ -101,7 +101,7 @@ struct GlftFont *GlftFontOpen(Display *d, int screen, const char *name)
     case FcResultNoMatch:
         font->index = 0;
         break;
-    case FcResultMatch:
+   case FcResultMatch:
         break;
     default:
         GlftDebug("error getting FC_INDEX from pattern\n");
@@ -235,8 +235,10 @@ struct GlftFont *GlftFontOpen(Display *d, int screen, const char *name)
         font->max_advance_width = font->face->size->metrics.max_advance >> 6;
     font->descent = -(font->face->size->metrics.descender >> 6);
     font->ascent = font->face->size->metrics.ascender >> 6;
-    if (font->minspace) font->height = font->ascent + font->descent;
-    else                font->height = font->face->size->metrics.height >> 6;
+    if (font->minspace)
+        font->height = font->ascent + font->descent;
+    else
+        font->height = font->face->size->metrics.height >> 6;
 
     font->kerning = FT_HAS_KERNING(font->face);
 
@@ -336,3 +338,13 @@ int GlftFontMaxCharWidth(struct GlftFont *font)
 {
     return font->max_advance_width;
 }
+
+int GlftFontAscent(struct GlftFont *font)
+{
+    return font->ascent;
+}
+
+int GlftFontDescent(struct GlftFont *font)
+{
+    return font->descent;
+}
index c6c2f00b65d2231bff19faa9d9e75dab5ef0f345..4d57e6b93275fdc177b103722fe65140467a97ed 100644 (file)
@@ -42,6 +42,8 @@ void GlftMeasureString(struct GlftFont *font,
                        int *w,
                        int *h);
 
+int GlftFontAscent(struct GlftFont *font);
+int GlftFontDescent(struct GlftFont *font);
 int GlftFontHeight(struct GlftFont *font);
 int GlftFontMaxCharWidth(struct GlftFont *font);
 
index 3590ad6a3c09937a9770b15129cf00f06aa4778a..7760934627bde33694552cb0639739d589aa09e0 100644 (file)
@@ -56,6 +56,8 @@ static void drawstring(struct GlftFont *font, const char *str, int bytes,
     const char *c;
     struct GlftGlyph *g, *p = NULL;
 
+    y += font->descent - 1; /* XXX why -1? it works tho, it seems.. */
+
     glColor4f(color->r, color->g, color->b, color->a);
     glPushMatrix();
     glTranslatef(x, y, 0.0);
index 44ed55974a4b0030a5ea5430929c17dd18096e44..341d26788dfd86be90377bc2a7fe57176db5f145 100644 (file)
@@ -1,16 +1,29 @@
 #include "render.h"
 #include "instance.h"
+#include "surface.h"
 #include "font.h"
 #include <stdlib.h>
 #include <string.h>
+#include <glib.h>
+
+#define ALPHAS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+               "1234567890`-=\\!@#$%^&*()~_+|[]{};':\",./<>?"
+#define ELIPSES "..."
 
 struct RrFont *RrFontOpen(struct RrInstance *inst, const char *fontstring)
 {
     struct RrFont *font;
+    int w, h;
 
     font = malloc(sizeof(struct RrFont));
     font->inst = inst;
     font->font = GlftFontOpen(RrDisplay(inst), RrScreen(inst), fontstring);
+
+    GlftMeasureString(font->font, ELIPSES, strlen(ELIPSES), &w, &h);
+    font->elipses = w;
+    GlftMeasureString(font->font, ALPHAS, strlen(ALPHAS), &w, &h);
+    font->height = h;
+
     return font;
 }
 
@@ -31,10 +44,81 @@ int RrFontMeasureString(struct RrFont *font, const char *string)
 
 int RrFontHeight(struct RrFont *font)
 {
-    return GlftFontHeight(font->font);
+    return font->height;
 }
 
 int RrFontMaxCharWidth(struct RrFont *font)
 {
     return GlftFontMaxCharWidth(font->font);
 }
+
+void RrFontRenderString(struct RrSurface *sur, struct RrFont *font,
+                        struct RrColor *color, enum RrLayout layout,
+                        const char *string, int x, int y, int w, int h)
+{
+    struct GlftColor col;
+    int fh = RrFontHeight(font);
+    int l, m;
+    GString *text;
+    int shortened = 0;
+
+    switch (layout) {
+    case RR_TOP_LEFT:
+    case RR_TOP:
+    case RR_TOP_RIGHT:
+        y += h - fh;
+        break;
+    case RR_LEFT:
+    case RR_CENTER:
+    case RR_RIGHT:
+        y += (h - fh) / 2;
+        break;
+    case RR_BOTTOM_LEFT:
+    case RR_BOTTOM:
+    case RR_BOTTOM_RIGHT:
+        break;
+    }
+
+    text = g_string_new(string);
+    l = g_utf8_strlen(text->str, -1);
+    m = RrFontMeasureString(font, text->str);
+    if (font->elipses > w)
+        l = 0; /* nothing fits.. */
+    else {
+        while (l && m > w) {
+            shortened = 1;
+            /* remove a character from the middle */
+            text = g_string_erase(text, l-- / 2, 1);
+            /* if the elipses are too large, don't show them at all */
+            m = RrFontMeasureString(font, text->str) + font->elipses;
+        }
+        if (shortened) {
+            text = g_string_insert(text, (l + 1) / 2, ELIPSES);
+            l += 3;
+        }
+    }
+    if (!l) return;
+
+    switch (layout) {
+    case RR_TOP_LEFT:
+    case RR_LEFT:
+    case RR_BOTTOM_LEFT:
+        break;
+    case RR_TOP:
+    case RR_CENTER:
+    case RR_BOTTOM:
+        x += (w - m) / 2;
+        break;
+    case RR_TOP_RIGHT:
+    case RR_RIGHT:
+    case RR_BOTTOM_RIGHT:
+        x += w - m;
+        break;
+    }
+
+    col.r = color->r;
+    col.g = color->g;
+    col.b = color->b;
+    col.a = color->a;
+    GlftRenderString(font->font, text->str, strlen(text->str), &col, x, y);
+}
index f73e4790adb88c17b2c9e717f368827a26c3fdfb..33e45a4f13bf9ac18e345de60d6e690c449fed7f 100644 (file)
@@ -8,6 +8,15 @@ struct RrInstance;
 struct RrFont {
     struct RrInstance *inst;
     struct GlftFont *font;
+
+    int height;
+    int elipses;
 };
 
+#define RrFontElipsesLength(f) ((f)->elipses)
+
+void RrFontRenderString(struct RrSurface *sur, struct RrFont *font,
+                        struct RrColor *color, enum RrLayout layout,
+                        const char *string, int x, int y, int w, int h);
+
 #endif
index e22f1f2062898d88bb4018f2c2b490eb5d134755..1981072fba7b1219276029f20e3352a6a483dfdd 100644 (file)
@@ -72,6 +72,7 @@ void RrPaint(struct RrSurface *sur, int recurse_always)
     struct RrSurface *p;
     int ok, i;
     int surx, sury;
+    int x, y, w, h, e;
     GSList *it;
 
     inst = RrSurfaceInstance(sur);
@@ -82,8 +83,6 @@ void RrPaint(struct RrSurface *sur, int recurse_always)
 
     if (!RrSurfaceVisible(sur)) return;
 
-    g_message("PAINTING SURFACE %p", sur);
-
     ok = glXMakeCurrent(RrDisplay(inst), RrSurfaceWindow(sur),RrContext(inst));
     assert(ok);
 
@@ -99,8 +98,7 @@ void RrPaint(struct RrSurface *sur, int recurse_always)
 */
 
     glPushMatrix();
-    glTranslatef(-RrSurfaceX(sur),
-                 -RrSurfaceY(sur), 0);
+    glTranslatef(-RrSurfaceX(sur), -RrSurfaceY(sur), 0);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
     p = sur;
@@ -114,16 +112,25 @@ void RrPaint(struct RrSurface *sur, int recurse_always)
     switch (RrSurfaceType(sur)) {
     case RR_SURFACE_PLANAR:
         RrPlanarPaint(sur, surx, sury);
+        e = RrPlanarEdgeWidth(sur);
+        x = RrSurfaceX(sur) + e;
+        y = RrSurfaceY(sur) + e;
+        w = RrSurfaceWidth(sur) - e * 2;
+        h = RrSurfaceHeight(sur) - e * 2;
         break;
     case RR_SURFACE_NONPLANAR:
         assert(0);
         break;
     case RR_SURFACE_NONE:
+        x = RrSurfaceX(sur);
+        y = RrSurfaceY(sur);
+        w = RrSurfaceWidth(sur);
+        h = RrSurfaceHeight(sur);
         break;
     }
 
     for (i = 0; i < sur->ntextures; ++i)
-        RrTexturePaint(sur, &sur->texture[i]);
+        RrTexturePaint(sur, &sur->texture[i], x, y, w, h);
 
     glPopMatrix();
 
index 2f9ce6707a17e88ee9c4806821a30fcf5064d0b0..ab3f252e78d6a30454234475f4cc935bda110c4c 100644 (file)
@@ -351,27 +351,30 @@ void RrPlanarPaint(struct RrSurface *sur, int absx, int absy)
                       RrPlanarBorderWidth(sur), &RrPlanarBorderColor(sur));
 }
 
-void RrPlanarMinSize(struct RrSurface *sur, int *w, int *h)
+int RrPlanarEdgeWidth(struct RrSurface *sur)
 {
-    *w = *h = RrPlanarBorderWidth(sur);
+    int w;
+    w = RrPlanarBorderWidth(sur);
     switch (RrPlanarBevelType(sur)) {
     case RR_SUNKEN_OUTER:
-        (*w)++;
-        (*h)++;
+        w++;
         break;
     case RR_SUNKEN_INNER:
-        (*w)+=2;
-        (*h)+=2;
+        w += 2;
         break;
     case RR_RAISED_OUTER:
-        (*w)++;
-        (*h)++;
+        w += 2;
         break;
     case RR_RAISED_INNER:
-        (*w)+=2;
-        (*h)+=2;
+        w++;
         break;
     case RR_BEVEL_NONE:
         break;
     }
+    return w;
+}
+
+void RrPlanarMinSize(struct RrSurface *sur, int *w, int *h)
+{
+    *w = *h = 2 * RrPlanarEdgeWidth(sur);
 }
index acaae8120404b150b754f3768909222d0be1f120..0cd52f6b21d8cc6633c85df022e02fa697234eb5 100644 (file)
@@ -27,4 +27,6 @@ void RrPlanarPaint(struct RrSurface *sur, int absx, int absy);
 
 void RrPlanarMinSize(struct RrSurface *sur, int *w, int *h);
 
+int RrPlanarEdgeWidth(struct RrSurface *sur);
+
 #endif
index 54062fd59c2177c172b99f21f1f694341b8971d1..01b224ad9f1d5af6d2ecb8634f7db2b299ba9a54 100644 (file)
@@ -84,25 +84,18 @@ void RrTextureSetNone(struct RrSurface *sur,
     RrTextureFreeContents(tex);
 }
 
-void RrTexturePaint(struct RrSurface *sur, struct RrTexture *tex)
+void RrTexturePaint(struct RrSurface *sur, struct RrTexture *tex,
+                    int x, int y, int w, int h)
 {
-    struct GlftColor col;
-
     glEnable(GL_TEXTURE_2D);
     
     switch (tex->type) {
     case RR_TEXTURE_NONE:
         break;
     case RR_TEXTURE_TEXT:
-        assert(tex->data.text.font);
-        col.r = tex->data.text.color.r;
-        col.g = tex->data.text.color.g;
-        col.b = tex->data.text.color.b;
-        col.a = tex->data.text.color.a;
-
-        GlftRenderString(tex->data.text.font->font, tex->data.text.string, 
-                         strlen(tex->data.text.string), &col,
-                         RrSurfaceX(sur) + 2, RrSurfaceY(sur) + 4);
+        RrFontRenderString(sur, tex->data.text.font, &tex->data.text.color,
+                           tex->data.text.layout, tex->data.text.string,
+                           x, y, w, h);
         break;
     }
     glDisable(GL_TEXTURE_2D);
index 5d535e3befe50a2fc5b5f79f23a5501189cbae66..a98efef124678061134d2abcae57bda37d6f2b7a 100644 (file)
@@ -39,6 +39,7 @@ struct RrTexture {
     union RrTextureData data;
 };
 
-void RrTexturePaint(struct RrSurface *sur, struct RrTexture *tex);
+void RrTexturePaint(struct RrSurface *sur, struct RrTexture *tex,
+                    int x, int y, int w, int h);
 
 #endif
index 9539902cac1e24731901a99947c263e6678e655b..144a7bcbd754570de5293b14cdfb0cf7b836c999 100644 (file)
@@ -1,5 +1,6 @@
 #include "render.h"
 #include "theme.h"
+#include "planar.h"
 #include <stdlib.h>
 
 struct RrTheme *RrThemeLoad(struct RrInstance *inst, const char *name)
@@ -308,3 +309,12 @@ void RrThemeDestroy(struct RrTheme *theme)
         free(theme);
     }
 }
+
+int RrThemeLabelHeight(struct RrTheme *t)
+{
+    int h;
+    h = RrFontHeight(t->title_font);
+    h += 2 * MAX(RrPlanarEdgeWidth(t->label),
+                 RrPlanarEdgeWidth(t->label_f));
+    return h;
+}
index 6637b948ff203f889ebc45f3cd3bba717154b7c8..718d8b5bcf7754e14717032bc0fa09b80f5343b0 100644 (file)
@@ -92,7 +92,7 @@ struct RrTheme {
     struct RrSurface *app_icon;
 };
 
-#define RrThemeLabelHeight(t) (RrFontHeight((t)->title_font))
+int RrThemeLabelHeight(struct RrTheme *t);
 #define RrThemeTitleHeight(t) (RrThemeLabelHeight(t) + \
                                ((t)->bevel + (t)->bwidth) * 2)
 #define RrThemeButtonSize(t)  (RrThemeLabelHeight(t) - (t)->bevel * 2)