aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/engines/common_8/evas_soft8_font.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/lib/engines/common_8/evas_soft8_font.c')
-rw-r--r--libraries/evas/src/lib/engines/common_8/evas_soft8_font.c285
1 files changed, 285 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/engines/common_8/evas_soft8_font.c b/libraries/evas/src/lib/engines/common_8/evas_soft8_font.c
new file mode 100644
index 0000000..8f69b86
--- /dev/null
+++ b/libraries/evas/src/lib/engines/common_8/evas_soft8_font.c
@@ -0,0 +1,285 @@
1#include "evas_common_soft8.h"
2#include "evas_soft8_scanline_blend.c"
3
4EFL_ALWAYS_INLINE void
5_glyph_pt_mask_solid_solid(DATA8 * dst, const DATA8 gry8, const DATA8 * mask)
6{
7 DATA8 alpha = *mask;
8
9 if (alpha == 0xff)
10 *dst = gry8;
11 else if (alpha > 0)
12 {
13 *dst = GRY_8_BLEND_UNMUL(gry8, *dst, alpha);
14 }
15}
16
17static void
18_glyph_scanline_mask_solid_solid(DATA8 * dst,
19 int size, const DATA8 gry8, const DATA8 * mask)
20{
21 DATA8 *start, *end;
22
23 start = dst;
24 pld(start, 0);
25 pld(mask, 0);
26 end = start + (size & ~3);
27
28 while (start < end)
29 {
30 pld(start, 8);
31 pld(mask, 4);
32 UNROLL4(
33 {
34 _glyph_pt_mask_solid_solid(start, gry8, mask);
35 start++; mask++;}
36 );
37 }
38
39 end = start + (size & 3);
40 for (; start < end; start++, mask++)
41 _glyph_pt_mask_solid_solid(start, gry8, mask);
42}
43
44EFL_ALWAYS_INLINE void
45_glyph_pt_mask_transp_solid(DATA8 * dst,
46 DATA8 gry8, DATA8 alpha, const DATA8 * mask)
47{
48 int rel_alpha;
49
50 rel_alpha = *mask;
51 alpha = (alpha * rel_alpha) >> 8;
52 if (alpha == 0)
53 return;
54
55 alpha++;
56
57 *dst = GRY_8_BLEND((gry8 * rel_alpha) >> 8, *dst, alpha);
58}
59
60static void
61_glyph_scanline_mask_transp_solid(DATA8 * dst,
62 int size,
63 const DATA8 gry8,
64 const DATA8 rel_alpha, const DATA8 * mask)
65{
66 DATA8 *start, *end;
67
68 start = dst;
69 pld(start, 0);
70 pld(mask, 0);
71 end = start + (size & ~3);
72
73 while (start < end)
74 {
75 pld(start, 8);
76 pld(mask, 4);
77 UNROLL4(
78 {
79 _glyph_pt_mask_transp_solid(start, gry8, rel_alpha, mask);
80 start++; mask++;}
81 );
82 }
83
84 end = start + (size & 3);
85 for (; start < end; start++, mask++)
86 _glyph_pt_mask_transp_solid(start, gry8, rel_alpha, mask);
87}
88
89static inline void
90_calc_ext(const Soft8_Image * dst, const RGBA_Draw_Context * dc,
91 Eina_Rectangle * ext)
92{
93 EINA_RECTANGLE_SET(ext, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
94
95 if (dc->clip.use)
96 {
97 int v;
98
99 EINA_RECTANGLE_SET(ext, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
100 if (ext->x < 0)
101 {
102 ext->w += ext->x;
103 ext->x = 0;
104 }
105 if (ext->y < 0)
106 {
107 ext->h += ext->y;
108 ext->y = 0;
109 }
110
111 v = dst->cache_entry.w - ext->x;
112 if (ext->w > v)
113 ext->w = v;
114
115 v = dst->cache_entry.h - ext->y;
116 if (ext->h > v)
117 ext->h = v;
118 }
119}
120
121static inline void
122_glyph_scanline(Soft8_Image * dst, const DATA8 * p_mask,
123 const Eina_Rectangle ext, int dx, int dy, int max_x, int max_y,
124 int w, DATA8 alpha, const DATA8 gry8)
125{
126 int size, in_x, in_w;
127 DATA8 *p_pixels;
128
129 if ((dx >= max_x) || (dy < ext.y) || (dy >= max_y))
130 return;
131
132 in_x = 0;
133 in_w = 0;
134
135 if (dx + w > max_x)
136 in_w += (dx + w) - max_x;
137
138 if (dx < ext.x)
139 {
140 in_w += ext.x - dx;
141 in_x = ext.x - dx;
142 dx = ext.x;
143 }
144
145 size = w - in_w;
146 p_pixels = dst->pixels + (dy * dst->stride) + dx;
147 p_mask += in_x;
148
149 if (size > 1)
150 {
151 if (alpha == 0xff)
152 _glyph_scanline_mask_solid_solid(p_pixels, size, gry8, p_mask);
153 else if (alpha != 0)
154 _glyph_scanline_mask_transp_solid
155 (p_pixels, size, gry8, alpha, p_mask);
156 }
157 else if (size == 1)
158 {
159 if (alpha == 0xff)
160 _glyph_pt_mask_solid_solid(p_pixels, gry8, p_mask);
161 else if (alpha != 0)
162 _glyph_pt_mask_transp_solid(p_pixels, gry8, alpha, p_mask);
163 }
164}
165
166static void
167_soft8_font_glyph_draw_grayscale(Soft8_Image * dst,
168 RGBA_Draw_Context * dc __UNUSED__,
169 RGBA_Font_Glyph * fg __UNUSED__, int x, int y,
170 DATA8 alpha, DATA8 gry8,
171 const Eina_Rectangle ext, int bw, int bh,
172 int bpitch, const DATA8 * bitmap)
173{
174 int i, max_x, max_y;
175
176 max_x = ext.x + ext.w;
177 max_y = ext.y + ext.h;
178
179 for (i = 0; i < bh; i++, bitmap += bpitch)
180 _glyph_scanline(dst, bitmap, ext, x, y + i, max_x, max_y, bw,
181 alpha, gry8);
182}
183
184static inline void
185_glyph_create_mask_line(DATA8 * mask, const DATA8 * bitmap, int w)
186{
187 const DATA8 bitrepl[2] = { 0x0, 0xff };
188 int i;
189
190 for (i = 0; i < w; i += 8, bitmap++)
191 {
192 int j, size;
193 DATA32 bits;
194
195 if (i + 8 < w)
196 size = 8;
197 else
198 size = w - i;
199
200 bits = *bitmap;
201
202 for (j = size - 1; j >= 0; j--, mask++)
203 *mask = bitrepl[(bits >> j) & 0x1];
204 }
205}
206
207static void
208_soft8_font_glyph_draw_mono(Soft8_Image * dst,
209 RGBA_Draw_Context * dc __UNUSED__,
210 RGBA_Font_Glyph * fg __UNUSED__, int x, int y,
211 DATA8 alpha, DATA8 gry8, const Eina_Rectangle ext,
212 int bw, int bh, int bpitch, const DATA8 * bitmap)
213{
214 DATA8 *mask;
215 int i, max_x, max_y;
216
217 max_x = ext.x + ext.w;
218 max_y = ext.y + ext.h;
219
220 mask = alloca(bpitch);
221 for (i = 0; i < bh; i++, bitmap += bpitch)
222 {
223 _glyph_create_mask_line(mask, bitmap, bw);
224 _glyph_scanline(dst, mask, ext, x, y + i, max_x, max_y, bw,
225 alpha, gry8);
226 }
227}
228
229void
230evas_common_soft8_font_glyph_draw(void *data, void *dest __UNUSED__, void *context,
231 RGBA_Font_Glyph * fg, int x, int y)
232{
233 Soft8_Image *dst;
234 RGBA_Draw_Context *dc;
235 const DATA8 *bitmap;
236 DATA8 alpha; // r, g, b
237 DATA8 gry8;
238 Eina_Rectangle ext;
239 int bpitch, bw, bh;
240
241 dst = data;
242 dc = context;
243
244 alpha = A_VAL(&dc->col.col);
245 if (alpha == 0)
246 return;
247
248 gry8 = GRY_8_FROM_RGB(&dc->col.col);
249
250 /*
251 * if (r > alpha) r = alpha;
252 * if (g > alpha) g = alpha;
253 * if (b > alpha) b = alpha;
254 *
255 * gry8 = GRY_8_FROM_COMPONENTS(r, g, b);
256 */
257
258 bitmap = fg->glyph_out->bitmap.buffer;
259 bh = fg->glyph_out->bitmap.rows;
260 bw = fg->glyph_out->bitmap.width;
261 bpitch = fg->glyph_out->bitmap.pitch;
262 if (bpitch < bw)
263 bpitch = bw;
264
265 _calc_ext(dst, dc, &ext);
266
267 if ((fg->glyph_out->bitmap.num_grays == 256) &&
268 (fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
269 _soft8_font_glyph_draw_grayscale(dst, dc, fg, x, y, alpha, gry8,
270 ext, bw, bh, bpitch, bitmap);
271 else
272 _soft8_font_glyph_draw_mono(dst, dc, fg, x, y, alpha, gry8,
273 ext, bw, bh, bpitch, bitmap);
274}
275
276void *
277evas_common_soft8_font_glyph_new(void *data __UNUSED__, RGBA_Font_Glyph * fg __UNUSED__)
278{
279 return (void *)1; /* core requires != NULL to work */
280}
281
282void
283evas_common_soft8_font_glyph_free(void *ext_dat __UNUSED__)
284{
285}