]> icculus.org git repositories - dana/openbox.git/blob - glft/render.c
use RrPlanarHasAlpha to determine if parent should be copied
[dana/openbox.git] / glft / render.c
1 #include "render.h"
2 #include "font.h"
3 #include "debug.h"
4 #include "glft.h"
5 #include <glib.h>
6 #include <GL/glx.h>
7
8 #define TPOINTS 15.0
9
10 #define TOFLOAT(x) (((x) >> 6) + ((x) & 63)/64.0)
11
12 void GlftRenderGlyph(FT_Face face, struct GlftGlyph *g)
13 {
14     unsigned char *padbuf;
15     int err, i;
16     FT_GlyphSlot slot = face->glyph;
17
18     err = FT_Render_Glyph(slot, ft_render_mode_normal);
19         g_assert(!err);
20
21     g->texw = slot->bitmap.width;
22     g->texh = slot->bitmap.rows;
23
24     g->left = slot->bitmap_left;
25
26     g->yoff = slot->bitmap.rows - slot->bitmap_top;
27     g->padx = 1;
28     while (g->padx < slot->bitmap.width)
29        g->padx <<= 1;
30
31     g->pady = 1;
32     while (g->pady < slot->bitmap.rows)
33        g->pady <<= 1;
34
35     padbuf = g_new0(unsigned char, g->padx * g->pady);
36     for (i = 0; i < slot->bitmap.rows; i++)
37         memcpy(padbuf + i*g->padx,
38                slot->bitmap.buffer + i*slot->bitmap.width,
39                slot->bitmap.width);
40     glBindTexture(GL_TEXTURE_2D, g->tnum);
41     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
42     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
43     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
44     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
45     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
46     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
47     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, g->padx, g->pady,
48                  0, GL_ALPHA, GL_UNSIGNED_BYTE, padbuf);
49
50     g_free(padbuf);
51 }
52
53 void GlftRenderString(struct GlftFont *font, const char *str, int bytes,
54                       struct GlftColor *color, int x, int y)
55 {
56     const char *c;
57     struct GlftGlyph *g, *p = NULL;
58
59     if (!g_utf8_validate(str, bytes, NULL)) {
60         GlftDebug("Invalid UTF-8 in string\n");
61         return;
62     }
63
64     glColor4f(color->r, color->g, color->b, color->a);
65     glPushMatrix();
66     glTranslatef(x, y, 0.0);
67     c = str;
68     while (c - str < bytes) {
69         g = GlftFontGlyph(font, c);
70         if (g) {
71             glTranslatef(GlftFontAdvance(font, p, g), 0.0, 0.0);
72             glBindTexture(GL_TEXTURE_2D, g->tnum);
73
74             glBegin(GL_QUADS);
75
76             glTexCoord2f(0, g->texh/(float)g->pady);
77             glVertex2i(g->left, 0 - g->yoff);
78
79             glTexCoord2f(g->texw/(float)g->padx, g->texh/(float)g->pady);
80             glVertex2i(g->left + g->texw, 0 - g->yoff);
81
82             glTexCoord2f(g->texw/(float)g->padx, 0);
83             glVertex2i(g->left + g->texw, g->texh - g->yoff);
84
85             glTexCoord2f(0, 0);
86             glVertex2i(g->left, g->texh - g->yoff);
87             glEnd();
88         } else
89             glTranslatef(font->max_advance_width, 0.0, 0.0);
90         p = g;
91         c = g_utf8_next_char(c);
92     }
93
94     glPopMatrix();
95 }
96
97 void GlftMeasureString(struct GlftFont *font,
98                        const char *str,
99                        int bytes,
100                        int *w,
101                        int *h)
102 {
103     const char *c;
104     struct GlftGlyph *g, *p = NULL;
105
106     if (!g_utf8_validate(str, bytes, NULL)) {
107         GlftDebug("Invalid UTF-8 in string\n");
108         return;
109     }
110
111     *w = 0;
112     *h = 0;
113
114     c = str;
115     while (c - str < bytes) {
116         g = GlftFontGlyph(font, c);
117         if (g) {
118             *w += GlftFontAdvance(font, p, g);
119             *h = MAX(g->height, *h);
120         } else
121             *w += font->max_advance_width;
122         p = g;
123         c = g_utf8_next_char(c);
124     }
125 }