|
1 diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c |
|
2 --- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c |
|
3 +++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c |
|
4 @@ -1426,16 +1426,104 @@ _cairo_win32_printing_surface_fill (void |
|
5 } |
|
6 |
|
7 fflush(stderr); |
|
8 |
|
9 return status; |
|
10 } |
|
11 |
|
12 static cairo_int_status_t |
|
13 +_cairo_win32_printing_surface_emit_win32_glyphs (cairo_win32_surface_t *surface, |
|
14 + cairo_operator_t op, |
|
15 + const cairo_pattern_t *source, |
|
16 + cairo_glyph_t *glyphs, |
|
17 + int num_glyphs, |
|
18 + cairo_scaled_font_t *scaled_font, |
|
19 + cairo_clip_t *clip, |
|
20 + int *remaining_glyphs) |
|
21 +{ |
|
22 + cairo_matrix_t ctm; |
|
23 + cairo_glyph_t *unicode_glyphs; |
|
24 + cairo_scaled_font_subsets_glyph_t subset_glyph; |
|
25 + int i, first; |
|
26 + cairo_bool_t sequence_is_unicode; |
|
27 + cairo_status_t status = CAIRO_STATUS_SUCCESS; |
|
28 + |
|
29 + /* Where possible reverse the glyph indices back to unicode |
|
30 + * characters. Strings of glyphs that could not be reversed to |
|
31 + * unicode will be printed with ETO_GLYPH_INDEX. |
|
32 + * |
|
33 + * As _cairo_win32_scaled_font_index_to_ucs4() is a slow |
|
34 + * operation, the font subsetting function |
|
35 + * _cairo_scaled_font_subsets_map_glyph() is used to obtain |
|
36 + * the unicode value because it caches the reverse mapping in |
|
37 + * the subsets. |
|
38 + */ |
|
39 + |
|
40 + if (surface->has_ctm) { |
|
41 + for (i = 0; i < num_glyphs; i++) |
|
42 + cairo_matrix_transform_point (&surface->ctm, &glyphs[i].x, &glyphs[i].y); |
|
43 + cairo_matrix_multiply (&ctm, &scaled_font->ctm, &surface->ctm); |
|
44 + scaled_font = cairo_scaled_font_create (scaled_font->font_face, |
|
45 + &scaled_font->font_matrix, |
|
46 + &ctm, |
|
47 + &scaled_font->options); |
|
48 + } |
|
49 + |
|
50 + unicode_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); |
|
51 + if (unicode_glyphs == NULL) |
|
52 + return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
|
53 + |
|
54 + memcpy (unicode_glyphs, glyphs, num_glyphs * sizeof (cairo_glyph_t)); |
|
55 + for (i = 0; i < num_glyphs; i++) { |
|
56 + status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets, |
|
57 + scaled_font, |
|
58 + glyphs[i].index, |
|
59 + NULL, 0, |
|
60 + &subset_glyph); |
|
61 + if (status) |
|
62 + goto fail; |
|
63 + |
|
64 + unicode_glyphs[i].index = subset_glyph.unicode; |
|
65 + } |
|
66 + |
|
67 + i = 0; |
|
68 + first = 0; |
|
69 + sequence_is_unicode = unicode_glyphs[0].index <= 0xffff; |
|
70 + while (i < num_glyphs) { |
|
71 + if (i == num_glyphs - 1 || |
|
72 + ((unicode_glyphs[i + 1].index < 0xffff) != sequence_is_unicode)) |
|
73 + { |
|
74 + status = _cairo_win32_surface_show_glyphs_internal ( |
|
75 + surface, |
|
76 + op, |
|
77 + source, |
|
78 + sequence_is_unicode ? &unicode_glyphs[first] : &glyphs[first], |
|
79 + i - first + 1, |
|
80 + scaled_font, |
|
81 + clip, |
|
82 + remaining_glyphs, |
|
83 + ! sequence_is_unicode); |
|
84 + first = i + 1; |
|
85 + if (i < num_glyphs - 1) |
|
86 + sequence_is_unicode = unicode_glyphs[i + 1].index <= 0xffff; |
|
87 + } |
|
88 + i++; |
|
89 + } |
|
90 + |
|
91 +fail: |
|
92 + if (surface->has_ctm) |
|
93 + cairo_scaled_font_destroy (scaled_font); |
|
94 + |
|
95 + free (unicode_glyphs); |
|
96 + |
|
97 + return status; |
|
98 +} |
|
99 + |
|
100 +static cairo_int_status_t |
|
101 _cairo_win32_printing_surface_show_glyphs (void *abstract_surface, |
|
102 cairo_operator_t op, |
|
103 const cairo_pattern_t *source, |
|
104 cairo_glyph_t *glyphs, |
|
105 int num_glyphs, |
|
106 cairo_scaled_font_t *scaled_font, |
|
107 cairo_clip_t *clip, |
|
108 int *remaining_glyphs) |
|
109 @@ -1533,77 +1621,24 @@ _cairo_win32_printing_surface_show_glyph |
|
110 } |
|
111 } |
|
112 #endif |
|
113 |
|
114 #if CAIRO_HAS_WIN32_FONT |
|
115 if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32 && |
|
116 source->type == CAIRO_PATTERN_TYPE_SOLID) |
|
117 { |
|
118 - cairo_matrix_t ctm; |
|
119 - cairo_glyph_t *type1_glyphs = NULL; |
|
120 - cairo_scaled_font_subsets_glyph_t subset_glyph; |
|
121 - |
|
122 - /* Calling ExtTextOutW() with ETO_GLYPH_INDEX and a Type 1 |
|
123 - * font on a printer DC prints garbled text. The text displays |
|
124 - * correctly on a display DC. When using a printer |
|
125 - * DC, ExtTextOutW() only works with characters and not glyph |
|
126 - * indices. |
|
127 - * |
|
128 - * For Type 1 fonts the glyph indices are converted back to |
|
129 - * unicode characters before calling _cairo_win32_surface_show_glyphs(). |
|
130 - * |
|
131 - * As _cairo_win32_scaled_font_index_to_ucs4() is a slow |
|
132 - * operation, the font subsetting function |
|
133 - * _cairo_scaled_font_subsets_map_glyph() is used to obtain |
|
134 - * the unicode value because it caches the reverse mapping in |
|
135 - * the subsets. |
|
136 - */ |
|
137 - if (_cairo_win32_scaled_font_is_type1 (scaled_font)) { |
|
138 - type1_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); |
|
139 - if (type1_glyphs == NULL) { |
|
140 - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); |
|
141 - goto FINISH; |
|
142 - } |
|
143 - memcpy (type1_glyphs, glyphs, num_glyphs * sizeof (cairo_glyph_t)); |
|
144 - for (i = 0; i < num_glyphs; i++) { |
|
145 - status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets, |
|
146 - scaled_font, |
|
147 - type1_glyphs[i].index, |
|
148 - NULL, 0, |
|
149 - &subset_glyph); |
|
150 - if (status) |
|
151 - goto FINISH; |
|
152 - |
|
153 - type1_glyphs[i].index = subset_glyph.unicode; |
|
154 - } |
|
155 - glyphs = type1_glyphs; |
|
156 - } |
|
157 - |
|
158 - if (surface->has_ctm || surface->has_gdi_ctm) { |
|
159 - cairo_matrix_multiply (&ctm, &surface->ctm, &surface->gdi_ctm); |
|
160 - for (i = 0; i < num_glyphs; i++) |
|
161 - cairo_matrix_transform_point (&ctm, &glyphs[i].x, &glyphs[i].y); |
|
162 - cairo_matrix_multiply (&ctm, &scaled_font->ctm, &ctm); |
|
163 - scaled_font = cairo_scaled_font_create (scaled_font->font_face, |
|
164 - &scaled_font->font_matrix, |
|
165 - &ctm, |
|
166 - &scaled_font->options); |
|
167 - } |
|
168 - status = _cairo_win32_surface_show_glyphs (surface, op, |
|
169 - source, glyphs, |
|
170 - num_glyphs, scaled_font, |
|
171 - clip, |
|
172 - remaining_glyphs); |
|
173 - if (surface->has_ctm || surface->has_gdi_ctm) |
|
174 - cairo_scaled_font_destroy (scaled_font); |
|
175 - |
|
176 - if (type1_glyphs != NULL) |
|
177 - free (type1_glyphs); |
|
178 - |
|
179 + status = _cairo_win32_printing_surface_emit_win32_glyphs (surface, |
|
180 + op, |
|
181 + source, |
|
182 + glyphs, |
|
183 + num_glyphs, |
|
184 + scaled_font, |
|
185 + clip, |
|
186 + remaining_glyphs); |
|
187 goto FINISH; |
|
188 } |
|
189 #endif |
|
190 |
|
191 SaveDC (surface->dc); |
|
192 old_ctm = surface->ctm; |
|
193 old_has_ctm = surface->has_ctm; |
|
194 surface->has_ctm = TRUE; |
|
195 diff --git a/gfx/cairo/cairo/src/cairo-win32-private.h b/gfx/cairo/cairo/src/cairo-win32-private.h |
|
196 --- a/gfx/cairo/cairo/src/cairo-win32-private.h |
|
197 +++ b/gfx/cairo/cairo/src/cairo-win32-private.h |
|
198 @@ -157,16 +157,27 @@ _cairo_win32_surface_get_extents (void |
|
199 uint32_t |
|
200 _cairo_win32_flags_for_dc (HDC dc); |
|
201 |
|
202 cairo_status_t |
|
203 _cairo_win32_surface_set_clip_region (void *abstract_surface, |
|
204 cairo_region_t *region); |
|
205 |
|
206 cairo_int_status_t |
|
207 +_cairo_win32_surface_show_glyphs_internal (void *surface, |
|
208 + cairo_operator_t op, |
|
209 + const cairo_pattern_t *source, |
|
210 + cairo_glyph_t *glyphs, |
|
211 + int num_glyphs, |
|
212 + cairo_scaled_font_t *scaled_font, |
|
213 + cairo_clip_t *clip, |
|
214 + int *remaining_glyphs, |
|
215 + cairo_bool_t glyph_indices); |
|
216 + |
|
217 +cairo_int_status_t |
|
218 _cairo_win32_surface_show_glyphs (void *surface, |
|
219 cairo_operator_t op, |
|
220 const cairo_pattern_t *source, |
|
221 cairo_glyph_t *glyphs, |
|
222 int num_glyphs, |
|
223 cairo_scaled_font_t *scaled_font, |
|
224 cairo_clip_t *clip, |
|
225 int *remaining_glyphs); |
|
226 diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c |
|
227 --- a/gfx/cairo/cairo/src/cairo-win32-surface.c |
|
228 +++ b/gfx/cairo/cairo/src/cairo-win32-surface.c |
|
229 @@ -1607,24 +1607,25 @@ static cairo_status_t |
|
230 _cairo_win32_surface_flush (void *abstract_surface) |
|
231 { |
|
232 return _cairo_win32_surface_set_clip_region (abstract_surface, NULL); |
|
233 } |
|
234 |
|
235 #define STACK_GLYPH_SIZE 256 |
|
236 |
|
237 cairo_int_status_t |
|
238 -_cairo_win32_surface_show_glyphs (void *surface, |
|
239 - cairo_operator_t op, |
|
240 - const cairo_pattern_t *source, |
|
241 - cairo_glyph_t *glyphs, |
|
242 - int num_glyphs, |
|
243 - cairo_scaled_font_t *scaled_font, |
|
244 - cairo_clip_t *clip, |
|
245 - int *remaining_glyphs) |
|
246 +_cairo_win32_surface_show_glyphs_internal (void *surface, |
|
247 + cairo_operator_t op, |
|
248 + const cairo_pattern_t *source, |
|
249 + cairo_glyph_t *glyphs, |
|
250 + int num_glyphs, |
|
251 + cairo_scaled_font_t *scaled_font, |
|
252 + cairo_clip_t *clip, |
|
253 + int *remaining_glyphs, |
|
254 + cairo_bool_t glyph_indexing) |
|
255 { |
|
256 #ifdef CAIRO_HAS_WIN32_FONT |
|
257 if (scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE) { |
|
258 #ifdef CAIRO_HAS_DWRITE_FONT |
|
259 return _cairo_dwrite_show_glyphs_on_surface(surface, op, source, glyphs, num_glyphs, scaled_font, clip); |
|
260 #endif |
|
261 } else { |
|
262 cairo_win32_surface_t *dst = surface; |
|
263 @@ -1737,29 +1738,20 @@ _cairo_win32_surface_show_glyphs (void |
|
264 dxy_buf[j+1] = _cairo_lround (logical_y - next_logical_y); |
|
265 /* note that GDI coordinate system is inverted */ |
|
266 |
|
267 logical_x = next_logical_x; |
|
268 logical_y = next_logical_y; |
|
269 } |
|
270 } |
|
271 |
|
272 - /* Using glyph indices for a Type 1 font does not work on a |
|
273 - * printer DC. The win32 printing surface will convert the the |
|
274 - * glyph indices of Type 1 fonts to the unicode values. |
|
275 - */ |
|
276 - if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) && |
|
277 - _cairo_win32_scaled_font_is_type1 (scaled_font)) |
|
278 - { |
|
279 + if (glyph_indexing) |
|
280 + glyph_index_option = ETO_GLYPH_INDEX; |
|
281 + else |
|
282 glyph_index_option = 0; |
|
283 - } |
|
284 - else |
|
285 - { |
|
286 - glyph_index_option = ETO_GLYPH_INDEX; |
|
287 - } |
|
288 |
|
289 win_result = ExtTextOutW(dst->dc, |
|
290 start_x, |
|
291 start_y, |
|
292 glyph_index_option | ETO_PDY, |
|
293 NULL, |
|
294 glyph_buf, |
|
295 num_glyphs, |
|
296 @@ -1778,16 +1770,37 @@ _cairo_win32_surface_show_glyphs (void |
|
297 } |
|
298 #else |
|
299 return CAIRO_INT_STATUS_UNSUPPORTED; |
|
300 #endif |
|
301 } |
|
302 |
|
303 #undef STACK_GLYPH_SIZE |
|
304 |
|
305 +cairo_int_status_t |
|
306 +_cairo_win32_surface_show_glyphs (void *surface, |
|
307 + cairo_operator_t op, |
|
308 + const cairo_pattern_t *source, |
|
309 + cairo_glyph_t *glyphs, |
|
310 + int num_glyphs, |
|
311 + cairo_scaled_font_t *scaled_font, |
|
312 + cairo_clip_t *clip, |
|
313 + int *remaining_glyphs) |
|
314 +{ |
|
315 + return _cairo_win32_surface_show_glyphs_internal (surface, |
|
316 + op, |
|
317 + source, |
|
318 + glyphs, |
|
319 + num_glyphs, |
|
320 + scaled_font, |
|
321 + clip, |
|
322 + remaining_glyphs, |
|
323 + TRUE); |
|
324 +} |
|
325 + |
|
326 static cairo_surface_t * |
|
327 cairo_win32_surface_create_internal (HDC hdc, cairo_format_t format) |
|
328 { |
|
329 cairo_win32_surface_t *surface; |
|
330 |
|
331 RECT rect; |
|
332 |
|
333 surface = malloc (sizeof (cairo_win32_surface_t)); |