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