7c3dd6c4cf88ed15756aad4794fe6ffc9585aca5
[framework/uifw/evas.git] / src / modules / engines / gl_common / evas_gl_font.c
1 #include "evas_gl_private.h"
2
3 void *
4 evas_gl_font_texture_new(void *context, RGBA_Font_Glyph *fg)
5 {
6    Evas_Engine_GL_Context *gc = context;
7    Evas_GL_Texture *tex;
8    DATA8 *data;
9    int w, h, j, nw;
10    DATA8 *ndata;
11    int fh;
12
13    if (fg->ext_dat) return fg->ext_dat; // FIXME: one engine at a time can do this :(
14
15    w = fg->glyph_out->bitmap.width;
16    h = fg->glyph_out->bitmap.rows;
17    if ((w == 0) || (h == 0)) return NULL;
18
19    data = fg->glyph_out->bitmap.buffer;
20    j = fg->glyph_out->bitmap.pitch;
21    if (j < w) j = w;
22
23    nw = ((w + 3) / 4) * 4;
24    ndata = alloca(nw *h);
25    if (!ndata) return NULL;
26    if (fg->glyph_out->bitmap.num_grays == 256)
27      {
28         int x, y;
29         DATA8 *p1, *p2;
30
31         for (y = 0; y < h; y++)
32           {
33              p1 = data + (j * y);
34              p2 = ndata + (nw * y);
35              for (x = 0; x < w; x++)
36                {
37                   *p2 = *p1;
38                   p1++;
39                   p2++;
40                }
41           }
42      }
43    else if (fg->glyph_out->bitmap.num_grays == 0)
44      {
45         DATA8 *tmpbuf = NULL, *dp, *tp, bits;
46         int bi, bj, end;
47         const DATA8 bitrepl[2] = {0x0, 0xff};
48
49         tmpbuf = alloca(w);
50         if (tmpbuf)
51           {
52              int x, y;
53              DATA8 *p1, *p2;
54
55              for (y = 0; y < h; y++)
56                {
57                   p1 = tmpbuf;
58                   p2 = ndata + (nw * y);
59                   tp = tmpbuf;
60                   dp = data + (y * fg->glyph_out->bitmap.pitch);
61                   for (bi = 0; bi < w; bi += 8)
62                     {
63                        bits = *dp;
64                        if ((w - bi) < 8) end = w - bi;
65                        else end = 8;
66                        for (bj = 0; bj < end; bj++)
67                          {
68                             *tp = bitrepl[(bits >> (7 - bj)) & 0x1];
69                             tp++;
70                          }
71                        dp++;
72                     }
73                   for (x = 0; x < w; x++)
74                     {
75                        *p2 = *p1;
76                        p1++;
77                        p2++;
78                     }
79                }
80           }
81      }
82 //   fh = h;
83    fh = fg->fi->max_h;
84    tex = evas_gl_common_texture_alpha_new(gc, ndata, w, h, fh);
85    tex->sx1 = ((double)(tex->x)) / (double)tex->pt->w;
86    tex->sy1 = ((double)(tex->y)) / (double)tex->pt->h;
87    tex->sx2 = ((double)(tex->x + tex->w)) / (double)tex->pt->w;
88    tex->sy2 = ((double)(tex->y + tex->h)) / (double)tex->pt->h;
89    return tex;
90 }
91
92 void
93 evas_gl_font_texture_free(void *tex)
94 {
95    if (!tex) return;
96    evas_gl_common_texture_free(tex);
97 }
98
99 void
100 evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_context, RGBA_Font_Glyph *fg, int x, int y)
101 {
102    Evas_Engine_GL_Context *gc = context;
103    RGBA_Draw_Context *dc = draw_context;
104    Evas_GL_Texture *tex;
105    Cutout_Rects *rects;
106    Cutout_Rect  *rct;
107    int r, g, b, a;
108    double ssx, ssy, ssw, ssh;
109    int c, cx, cy, cw, ch;
110    int i;
111    int sx, sy, sw, sh;
112
113    if (dc != gc->dc) return;
114    tex = fg->ext_dat;
115    if (!tex) return;
116    a = (dc->col.col >> 24) & 0xff;
117    if (a == 0) return;
118    r = (dc->col.col >> 16) & 0xff;
119    g = (dc->col.col >> 8 ) & 0xff;
120    b = (dc->col.col      ) & 0xff;
121    sx = 0; sy = 0; sw = tex->w, sh = tex->h;
122    if ((!gc->dc->cutout.rects)
123 //       || (gc->dc->cutout.active > 32)
124        )
125      {
126         if (gc->dc->clip.use)
127           {
128              int nx, ny, nw, nh;
129
130              nx = x; ny = y; nw = tex->w; nh = tex->h;
131              RECTS_CLIP_TO_RECT(nx, ny, nw, nh,
132                                 gc->dc->clip.x, gc->dc->clip.y,
133                                 gc->dc->clip.w, gc->dc->clip.h);
134              if ((nw < 1) || (nh < 1)) return;
135              if ((nx == x) && (ny == y) && (nw == tex->w) && (nh == tex->h))
136                {
137                   evas_gl_common_context_font_push(gc, tex,
138                                                    0.0, 0.0, 0.0, 0.0,
139 //                                                   sx, sy, sw, sh,
140                                                    x, y, tex->w, tex->h,
141                                                    r, g, b, a);
142                   return;
143                }
144              ssx = (double)sx + ((double)(sw * (nx - x)) / (double)(tex->w));
145              ssy = (double)sy + ((double)(sh * (ny - y)) / (double)(tex->h));
146              ssw = ((double)sw * (double)(nw)) / (double)(tex->w);
147              ssh = ((double)sh * (double)(nh)) / (double)(tex->h);
148              evas_gl_common_context_font_push(gc, tex,
149                                               ssx, ssy, ssw, ssh,
150                                               nx, ny, nw, nh,
151                                               r, g, b, a);
152           }
153         else
154           {
155              evas_gl_common_context_font_push(gc, tex,
156                                               0.0, 0.0, 0.0, 0.0,
157 //                                              sx, sy, sw, sh,
158                                               x, y, tex->w, tex->h,
159                                               r, g, b, a);
160           }
161         return;
162      }
163    /* save out clip info */
164    c = gc->dc->clip.use; cx = gc->dc->clip.x; cy = gc->dc->clip.y; cw = gc->dc->clip.w; ch = gc->dc->clip.h;
165    evas_common_draw_context_clip_clip(gc->dc, 0, 0, gc->w, gc->h);
166    evas_common_draw_context_clip_clip(gc->dc, x, y, tex->w, tex->h);
167    /* our clip is 0 size.. abort */
168    if ((gc->dc->clip.w <= 0) || (gc->dc->clip.h <= 0))
169      {
170         gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
171         return;
172      }
173    rects = evas_common_draw_context_apply_cutouts(dc);
174    for (i = 0; i < rects->active; ++i)
175      {
176         int nx, ny, nw, nh;
177
178         rct = rects->rects + i;
179         nx = x; ny = y; nw = tex->w; nh = tex->h;
180         RECTS_CLIP_TO_RECT(nx, ny, nw, nh, rct->x, rct->y, rct->w, rct->h);
181         if ((nw < 1) || (nh < 1)) continue;
182         if ((nx == x) && (ny == y) && (nw == tex->w) && (nh == tex->h))
183           {
184              evas_gl_common_context_font_push(gc, tex,
185                                               0.0, 0.0, 0.0, 0.0,
186 //                                              sx, sy, sw, sh,
187                                               x, y, tex->w, tex->h,
188                                               r, g, b, a);
189              continue;
190           }
191         ssx = (double)sx + ((double)(sw * (nx - x)) / (double)(tex->w));
192         ssy = (double)sy + ((double)(sh * (ny - y)) / (double)(tex->h));
193         ssw = ((double)sw * (double)(nw)) / (double)(tex->w);
194         ssh = ((double)sh * (double)(nh)) / (double)(tex->h);
195         evas_gl_common_context_font_push(gc, tex,
196                                          ssx, ssy, ssw, ssh,
197                                          nx, ny, nw, nh,
198                                          r, g, b, a);
199      }
200    evas_common_draw_context_apply_clear_cutouts(rects);
201    /* restore clip info */
202    gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
203 }