Merge lp:~3v1n0/ubuntu/vivid/freetype/multithread-safe into lp:ubuntu/vivid/freetype

Proposed by Marco Trevisan (Treviño) on 2015-01-23
Status: Merged
Merged at revision: 63
Proposed branch: lp:~3v1n0/ubuntu/vivid/freetype/multithread-safe
Merge into: lp:ubuntu/vivid/freetype
Diff against target: 2133 lines (+2113/-0)
3 files modified
debian/changelog (+7/-0)
debian/patches-freetype/multi-thread-violations.patch (+2105/-0)
debian/patches-freetype/series (+1/-0)
To merge this branch: bzr merge lp:~3v1n0/ubuntu/vivid/freetype/multithread-safe
Reviewer Review Type Date Requested Status
Dmitry Shachnev 2015-01-23 Needs Information on 2015-01-26
Review via email: mp+247373@code.launchpad.net

Description of the change

Backported patches coming from this patchset [1] that has been just merged upstream [2] and that fixes huge multithread violations that are causing crashes in a lot of places in the upper stack.

Here [3] you can read more details about this patch.

[1] https://github.com/behdad/freetype/tree/ftthread
[2] http://<email address hidden>/msg06780.html
[3] http://<email address hidden>/msg06758.html

For being precise, this patch includes the changes merged in commits:
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=89bc8d4d
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=531d463a
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=747ae2c8
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=8dc86358
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=a773c304
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=6dfdaf4d
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=51634253
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=603292d7
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=b2ba6866
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=c242fe41
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=ae6699f8
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=a4117fbd
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=c2733656
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=6f16b100
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=56ddafa0
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=48c86628
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=4eff854c
  http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=264b5e46

To post a comment you must log in.
Dmitry Shachnev (mitya57) wrote :

Can we just update to ≥ 2.5.6, instead of cherry-picking a ton of commits?

review: Needs Information
Marco Trevisan (Treviño) (3v1n0) wrote :

Well, I'd say yes... Although it has not been released yet.

