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

Proposed by Marco Trevisan (Treviño)
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 Needs Information
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.
Revision history for this message
Dmitry Shachnev (mitya57) wrote :

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

review: Needs Information
Revision history for this message
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)

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) :

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