1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include "fb.h"
#include "mipict.h"
#include "glyph_assemble.h"
#include "glyph_cache.h"
#include "glyph_extents.h"
static size_t glyph_list_count(int nlist, GlyphListPtr list)
{
size_t total = 0;
while (nlist--) {
total += list->len;
list++;
}
return total;
}
int glyphs_assemble(ScreenPtr pScreen, struct glyph_render **gp,
BoxPtr extents, int nlist, GlyphListPtr list, GlyphPtr *glyphs)
{
struct glyph_render *gr, *grp;
int x, y, total;
/*
* Preload the cache with the glyphs which we intend to use.
* This means we can avoid having to reset the destination
* for the PictOpAdd below. If this fails, fallback.
*/
if (!glyph_cache_preload(pScreen, nlist, list, glyphs))
return -1;
GlyphExtents(nlist, list, glyphs, extents);
if (extents->x2 <= extents->x1 || extents->y2 <= extents->y1)
return 0;
total = glyph_list_count(nlist, list);
gr = malloc(sizeof(struct glyph_render) * total);
if (!gr)
return -1;
x = -extents->x1;
y = -extents->y1;
grp = gr;
while (nlist--) {
int n = list->len;
x += list->xOff;
y += list->yOff;
while (n--) {
GlyphPtr glyph = *glyphs++;
if (glyph->info.width && glyph->info.height) {
grp->dest_box.x1 = x - glyph->info.x;
grp->dest_box.y1 = y - glyph->info.y;
grp->dest_box.x2 = grp->dest_box.x1 +
glyph->info.width;
grp->dest_box.y2 = grp->dest_box.y1 +
glyph->info.height;
grp->picture = glyph_cache_only(pScreen, glyph,
&grp->glyph_pos);
if (!grp->picture) {
free(gr);
return -1;
}
grp++;
}
x += glyph->info.xOff;
y += glyph->info.yOff;
}
list++;
}
*gp = gr;
return grp - gr;
}
|