And I was also thinking this as something that can be backported to trusty (this is probably one of the more frequent crashes in e.u.c)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2014-09-19 17:11:19 +0000
3+++ debian/changelog 2015-01-26 16:03:08 +0000
4@@ -1,3 +1,10 @@
5+freetype (2.5.2-2ubuntu2) UNRELEASED; urgency=medium
6+
7+ * Added patchset to fix multithread violations, LP: #1199571
8+ - debian/patches-freetype/multi-thread-violations.patch
9+
10+ -- Marco Trevisan (Treviño) <marco@ubuntu.com> Fri, 23 Jan 2015 03:23:18 +0100
11+
12 freetype (2.5.2-2ubuntu1) utopic; urgency=medium
13
14 * Merge from Debian unstable, remaining changes:
15
16=== added file 'debian/patches-freetype/multi-thread-violations.patch'
17--- debian/patches-freetype/multi-thread-violations.patch 1970-01-01 00:00:00 +0000
18+++ debian/patches-freetype/multi-thread-violations.patch 2015-01-26 16:03:08 +0000
19@@ -0,0 +1,2105 @@
20+Author: Behdad Esfahbod <behdad@behdad.org>
21+Description: Multithread-safe FreeType
22+Forwarded: http://www.mail-archive.com/freetype-devel@nongnu.org/msg06758.html
23+Bug: https://bugs.freedesktop.org/show_bug.cgi?id=69034
24+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/freetype/+bug/1199571
25+Origin: upstream, https://github.com/behdad/freetype/commits/ftthread
26+Applied-Upstream: 2.5.6, git commits 89bc8d4d, 531d463a, 747ae2c8, 8dc86358,
27+ a773c304, 6dfdaf4d, 51634253, 603292d7, b2ba6866, c242fe41, ae6699f8, a4117fbd,
28+ c2733656, 6f16b100, 56ddafa0, 48c86628, 4eff854c, 264b5e46
29+
30+
31+Index: freetype-2.5.2/devel/ftoption.h
32+===================================================================
33+--- freetype-2.5.2.orig/devel/ftoption.h
34++++ freetype-2.5.2/devel/ftoption.h
35+@@ -365,10 +365,6 @@
36+ /* The size in bytes of the render pool used by the scan-line converter */
37+ /* to do all of its work. */
38+ /* */
39+- /* This must be greater than 4KByte if you use FreeType to rasterize */
40+- /* glyphs; otherwise, you may set it to zero to avoid unnecessary */
41+- /* allocation of the render pool. */
42+- /* */
43+ #define FT_RENDER_POOL_SIZE 16384L
44+
45+
46+Index: freetype-2.5.2/include/config/ftoption.h
47+===================================================================
48+--- freetype-2.5.2.orig/include/config/ftoption.h
49++++ freetype-2.5.2/include/config/ftoption.h
50+@@ -365,10 +365,6 @@
51+ /* The size in bytes of the render pool used by the scan-line converter */
52+ /* to do all of its work. */
53+ /* */
54+- /* This must be greater than 4KByte if you use FreeType to rasterize */
55+- /* glyphs; otherwise, you may set it to zero to avoid unnecessary */
56+- /* allocation of the render pool. */
57+- /* */
58+ #define FT_RENDER_POOL_SIZE 16384L
59+
60+
61+Index: freetype-2.5.2/include/freetype.h
62+===================================================================
63+--- freetype-2.5.2.orig/include/freetype.h
64++++ freetype-2.5.2/include/freetype.h
65+@@ -332,8 +332,11 @@
66+ /* It also embeds a memory manager (see @FT_Memory), as well as a */
67+ /* scan-line converter object (see @FT_Raster). */
68+ /* */
69+- /* In multi-threaded applications, make sure that the same FT_Library */
70+- /* object or any of its children doesn't get accessed in parallel. */
71++ /* In multi-threaded applications it is easiest to use one */
72++ /* `FT_Library' object per thread. In case this is too cumbersome, */
73++ /* a single `FT_Library' object across threads is possible also */
74++ /* (since FreeType version 2.5.6), as long as a mutex lock is used */
75++ /* around @FT_New_Face and @FT_Done_Face. */
76+ /* */
77+ /* <Note> */
78+ /* Library objects are normally created by @FT_Init_FreeType, and */
79+@@ -401,6 +404,14 @@
80+ /* */
81+ /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */
82+ /* */
83++ /* An `FT_Face' object can only be safely used from one thread at a */
84++ /* time. Similarly, creation and destruction of `FT_Face' with the */
85++ /* same @FT_Library object can only be done from one thread at a */
86++ /* time. On the other hand, functions like @FT_Load_Glyph and its */
87++ /* siblings are thread-safe and do not need the lock to be held as */
88++ /* long as the same `FT_Face' object is not used from multiple */
89++ /* threads at the same time. */
90++ /* */
91+ /* <Also> */
92+ /* See @FT_FaceRec for the publicly accessible fields of a given face */
93+ /* object. */
94+@@ -1701,8 +1712,8 @@
95+ /* use @FT_New_Library instead, followed by a call to */
96+ /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */
97+ /* */
98+- /* For multi-threading applications each thread should have its own */
99+- /* FT_Library object. */
100++ /* See the documentation of @FT_Library and @FT_Face for */
101++ /* multi-threading issues. */
102+ /* */
103+ /* If you need reference-counting (cf. @FT_Reference_Library), use */
104+ /* @FT_New_Library and @FT_Done_Library. */
105+Index: freetype-2.5.2/include/ftimage.h
106+===================================================================
107+--- freetype-2.5.2.orig/include/ftimage.h
108++++ freetype-2.5.2/include/ftimage.h
109+@@ -1179,10 +1179,10 @@
110+ /* FT_Raster_ResetFunc */
111+ /* */
112+ /* <Description> */
113+- /* FreeType provides an area of memory called the `render pool', */
114+- /* available to all registered rasters. This pool can be freely used */
115+- /* during a given scan-conversion but is shared by all rasters. Its */
116+- /* content is thus transient. */
117++ /* FreeType used to provide an area of memory called the `render */
118++ /* pool' available to all registered rasters. This was not thread */
119++ /* safe however and now FreeType never allocates this pool. NULL */
120++ /* is always passed in as pool_base. */
121+ /* */
122+ /* This function is called each time the render pool changes, or just */
123+ /* after a new raster object is created. */
124+@@ -1195,10 +1195,9 @@
125+ /* pool_size :: The size in bytes of the render pool. */
126+ /* */
127+ /* <Note> */
128+- /* Rasters can ignore the render pool and rely on dynamic memory */
129++ /* Rasters should ignore the render pool and rely on dynamic or stack */
130+ /* allocation if they want to (a handle to the memory allocator is */
131+- /* passed to the raster constructor). However, this is not */
132+- /* recommended for efficiency purposes. */
133++ /* passed to the raster constructor). */
134+ /* */
135+ typedef void
136+ (*FT_Raster_ResetFunc)( FT_Raster raster,
137+Index: freetype-2.5.2/include/ftrender.h
138+===================================================================
139+--- freetype-2.5.2.orig/include/ftrender.h
140++++ freetype-2.5.2/include/ftrender.h
141+@@ -212,13 +212,8 @@
142+ /* */
143+ /* This doesn't change the current renderer for other formats. */
144+ /* */
145+- /* Currently, only the B/W renderer, if compiled with */
146+- /* FT_RASTER_OPTION_ANTI_ALIASING (providing a 5-levels */
147+- /* anti-aliasing mode; this option must be set directly in */
148+- /* `ftraster.c' and is undefined by default) accepts a single tag */
149+- /* `pal5' to set its gray palette as a character string with */
150+- /* 5~elements. Consequently, the third and fourth argument are zero */
151+- /* normally. */
152++ /* Currently, no FreeType renderer module uses `parameters'; you */
153++ /* should thus always pass NULL as the value. */
154+ /* */
155+ FT_EXPORT( FT_Error )
156+ FT_Set_Renderer( FT_Library library,
157+Index: freetype-2.5.2/include/internal/ftobjs.h
158+===================================================================
159+--- freetype-2.5.2.orig/include/internal/ftobjs.h
160++++ freetype-2.5.2/include/internal/ftobjs.h
161+@@ -738,9 +738,8 @@
162+ /* faces_list :: The list of faces currently opened by this */
163+ /* driver. */
164+ /* */
165+- /* glyph_loader :: The glyph loader for all faces managed by this */
166+- /* driver. This object isn't defined for unscalable */
167+- /* formats. */
168++ /* glyph_loader :: Unused. Used to be glyph loader for all faces */
169++ /* managed by this driver. */
170+ /* */
171+ typedef struct FT_DriverRec_
172+ {
173+Index: freetype-2.5.2/src/autofit/afhints.c
174+===================================================================
175+--- freetype-2.5.2.orig/src/autofit/afhints.c
176++++ freetype-2.5.2/src/autofit/afhints.c
177+@@ -43,7 +43,15 @@
178+ AF_Segment segment = NULL;
179+
180+
181+- if ( axis->num_segments >= axis->max_segments )
182++ if ( axis->num_segments < AF_SEGMENTS_EMBEDDED )
183++ {
184++ if ( axis->segments == NULL )
185++ {
186++ axis->segments = axis->embedded.segments;
187++ axis->max_segments = AF_SEGMENTS_EMBEDDED;
188++ }
189++ }
190++ else if ( axis->num_segments >= axis->max_segments )
191+ {
192+ FT_Int old_max = axis->max_segments;
193+ FT_Int new_max = old_max;
194+@@ -60,8 +68,18 @@
195+ if ( new_max < old_max || new_max > big_max )
196+ new_max = big_max;
197+
198+- if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
199+- goto Exit;
200++ if ( axis->segments == axis->embedded.segments )
201++ {
202++ if ( FT_NEW_ARRAY( axis->segments, new_max ) )
203++ goto Exit;
204++ ft_memcpy( axis->segments, axis->embedded.segments,
205++ sizeof ( axis->embedded.segments ) );
206++ }
207++ else
208++ {
209++ if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
210++ goto Exit;
211++ }
212+
213+ axis->max_segments = new_max;
214+ }
215+@@ -88,7 +106,15 @@
216+ AF_Edge edges;
217+
218+
219+- if ( axis->num_edges >= axis->max_edges )
220++ if ( axis->num_edges < AF_EDGES_EMBEDDED )
221++ {
222++ if ( axis->edges == NULL )
223++ {
224++ axis->edges = axis->embedded.edges;
225++ axis->max_edges = AF_EDGES_EMBEDDED;
226++ }
227++ }
228++ else if ( axis->num_edges >= axis->max_edges )
229+ {
230+ FT_Int old_max = axis->max_edges;
231+ FT_Int new_max = old_max;
232+@@ -105,8 +131,18 @@
233+ if ( new_max < old_max || new_max > big_max )
234+ new_max = big_max;
235+
236+- if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
237+- goto Exit;
238++ if ( axis->edges == axis->embedded.edges )
239++ {
240++ if ( FT_NEW_ARRAY( axis->edges, new_max ) )
241++ goto Exit;
242++ ft_memcpy( axis->edges, axis->embedded.edges,
243++ sizeof ( axis->embedded.edges ) );
244++ }
245++ else
246++ {
247++ if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
248++ goto Exit;
249++ }
250+
251+ axis->max_edges = new_max;
252+ }
253+@@ -485,7 +521,8 @@
254+ af_glyph_hints_init( AF_GlyphHints hints,
255+ FT_Memory memory )
256+ {
257+- FT_ZERO( hints );
258++ /* no need to initialize the embedded items */
259++ FT_MEM_ZERO( hints, sizeof ( *hints ) - sizeof ( hints->embedded ) );
260+ hints->memory = memory;
261+ }
262+
263+@@ -511,20 +548,24 @@
264+
265+ axis->num_segments = 0;
266+ axis->max_segments = 0;
267+- FT_FREE( axis->segments );
268++ if ( axis->segments != axis->embedded.segments )
269++ FT_FREE( axis->segments );
270+
271+ axis->num_edges = 0;
272+ axis->max_edges = 0;
273+- FT_FREE( axis->edges );
274++ if ( axis->edges != axis->embedded.edges )
275++ FT_FREE( axis->edges );
276+ }
277+
278+- FT_FREE( hints->contours );
279++ if ( hints->contours != hints->embedded.contours )
280++ FT_FREE( hints->contours );
281+ hints->max_contours = 0;
282+ hints->num_contours = 0;
283+
284+- FT_FREE( hints->points );
285+- hints->num_points = 0;
286++ if ( hints->points != hints->embedded.points )
287++ FT_FREE( hints->points );
288+ hints->max_points = 0;
289++ hints->num_points = 0;
290+
291+ hints->memory = NULL;
292+ }
293+@@ -569,8 +610,14 @@
294+ /* first of all, reallocate the contours array if necessary */
295+ new_max = (FT_UInt)outline->n_contours;
296+ old_max = hints->max_contours;
297+- if ( new_max > old_max )
298++
299++ if ( new_max <= AF_CONTOURS_EMBEDDED )
300++ hints->contours = hints->embedded.contours;
301++ else if ( new_max > old_max )
302+ {
303++ if ( hints->contours == hints->embedded.contours )
304++ hints->contours = NULL;
305++
306+ new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */
307+
308+ if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
309+@@ -586,8 +633,14 @@
310+ */
311+ new_max = (FT_UInt)( outline->n_points + 2 );
312+ old_max = hints->max_points;
313+- if ( new_max > old_max )
314++
315++ if ( new_max <= AF_POINTS_EMBEDDED )
316++ hints->points = hints->embedded.points;
317++ else if ( new_max > old_max )
318+ {
319++ if ( hints->points == hints->embedded.points )
320++ hints->points = NULL;
321++
322+ new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */
323+
324+ if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )
325+Index: freetype-2.5.2/src/autofit/afhints.h
326+===================================================================
327+--- freetype-2.5.2.orig/src/autofit/afhints.h
328++++ freetype-2.5.2/src/autofit/afhints.h
329+@@ -322,6 +322,8 @@
330+
331+ } AF_EdgeRec;
332+
333++#define AF_SEGMENTS_EMBEDDED 18 /* number of embedded segments */
334++#define AF_EDGES_EMBEDDED 12 /* number of embedded edges */
335+
336+ typedef struct AF_AxisHintsRec_
337+ {
338+@@ -338,9 +340,20 @@
339+
340+ AF_Direction major_dir; /* either vertical or horizontal */
341+
342++ /* two arrays to avoid allocation penalty */
343++ struct
344++ {
345++ AF_SegmentRec segments[AF_SEGMENTS_EMBEDDED];
346++ AF_EdgeRec edges[AF_EDGES_EMBEDDED];
347++ } embedded;
348++
349++
350+ } AF_AxisHintsRec, *AF_AxisHints;
351+
352+
353++#define AF_POINTS_EMBEDDED 96 /* number of embedded points */
354++#define AF_CONTOURS_EMBEDDED 8 /* number of embedded contours */
355++
356+ typedef struct AF_GlyphHintsRec_
357+ {
358+ FT_Memory memory;
359+@@ -369,6 +382,14 @@
360+ FT_Pos xmin_delta; /* used for warping */
361+ FT_Pos xmax_delta;
362+
363++ /* Two arrays to avoid allocation penalty. */
364++ /* The `embedded' structure must be the last element! */
365++ struct
366++ {
367++ AF_Point contours[AF_CONTOURS_EMBEDDED];
368++ AF_PointRec points[AF_POINTS_EMBEDDED];
369++ } embedded;
370++
371+ } AF_GlyphHintsRec;
372+
373+
374+Index: freetype-2.5.2/src/autofit/afloader.c
375+===================================================================
376+--- freetype-2.5.2.orig/src/autofit/afloader.c
377++++ freetype-2.5.2/src/autofit/afloader.c
378+@@ -26,38 +26,32 @@
379+
380+ /* Initialize glyph loader. */
381+
382+- FT_LOCAL_DEF( FT_Error )
383+- af_loader_init( AF_Module module )
384++ FT_LOCAL_DEF( void )
385++ af_loader_init( AF_Loader loader,
386++ AF_GlyphHints hints )
387+ {
388+- AF_Loader loader = module->loader;
389+- FT_Memory memory = module->root.library->memory;
390+-
391+-
392+ FT_ZERO( loader );
393+
394+- af_glyph_hints_init( &loader->hints, memory );
395++ loader->hints = hints;
396+ #ifdef FT_DEBUG_AUTOFIT
397+- _af_debug_hints = &loader->hints;
398++ _af_debug_hints = loader->hints;
399+ #endif
400+- return FT_GlyphLoader_New( memory, &loader->gloader );
401+ }
402+
403+
404+ /* Reset glyph loader and compute globals if necessary. */
405+
406+ FT_LOCAL_DEF( FT_Error )
407+- af_loader_reset( AF_Module module,
408++ af_loader_reset( AF_Loader loader,
409++ AF_Module module,
410+ FT_Face face )
411+ {
412+- FT_Error error = FT_Err_Ok;
413+- AF_Loader loader = module->loader;
414++ FT_Error error = FT_Err_Ok;
415+
416+
417+ loader->face = face;
418+ loader->globals = (AF_FaceGlobals)face->autohint.data;
419+
420+- FT_GlyphLoader_Rewind( loader->gloader );
421+-
422+ if ( loader->globals == NULL )
423+ {
424+ error = af_face_globals_new( face, &loader->globals, module );
425+@@ -77,42 +71,37 @@
426+ /* Finalize glyph loader. */
427+
428+ FT_LOCAL_DEF( void )
429+- af_loader_done( AF_Module module )
430++ af_loader_done( AF_Loader loader )
431+ {
432+- AF_Loader loader = module->loader;
433+-
434+-
435+- af_glyph_hints_done( &loader->hints );
436+-
437+ loader->face = NULL;
438+ loader->globals = NULL;
439++ loader->hints = NULL;
440+
441+ #ifdef FT_DEBUG_AUTOFIT
442+ _af_debug_hints = NULL;
443+ #endif
444+- FT_GlyphLoader_Done( loader->gloader );
445+- loader->gloader = NULL;
446+ }
447+
448+
449+- /* Load a single glyph component. This routine calls itself */
450+- /* recursively, if necessary, and does the main work of */
451+- /* `af_loader_load_glyph.' */
452++ /* Do the main work of `af_loader_load_glyph'. Note that we never */
453++ /* have to deal with composite glyphs as those get loaded into */
454++ /* FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. */
455++ /* In the rare cases where FT_LOAD_NO_RECURSE is set, it implies */
456++ /* FT_LOAD_NO_SCALE and as such the auto-hinter is never called. */
457+
458+ static FT_Error
459+ af_loader_load_g( AF_Loader loader,
460+ AF_Scaler scaler,
461+ FT_UInt glyph_index,
462+- FT_Int32 load_flags,
463+- FT_UInt depth )
464++ FT_Int32 load_flags )
465+ {
466+ FT_Error error;
467+ FT_Face face = loader->face;
468+- FT_GlyphLoader gloader = loader->gloader;
469+ AF_ScriptMetrics metrics = loader->metrics;
470+- AF_GlyphHints hints = &loader->hints;
471++ AF_GlyphHints hints = loader->hints;
472+ FT_GlyphSlot slot = face->glyph;
473+ FT_Slot_Internal internal = slot->internal;
474++ FT_GlyphLoader gloader = internal->loader;
475+ FT_Int32 flags;
476+
477+
478+@@ -144,29 +133,6 @@
479+ loader->trans_delta.x,
480+ loader->trans_delta.y );
481+
482+- /* copy the outline points in the loader's current */
483+- /* extra points which are used to keep original glyph coordinates */
484+- error = FT_GLYPHLOADER_CHECK_POINTS( gloader,
485+- slot->outline.n_points + 4,
486+- slot->outline.n_contours );
487+- if ( error )
488+- goto Exit;
489+-
490+- FT_ARRAY_COPY( gloader->current.outline.points,
491+- slot->outline.points,
492+- slot->outline.n_points );
493+-
494+- FT_ARRAY_COPY( gloader->current.outline.contours,
495+- slot->outline.contours,
496+- slot->outline.n_contours );
497+-
498+- FT_ARRAY_COPY( gloader->current.outline.tags,
499+- slot->outline.tags,
500+- slot->outline.n_points );
501+-
502+- gloader->current.outline.n_points = slot->outline.n_points;
503+- gloader->current.outline.n_contours = slot->outline.n_contours;
504+-
505+ /* compute original horizontal phantom points (and ignore */
506+ /* vertical ones) */
507+ loader->pp1.x = hints->x_delta;
508+@@ -192,7 +158,7 @@
509+
510+ if ( writing_system_class->script_hints_apply )
511+ writing_system_class->script_hints_apply( hints,
512+- &gloader->current.outline,
513++ &gloader->base.outline,
514+ metrics );
515+ }
516+
517+@@ -267,133 +233,6 @@
518+ slot->rsb_delta = loader->pp2.x - pp2x;
519+ }
520+
521+- /* good, we simply add the glyph to our loader's base */
522+- FT_GlyphLoader_Add( gloader );
523+- break;
524+-
525+- case FT_GLYPH_FORMAT_COMPOSITE:
526+- {
527+- FT_UInt nn, num_subglyphs = slot->num_subglyphs;
528+- FT_UInt num_base_subgs, start_point;
529+- FT_SubGlyph subglyph;
530+-
531+-
532+- start_point = gloader->base.outline.n_points;
533+-
534+- /* first of all, copy the subglyph descriptors in the glyph loader */
535+- error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs );
536+- if ( error )
537+- goto Exit;
538+-
539+- FT_ARRAY_COPY( gloader->current.subglyphs,
540+- slot->subglyphs,
541+- num_subglyphs );
542+-
543+- gloader->current.num_subglyphs = num_subglyphs;
544+- num_base_subgs = gloader->base.num_subglyphs;
545+-
546+- /* now read each subglyph independently */
547+- for ( nn = 0; nn < num_subglyphs; nn++ )
548+- {
549+- FT_Vector pp1, pp2;
550+- FT_Pos x, y;
551+- FT_UInt num_points, num_new_points, num_base_points;
552+-
553+-
554+- /* gloader.current.subglyphs can change during glyph loading due */
555+- /* to re-allocation -- we must recompute the current subglyph on */
556+- /* each iteration */
557+- subglyph = gloader->base.subglyphs + num_base_subgs + nn;
558+-
559+- pp1 = loader->pp1;
560+- pp2 = loader->pp2;
561+-
562+- num_base_points = gloader->base.outline.n_points;
563+-
564+- error = af_loader_load_g( loader, scaler, subglyph->index,
565+- load_flags, depth + 1 );
566+- if ( error )
567+- goto Exit;
568+-
569+- /* recompute subglyph pointer */
570+- subglyph = gloader->base.subglyphs + num_base_subgs + nn;
571+-
572+- if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )
573+- {
574+- pp1 = loader->pp1;
575+- pp2 = loader->pp2;
576+- }
577+- else
578+- {
579+- loader->pp1 = pp1;
580+- loader->pp2 = pp2;
581+- }
582+-
583+- num_points = gloader->base.outline.n_points;
584+- num_new_points = num_points - num_base_points;
585+-
586+- /* now perform the transformation required for this subglyph */
587+-
588+- if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE |
589+- FT_SUBGLYPH_FLAG_XY_SCALE |
590+- FT_SUBGLYPH_FLAG_2X2 ) )
591+- {
592+- FT_Vector* cur = gloader->base.outline.points +
593+- num_base_points;
594+- FT_Vector* limit = cur + num_new_points;
595+-
596+-
597+- for ( ; cur < limit; cur++ )
598+- FT_Vector_Transform( cur, &subglyph->transform );
599+- }
600+-
601+- /* apply offset */
602+-
603+- if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
604+- {
605+- FT_Int k = subglyph->arg1;
606+- FT_UInt l = subglyph->arg2;
607+- FT_Vector* p1;
608+- FT_Vector* p2;
609+-
610+-
611+- if ( start_point + k >= num_base_points ||
612+- l >= (FT_UInt)num_new_points )
613+- {
614+- error = FT_THROW( Invalid_Composite );
615+- goto Exit;
616+- }
617+-
618+- l += num_base_points;
619+-
620+- /* for now, only use the current point coordinates; */
621+- /* we eventually may consider another approach */
622+- p1 = gloader->base.outline.points + start_point + k;
623+- p2 = gloader->base.outline.points + start_point + l;
624+-
625+- x = p1->x - p2->x;
626+- y = p1->y - p2->y;
627+- }
628+- else
629+- {
630+- x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta;
631+- y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta;
632+-
633+- x = FT_PIX_ROUND( x );
634+- y = FT_PIX_ROUND( y );
635+- }
636+-
637+- {
638+- FT_Outline dummy = gloader->base.outline;
639+-
640+-
641+- dummy.points += num_base_points;
642+- dummy.n_points = (short)num_new_points;
643+-
644+- FT_Outline_Translate( &dummy, x, y );
645+- }
646+- }
647+- }
648+ break;
649+
650+ default:
651+@@ -402,7 +241,6 @@
652+ }
653+
654+ Hint_Metrics:
655+- if ( depth == 0 )
656+ {
657+ FT_BBox bbox;
658+ FT_Vector vvector;
659+@@ -477,18 +315,14 @@
660+ slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
661+ slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );
662+
663+- /* now copy outline into glyph slot */
664+- FT_GlyphLoader_Rewind( internal->loader );
665+- error = FT_GlyphLoader_CopyPoints( internal->loader, gloader );
666+- if ( error )
667+- goto Exit;
668+-
669++#if 0
670+ /* reassign all outline fields except flags to protect them */
671+ slot->outline.n_contours = internal->loader->base.outline.n_contours;
672+ slot->outline.n_points = internal->loader->base.outline.n_points;
673+ slot->outline.points = internal->loader->base.outline.points;
674+ slot->outline.tags = internal->loader->base.outline.tags;
675+ slot->outline.contours = internal->loader->base.outline.contours;
676++#endif
677+
678+ slot->format = FT_GLYPH_FORMAT_OUTLINE;
679+ }
680+@@ -501,14 +335,14 @@
681+ /* Load a glyph. */
682+
683+ FT_LOCAL_DEF( FT_Error )
684+- af_loader_load_glyph( AF_Module module,
685++ af_loader_load_glyph( AF_Loader loader,
686++ AF_Module module,
687+ FT_Face face,
688+ FT_UInt gindex,
689+ FT_Int32 load_flags )
690+ {
691+ FT_Error error;
692+ FT_Size size = face->size;
693+- AF_Loader loader = module->loader;
694+ AF_ScalerRec scaler;
695+
696+
697+@@ -526,7 +360,7 @@
698+ scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
699+ scaler.flags = 0; /* XXX: fix this */
700+
701+- error = af_loader_reset( module, face );
702++ error = af_loader_reset( loader, module, face );
703+ if ( !error )
704+ {
705+ AF_ScriptMetrics metrics;
706+@@ -563,13 +397,13 @@
707+
708+ if ( writing_system_class->script_hints_init )
709+ {
710+- error = writing_system_class->script_hints_init( &loader->hints,
711++ error = writing_system_class->script_hints_init( loader->hints,
712+ metrics );
713+ if ( error )
714+ goto Exit;
715+ }
716+
717+- error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 );
718++ error = af_loader_load_g( loader, &scaler, gindex, load_flags );
719+ }
720+ }
721+ Exit:
722+Index: freetype-2.5.2/src/autofit/afloader.h
723+===================================================================
724+--- freetype-2.5.2.orig/src/autofit/afloader.h
725++++ freetype-2.5.2/src/autofit/afloader.h
726+@@ -20,13 +20,12 @@
727+ #define __AFLOADER_H__
728+
729+ #include "afhints.h"
730++#include "afmodule.h"
731+ #include "afglobal.h"
732+
733+
734+ FT_BEGIN_HEADER
735+
736+- typedef struct AF_ModuleRec_* AF_Module;
737+-
738+ /*
739+ * The autofitter module's (global) data structure to communicate with
740+ * actual fonts. If necessary, `local' data like the current face, the
741+@@ -42,8 +41,7 @@
742+ AF_FaceGlobals globals;
743+
744+ /* current glyph data */
745+- FT_GlyphLoader gloader;
746+- AF_GlyphHintsRec hints;
747++ AF_GlyphHints hints;
748+ AF_ScriptMetrics metrics;
749+ FT_Bool transformed;
750+ FT_Matrix trans_matrix;
751+@@ -55,21 +53,24 @@
752+ } AF_LoaderRec, *AF_Loader;
753+
754+
755+- FT_LOCAL( FT_Error )
756+- af_loader_init( AF_Module module );
757++ FT_LOCAL( void )
758++ af_loader_init( AF_Loader loader,
759++ AF_GlyphHints hints );
760+
761+
762+ FT_LOCAL( FT_Error )
763+- af_loader_reset( AF_Module module,
764++ af_loader_reset( AF_Loader loader,
765++ AF_Module module,
766+ FT_Face face );
767+
768+
769+ FT_LOCAL( void )
770+- af_loader_done( AF_Module module );
771++ af_loader_done( AF_Loader loader );
772+
773+
774+ FT_LOCAL( FT_Error )
775+- af_loader_load_glyph( AF_Module module,
776++ af_loader_load_glyph( AF_Loader loader,
777++ AF_Module module,
778+ FT_Face face,
779+ FT_UInt gindex,
780+ FT_Int32 load_flags );
781+Index: freetype-2.5.2/src/autofit/afmodule.c
782+===================================================================
783+--- freetype-2.5.2.orig/src/autofit/afmodule.c
784++++ freetype-2.5.2/src/autofit/afmodule.c
785+@@ -208,17 +208,14 @@
786+
787+ module->fallback_script = AF_SCRIPT_FALLBACK;
788+
789+- return af_loader_init( module );
790++ return FT_Err_Ok;
791+ }
792+
793+
794+ FT_CALLBACK_DEF( void )
795+ af_autofitter_done( FT_Module ft_module ) /* AF_Module */
796+ {
797+- AF_Module module = (AF_Module)ft_module;
798+-
799+-
800+- af_loader_done( module );
801++ FT_UNUSED( ft_module );
802+ }
803+
804+
805+@@ -229,10 +226,25 @@
806+ FT_UInt glyph_index,
807+ FT_Int32 load_flags )
808+ {
809++ FT_Error error = FT_Err_Ok;
810++ FT_Memory memory = module->root.library->memory;
811++
812++ AF_GlyphHintsRec hints[1];
813++ AF_LoaderRec loader[1];
814++
815+ FT_UNUSED( size );
816+
817+- return af_loader_load_glyph( module, slot->face,
818+- glyph_index, load_flags );
819++
820++ af_glyph_hints_init( hints, memory );
821++ af_loader_init( loader, hints );
822++
823++ error = af_loader_load_glyph( loader, module, slot->face,
824++ glyph_index, load_flags );
825++
826++ af_loader_done( loader );
827++ af_glyph_hints_done( hints );
828++
829++ return error;
830+ }
831+
832+
833+Index: freetype-2.5.2/src/autofit/afmodule.h
834+===================================================================
835+--- freetype-2.5.2.orig/src/autofit/afmodule.h
836++++ freetype-2.5.2/src/autofit/afmodule.h
837+@@ -23,17 +23,13 @@
838+ #include FT_INTERNAL_OBJECTS_H
839+ #include FT_MODULE_H
840+
841+-#include "afloader.h"
842+-
843+
844+ FT_BEGIN_HEADER
845+
846+
847+ /*
848+ * This is the `extended' FT_Module structure which holds the
849+- * autofitter's global data. Right before hinting a glyph, the data
850+- * specific to the glyph's face (blue zones, stem widths, etc.) are
851+- * loaded into `loader' (see function `af_loader_reset').
852++ * autofitter's global data.
853+ */
854+
855+ typedef struct AF_ModuleRec_
856+@@ -42,9 +38,7 @@
857+
858+ FT_UInt fallback_script;
859+
860+- AF_LoaderRec loader[1];
861+-
862+- } AF_ModuleRec;
863++ } AF_ModuleRec, *AF_Module;
864+
865+
866+ FT_DECLARE_MODULE(autofit_module_class)
867+Index: freetype-2.5.2/src/base/ftobjs.c
868+===================================================================
869+--- freetype-2.5.2.orig/src/base/ftobjs.c
870++++ freetype-2.5.2/src/base/ftobjs.c
871+@@ -963,10 +963,6 @@
872+ (FT_List_Destructor)destroy_face,
873+ driver->root.memory,
874+ driver );
875+-
876+- /* check whether we need to drop the driver's glyph loader */
877+- if ( FT_DRIVER_USES_OUTLINES( driver ) )
878+- FT_GlyphLoader_Done( driver->glyph_loader );
879+ }
880+
881+
882+@@ -4046,8 +4042,7 @@
883+
884+ default:
885+ {
886+- FT_ListNode node = 0;
887+- FT_Bool update = 0;
888++ FT_ListNode node = 0;
889+
890+
891+ /* small shortcut for the very common case */
892+@@ -4074,13 +4069,7 @@
893+ /* now, look for another renderer that supports the same */
894+ /* format. */
895+ renderer = FT_Lookup_Renderer( library, slot->format, &node );
896+- update = 1;
897+ }
898+-
899+- /* if we changed the current renderer for the glyph image format */
900+- /* we need to select it as the next current one */
901+- if ( !error && update && renderer )
902+- FT_Set_Renderer( library, renderer, 0, 0 );
903+ }
904+ }
905+
906+@@ -4280,17 +4269,10 @@
907+ /* if the module is a font driver */
908+ if ( FT_MODULE_IS_DRIVER( module ) )
909+ {
910+- /* allocate glyph loader if needed */
911+ FT_Driver driver = FT_DRIVER( module );
912+
913+
914+ driver->clazz = (FT_Driver_Class)module->clazz;
915+- if ( FT_DRIVER_USES_OUTLINES( driver ) )
916+- {
917+- error = FT_GlyphLoader_New( memory, &driver->glyph_loader );
918+- if ( error )
919+- goto Fail;
920+- }
921+ }
922+
923+ if ( clazz->module_init )
924+@@ -4307,15 +4289,6 @@
925+ return error;
926+
927+ Fail:
928+- if ( FT_MODULE_IS_DRIVER( module ) )
929+- {
930+- FT_Driver driver = FT_DRIVER( module );
931+-
932+-
933+- if ( FT_DRIVER_USES_OUTLINES( driver ) )
934+- FT_GlyphLoader_Done( driver->glyph_loader );
935+- }
936+-
937+ if ( FT_MODULE_IS_RENDERER( module ) )
938+ {
939+ FT_Renderer renderer = FT_RENDERER( module );
940+@@ -4630,12 +4603,9 @@
941+ goto Fail;
942+ #endif
943+
944+- /* allocate the render pool */
945+- library->raster_pool_size = FT_RENDER_POOL_SIZE;
946+-#if FT_RENDER_POOL_SIZE > 0
947+- if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
948+- goto Fail;
949+-#endif
950++ /* we don't use raster_pool anymore. */
951++ library->raster_pool_size = 0;
952++ library->raster_pool = NULL;
953+
954+ library->version_major = FREETYPE_MAJOR;
955+ library->version_minor = FREETYPE_MINOR;
956+@@ -4648,6 +4618,8 @@
957+
958+ return FT_Err_Ok;
959+
960++ /* Fix compilation warning */
961++ goto Fail;
962+ Fail:
963+ #ifdef FT_CONFIG_OPTION_PIC
964+ ft_pic_container_destroy( library );
965+@@ -4784,10 +4756,6 @@
966+ }
967+ #endif
968+
969+- /* Destroy raster objects */
970+- FT_FREE( library->raster_pool );
971+- library->raster_pool_size = 0;
972+-
973+ #ifdef FT_CONFIG_OPTION_PIC
974+ /* Destroy pic container contents */
975+ ft_pic_container_destroy( library );
976+Index: freetype-2.5.2/src/base/ftoutln.c
977+===================================================================
978+--- freetype-2.5.2.orig/src/base/ftoutln.c
979++++ freetype-2.5.2/src/base/ftoutln.c
980+@@ -606,7 +606,6 @@
981+ FT_Raster_Params* params )
982+ {
983+ FT_Error error;
984+- FT_Bool update = FALSE;
985+ FT_Renderer renderer;
986+ FT_ListNode node;
987+
988+@@ -637,14 +636,8 @@
989+ /* format */
990+ renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE,
991+ &node );
992+- update = TRUE;
993+ }
994+
995+- /* if we changed the current renderer for the glyph image format */
996+- /* we need to select it as the next current one */
997+- if ( !error && update && renderer )
998+- FT_Set_Renderer( library, renderer, 0, 0 );
999+-
1000+ return error;
1001+ }
1002+
1003+Index: freetype-2.5.2/src/raster/ftraster.c
1004+===================================================================
1005+--- freetype-2.5.2.orig/src/raster/ftraster.c
1006++++ freetype-2.5.2/src/raster/ftraster.c
1007+@@ -150,14 +150,6 @@
1008+ /* define DEBUG_RASTER if you want to compile a debugging version */
1009+ /* #define DEBUG_RASTER */
1010+
1011+- /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */
1012+- /* 5-levels anti-aliasing */
1013+-/* #define FT_RASTER_OPTION_ANTI_ALIASING */
1014+-
1015+- /* The size of the two-lines intermediate bitmap used */
1016+- /* for anti-aliasing, in bytes. */
1017+-#define RASTER_GRAY_LINES 2048
1018+-
1019+
1020+ /*************************************************************************/
1021+ /*************************************************************************/
1022+@@ -514,9 +506,6 @@
1023+
1024+ Short traceIncr; /* sweep's increment in target bitmap */
1025+
1026+- Short gray_min_x; /* current min x during gray rendering */
1027+- Short gray_max_x; /* current max x during gray rendering */
1028+-
1029+ /* dispatch variables */
1030+
1031+ Function_Sweep_Init* Proc_Sweep_Init;
1032+@@ -529,45 +518,19 @@
1033+ Bool second_pass; /* indicates whether a horizontal pass */
1034+ /* should be performed to control */
1035+ /* drop-out accurately when calling */
1036+- /* Render_Glyph. Note that there is */
1037+- /* no horizontal pass during gray */
1038+- /* rendering. */
1039++ /* Render_Glyph. */
1040+
1041+ TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */
1042+
1043+ black_TBand band_stack[16]; /* band stack used for sub-banding */
1044+ Int band_top; /* band stack top */
1045+
1046+-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
1047+-
1048+- Byte* grays;
1049+-
1050+- Byte gray_lines[RASTER_GRAY_LINES];
1051+- /* Intermediate table used to render the */
1052+- /* graylevels pixmaps. */
1053+- /* gray_lines is a buffer holding two */
1054+- /* monochrome scanlines */
1055+-
1056+- Short gray_width; /* width in bytes of one monochrome */
1057+- /* intermediate scanline of gray_lines. */
1058+- /* Each gray pixel takes 2 bits long there */
1059+-
1060+- /* The gray_lines must hold 2 lines, thus with size */
1061+- /* in bytes of at least `gray_width*2'. */
1062+-
1063+-#endif /* FT_RASTER_ANTI_ALIASING */
1064+-
1065+ };
1066+
1067+
1068+ typedef struct black_TRaster_
1069+ {
1070+- char* buffer;
1071+- long buffer_size;
1072+ void* memory;
1073+- black_PWorker worker;
1074+- Byte grays[5];
1075+- Short gray_width;
1076+
1077+ } black_TRaster, *black_PRaster;
1078+
1079+@@ -583,70 +546,6 @@
1080+ #endif /* !FT_STATIC_RASTER */
1081+
1082+
1083+-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
1084+-
1085+- /* A lookup table used to quickly count set bits in four gray 2x2 */
1086+- /* cells. The values of the table have been produced with the */
1087+- /* following code: */
1088+- /* */
1089+- /* for ( i = 0; i < 256; i++ ) */
1090+- /* { */
1091+- /* l = 0; */
1092+- /* j = i; */
1093+- /* */
1094+- /* for ( c = 0; c < 4; c++ ) */
1095+- /* { */
1096+- /* l <<= 4; */
1097+- /* */
1098+- /* if ( j & 0x80 ) l++; */
1099+- /* if ( j & 0x40 ) l++; */
1100+- /* */
1101+- /* j = ( j << 2 ) & 0xFF; */
1102+- /* } */
1103+- /* printf( "0x%04X", l ); */
1104+- /* } */
1105+- /* */
1106+-
1107+- static const short count_table[256] =
1108+- {
1109+- 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012,
1110+- 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022,
1111+- 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
1112+- 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
1113+- 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
1114+- 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
1115+- 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212,
1116+- 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222,
1117+- 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
1118+- 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
1119+- 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
1120+- 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
1121+- 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
1122+- 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
1123+- 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
1124+- 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
1125+- 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
1126+- 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
1127+- 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
1128+- 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
1129+- 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
1130+- 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
1131+- 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
1132+- 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
1133+- 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012,
1134+- 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022,
1135+- 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
1136+- 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
1137+- 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
1138+- 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
1139+- 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212,
1140+- 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222
1141+- };
1142+-
1143+-#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
1144+-
1145+-
1146+-
1147+ /*************************************************************************/
1148+ /*************************************************************************/
1149+ /** **/
1150+@@ -2083,7 +1982,8 @@
1151+ /* to be drawn. */
1152+
1153+ lastProfile = ras.cProfile;
1154+- if ( ras.cProfile->flags & Flow_Up )
1155++ if ( ras.top != ras.cProfile->offset &&
1156++ ( ras.cProfile->flags & Flow_Up ) )
1157+ o = IS_TOP_OVERSHOOT( ras.lastY );
1158+ else
1159+ o = IS_BOTTOM_OVERSHOOT( ras.lastY );
1160+@@ -2268,9 +2168,6 @@
1161+ ras.traceOfs = -*min * pitch;
1162+ if ( pitch > 0 )
1163+ ras.traceOfs += ( ras.target.rows - 1 ) * pitch;
1164+-
1165+- ras.gray_min_x = 0;
1166+- ras.gray_max_x = 0;
1167+ }
1168+
1169+
1170+@@ -2315,11 +2212,6 @@
1171+ f1 = (Byte) ( 0xFF >> ( e1 & 7 ) );
1172+ f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) );
1173+
1174+- if ( ras.gray_min_x > c1 )
1175+- ras.gray_min_x = (short)c1;
1176+- if ( ras.gray_max_x < c2 )
1177+- ras.gray_max_x = (short)c2;
1178+-
1179+ target = ras.bTarget + ras.traceOfs + c1;
1180+ c2 -= c1;
1181+
1182+@@ -2483,11 +2375,6 @@
1183+ c1 = (Short)( e1 >> 3 );
1184+ f1 = (Short)( e1 & 7 );
1185+
1186+- if ( ras.gray_min_x > c1 )
1187+- ras.gray_min_x = c1;
1188+- if ( ras.gray_max_x < c1 )
1189+- ras.gray_max_x = c1;
1190+-
1191+ ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 );
1192+ }
1193+ }
1194+@@ -2692,249 +2579,6 @@
1195+ }
1196+
1197+
1198+-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
1199+-
1200+-
1201+- /*************************************************************************/
1202+- /* */
1203+- /* Vertical Gray Sweep Procedure Set */
1204+- /* */
1205+- /* These two routines are used during the vertical gray-levels sweep */
1206+- /* phase by the generic Draw_Sweep() function. */
1207+- /* */
1208+- /* NOTES */
1209+- /* */
1210+- /* - The target pixmap's width *must* be a multiple of 4. */
1211+- /* */
1212+- /* - You have to use the function Vertical_Sweep_Span() for the gray */
1213+- /* span call. */
1214+- /* */
1215+- /*************************************************************************/
1216+-
1217+- static void
1218+- Vertical_Gray_Sweep_Init( RAS_ARGS Short* min,
1219+- Short* max )
1220+- {
1221+- Long pitch, byte_len;
1222+-
1223+-
1224+- *min = *min & -2;
1225+- *max = ( *max + 3 ) & -2;
1226+-
1227+- ras.traceOfs = 0;
1228+- pitch = ras.target.pitch;
1229+- byte_len = -pitch;
1230+- ras.traceIncr = (Short)byte_len;
1231+- ras.traceG = ( *min / 2 ) * byte_len;
1232+-
1233+- if ( pitch > 0 )
1234+- {
1235+- ras.traceG += ( ras.target.rows - 1 ) * pitch;
1236+- byte_len = -byte_len;
1237+- }
1238+-
1239+- ras.gray_min_x = (Short)byte_len;
1240+- ras.gray_max_x = -(Short)byte_len;
1241+- }
1242+-
1243+-
1244+- static void
1245+- Vertical_Gray_Sweep_Step( RAS_ARG )
1246+- {
1247+- short* count = (short*)count_table;
1248+- Byte* grays;
1249+-
1250+-
1251+- ras.traceOfs += ras.gray_width;
1252+-
1253+- if ( ras.traceOfs > ras.gray_width )
1254+- {
1255+- PByte pix;
1256+-
1257+-
1258+- pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4;
1259+- grays = ras.grays;
1260+-
1261+- if ( ras.gray_max_x >= 0 )
1262+- {
1263+- Long last_pixel = ras.target.width - 1;
1264+- Int last_cell = last_pixel >> 2;
1265+- Int last_bit = last_pixel & 3;
1266+- Bool over = 0;
1267+-
1268+- Int c1, c2;
1269+- PByte bit, bit2;
1270+-
1271+-
1272+- if ( ras.gray_max_x >= last_cell && last_bit != 3 )
1273+- {
1274+- ras.gray_max_x = last_cell - 1;
1275+- over = 1;
1276+- }
1277+-
1278+- if ( ras.gray_min_x < 0 )
1279+- ras.gray_min_x = 0;
1280+-
1281+- bit = ras.bTarget + ras.gray_min_x;
1282+- bit2 = bit + ras.gray_width;
1283+-
1284+- c1 = ras.gray_max_x - ras.gray_min_x;
1285+-
1286+- while ( c1 >= 0 )
1287+- {
1288+- c2 = count[*bit] + count[*bit2];
1289+-
1290+- if ( c2 )
1291+- {
1292+- pix[0] = grays[(c2 >> 12) & 0x000F];
1293+- pix[1] = grays[(c2 >> 8 ) & 0x000F];
1294+- pix[2] = grays[(c2 >> 4 ) & 0x000F];
1295+- pix[3] = grays[ c2 & 0x000F];
1296+-
1297+- *bit = 0;
1298+- *bit2 = 0;
1299+- }
1300+-
1301+- bit++;
1302+- bit2++;
1303+- pix += 4;
1304+- c1--;
1305+- }
1306+-
1307+- if ( over )
1308+- {
1309+- c2 = count[*bit] + count[*bit2];
1310+- if ( c2 )
1311+- {
1312+- switch ( last_bit )
1313+- {
1314+- case 2:
1315+- pix[2] = grays[(c2 >> 4 ) & 0x000F];
1316+- case 1:
1317+- pix[1] = grays[(c2 >> 8 ) & 0x000F];
1318+- default:
1319+- pix[0] = grays[(c2 >> 12) & 0x000F];
1320+- }
1321+-
1322+- *bit = 0;
1323+- *bit2 = 0;
1324+- }
1325+- }
1326+- }
1327+-
1328+- ras.traceOfs = 0;
1329+- ras.traceG += ras.traceIncr;
1330+-
1331+- ras.gray_min_x = 32000;
1332+- ras.gray_max_x = -32000;
1333+- }
1334+- }
1335+-
1336+-
1337+- static void
1338+- Horizontal_Gray_Sweep_Span( RAS_ARGS Short y,
1339+- FT_F26Dot6 x1,
1340+- FT_F26Dot6 x2,
1341+- PProfile left,
1342+- PProfile right )
1343+- {
1344+- /* nothing, really */
1345+- FT_UNUSED_RASTER;
1346+- FT_UNUSED( y );
1347+- FT_UNUSED( x1 );
1348+- FT_UNUSED( x2 );
1349+- FT_UNUSED( left );
1350+- FT_UNUSED( right );
1351+- }
1352+-
1353+-
1354+- static void
1355+- Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y,
1356+- FT_F26Dot6 x1,
1357+- FT_F26Dot6 x2,
1358+- PProfile left,
1359+- PProfile right )
1360+- {
1361+- Long e1, e2;
1362+- PByte pixel;
1363+-
1364+-
1365+- /* During the horizontal sweep, we only take care of drop-outs */
1366+-
1367+- e1 = CEILING( x1 );
1368+- e2 = FLOOR ( x2 );
1369+-
1370+- if ( e1 > e2 )
1371+- {
1372+- Int dropOutControl = left->flags & 7;
1373+-
1374+-
1375+- if ( e1 == e2 + ras.precision )
1376+- {
1377+- switch ( dropOutControl )
1378+- {
1379+- case 0: /* simple drop-outs including stubs */
1380+- e1 = e2;
1381+- break;
1382+-
1383+- case 4: /* smart drop-outs including stubs */
1384+- e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
1385+- break;
1386+-
1387+- case 1: /* simple drop-outs excluding stubs */
1388+- case 5: /* smart drop-outs excluding stubs */
1389+- /* see Vertical_Sweep_Drop for details */
1390+-
1391+- /* rightmost stub test */
1392+- if ( left->next == right && left->height <= 0 )
1393+- return;
1394+-
1395+- /* leftmost stub test */
1396+- if ( right->next == left && left->start == y )
1397+- return;
1398+-
1399+- if ( dropOutControl == 1 )
1400+- e1 = e2;
1401+- else
1402+- e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
1403+-
1404+- break;
1405+-
1406+- default: /* modes 2, 3, 6, 7 */
1407+- return; /* no drop-out control */
1408+- }
1409+- }
1410+- else
1411+- return;
1412+- }
1413+-
1414+- if ( e1 >= 0 )
1415+- {
1416+- Byte color;
1417+-
1418+-
1419+- if ( x2 - x1 >= ras.precision_half )
1420+- color = ras.grays[2];
1421+- else
1422+- color = ras.grays[1];
1423+-
1424+- e1 = TRUNC( e1 ) / 2;
1425+- if ( e1 < ras.target.rows )
1426+- {
1427+- pixel = ras.gTarget - e1 * ras.target.pitch + y / 2;
1428+- if ( ras.target.pitch > 0 )
1429+- pixel += ( ras.target.rows - 1 ) * ras.target.pitch;
1430+-
1431+- if ( pixel[0] == ras.grays[0] )
1432+- pixel[0] = color;
1433+- }
1434+- }
1435+- }
1436+-
1437+-
1438+-#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
1439+-
1440+-
1441+ /*************************************************************************/
1442+ /* */
1443+ /* Generic Sweep Drawing routine */
1444+@@ -3329,118 +2973,10 @@
1445+ }
1446+
1447+
1448+-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
1449+-
1450+- /*************************************************************************/
1451+- /* */
1452+- /* <Function> */
1453+- /* Render_Gray_Glyph */
1454+- /* */
1455+- /* <Description> */
1456+- /* Render a glyph with grayscaling. Sub-banding if needed. */
1457+- /* */
1458+- /* <Return> */
1459+- /* FreeType error code. 0 means success. */
1460+- /* */
1461+- FT_LOCAL_DEF( FT_Error )
1462+- Render_Gray_Glyph( RAS_ARG )
1463+- {
1464+- Long pixel_width;
1465+- FT_Error error;
1466+-
1467+-
1468+- Set_High_Precision( RAS_VARS ras.outline.flags &
1469+- FT_OUTLINE_HIGH_PRECISION );
1470+- ras.scale_shift = ras.precision_shift + 1;
1471+-
1472+- if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
1473+- ras.dropOutControl = 2;
1474+- else
1475+- {
1476+- if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )
1477+- ras.dropOutControl = 4;
1478+- else
1479+- ras.dropOutControl = 0;
1480+-
1481+- if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )
1482+- ras.dropOutControl += 1;
1483+- }
1484+-
1485+- ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS );
1486+-
1487+- /* Vertical Sweep */
1488+-
1489+- ras.band_top = 0;
1490+- ras.band_stack[0].y_min = 0;
1491+- ras.band_stack[0].y_max = 2 * ras.target.rows - 1;
1492+-
1493+- ras.bWidth = ras.gray_width;
1494+- pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 );
1495+-
1496+- if ( ras.bWidth > pixel_width )
1497+- ras.bWidth = pixel_width;
1498+-
1499+- ras.bWidth = ras.bWidth * 8;
1500+- ras.bTarget = (Byte*)ras.gray_lines;
1501+- ras.gTarget = (Byte*)ras.target.buffer;
1502+-
1503+- ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init;
1504+- ras.Proc_Sweep_Span = Vertical_Sweep_Span;
1505+- ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
1506+- ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step;
1507+-
1508+- error = Render_Single_Pass( RAS_VARS 0 );
1509+- if ( error )
1510+- return error;
1511+-
1512+- /* Horizontal Sweep */
1513+- if ( ras.second_pass && ras.dropOutControl != 2 )
1514+- {
1515+- ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
1516+- ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span;
1517+- ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop;
1518+- ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
1519+-
1520+- ras.band_top = 0;
1521+- ras.band_stack[0].y_min = 0;
1522+- ras.band_stack[0].y_max = ras.target.width * 2 - 1;
1523+-
1524+- error = Render_Single_Pass( RAS_VARS 1 );
1525+- if ( error )
1526+- return error;
1527+- }
1528+-
1529+- return Raster_Err_None;
1530+- }
1531+-
1532+-#else /* !FT_RASTER_OPTION_ANTI_ALIASING */
1533+-
1534+- FT_LOCAL_DEF( FT_Error )
1535+- Render_Gray_Glyph( RAS_ARG )
1536+- {
1537+- FT_UNUSED_RASTER;
1538+-
1539+- return FT_THROW( Unsupported );
1540+- }
1541+-
1542+-#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */
1543+-
1544+-
1545+ static void
1546+ ft_black_init( black_PRaster raster )
1547+ {
1548+-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
1549+- FT_UInt n;
1550+-
1551+-
1552+- /* set default 5-levels gray palette */
1553+- for ( n = 0; n < 5; n++ )
1554+- raster->grays[n] = n * 255 / 4;
1555+-
1556+- raster->gray_width = RASTER_GRAY_LINES / 2;
1557+-#else
1558+ FT_UNUSED( raster );
1559+-#endif
1560+ }
1561+
1562+
1563+@@ -3517,25 +3053,9 @@
1564+ char* pool_base,
1565+ long pool_size )
1566+ {
1567+- if ( raster )
1568+- {
1569+- if ( pool_base && pool_size >= (long)sizeof ( black_TWorker ) + 2048 )
1570+- {
1571+- black_PWorker worker = (black_PWorker)pool_base;
1572+-
1573+-
1574+- raster->buffer = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 );
1575+- raster->buffer_size = (long)( pool_base + pool_size -
1576+- (char*)raster->buffer );
1577+- raster->worker = worker;
1578+- }
1579+- else
1580+- {
1581+- raster->buffer = NULL;
1582+- raster->buffer_size = 0;
1583+- raster->worker = NULL;
1584+- }
1585+- }
1586++ FT_UNUSED( raster );
1587++ FT_UNUSED( pool_base );
1588++ FT_UNUSED( pool_size );
1589+ }
1590+
1591+
1592+@@ -3544,25 +3064,9 @@
1593+ unsigned long mode,
1594+ const char* palette )
1595+ {
1596+-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
1597+-
1598+- if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) )
1599+- {
1600+- /* set 5-levels gray palette */
1601+- raster->grays[0] = palette[0];
1602+- raster->grays[1] = palette[1];
1603+- raster->grays[2] = palette[2];
1604+- raster->grays[3] = palette[3];
1605+- raster->grays[4] = palette[4];
1606+- }
1607+-
1608+-#else
1609+-
1610+ FT_UNUSED( raster );
1611+ FT_UNUSED( mode );
1612+ FT_UNUSED( palette );
1613+-
1614+-#endif
1615+ }
1616+
1617+
1618+@@ -3572,10 +3076,13 @@
1619+ {
1620+ const FT_Outline* outline = (const FT_Outline*)params->source;
1621+ const FT_Bitmap* target_map = params->target;
1622+- black_PWorker worker;
1623+
1624++ black_TWorker worker[1];
1625+
1626+- if ( !raster || !raster->buffer || !raster->buffer_size )
1627++ Long buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( Long )];
1628++
1629++
1630++ if ( !raster )
1631+ return FT_THROW( Not_Ini );
1632+
1633+ if ( !outline )
1634+@@ -3592,12 +3099,13 @@
1635+ outline->contours[outline->n_contours - 1] + 1 )
1636+ return FT_THROW( Invalid );
1637+
1638+- worker = raster->worker;
1639+-
1640+ /* this version of the raster does not support direct rendering, sorry */
1641+ if ( params->flags & FT_RASTER_FLAG_DIRECT )
1642+ return FT_THROW( Unsupported );
1643+
1644++ if ( params->flags & FT_RASTER_FLAG_AA )
1645++ return FT_THROW( Unsupported );
1646++
1647+ if ( !target_map )
1648+ return FT_THROW( Invalid );
1649+
1650+@@ -3611,19 +3119,10 @@
1651+ ras.outline = *outline;
1652+ ras.target = *target_map;
1653+
1654+- worker->buff = (PLong) raster->buffer;
1655+- worker->sizeBuff = worker->buff +
1656+- raster->buffer_size / sizeof ( Long );
1657+-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
1658+- worker->grays = raster->grays;
1659+- worker->gray_width = raster->gray_width;
1660+-
1661+- FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 );
1662+-#endif
1663++ worker->buff = buffer;
1664++ worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */
1665+
1666+- return ( params->flags & FT_RASTER_FLAG_AA )
1667+- ? Render_Gray_Glyph( RAS_VAR )
1668+- : Render_Glyph( RAS_VAR );
1669++ return Render_Glyph( RAS_VAR );
1670+ }
1671+
1672+
1673+Index: freetype-2.5.2/src/raster/ftrend1.c
1674+===================================================================
1675+--- freetype-2.5.2.orig/src/raster/ftrend1.c
1676++++ freetype-2.5.2/src/raster/ftrend1.c
1677+@@ -120,38 +120,11 @@
1678+ }
1679+
1680+ /* check rendering mode */
1681+-#ifndef FT_CONFIG_OPTION_PIC
1682+ if ( mode != FT_RENDER_MODE_MONO )
1683+ {
1684+ /* raster1 is only capable of producing monochrome bitmaps */
1685+- if ( render->clazz == &ft_raster1_renderer_class )
1686+- return FT_THROW( Cannot_Render_Glyph );
1687++ return FT_THROW( Cannot_Render_Glyph );
1688+ }
1689+- else
1690+- {
1691+- /* raster5 is only capable of producing 5-gray-levels bitmaps */
1692+- if ( render->clazz == &ft_raster5_renderer_class )
1693+- return FT_THROW( Cannot_Render_Glyph );
1694+- }
1695+-#else /* FT_CONFIG_OPTION_PIC */
1696+- /* When PIC is enabled, we cannot get to the class object */
1697+- /* so instead we check the final character in the class name */
1698+- /* ("raster5" or "raster1"). Yes this is a hack. */
1699+- /* The "correct" thing to do is have different render function */
1700+- /* for each of the classes. */
1701+- if ( mode != FT_RENDER_MODE_MONO )
1702+- {
1703+- /* raster1 is only capable of producing monochrome bitmaps */
1704+- if ( render->clazz->root.module_name[6] == '1' )
1705+- return FT_THROW( Cannot_Render_Glyph );
1706+- }
1707+- else
1708+- {
1709+- /* raster5 is only capable of producing 5-gray-levels bitmaps */
1710+- if ( render->clazz->root.module_name[6] == '5' )
1711+- return FT_THROW( Cannot_Render_Glyph );
1712+- }
1713+-#endif /* FT_CONFIG_OPTION_PIC */
1714+
1715+ outline = &slot->outline;
1716+
1717+@@ -194,19 +167,8 @@
1718+ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
1719+ }
1720+
1721+- /* allocate new one, depends on pixel format */
1722+- if ( !( mode & FT_RENDER_MODE_MONO ) )
1723+- {
1724+- /* we pad to 32 bits, only for backwards compatibility with FT 1.x */
1725+- pitch = FT_PAD_CEIL( width, 4 );
1726+- bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
1727+- bitmap->num_grays = 256;
1728+- }
1729+- else
1730+- {
1731+- pitch = ( ( width + 15 ) >> 4 ) << 1;
1732+- bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
1733+- }
1734++ pitch = ( ( width + 15 ) >> 4 ) << 1;
1735++ bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
1736+
1737+ bitmap->width = width;
1738+ bitmap->rows = height;
1739+@@ -225,9 +187,6 @@
1740+ params.source = outline;
1741+ params.flags = 0;
1742+
1743+- if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY )
1744+- params.flags |= FT_RASTER_FLAG_AA;
1745+-
1746+ /* render outline into the bitmap */
1747+ error = render->raster_render( render->raster, &params );
1748+
1749+Index: freetype-2.5.2/src/smooth/ftgrays.c
1750+===================================================================
1751+--- freetype-2.5.2.orig/src/smooth/ftgrays.c
1752++++ freetype-2.5.2/src/smooth/ftgrays.c
1753+@@ -461,11 +461,7 @@
1754+
1755+ typedef struct gray_TRaster_
1756+ {
1757+- void* buffer;
1758+- long buffer_size;
1759+- int band_size;
1760+ void* memory;
1761+- gray_PWorker worker;
1762+
1763+ } gray_TRaster, *gray_PRaster;
1764+
1765+@@ -1940,12 +1936,17 @@
1766+ gray_raster_render( gray_PRaster raster,
1767+ const FT_Raster_Params* params )
1768+ {
1769+- const FT_Outline* outline = (const FT_Outline*)params->source;
1770+- const FT_Bitmap* target_map = params->target;
1771+- gray_PWorker worker;
1772++ const FT_Outline* outline = (const FT_Outline*)params->source;
1773++ const FT_Bitmap* target_map = params->target;
1774+
1775++ gray_TWorker worker[1];
1776+
1777+- if ( !raster || !raster->buffer || !raster->buffer_size )
1778++ TCell buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( TCell )];
1779++ long buffer_size = sizeof ( buffer );
1780++ int band_size = (int)( buffer_size / ( sizeof ( TCell ) * 8 ) );
1781++
1782++
1783++ if ( !raster )
1784+ return FT_THROW( Invalid_Argument );
1785+
1786+ if ( !outline )
1787+@@ -1962,8 +1963,6 @@
1788+ outline->contours[outline->n_contours - 1] + 1 )
1789+ return FT_THROW( Invalid_Outline );
1790+
1791+- worker = raster->worker;
1792+-
1793+ /* if direct mode is not set, we must have a target bitmap */
1794+ if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
1795+ {
1796+@@ -2001,13 +2000,14 @@
1797+ ras.clip_box.yMax = 32767L;
1798+ }
1799+
1800+- gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size );
1801++ gray_init_cells( RAS_VAR_ buffer, buffer_size );
1802+
1803+ ras.outline = *outline;
1804+ ras.num_cells = 0;
1805+ ras.invalid = 1;
1806+- ras.band_size = raster->band_size;
1807++ ras.band_size = band_size;
1808+ ras.num_gray_spans = 0;
1809++ ras.span_y = 0;
1810+
1811+ if ( params->flags & FT_RASTER_FLAG_DIRECT )
1812+ {
1813+@@ -2091,34 +2091,9 @@
1814+ char* pool_base,
1815+ long pool_size )
1816+ {
1817+- gray_PRaster rast = (gray_PRaster)raster;
1818+-
1819+-
1820+- if ( raster )
1821+- {
1822+- if ( pool_base && pool_size >= (long)sizeof ( gray_TWorker ) + 2048 )
1823+- {
1824+- gray_PWorker worker = (gray_PWorker)pool_base;
1825+-
1826+-
1827+- rast->worker = worker;
1828+- rast->buffer = pool_base +
1829+- ( ( sizeof ( gray_TWorker ) +
1830+- sizeof ( TCell ) - 1 ) &
1831+- ~( sizeof ( TCell ) - 1 ) );
1832+- rast->buffer_size = (long)( ( pool_base + pool_size ) -
1833+- (char*)rast->buffer ) &
1834+- ~( sizeof ( TCell ) - 1 );
1835+- rast->band_size = (int)( rast->buffer_size /
1836+- ( sizeof ( TCell ) * 8 ) );
1837+- }
1838+- else
1839+- {
1840+- rast->buffer = NULL;
1841+- rast->buffer_size = 0;
1842+- rast->worker = NULL;
1843+- }
1844+- }
1845++ FT_UNUSED( raster );
1846++ FT_UNUSED( pool_base );
1847++ FT_UNUSED( pool_size );
1848+ }
1849+
1850+
1851+Index: freetype-2.5.2/src/truetype/ttgload.c
1852+===================================================================
1853+--- freetype-2.5.2.orig/src/truetype/ttgload.c
1854++++ freetype-2.5.2/src/truetype/ttgload.c
1855+@@ -802,7 +802,6 @@
1856+
1857+ if ( n_ins > 0 )
1858+ {
1859+- FT_Bool debug;
1860+ FT_Error error;
1861+
1862+ FT_GlyphLoader gloader = loader->gloader;
1863+@@ -817,10 +816,7 @@
1864+ loader->exec->is_composite = is_composite;
1865+ loader->exec->pts = *zone;
1866+
1867+- debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) &&
1868+- ((TT_Size)loader->size)->debug );
1869+-
1870+- error = TT_Run_Context( loader->exec, debug );
1871++ error = TT_Run_Context( loader->exec );
1872+ if ( error && loader->exec->pedantic_hinting )
1873+ return error;
1874+
1875+@@ -2116,8 +2112,7 @@
1876+ }
1877+
1878+ /* query new execution context */
1879+- exec = size->debug ? size->context
1880+- : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
1881++ exec = size->context;
1882+ if ( !exec )
1883+ return FT_THROW( Could_Not_Find_Context );
1884+
1885+Index: freetype-2.5.2/src/truetype/ttinterp.c
1886+===================================================================
1887+--- freetype-2.5.2.orig/src/truetype/ttinterp.c
1888++++ freetype-2.5.2/src/truetype/ttinterp.c
1889+@@ -714,12 +714,8 @@
1890+ /* <Return> */
1891+ /* TrueType error code. 0 means success. */
1892+ /* */
1893+- /* <Note> */
1894+- /* Only the glyph loader and debugger should call this function. */
1895+- /* */
1896+ FT_LOCAL_DEF( FT_Error )
1897+- TT_Run_Context( TT_ExecContext exec,
1898+- FT_Bool debug )
1899++ TT_Run_Context( TT_ExecContext exec )
1900+ {
1901+ FT_Error error;
1902+
1903+@@ -754,16 +750,7 @@
1904+ exec->top = 0;
1905+ exec->callTop = 0;
1906+
1907+-#if 1
1908+- FT_UNUSED( debug );
1909+-
1910+ return exec->face->interpreter( exec );
1911+-#else
1912+- if ( !debug )
1913+- return TT_RunIns( exec );
1914+- else
1915+- return FT_Err_Ok;
1916+-#endif
1917+ }
1918+
1919+
1920+@@ -796,32 +783,26 @@
1921+ FT_EXPORT_DEF( TT_ExecContext )
1922+ TT_New_Context( TT_Driver driver )
1923+ {
1924+- TT_ExecContext exec;
1925+ FT_Memory memory;
1926++ FT_Error error;
1927+
1928++ TT_ExecContext exec;
1929+
1930+- memory = driver->root.root.memory;
1931+- exec = driver->context;
1932+-
1933+- if ( !driver->context )
1934+- {
1935+- FT_Error error;
1936+-
1937+-
1938+- /* allocate object */
1939+- if ( FT_NEW( exec ) )
1940+- goto Fail;
1941++ if ( !driver )
1942++ goto Fail;
1943+
1944+- /* initialize it; in case of error this deallocates `exec' too */
1945+- error = Init_Context( exec, memory );
1946+- if ( error )
1947+- goto Fail;
1948++ memory = driver->root.root.memory;
1949+
1950+- /* store it into the driver */
1951+- driver->context = exec;
1952+- }
1953++ /* allocate object */
1954++ if ( FT_NEW( exec ) )
1955++ goto Fail;
1956++
1957++ /* initialize it; in case of error this deallocates `exec' too */
1958++ error = Init_Context( exec, memory );
1959++ if ( error )
1960++ goto Fail;
1961+
1962+- return driver->context;
1963++ return exec;
1964+
1965+ Fail:
1966+ return NULL;
1967+Index: freetype-2.5.2/src/truetype/ttinterp.h
1968+===================================================================
1969+--- freetype-2.5.2.orig/src/truetype/ttinterp.h
1970++++ freetype-2.5.2/src/truetype/ttinterp.h
1971+@@ -340,6 +340,7 @@
1972+ /* */
1973+ /* <Note> */
1974+ /* Only the glyph loader and debugger should call this function. */
1975++ /* (And right now only the glyph loader uses it.) */
1976+ /* */
1977+ FT_EXPORT( TT_ExecContext )
1978+ TT_New_Context( TT_Driver driver );
1979+@@ -359,8 +360,7 @@
1980+ TT_Size ins );
1981+
1982+ FT_LOCAL( FT_Error )
1983+- TT_Run_Context( TT_ExecContext exec,
1984+- FT_Bool debug );
1985++ TT_Run_Context( TT_ExecContext exec );
1986+ #endif /* TT_USE_BYTECODE_INTERPRETER */
1987+
1988+
1989+Index: freetype-2.5.2/src/truetype/ttobjs.c
1990+===================================================================
1991+--- freetype-2.5.2.orig/src/truetype/ttobjs.c
1992++++ freetype-2.5.2/src/truetype/ttobjs.c
1993+@@ -751,14 +751,7 @@
1994+ FT_Error error;
1995+
1996+
1997+- /* debugging instances have their own context */
1998+- if ( size->debug )
1999+- exec = size->context;
2000+- else
2001+- exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
2002+-
2003+- if ( !exec )
2004+- return FT_THROW( Could_Not_Find_Context );
2005++ exec = size->context;
2006+
2007+ TT_Load_Context( exec, face, size );
2008+
2009+@@ -845,14 +838,7 @@
2010+ FT_Error error;
2011+
2012+
2013+- /* debugging instances have their own context */
2014+- if ( size->debug )
2015+- exec = size->context;
2016+- else
2017+- exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
2018+-
2019+- if ( !exec )
2020+- return FT_THROW( Could_Not_Find_Context );
2021++ exec = size->context;
2022+
2023+ TT_Load_Context( exec, face, size );
2024+
2025+@@ -872,14 +858,11 @@
2026+
2027+ if ( face->cvt_program_size > 0 )
2028+ {
2029+- error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
2030++ TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
2031+
2032+- if ( !error && !size->debug )
2033+- {
2034+- FT_TRACE4(( "Executing `prep' table.\n" ));
2035++ FT_TRACE4(( "Executing `prep' table.\n" ));
2036+
2037+- error = face->interpreter( exec );
2038+- }
2039++ error = face->interpreter( exec );
2040+ }
2041+ else
2042+ error = FT_Err_Ok;
2043+@@ -924,12 +907,10 @@
2044+ TT_Face face = (TT_Face)ftsize->face;
2045+ FT_Memory memory = face->root.memory;
2046+
2047+-
2048+- if ( size->debug )
2049++ if ( size->context )
2050+ {
2051+- /* the debug context must be deleted by the debugger itself */
2052++ TT_Done_Context( size->context );
2053+ size->context = NULL;
2054+- size->debug = FALSE;
2055+ }
2056+
2057+ FT_FREE( size->cvt );
2058+@@ -977,6 +958,8 @@
2059+ size->bytecode_ready = 1;
2060+ size->cvt_ready = 0;
2061+
2062++ size->context = TT_New_Context( (TT_Driver)face->root.driver );
2063++
2064+ size->max_function_defs = maxp->maxFunctionDefs;
2065+ size->max_instruction_defs = maxp->maxInstructionDefs;
2066+
2067+@@ -1261,10 +1244,6 @@
2068+
2069+ TT_Driver driver = (TT_Driver)ttdriver;
2070+
2071+-
2072+- if ( !TT_New_Context( driver ) )
2073+- return FT_THROW( Could_Not_Find_Context );
2074+-
2075+ #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2076+ driver->interpreter_version = TT_INTERPRETER_VERSION_38;
2077+ #else
2078+@@ -1295,20 +1274,7 @@
2079+ FT_LOCAL_DEF( void )
2080+ tt_driver_done( FT_Module ttdriver ) /* TT_Driver */
2081+ {
2082+-#ifdef TT_USE_BYTECODE_INTERPRETER
2083+- TT_Driver driver = (TT_Driver)ttdriver;
2084+-
2085+-
2086+- /* destroy the execution context */
2087+- if ( driver->context )
2088+- {
2089+- TT_Done_Context( driver->context );
2090+- driver->context = NULL;
2091+- }
2092+-#else
2093+ FT_UNUSED( ttdriver );
2094+-#endif
2095+-
2096+ }
2097+
2098+
2099+Index: freetype-2.5.2/src/truetype/ttobjs.h
2100+===================================================================
2101+--- freetype-2.5.2.orig/src/truetype/ttobjs.h
2102++++ freetype-2.5.2/src/truetype/ttobjs.h
2103+@@ -324,13 +324,6 @@
2104+
2105+ TT_GlyphZoneRec twilight; /* The instance's twilight zone */
2106+
2107+- /* debugging variables */
2108+-
2109+- /* When using the debugger, we must keep the */
2110+- /* execution context tied to the instance */
2111+- /* object rather than asking it on demand. */
2112+-
2113+- FT_Bool debug;
2114+ TT_ExecContext context;
2115+
2116+ FT_Bool bytecode_ready;
2117+@@ -349,7 +342,6 @@
2118+ {
2119+ FT_DriverRec root;
2120+
2121+- TT_ExecContext context; /* execution context */
2122+ TT_GlyphZoneRec zone; /* glyph loader points zone */
2123+
2124+ FT_UInt interpreter_version;
2125
2126=== modified file 'debian/patches-freetype/series'
2127--- debian/patches-freetype/series 2014-09-19 17:10:38 +0000
2128+++ debian/patches-freetype/series 2015-01-26 16:03:08 +0000
2129@@ -10,3 +10,4 @@
2130 0002-Fix-Savannah-bug-42418.patch
2131 freetype-config.diff
2132 verbose-libtool.patch
2133+multi-thread-violations.patch

Subscribers

People subscribed via source and target branches