[Merge] lp:~3v1n0/ubuntu/vivid/freetype/multithread-safe into lp:ubuntu/freetype
Marco Trevisan (Treviño)
mail at 3v1n0.net
Mon Jan 26 14:42:12 UTC 2015
Diff comments:
> === modified file 'debian/changelog'
> --- debian/changelog 2014-09-19 17:11:19 +0000
> +++ debian/changelog 2015-01-23 02:45:23 +0000
> @@ -1,3 +1,10 @@
> +freetype (2.5.2-2ubuntu2) UNRELEASED; urgency=medium
> +
> + * Added patchset to fix multithread violations, LP: #1199571
> + - debian/patches-freetype/multi-thread-violations.patch
> +
> + -- Marco Trevisan (Treviño) <marco at ubuntu.com> Fri, 23 Jan 2015 03:23:18 +0100
> +
> freetype (2.5.2-2ubuntu1) utopic; urgency=medium
>
> * Merge from Debian unstable, remaining changes:
>
> === modified file 'debian/libfreetype6.symbols'
> --- debian/libfreetype6.symbols 2013-12-29 02:56:08 +0000
> +++ debian/libfreetype6.symbols 2015-01-23 02:45:23 +0000
> @@ -311,7 +311,6 @@
> ft_property_do at Base 2.4.11
> ft_raccess_guess_table at Base 2.4.9
> ft_raster1_renderer_class at Base 2.2.1
> - ft_raster5_renderer_class at Base 2.2.1
This looks like a private symbol to me, BTW I guess we can both update the SONAME and re-add this definition.
> ft_service_list_lookup at Base 2.2.1
> ft_smooth_lcd_renderer_class at Base 2.2.1
> ft_smooth_lcdv_renderer_class at Base 2.2.1
>
> === added file 'debian/patches-freetype/multi-thread-violations.patch'
> --- debian/patches-freetype/multi-thread-violations.patch 1970-01-01 00:00:00 +0000
> +++ debian/patches-freetype/multi-thread-violations.patch 2015-01-23 02:45:23 +0000
> @@ -0,0 +1,2098 @@
> +Author: Behdad Esfahbod <behdad at behdad.org>
> +Description: Multithread-safe FreeType
> +Forwarded: http://www.mail-archive.com/freetype-devel@nongnu.org/msg06758.html
> +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=69034
> +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/freetype/+bug/1199571
> +Origin: upstream, https://github.com/behdad/freetype/commits/ftthread
> +Applied-Upstream: 2.5.6, git commits 89bc8d4d, 531d463a, 747ae2c8, 8dc86358,
> + a773c304, 6dfdaf4d, 51634253, 603292d7, b2ba6866, c242fe41, ae6699f8, a4117fbd,
> + c2733656, 6f16b100, 56ddafa0, 48c86628, 4eff854c
> +
> +
> +Index: freetype-2.5.2/devel/ftoption.h
> +===================================================================
> +--- freetype-2.5.2.orig/devel/ftoption.h 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/devel/ftoption.h 2015-01-23 02:55:34.532290414 +0100
> +@@ -365,10 +365,6 @@
> + /* The size in bytes of the render pool used by the scan-line converter */
> + /* to do all of its work. */
> + /* */
> +- /* This must be greater than 4KByte if you use FreeType to rasterize */
> +- /* glyphs; otherwise, you may set it to zero to avoid unnecessary */
> +- /* allocation of the render pool. */
> +- /* */
> + #define FT_RENDER_POOL_SIZE 16384L
> +
> +
> +Index: freetype-2.5.2/include/config/ftoption.h
> +===================================================================
> +--- freetype-2.5.2.orig/include/config/ftoption.h 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/include/config/ftoption.h 2015-01-23 02:55:34.536290423 +0100
> +@@ -365,10 +365,6 @@
> + /* The size in bytes of the render pool used by the scan-line converter */
> + /* to do all of its work. */
> + /* */
> +- /* This must be greater than 4KByte if you use FreeType to rasterize */
> +- /* glyphs; otherwise, you may set it to zero to avoid unnecessary */
> +- /* allocation of the render pool. */
> +- /* */
> + #define FT_RENDER_POOL_SIZE 16384L
> +
> +
> +Index: freetype-2.5.2/include/freetype.h
> +===================================================================
> +--- freetype-2.5.2.orig/include/freetype.h 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/include/freetype.h 2015-01-23 02:55:34.536290423 +0100
> +@@ -332,8 +332,11 @@
> + /* It also embeds a memory manager (see @FT_Memory), as well as a */
> + /* scan-line converter object (see @FT_Raster). */
> + /* */
> +- /* In multi-threaded applications, make sure that the same FT_Library */
> +- /* object or any of its children doesn't get accessed in parallel. */
> ++ /* In multi-threaded applications it is easiest to use one */
> ++ /* `FT_Library' object per thread. In case this is too cumbersome, */
> ++ /* a single `FT_Library' object across threads is possible also */
> ++ /* (since FreeType version 2.5.6), as long as a mutex lock is used */
> ++ /* around @FT_New_Face and @FT_Done_Face. */
> + /* */
> + /* <Note> */
> + /* Library objects are normally created by @FT_Init_FreeType, and */
> +@@ -401,6 +404,14 @@
> + /* */
> + /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */
> + /* */
> ++ /* An `FT_Face' object can only be safely used from one thread at a */
> ++ /* time. Similarly, creation and destruction of `FT_Face' with the */
> ++ /* same @FT_Library object can only be done from one thread at a */
> ++ /* time. On the other hand, functions like @FT_Load_Glyph and its */
> ++ /* siblings are thread-safe and do not need the lock to be held as */
> ++ /* long as the same `FT_Face' object is not used from multiple */
> ++ /* threads at the same time. */
> ++ /* */
> + /* <Also> */
> + /* See @FT_FaceRec for the publicly accessible fields of a given face */
> + /* object. */
> +@@ -1701,8 +1712,8 @@
> + /* use @FT_New_Library instead, followed by a call to */
> + /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */
> + /* */
> +- /* For multi-threading applications each thread should have its own */
> +- /* FT_Library object. */
> ++ /* See the documentation of @FT_Library and @FT_Face for */
> ++ /* multi-threading issues. */
> + /* */
> + /* If you need reference-counting (cf. @FT_Reference_Library), use */
> + /* @FT_New_Library and @FT_Done_Library. */
> +Index: freetype-2.5.2/include/ftimage.h
> +===================================================================
> +--- freetype-2.5.2.orig/include/ftimage.h 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/include/ftimage.h 2015-01-23 02:55:34.536290423 +0100
> +@@ -1179,10 +1179,10 @@
> + /* FT_Raster_ResetFunc */
> + /* */
> + /* <Description> */
> +- /* FreeType provides an area of memory called the `render pool', */
> +- /* available to all registered rasters. This pool can be freely used */
> +- /* during a given scan-conversion but is shared by all rasters. Its */
> +- /* content is thus transient. */
> ++ /* FreeType used to provide an area of memory called the `render */
> ++ /* pool' available to all registered rasters. This was not thread */
> ++ /* safe however and now FreeType never allocates this pool. NULL */
> ++ /* is always passed in as pool_base. */
> + /* */
> + /* This function is called each time the render pool changes, or just */
> + /* after a new raster object is created. */
> +@@ -1195,10 +1195,9 @@
> + /* pool_size :: The size in bytes of the render pool. */
> + /* */
> + /* <Note> */
> +- /* Rasters can ignore the render pool and rely on dynamic memory */
> ++ /* Rasters should ignore the render pool and rely on dynamic or stack */
> + /* allocation if they want to (a handle to the memory allocator is */
> +- /* passed to the raster constructor). However, this is not */
> +- /* recommended for efficiency purposes. */
> ++ /* passed to the raster constructor). */
> + /* */
> + typedef void
> + (*FT_Raster_ResetFunc)( FT_Raster raster,
> +Index: freetype-2.5.2/include/ftrender.h
> +===================================================================
> +--- freetype-2.5.2.orig/include/ftrender.h 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/include/ftrender.h 2015-01-23 02:55:34.536290423 +0100
> +@@ -212,13 +212,8 @@
> + /* */
> + /* This doesn't change the current renderer for other formats. */
> + /* */
> +- /* Currently, only the B/W renderer, if compiled with */
> +- /* FT_RASTER_OPTION_ANTI_ALIASING (providing a 5-levels */
> +- /* anti-aliasing mode; this option must be set directly in */
> +- /* `ftraster.c' and is undefined by default) accepts a single tag */
> +- /* `pal5' to set its gray palette as a character string with */
> +- /* 5~elements. Consequently, the third and fourth argument are zero */
> +- /* normally. */
> ++ /* Currently, no FreeType renderer module uses `parameters'; you */
> ++ /* should thus always pass NULL as the value. */
> + /* */
> + FT_EXPORT( FT_Error )
> + FT_Set_Renderer( FT_Library library,
> +Index: freetype-2.5.2/include/internal/ftobjs.h
> +===================================================================
> +--- freetype-2.5.2.orig/include/internal/ftobjs.h 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/include/internal/ftobjs.h 2015-01-23 02:55:34.540290431 +0100
> +@@ -738,9 +738,8 @@
> + /* faces_list :: The list of faces currently opened by this */
> + /* driver. */
> + /* */
> +- /* glyph_loader :: The glyph loader for all faces managed by this */
> +- /* driver. This object isn't defined for unscalable */
> +- /* formats. */
> ++ /* glyph_loader :: Unused. Used to be glyph loader for all faces */
> ++ /* managed by this driver. */
> + /* */
> + typedef struct FT_DriverRec_
> + {
> +Index: freetype-2.5.2/src/autofit/afhints.c
> +===================================================================
> +--- freetype-2.5.2.orig/src/autofit/afhints.c 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/autofit/afhints.c 2015-01-23 02:55:34.540290431 +0100
> +@@ -43,7 +43,15 @@
> + AF_Segment segment = NULL;
> +
> +
> +- if ( axis->num_segments >= axis->max_segments )
> ++ if ( axis->num_segments < AF_SEGMENTS_EMBEDDED )
> ++ {
> ++ if ( axis->segments == NULL )
> ++ {
> ++ axis->segments = axis->embedded.segments;
> ++ axis->max_segments = AF_SEGMENTS_EMBEDDED;
> ++ }
> ++ }
> ++ else if ( axis->num_segments >= axis->max_segments )
> + {
> + FT_Int old_max = axis->max_segments;
> + FT_Int new_max = old_max;
> +@@ -60,8 +68,18 @@
> + if ( new_max < old_max || new_max > big_max )
> + new_max = big_max;
> +
> +- if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
> +- goto Exit;
> ++ if ( axis->segments == axis->embedded.segments )
> ++ {
> ++ if ( FT_NEW_ARRAY( axis->segments, new_max ) )
> ++ goto Exit;
> ++ ft_memcpy( axis->segments, axis->embedded.segments,
> ++ sizeof ( axis->embedded.segments ) );
> ++ }
> ++ else
> ++ {
> ++ if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
> ++ goto Exit;
> ++ }
> +
> + axis->max_segments = new_max;
> + }
> +@@ -88,7 +106,15 @@
> + AF_Edge edges;
> +
> +
> +- if ( axis->num_edges >= axis->max_edges )
> ++ if ( axis->num_edges < AF_EDGES_EMBEDDED )
> ++ {
> ++ if ( axis->edges == NULL )
> ++ {
> ++ axis->edges = axis->embedded.edges;
> ++ axis->max_edges = AF_EDGES_EMBEDDED;
> ++ }
> ++ }
> ++ else if ( axis->num_edges >= axis->max_edges )
> + {
> + FT_Int old_max = axis->max_edges;
> + FT_Int new_max = old_max;
> +@@ -105,8 +131,18 @@
> + if ( new_max < old_max || new_max > big_max )
> + new_max = big_max;
> +
> +- if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
> +- goto Exit;
> ++ if ( axis->edges == axis->embedded.edges )
> ++ {
> ++ if ( FT_NEW_ARRAY( axis->edges, new_max ) )
> ++ goto Exit;
> ++ ft_memcpy( axis->edges, axis->embedded.edges,
> ++ sizeof ( axis->embedded.edges ) );
> ++ }
> ++ else
> ++ {
> ++ if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
> ++ goto Exit;
> ++ }
> +
> + axis->max_edges = new_max;
> + }
> +@@ -485,7 +521,8 @@
> + af_glyph_hints_init( AF_GlyphHints hints,
> + FT_Memory memory )
> + {
> +- FT_ZERO( hints );
> ++ /* no need to initialize the embedded items */
> ++ FT_MEM_ZERO( hints, sizeof ( *hints ) - sizeof ( hints->embedded ) );
> + hints->memory = memory;
> + }
> +
> +@@ -511,20 +548,24 @@
> +
> + axis->num_segments = 0;
> + axis->max_segments = 0;
> +- FT_FREE( axis->segments );
> ++ if ( axis->segments != axis->embedded.segments )
> ++ FT_FREE( axis->segments );
> +
> + axis->num_edges = 0;
> + axis->max_edges = 0;
> +- FT_FREE( axis->edges );
> ++ if ( axis->edges != axis->embedded.edges )
> ++ FT_FREE( axis->edges );
> + }
> +
> +- FT_FREE( hints->contours );
> ++ if ( hints->contours != hints->embedded.contours )
> ++ FT_FREE( hints->contours );
> + hints->max_contours = 0;
> + hints->num_contours = 0;
> +
> +- FT_FREE( hints->points );
> +- hints->num_points = 0;
> ++ if ( hints->points != hints->embedded.points )
> ++ FT_FREE( hints->points );
> + hints->max_points = 0;
> ++ hints->num_points = 0;
> +
> + hints->memory = NULL;
> + }
> +@@ -569,8 +610,14 @@
> + /* first of all, reallocate the contours array if necessary */
> + new_max = (FT_UInt)outline->n_contours;
> + old_max = hints->max_contours;
> +- if ( new_max > old_max )
> ++
> ++ if ( new_max <= AF_CONTOURS_EMBEDDED )
> ++ hints->contours = hints->embedded.contours;
> ++ else if ( new_max > old_max )
> + {
> ++ if ( hints->contours == hints->embedded.contours )
> ++ hints->contours = NULL;
> ++
> + new_max = ( new_max + 3 ) & ~3; /* round up to a multiple of 4 */
> +
> + if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
> +@@ -586,8 +633,14 @@
> + */
> + new_max = (FT_UInt)( outline->n_points + 2 );
> + old_max = hints->max_points;
> +- if ( new_max > old_max )
> ++
> ++ if ( new_max <= AF_POINTS_EMBEDDED )
> ++ hints->points = hints->embedded.points;
> ++ else if ( new_max > old_max )
> + {
> ++ if ( hints->points == hints->embedded.points )
> ++ hints->points = NULL;
> ++
> + new_max = ( new_max + 2 + 7 ) & ~7; /* round up to a multiple of 8 */
> +
> + if ( FT_RENEW_ARRAY( hints->points, old_max, new_max ) )
> +Index: freetype-2.5.2/src/autofit/afhints.h
> +===================================================================
> +--- freetype-2.5.2.orig/src/autofit/afhints.h 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/autofit/afhints.h 2015-01-23 02:55:34.540290431 +0100
> +@@ -322,6 +322,8 @@
> +
> + } AF_EdgeRec;
> +
> ++#define AF_SEGMENTS_EMBEDDED 18 /* number of embedded segments */
> ++#define AF_EDGES_EMBEDDED 12 /* number of embedded edges */
> +
> + typedef struct AF_AxisHintsRec_
> + {
> +@@ -338,9 +340,20 @@
> +
> + AF_Direction major_dir; /* either vertical or horizontal */
> +
> ++ /* two arrays to avoid allocation penalty */
> ++ struct
> ++ {
> ++ AF_SegmentRec segments[AF_SEGMENTS_EMBEDDED];
> ++ AF_EdgeRec edges[AF_EDGES_EMBEDDED];
> ++ } embedded;
> ++
> ++
> + } AF_AxisHintsRec, *AF_AxisHints;
> +
> +
> ++#define AF_POINTS_EMBEDDED 96 /* number of embedded points */
> ++#define AF_CONTOURS_EMBEDDED 8 /* number of embedded contours */
> ++
> + typedef struct AF_GlyphHintsRec_
> + {
> + FT_Memory memory;
> +@@ -369,6 +382,14 @@
> + FT_Pos xmin_delta; /* used for warping */
> + FT_Pos xmax_delta;
> +
> ++ /* Two arrays to avoid allocation penalty. */
> ++ /* The `embedded' structure must be the last element! */
> ++ struct
> ++ {
> ++ AF_Point contours[AF_CONTOURS_EMBEDDED];
> ++ AF_PointRec points[AF_POINTS_EMBEDDED];
> ++ } embedded;
> ++
> + } AF_GlyphHintsRec;
> +
> +
> +Index: freetype-2.5.2/src/autofit/afloader.c
> +===================================================================
> +--- freetype-2.5.2.orig/src/autofit/afloader.c 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/autofit/afloader.c 2015-01-23 02:59:34.576788306 +0100
> +@@ -26,38 +26,32 @@
> +
> + /* Initialize glyph loader. */
> +
> +- FT_LOCAL_DEF( FT_Error )
> +- af_loader_init( AF_Module module )
> ++ FT_LOCAL_DEF( void )
> ++ af_loader_init( AF_Loader loader,
> ++ AF_GlyphHints hints )
> + {
> +- AF_Loader loader = module->loader;
> +- FT_Memory memory = module->root.library->memory;
> +-
> +-
> + FT_ZERO( loader );
> +
> +- af_glyph_hints_init( &loader->hints, memory );
> ++ loader->hints = hints;
> + #ifdef FT_DEBUG_AUTOFIT
> +- _af_debug_hints = &loader->hints;
> ++ _af_debug_hints = loader->hints;
> + #endif
> +- return FT_GlyphLoader_New( memory, &loader->gloader );
> + }
> +
> +
> + /* Reset glyph loader and compute globals if necessary. */
> +
> + FT_LOCAL_DEF( FT_Error )
> +- af_loader_reset( AF_Module module,
> ++ af_loader_reset( AF_Loader loader,
> ++ AF_Module module,
> + FT_Face face )
> + {
> +- FT_Error error = FT_Err_Ok;
> +- AF_Loader loader = module->loader;
> ++ FT_Error error = FT_Err_Ok;
> +
> +
> + loader->face = face;
> + loader->globals = (AF_FaceGlobals)face->autohint.data;
> +
> +- FT_GlyphLoader_Rewind( loader->gloader );
> +-
> + if ( loader->globals == NULL )
> + {
> + error = af_face_globals_new( face, &loader->globals, module );
> +@@ -77,42 +71,37 @@
> + /* Finalize glyph loader. */
> +
> + FT_LOCAL_DEF( void )
> +- af_loader_done( AF_Module module )
> ++ af_loader_done( AF_Loader loader )
> + {
> +- AF_Loader loader = module->loader;
> +-
> +-
> +- af_glyph_hints_done( &loader->hints );
> +-
> + loader->face = NULL;
> + loader->globals = NULL;
> ++ loader->hints = NULL;
> +
> + #ifdef FT_DEBUG_AUTOFIT
> + _af_debug_hints = NULL;
> + #endif
> +- FT_GlyphLoader_Done( loader->gloader );
> +- loader->gloader = NULL;
> + }
> +
> +
> +- /* Load a single glyph component. This routine calls itself */
> +- /* recursively, if necessary, and does the main work of */
> +- /* `af_loader_load_glyph.' */
> ++ /* Do the main work of `af_loader_load_glyph'. Note that we never */
> ++ /* have to deal with composite glyphs as those get loaded into */
> ++ /* FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. */
> ++ /* In the rare cases where FT_LOAD_NO_RECURSE is set, it implies */
> ++ /* FT_LOAD_NO_SCALE and as such the auto-hinter is never called. */
> +
> + static FT_Error
> + af_loader_load_g( AF_Loader loader,
> + AF_Scaler scaler,
> + FT_UInt glyph_index,
> +- FT_Int32 load_flags,
> +- FT_UInt depth )
> ++ FT_Int32 load_flags )
> + {
> + FT_Error error;
> + FT_Face face = loader->face;
> +- FT_GlyphLoader gloader = loader->gloader;
> + AF_ScriptMetrics metrics = loader->metrics;
> +- AF_GlyphHints hints = &loader->hints;
> ++ AF_GlyphHints hints = loader->hints;
> + FT_GlyphSlot slot = face->glyph;
> + FT_Slot_Internal internal = slot->internal;
> ++ FT_GlyphLoader gloader = internal->loader;
> + FT_Int32 flags;
> +
> +
> +@@ -144,29 +133,6 @@
> + loader->trans_delta.x,
> + loader->trans_delta.y );
> +
> +- /* copy the outline points in the loader's current */
> +- /* extra points which are used to keep original glyph coordinates */
> +- error = FT_GLYPHLOADER_CHECK_POINTS( gloader,
> +- slot->outline.n_points + 4,
> +- slot->outline.n_contours );
> +- if ( error )
> +- goto Exit;
> +-
> +- FT_ARRAY_COPY( gloader->current.outline.points,
> +- slot->outline.points,
> +- slot->outline.n_points );
> +-
> +- FT_ARRAY_COPY( gloader->current.outline.contours,
> +- slot->outline.contours,
> +- slot->outline.n_contours );
> +-
> +- FT_ARRAY_COPY( gloader->current.outline.tags,
> +- slot->outline.tags,
> +- slot->outline.n_points );
> +-
> +- gloader->current.outline.n_points = slot->outline.n_points;
> +- gloader->current.outline.n_contours = slot->outline.n_contours;
> +-
> + /* compute original horizontal phantom points (and ignore */
> + /* vertical ones) */
> + loader->pp1.x = hints->x_delta;
> +@@ -192,7 +158,7 @@
> +
> + if ( writing_system_class->script_hints_apply )
> + writing_system_class->script_hints_apply( hints,
> +- &gloader->current.outline,
> ++ &gloader->base.outline,
> + metrics );
> + }
> +
> +@@ -267,133 +233,6 @@
> + slot->rsb_delta = loader->pp2.x - pp2x;
> + }
> +
> +- /* good, we simply add the glyph to our loader's base */
> +- FT_GlyphLoader_Add( gloader );
> +- break;
> +-
> +- case FT_GLYPH_FORMAT_COMPOSITE:
> +- {
> +- FT_UInt nn, num_subglyphs = slot->num_subglyphs;
> +- FT_UInt num_base_subgs, start_point;
> +- FT_SubGlyph subglyph;
> +-
> +-
> +- start_point = gloader->base.outline.n_points;
> +-
> +- /* first of all, copy the subglyph descriptors in the glyph loader */
> +- error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs );
> +- if ( error )
> +- goto Exit;
> +-
> +- FT_ARRAY_COPY( gloader->current.subglyphs,
> +- slot->subglyphs,
> +- num_subglyphs );
> +-
> +- gloader->current.num_subglyphs = num_subglyphs;
> +- num_base_subgs = gloader->base.num_subglyphs;
> +-
> +- /* now read each subglyph independently */
> +- for ( nn = 0; nn < num_subglyphs; nn++ )
> +- {
> +- FT_Vector pp1, pp2;
> +- FT_Pos x, y;
> +- FT_UInt num_points, num_new_points, num_base_points;
> +-
> +-
> +- /* gloader.current.subglyphs can change during glyph loading due */
> +- /* to re-allocation -- we must recompute the current subglyph on */
> +- /* each iteration */
> +- subglyph = gloader->base.subglyphs + num_base_subgs + nn;
> +-
> +- pp1 = loader->pp1;
> +- pp2 = loader->pp2;
> +-
> +- num_base_points = gloader->base.outline.n_points;
> +-
> +- error = af_loader_load_g( loader, scaler, subglyph->index,
> +- load_flags, depth + 1 );
> +- if ( error )
> +- goto Exit;
> +-
> +- /* recompute subglyph pointer */
> +- subglyph = gloader->base.subglyphs + num_base_subgs + nn;
> +-
> +- if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )
> +- {
> +- pp1 = loader->pp1;
> +- pp2 = loader->pp2;
> +- }
> +- else
> +- {
> +- loader->pp1 = pp1;
> +- loader->pp2 = pp2;
> +- }
> +-
> +- num_points = gloader->base.outline.n_points;
> +- num_new_points = num_points - num_base_points;
> +-
> +- /* now perform the transformation required for this subglyph */
> +-
> +- if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE |
> +- FT_SUBGLYPH_FLAG_XY_SCALE |
> +- FT_SUBGLYPH_FLAG_2X2 ) )
> +- {
> +- FT_Vector* cur = gloader->base.outline.points +
> +- num_base_points;
> +- FT_Vector* limit = cur + num_new_points;
> +-
> +-
> +- for ( ; cur < limit; cur++ )
> +- FT_Vector_Transform( cur, &subglyph->transform );
> +- }
> +-
> +- /* apply offset */
> +-
> +- if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
> +- {
> +- FT_Int k = subglyph->arg1;
> +- FT_UInt l = subglyph->arg2;
> +- FT_Vector* p1;
> +- FT_Vector* p2;
> +-
> +-
> +- if ( start_point + k >= num_base_points ||
> +- l >= (FT_UInt)num_new_points )
> +- {
> +- error = FT_THROW( Invalid_Composite );
> +- goto Exit;
> +- }
> +-
> +- l += num_base_points;
> +-
> +- /* for now, only use the current point coordinates; */
> +- /* we eventually may consider another approach */
> +- p1 = gloader->base.outline.points + start_point + k;
> +- p2 = gloader->base.outline.points + start_point + l;
> +-
> +- x = p1->x - p2->x;
> +- y = p1->y - p2->y;
> +- }
> +- else
> +- {
> +- x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta;
> +- y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta;
> +-
> +- x = FT_PIX_ROUND( x );
> +- y = FT_PIX_ROUND( y );
> +- }
> +-
> +- {
> +- FT_Outline dummy = gloader->base.outline;
> +-
> +-
> +- dummy.points += num_base_points;
> +- dummy.n_points = (short)num_new_points;
> +-
> +- FT_Outline_Translate( &dummy, x, y );
> +- }
> +- }
> +- }
> + break;
> +
> + default:
> +@@ -402,7 +241,6 @@
> + }
> +
> + Hint_Metrics:
> +- if ( depth == 0 )
> + {
> + FT_BBox bbox;
> + FT_Vector vvector;
> +@@ -477,18 +315,14 @@
> + slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
> + slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );
> +
> +- /* now copy outline into glyph slot */
> +- FT_GlyphLoader_Rewind( internal->loader );
> +- error = FT_GlyphLoader_CopyPoints( internal->loader, gloader );
> +- if ( error )
> +- goto Exit;
> +-
> ++#if 0
> + /* reassign all outline fields except flags to protect them */
> + slot->outline.n_contours = internal->loader->base.outline.n_contours;
> + slot->outline.n_points = internal->loader->base.outline.n_points;
> + slot->outline.points = internal->loader->base.outline.points;
> + slot->outline.tags = internal->loader->base.outline.tags;
> + slot->outline.contours = internal->loader->base.outline.contours;
> ++#endif
> +
> + slot->format = FT_GLYPH_FORMAT_OUTLINE;
> + }
> +@@ -501,14 +335,14 @@
> + /* Load a glyph. */
> +
> + FT_LOCAL_DEF( FT_Error )
> +- af_loader_load_glyph( AF_Module module,
> ++ af_loader_load_glyph( AF_Loader loader,
> ++ AF_Module module,
> + FT_Face face,
> + FT_UInt gindex,
> + FT_Int32 load_flags )
> + {
> + FT_Error error;
> + FT_Size size = face->size;
> +- AF_Loader loader = module->loader;
> + AF_ScalerRec scaler;
> +
> +
> +@@ -526,7 +360,7 @@
> + scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
> + scaler.flags = 0; /* XXX: fix this */
> +
> +- error = af_loader_reset( module, face );
> ++ error = af_loader_reset( loader, module, face );
> + if ( !error )
> + {
> + AF_ScriptMetrics metrics;
> +@@ -563,13 +397,13 @@
> +
> + if ( writing_system_class->script_hints_init )
> + {
> +- error = writing_system_class->script_hints_init( &loader->hints,
> ++ error = writing_system_class->script_hints_init( loader->hints,
> + metrics );
> + if ( error )
> + goto Exit;
> + }
> +
> +- error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 );
> ++ error = af_loader_load_g( loader, &scaler, gindex, load_flags );
> + }
> + }
> + Exit:
> +Index: freetype-2.5.2/src/autofit/afloader.h
> +===================================================================
> +--- freetype-2.5.2.orig/src/autofit/afloader.h 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/autofit/afloader.h 2015-01-23 02:55:34.540290431 +0100
> +@@ -20,13 +20,12 @@
> + #define __AFLOADER_H__
> +
> + #include "afhints.h"
> ++#include "afmodule.h"
> + #include "afglobal.h"
> +
> +
> + FT_BEGIN_HEADER
> +
> +- typedef struct AF_ModuleRec_* AF_Module;
> +-
> + /*
> + * The autofitter module's (global) data structure to communicate with
> + * actual fonts. If necessary, `local' data like the current face, the
> +@@ -42,8 +41,7 @@
> + AF_FaceGlobals globals;
> +
> + /* current glyph data */
> +- FT_GlyphLoader gloader;
> +- AF_GlyphHintsRec hints;
> ++ AF_GlyphHints hints;
> + AF_ScriptMetrics metrics;
> + FT_Bool transformed;
> + FT_Matrix trans_matrix;
> +@@ -55,21 +53,24 @@
> + } AF_LoaderRec, *AF_Loader;
> +
> +
> +- FT_LOCAL( FT_Error )
> +- af_loader_init( AF_Module module );
> ++ FT_LOCAL( void )
> ++ af_loader_init( AF_Loader loader,
> ++ AF_GlyphHints hints );
> +
> +
> + FT_LOCAL( FT_Error )
> +- af_loader_reset( AF_Module module,
> ++ af_loader_reset( AF_Loader loader,
> ++ AF_Module module,
> + FT_Face face );
> +
> +
> + FT_LOCAL( void )
> +- af_loader_done( AF_Module module );
> ++ af_loader_done( AF_Loader loader );
> +
> +
> + FT_LOCAL( FT_Error )
> +- af_loader_load_glyph( AF_Module module,
> ++ af_loader_load_glyph( AF_Loader loader,
> ++ AF_Module module,
> + FT_Face face,
> + FT_UInt gindex,
> + FT_Int32 load_flags );
> +Index: freetype-2.5.2/src/autofit/afmodule.c
> +===================================================================
> +--- freetype-2.5.2.orig/src/autofit/afmodule.c 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/autofit/afmodule.c 2015-01-23 02:55:34.544290440 +0100
> +@@ -208,17 +208,14 @@
> +
> + module->fallback_script = AF_SCRIPT_FALLBACK;
> +
> +- return af_loader_init( module );
> ++ return FT_Err_Ok;
> + }
> +
> +
> + FT_CALLBACK_DEF( void )
> + af_autofitter_done( FT_Module ft_module ) /* AF_Module */
> + {
> +- AF_Module module = (AF_Module)ft_module;
> +-
> +-
> +- af_loader_done( module );
> ++ FT_UNUSED( ft_module );
> + }
> +
> +
> +@@ -229,10 +226,25 @@
> + FT_UInt glyph_index,
> + FT_Int32 load_flags )
> + {
> ++ FT_Error error = FT_Err_Ok;
> ++ FT_Memory memory = module->root.library->memory;
> ++
> ++ AF_GlyphHintsRec hints[1];
> ++ AF_LoaderRec loader[1];
> ++
> + FT_UNUSED( size );
> +
> +- return af_loader_load_glyph( module, slot->face,
> +- glyph_index, load_flags );
> ++
> ++ af_glyph_hints_init( hints, memory );
> ++ af_loader_init( loader, hints );
> ++
> ++ error = af_loader_load_glyph( loader, module, slot->face,
> ++ glyph_index, load_flags );
> ++
> ++ af_loader_done( loader );
> ++ af_glyph_hints_done( hints );
> ++
> ++ return error;
> + }
> +
> +
> +Index: freetype-2.5.2/src/autofit/afmodule.h
> +===================================================================
> +--- freetype-2.5.2.orig/src/autofit/afmodule.h 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/autofit/afmodule.h 2015-01-23 02:55:34.544290440 +0100
> +@@ -23,17 +23,13 @@
> + #include FT_INTERNAL_OBJECTS_H
> + #include FT_MODULE_H
> +
> +-#include "afloader.h"
> +-
> +
> + FT_BEGIN_HEADER
> +
> +
> + /*
> + * This is the `extended' FT_Module structure which holds the
> +- * autofitter's global data. Right before hinting a glyph, the data
> +- * specific to the glyph's face (blue zones, stem widths, etc.) are
> +- * loaded into `loader' (see function `af_loader_reset').
> ++ * autofitter's global data.
> + */
> +
> + typedef struct AF_ModuleRec_
> +@@ -42,9 +38,7 @@
> +
> + FT_UInt fallback_script;
> +
> +- AF_LoaderRec loader[1];
> +-
> +- } AF_ModuleRec;
> ++ } AF_ModuleRec, *AF_Module;
> +
> +
> + FT_DECLARE_MODULE(autofit_module_class)
> +Index: freetype-2.5.2/src/base/ftobjs.c
> +===================================================================
> +--- freetype-2.5.2.orig/src/base/ftobjs.c 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/base/ftobjs.c 2015-01-23 02:57:43.332560770 +0100
> +@@ -963,10 +963,6 @@
> + (FT_List_Destructor)destroy_face,
> + driver->root.memory,
> + driver );
> +-
> +- /* check whether we need to drop the driver's glyph loader */
> +- if ( FT_DRIVER_USES_OUTLINES( driver ) )
> +- FT_GlyphLoader_Done( driver->glyph_loader );
> + }
> +
> +
> +@@ -4046,8 +4042,7 @@
> +
> + default:
> + {
> +- FT_ListNode node = 0;
> +- FT_Bool update = 0;
> ++ FT_ListNode node = 0;
> +
> +
> + /* small shortcut for the very common case */
> +@@ -4074,13 +4069,7 @@
> + /* now, look for another renderer that supports the same */
> + /* format. */
> + renderer = FT_Lookup_Renderer( library, slot->format, &node );
> +- update = 1;
> + }
> +-
> +- /* if we changed the current renderer for the glyph image format */
> +- /* we need to select it as the next current one */
> +- if ( !error && update && renderer )
> +- FT_Set_Renderer( library, renderer, 0, 0 );
> + }
> + }
> +
> +@@ -4280,17 +4269,10 @@
> + /* if the module is a font driver */
> + if ( FT_MODULE_IS_DRIVER( module ) )
> + {
> +- /* allocate glyph loader if needed */
> + FT_Driver driver = FT_DRIVER( module );
> +
> +
> + driver->clazz = (FT_Driver_Class)module->clazz;
> +- if ( FT_DRIVER_USES_OUTLINES( driver ) )
> +- {
> +- error = FT_GlyphLoader_New( memory, &driver->glyph_loader );
> +- if ( error )
> +- goto Fail;
> +- }
> + }
> +
> + if ( clazz->module_init )
> +@@ -4307,15 +4289,6 @@
> + return error;
> +
> + Fail:
> +- if ( FT_MODULE_IS_DRIVER( module ) )
> +- {
> +- FT_Driver driver = FT_DRIVER( module );
> +-
> +-
> +- if ( FT_DRIVER_USES_OUTLINES( driver ) )
> +- FT_GlyphLoader_Done( driver->glyph_loader );
> +- }
> +-
> + if ( FT_MODULE_IS_RENDERER( module ) )
> + {
> + FT_Renderer renderer = FT_RENDERER( module );
> +@@ -4630,12 +4603,9 @@
> + goto Fail;
> + #endif
> +
> +- /* allocate the render pool */
> +- library->raster_pool_size = FT_RENDER_POOL_SIZE;
> +-#if FT_RENDER_POOL_SIZE > 0
> +- if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
> +- goto Fail;
> +-#endif
> ++ /* we don't use raster_pool anymore. */
> ++ library->raster_pool_size = 0;
> ++ library->raster_pool = NULL;
> +
> + library->version_major = FREETYPE_MAJOR;
> + library->version_minor = FREETYPE_MINOR;
> +@@ -4648,8 +4618,8 @@
> +
> + return FT_Err_Ok;
> +
> +- Fail:
> + #ifdef FT_CONFIG_OPTION_PIC
> ++ Fail:
> + ft_pic_container_destroy( library );
> + #endif
> + FT_FREE( library );
> +@@ -4784,10 +4754,6 @@
> + }
> + #endif
> +
> +- /* Destroy raster objects */
> +- FT_FREE( library->raster_pool );
> +- library->raster_pool_size = 0;
> +-
> + #ifdef FT_CONFIG_OPTION_PIC
> + /* Destroy pic container contents */
> + ft_pic_container_destroy( library );
> +Index: freetype-2.5.2/src/base/ftoutln.c
> +===================================================================
> +--- freetype-2.5.2.orig/src/base/ftoutln.c 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/base/ftoutln.c 2015-01-23 02:55:34.544290440 +0100
> +@@ -606,7 +606,6 @@
> + FT_Raster_Params* params )
> + {
> + FT_Error error;
> +- FT_Bool update = FALSE;
> + FT_Renderer renderer;
> + FT_ListNode node;
> +
> +@@ -637,14 +636,8 @@
> + /* format */
> + renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE,
> + &node );
> +- update = TRUE;
> + }
> +
> +- /* if we changed the current renderer for the glyph image format */
> +- /* we need to select it as the next current one */
> +- if ( !error && update && renderer )
> +- FT_Set_Renderer( library, renderer, 0, 0 );
> +-
> + return error;
> + }
> +
> +Index: freetype-2.5.2/src/raster/ftraster.c
> +===================================================================
> +--- freetype-2.5.2.orig/src/raster/ftraster.c 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/raster/ftraster.c 2015-01-23 02:55:34.548290448 +0100
> +@@ -150,14 +150,6 @@
> + /* define DEBUG_RASTER if you want to compile a debugging version */
> + /* #define DEBUG_RASTER */
> +
> +- /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */
> +- /* 5-levels anti-aliasing */
> +-/* #define FT_RASTER_OPTION_ANTI_ALIASING */
> +-
> +- /* The size of the two-lines intermediate bitmap used */
> +- /* for anti-aliasing, in bytes. */
> +-#define RASTER_GRAY_LINES 2048
> +-
> +
> + /*************************************************************************/
> + /*************************************************************************/
> +@@ -514,9 +506,6 @@
> +
> + Short traceIncr; /* sweep's increment in target bitmap */
> +
> +- Short gray_min_x; /* current min x during gray rendering */
> +- Short gray_max_x; /* current max x during gray rendering */
> +-
> + /* dispatch variables */
> +
> + Function_Sweep_Init* Proc_Sweep_Init;
> +@@ -529,45 +518,19 @@
> + Bool second_pass; /* indicates whether a horizontal pass */
> + /* should be performed to control */
> + /* drop-out accurately when calling */
> +- /* Render_Glyph. Note that there is */
> +- /* no horizontal pass during gray */
> +- /* rendering. */
> ++ /* Render_Glyph. */
> +
> + TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */
> +
> + black_TBand band_stack[16]; /* band stack used for sub-banding */
> + Int band_top; /* band stack top */
> +
> +-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
> +-
> +- Byte* grays;
> +-
> +- Byte gray_lines[RASTER_GRAY_LINES];
> +- /* Intermediate table used to render the */
> +- /* graylevels pixmaps. */
> +- /* gray_lines is a buffer holding two */
> +- /* monochrome scanlines */
> +-
> +- Short gray_width; /* width in bytes of one monochrome */
> +- /* intermediate scanline of gray_lines. */
> +- /* Each gray pixel takes 2 bits long there */
> +-
> +- /* The gray_lines must hold 2 lines, thus with size */
> +- /* in bytes of at least `gray_width*2'. */
> +-
> +-#endif /* FT_RASTER_ANTI_ALIASING */
> +-
> + };
> +
> +
> + typedef struct black_TRaster_
> + {
> +- char* buffer;
> +- long buffer_size;
> + void* memory;
> +- black_PWorker worker;
> +- Byte grays[5];
> +- Short gray_width;
> +
> + } black_TRaster, *black_PRaster;
> +
> +@@ -583,70 +546,6 @@
> + #endif /* !FT_STATIC_RASTER */
> +
> +
> +-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
> +-
> +- /* A lookup table used to quickly count set bits in four gray 2x2 */
> +- /* cells. The values of the table have been produced with the */
> +- /* following code: */
> +- /* */
> +- /* for ( i = 0; i < 256; i++ ) */
> +- /* { */
> +- /* l = 0; */
> +- /* j = i; */
> +- /* */
> +- /* for ( c = 0; c < 4; c++ ) */
> +- /* { */
> +- /* l <<= 4; */
> +- /* */
> +- /* if ( j & 0x80 ) l++; */
> +- /* if ( j & 0x40 ) l++; */
> +- /* */
> +- /* j = ( j << 2 ) & 0xFF; */
> +- /* } */
> +- /* printf( "0x%04X", l ); */
> +- /* } */
> +- /* */
> +-
> +- static const short count_table[256] =
> +- {
> +- 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012,
> +- 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022,
> +- 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
> +- 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
> +- 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112,
> +- 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122,
> +- 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212,
> +- 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222,
> +- 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
> +- 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
> +- 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
> +- 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
> +- 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
> +- 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
> +- 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
> +- 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
> +- 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012,
> +- 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022,
> +- 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
> +- 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
> +- 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112,
> +- 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122,
> +- 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212,
> +- 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222,
> +- 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012,
> +- 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022,
> +- 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
> +- 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
> +- 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112,
> +- 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122,
> +- 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212,
> +- 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222
> +- };
> +-
> +-#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
> +-
> +-
> +-
> + /*************************************************************************/
> + /*************************************************************************/
> + /** **/
> +@@ -2083,7 +1982,8 @@
> + /* to be drawn. */
> +
> + lastProfile = ras.cProfile;
> +- if ( ras.cProfile->flags & Flow_Up )
> ++ if ( ras.top != ras.cProfile->offset &&
> ++ ( ras.cProfile->flags & Flow_Up ) )
> + o = IS_TOP_OVERSHOOT( ras.lastY );
> + else
> + o = IS_BOTTOM_OVERSHOOT( ras.lastY );
> +@@ -2268,9 +2168,6 @@
> + ras.traceOfs = -*min * pitch;
> + if ( pitch > 0 )
> + ras.traceOfs += ( ras.target.rows - 1 ) * pitch;
> +-
> +- ras.gray_min_x = 0;
> +- ras.gray_max_x = 0;
> + }
> +
> +
> +@@ -2315,11 +2212,6 @@
> + f1 = (Byte) ( 0xFF >> ( e1 & 7 ) );
> + f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) );
> +
> +- if ( ras.gray_min_x > c1 )
> +- ras.gray_min_x = (short)c1;
> +- if ( ras.gray_max_x < c2 )
> +- ras.gray_max_x = (short)c2;
> +-
> + target = ras.bTarget + ras.traceOfs + c1;
> + c2 -= c1;
> +
> +@@ -2483,11 +2375,6 @@
> + c1 = (Short)( e1 >> 3 );
> + f1 = (Short)( e1 & 7 );
> +
> +- if ( ras.gray_min_x > c1 )
> +- ras.gray_min_x = c1;
> +- if ( ras.gray_max_x < c1 )
> +- ras.gray_max_x = c1;
> +-
> + ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 );
> + }
> + }
> +@@ -2692,249 +2579,6 @@
> + }
> +
> +
> +-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
> +-
> +-
> +- /*************************************************************************/
> +- /* */
> +- /* Vertical Gray Sweep Procedure Set */
> +- /* */
> +- /* These two routines are used during the vertical gray-levels sweep */
> +- /* phase by the generic Draw_Sweep() function. */
> +- /* */
> +- /* NOTES */
> +- /* */
> +- /* - The target pixmap's width *must* be a multiple of 4. */
> +- /* */
> +- /* - You have to use the function Vertical_Sweep_Span() for the gray */
> +- /* span call. */
> +- /* */
> +- /*************************************************************************/
> +-
> +- static void
> +- Vertical_Gray_Sweep_Init( RAS_ARGS Short* min,
> +- Short* max )
> +- {
> +- Long pitch, byte_len;
> +-
> +-
> +- *min = *min & -2;
> +- *max = ( *max + 3 ) & -2;
> +-
> +- ras.traceOfs = 0;
> +- pitch = ras.target.pitch;
> +- byte_len = -pitch;
> +- ras.traceIncr = (Short)byte_len;
> +- ras.traceG = ( *min / 2 ) * byte_len;
> +-
> +- if ( pitch > 0 )
> +- {
> +- ras.traceG += ( ras.target.rows - 1 ) * pitch;
> +- byte_len = -byte_len;
> +- }
> +-
> +- ras.gray_min_x = (Short)byte_len;
> +- ras.gray_max_x = -(Short)byte_len;
> +- }
> +-
> +-
> +- static void
> +- Vertical_Gray_Sweep_Step( RAS_ARG )
> +- {
> +- short* count = (short*)count_table;
> +- Byte* grays;
> +-
> +-
> +- ras.traceOfs += ras.gray_width;
> +-
> +- if ( ras.traceOfs > ras.gray_width )
> +- {
> +- PByte pix;
> +-
> +-
> +- pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4;
> +- grays = ras.grays;
> +-
> +- if ( ras.gray_max_x >= 0 )
> +- {
> +- Long last_pixel = ras.target.width - 1;
> +- Int last_cell = last_pixel >> 2;
> +- Int last_bit = last_pixel & 3;
> +- Bool over = 0;
> +-
> +- Int c1, c2;
> +- PByte bit, bit2;
> +-
> +-
> +- if ( ras.gray_max_x >= last_cell && last_bit != 3 )
> +- {
> +- ras.gray_max_x = last_cell - 1;
> +- over = 1;
> +- }
> +-
> +- if ( ras.gray_min_x < 0 )
> +- ras.gray_min_x = 0;
> +-
> +- bit = ras.bTarget + ras.gray_min_x;
> +- bit2 = bit + ras.gray_width;
> +-
> +- c1 = ras.gray_max_x - ras.gray_min_x;
> +-
> +- while ( c1 >= 0 )
> +- {
> +- c2 = count[*bit] + count[*bit2];
> +-
> +- if ( c2 )
> +- {
> +- pix[0] = grays[(c2 >> 12) & 0x000F];
> +- pix[1] = grays[(c2 >> 8 ) & 0x000F];
> +- pix[2] = grays[(c2 >> 4 ) & 0x000F];
> +- pix[3] = grays[ c2 & 0x000F];
> +-
> +- *bit = 0;
> +- *bit2 = 0;
> +- }
> +-
> +- bit++;
> +- bit2++;
> +- pix += 4;
> +- c1--;
> +- }
> +-
> +- if ( over )
> +- {
> +- c2 = count[*bit] + count[*bit2];
> +- if ( c2 )
> +- {
> +- switch ( last_bit )
> +- {
> +- case 2:
> +- pix[2] = grays[(c2 >> 4 ) & 0x000F];
> +- case 1:
> +- pix[1] = grays[(c2 >> 8 ) & 0x000F];
> +- default:
> +- pix[0] = grays[(c2 >> 12) & 0x000F];
> +- }
> +-
> +- *bit = 0;
> +- *bit2 = 0;
> +- }
> +- }
> +- }
> +-
> +- ras.traceOfs = 0;
> +- ras.traceG += ras.traceIncr;
> +-
> +- ras.gray_min_x = 32000;
> +- ras.gray_max_x = -32000;
> +- }
> +- }
> +-
> +-
> +- static void
> +- Horizontal_Gray_Sweep_Span( RAS_ARGS Short y,
> +- FT_F26Dot6 x1,
> +- FT_F26Dot6 x2,
> +- PProfile left,
> +- PProfile right )
> +- {
> +- /* nothing, really */
> +- FT_UNUSED_RASTER;
> +- FT_UNUSED( y );
> +- FT_UNUSED( x1 );
> +- FT_UNUSED( x2 );
> +- FT_UNUSED( left );
> +- FT_UNUSED( right );
> +- }
> +-
> +-
> +- static void
> +- Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y,
> +- FT_F26Dot6 x1,
> +- FT_F26Dot6 x2,
> +- PProfile left,
> +- PProfile right )
> +- {
> +- Long e1, e2;
> +- PByte pixel;
> +-
> +-
> +- /* During the horizontal sweep, we only take care of drop-outs */
> +-
> +- e1 = CEILING( x1 );
> +- e2 = FLOOR ( x2 );
> +-
> +- if ( e1 > e2 )
> +- {
> +- Int dropOutControl = left->flags & 7;
> +-
> +-
> +- if ( e1 == e2 + ras.precision )
> +- {
> +- switch ( dropOutControl )
> +- {
> +- case 0: /* simple drop-outs including stubs */
> +- e1 = e2;
> +- break;
> +-
> +- case 4: /* smart drop-outs including stubs */
> +- e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
> +- break;
> +-
> +- case 1: /* simple drop-outs excluding stubs */
> +- case 5: /* smart drop-outs excluding stubs */
> +- /* see Vertical_Sweep_Drop for details */
> +-
> +- /* rightmost stub test */
> +- if ( left->next == right && left->height <= 0 )
> +- return;
> +-
> +- /* leftmost stub test */
> +- if ( right->next == left && left->start == y )
> +- return;
> +-
> +- if ( dropOutControl == 1 )
> +- e1 = e2;
> +- else
> +- e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half );
> +-
> +- break;
> +-
> +- default: /* modes 2, 3, 6, 7 */
> +- return; /* no drop-out control */
> +- }
> +- }
> +- else
> +- return;
> +- }
> +-
> +- if ( e1 >= 0 )
> +- {
> +- Byte color;
> +-
> +-
> +- if ( x2 - x1 >= ras.precision_half )
> +- color = ras.grays[2];
> +- else
> +- color = ras.grays[1];
> +-
> +- e1 = TRUNC( e1 ) / 2;
> +- if ( e1 < ras.target.rows )
> +- {
> +- pixel = ras.gTarget - e1 * ras.target.pitch + y / 2;
> +- if ( ras.target.pitch > 0 )
> +- pixel += ( ras.target.rows - 1 ) * ras.target.pitch;
> +-
> +- if ( pixel[0] == ras.grays[0] )
> +- pixel[0] = color;
> +- }
> +- }
> +- }
> +-
> +-
> +-#endif /* FT_RASTER_OPTION_ANTI_ALIASING */
> +-
> +-
> + /*************************************************************************/
> + /* */
> + /* Generic Sweep Drawing routine */
> +@@ -3329,118 +2973,10 @@
> + }
> +
> +
> +-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
> +-
> +- /*************************************************************************/
> +- /* */
> +- /* <Function> */
> +- /* Render_Gray_Glyph */
> +- /* */
> +- /* <Description> */
> +- /* Render a glyph with grayscaling. Sub-banding if needed. */
> +- /* */
> +- /* <Return> */
> +- /* FreeType error code. 0 means success. */
> +- /* */
> +- FT_LOCAL_DEF( FT_Error )
> +- Render_Gray_Glyph( RAS_ARG )
> +- {
> +- Long pixel_width;
> +- FT_Error error;
> +-
> +-
> +- Set_High_Precision( RAS_VARS ras.outline.flags &
> +- FT_OUTLINE_HIGH_PRECISION );
> +- ras.scale_shift = ras.precision_shift + 1;
> +-
> +- if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS )
> +- ras.dropOutControl = 2;
> +- else
> +- {
> +- if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS )
> +- ras.dropOutControl = 4;
> +- else
> +- ras.dropOutControl = 0;
> +-
> +- if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) )
> +- ras.dropOutControl += 1;
> +- }
> +-
> +- ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS );
> +-
> +- /* Vertical Sweep */
> +-
> +- ras.band_top = 0;
> +- ras.band_stack[0].y_min = 0;
> +- ras.band_stack[0].y_max = 2 * ras.target.rows - 1;
> +-
> +- ras.bWidth = ras.gray_width;
> +- pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 );
> +-
> +- if ( ras.bWidth > pixel_width )
> +- ras.bWidth = pixel_width;
> +-
> +- ras.bWidth = ras.bWidth * 8;
> +- ras.bTarget = (Byte*)ras.gray_lines;
> +- ras.gTarget = (Byte*)ras.target.buffer;
> +-
> +- ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init;
> +- ras.Proc_Sweep_Span = Vertical_Sweep_Span;
> +- ras.Proc_Sweep_Drop = Vertical_Sweep_Drop;
> +- ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step;
> +-
> +- error = Render_Single_Pass( RAS_VARS 0 );
> +- if ( error )
> +- return error;
> +-
> +- /* Horizontal Sweep */
> +- if ( ras.second_pass && ras.dropOutControl != 2 )
> +- {
> +- ras.Proc_Sweep_Init = Horizontal_Sweep_Init;
> +- ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span;
> +- ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop;
> +- ras.Proc_Sweep_Step = Horizontal_Sweep_Step;
> +-
> +- ras.band_top = 0;
> +- ras.band_stack[0].y_min = 0;
> +- ras.band_stack[0].y_max = ras.target.width * 2 - 1;
> +-
> +- error = Render_Single_Pass( RAS_VARS 1 );
> +- if ( error )
> +- return error;
> +- }
> +-
> +- return Raster_Err_None;
> +- }
> +-
> +-#else /* !FT_RASTER_OPTION_ANTI_ALIASING */
> +-
> +- FT_LOCAL_DEF( FT_Error )
> +- Render_Gray_Glyph( RAS_ARG )
> +- {
> +- FT_UNUSED_RASTER;
> +-
> +- return FT_THROW( Unsupported );
> +- }
> +-
> +-#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */
> +-
> +-
> + static void
> + ft_black_init( black_PRaster raster )
> + {
> +-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
> +- FT_UInt n;
> +-
> +-
> +- /* set default 5-levels gray palette */
> +- for ( n = 0; n < 5; n++ )
> +- raster->grays[n] = n * 255 / 4;
> +-
> +- raster->gray_width = RASTER_GRAY_LINES / 2;
> +-#else
> + FT_UNUSED( raster );
> +-#endif
> + }
> +
> +
> +@@ -3517,25 +3053,9 @@
> + char* pool_base,
> + long pool_size )
> + {
> +- if ( raster )
> +- {
> +- if ( pool_base && pool_size >= (long)sizeof ( black_TWorker ) + 2048 )
> +- {
> +- black_PWorker worker = (black_PWorker)pool_base;
> +-
> +-
> +- raster->buffer = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 );
> +- raster->buffer_size = (long)( pool_base + pool_size -
> +- (char*)raster->buffer );
> +- raster->worker = worker;
> +- }
> +- else
> +- {
> +- raster->buffer = NULL;
> +- raster->buffer_size = 0;
> +- raster->worker = NULL;
> +- }
> +- }
> ++ FT_UNUSED( raster );
> ++ FT_UNUSED( pool_base );
> ++ FT_UNUSED( pool_size );
> + }
> +
> +
> +@@ -3544,25 +3064,9 @@
> + unsigned long mode,
> + const char* palette )
> + {
> +-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
> +-
> +- if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) )
> +- {
> +- /* set 5-levels gray palette */
> +- raster->grays[0] = palette[0];
> +- raster->grays[1] = palette[1];
> +- raster->grays[2] = palette[2];
> +- raster->grays[3] = palette[3];
> +- raster->grays[4] = palette[4];
> +- }
> +-
> +-#else
> +-
> + FT_UNUSED( raster );
> + FT_UNUSED( mode );
> + FT_UNUSED( palette );
> +-
> +-#endif
> + }
> +
> +
> +@@ -3572,10 +3076,13 @@
> + {
> + const FT_Outline* outline = (const FT_Outline*)params->source;
> + const FT_Bitmap* target_map = params->target;
> +- black_PWorker worker;
> ++
> ++ black_TWorker worker[1];
> ++
> ++ Long buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( Long )];
> +
> +
> +- if ( !raster || !raster->buffer || !raster->buffer_size )
> ++ if ( !raster )
> + return FT_THROW( Not_Ini );
> +
> + if ( !outline )
> +@@ -3592,8 +3099,6 @@
> + outline->contours[outline->n_contours - 1] + 1 )
> + return FT_THROW( Invalid );
> +
> +- worker = raster->worker;
> +-
> + /* this version of the raster does not support direct rendering, sorry */
> + if ( params->flags & FT_RASTER_FLAG_DIRECT )
> + return FT_THROW( Unsupported );
> +@@ -3611,19 +3116,10 @@
> + ras.outline = *outline;
> + ras.target = *target_map;
> +
> +- worker->buff = (PLong) raster->buffer;
> +- worker->sizeBuff = worker->buff +
> +- raster->buffer_size / sizeof ( Long );
> +-#ifdef FT_RASTER_OPTION_ANTI_ALIASING
> +- worker->grays = raster->grays;
> +- worker->gray_width = raster->gray_width;
> +-
> +- FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 );
> +-#endif
> ++ worker->buff = buffer;
> ++ worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */
> +
> +- return ( params->flags & FT_RASTER_FLAG_AA )
> +- ? Render_Gray_Glyph( RAS_VAR )
> +- : Render_Glyph( RAS_VAR );
> ++ return Render_Glyph( RAS_VAR );
> + }
> +
> +
> +Index: freetype-2.5.2/src/raster/ftrend1.c
> +===================================================================
> +--- freetype-2.5.2.orig/src/raster/ftrend1.c 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/raster/ftrend1.c 2015-01-23 02:55:34.548290448 +0100
> +@@ -120,38 +120,11 @@
> + }
> +
> + /* check rendering mode */
> +-#ifndef FT_CONFIG_OPTION_PIC
> + if ( mode != FT_RENDER_MODE_MONO )
> + {
> + /* raster1 is only capable of producing monochrome bitmaps */
> +- if ( render->clazz == &ft_raster1_renderer_class )
> +- return FT_THROW( Cannot_Render_Glyph );
> ++ return FT_THROW( Cannot_Render_Glyph );
> + }
> +- else
> +- {
> +- /* raster5 is only capable of producing 5-gray-levels bitmaps */
> +- if ( render->clazz == &ft_raster5_renderer_class )
> +- return FT_THROW( Cannot_Render_Glyph );
> +- }
> +-#else /* FT_CONFIG_OPTION_PIC */
> +- /* When PIC is enabled, we cannot get to the class object */
> +- /* so instead we check the final character in the class name */
> +- /* ("raster5" or "raster1"). Yes this is a hack. */
> +- /* The "correct" thing to do is have different render function */
> +- /* for each of the classes. */
> +- if ( mode != FT_RENDER_MODE_MONO )
> +- {
> +- /* raster1 is only capable of producing monochrome bitmaps */
> +- if ( render->clazz->root.module_name[6] == '1' )
> +- return FT_THROW( Cannot_Render_Glyph );
> +- }
> +- else
> +- {
> +- /* raster5 is only capable of producing 5-gray-levels bitmaps */
> +- if ( render->clazz->root.module_name[6] == '5' )
> +- return FT_THROW( Cannot_Render_Glyph );
> +- }
> +-#endif /* FT_CONFIG_OPTION_PIC */
> +
> + outline = &slot->outline;
> +
> +@@ -254,37 +227,6 @@
> + 0x10000L,
> + 0x20000L,
> +
> +- 0, /* module specific interface */
> +-
> +- (FT_Module_Constructor)ft_raster1_init,
> +- (FT_Module_Destructor) 0,
> +- (FT_Module_Requester) 0
> +- ,
> +-
> +- FT_GLYPH_FORMAT_OUTLINE,
> +-
> +- (FT_Renderer_RenderFunc) ft_raster1_render,
> +- (FT_Renderer_TransformFunc)ft_raster1_transform,
> +- (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox,
> +- (FT_Renderer_SetModeFunc) ft_raster1_set_mode,
> +-
> +- (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET
> +- )
> +-
> +-
> +- /* This renderer is _NOT_ part of the default modules; you will need */
> +- /* to register it by hand in your application. It should only be */
> +- /* used for backwards-compatibility with FT 1.x anyway. */
> +- /* */
> +- FT_DEFINE_RENDERER( ft_raster5_renderer_class,
> +-
> +- FT_MODULE_RENDERER,
> +- sizeof ( FT_RendererRec ),
> +-
> +- "raster5",
> +- 0x10000L,
> +- 0x20000L,
> +-
> + 0, /* module specific interface */
> +
> + (FT_Module_Constructor)ft_raster1_init,
> +Index: freetype-2.5.2/src/smooth/ftgrays.c
> +===================================================================
> +--- freetype-2.5.2.orig/src/smooth/ftgrays.c 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/smooth/ftgrays.c 2015-01-23 02:55:34.548290448 +0100
> +@@ -461,11 +461,7 @@
> +
> + typedef struct gray_TRaster_
> + {
> +- void* buffer;
> +- long buffer_size;
> +- int band_size;
> + void* memory;
> +- gray_PWorker worker;
> +
> + } gray_TRaster, *gray_PRaster;
> +
> +@@ -1940,12 +1936,17 @@
> + gray_raster_render( gray_PRaster raster,
> + const FT_Raster_Params* params )
> + {
> +- const FT_Outline* outline = (const FT_Outline*)params->source;
> +- const FT_Bitmap* target_map = params->target;
> +- gray_PWorker worker;
> ++ const FT_Outline* outline = (const FT_Outline*)params->source;
> ++ const FT_Bitmap* target_map = params->target;
> +
> ++ gray_TWorker worker[1];
> +
> +- if ( !raster || !raster->buffer || !raster->buffer_size )
> ++ TCell buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( TCell )];
> ++ long buffer_size = sizeof ( buffer );
> ++ int band_size = (int)( buffer_size / ( sizeof ( TCell ) * 8 ) );
> ++
> ++
> ++ if ( !raster )
> + return FT_THROW( Invalid_Argument );
> +
> + if ( !outline )
> +@@ -1962,8 +1963,6 @@
> + outline->contours[outline->n_contours - 1] + 1 )
> + return FT_THROW( Invalid_Outline );
> +
> +- worker = raster->worker;
> +-
> + /* if direct mode is not set, we must have a target bitmap */
> + if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
> + {
> +@@ -2001,13 +2000,14 @@
> + ras.clip_box.yMax = 32767L;
> + }
> +
> +- gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size );
> ++ gray_init_cells( RAS_VAR_ buffer, buffer_size );
> +
> + ras.outline = *outline;
> + ras.num_cells = 0;
> + ras.invalid = 1;
> +- ras.band_size = raster->band_size;
> ++ ras.band_size = band_size;
> + ras.num_gray_spans = 0;
> ++ ras.span_y = 0;
> +
> + if ( params->flags & FT_RASTER_FLAG_DIRECT )
> + {
> +@@ -2091,34 +2091,9 @@
> + char* pool_base,
> + long pool_size )
> + {
> +- gray_PRaster rast = (gray_PRaster)raster;
> +-
> +-
> +- if ( raster )
> +- {
> +- if ( pool_base && pool_size >= (long)sizeof ( gray_TWorker ) + 2048 )
> +- {
> +- gray_PWorker worker = (gray_PWorker)pool_base;
> +-
> +-
> +- rast->worker = worker;
> +- rast->buffer = pool_base +
> +- ( ( sizeof ( gray_TWorker ) +
> +- sizeof ( TCell ) - 1 ) &
> +- ~( sizeof ( TCell ) - 1 ) );
> +- rast->buffer_size = (long)( ( pool_base + pool_size ) -
> +- (char*)rast->buffer ) &
> +- ~( sizeof ( TCell ) - 1 );
> +- rast->band_size = (int)( rast->buffer_size /
> +- ( sizeof ( TCell ) * 8 ) );
> +- }
> +- else
> +- {
> +- rast->buffer = NULL;
> +- rast->buffer_size = 0;
> +- rast->worker = NULL;
> +- }
> +- }
> ++ FT_UNUSED( raster );
> ++ FT_UNUSED( pool_base );
> ++ FT_UNUSED( pool_size );
> + }
> +
> +
> +Index: freetype-2.5.2/src/truetype/ttgload.c
> +===================================================================
> +--- freetype-2.5.2.orig/src/truetype/ttgload.c 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/truetype/ttgload.c 2015-01-23 02:55:34.552290457 +0100
> +@@ -802,7 +802,6 @@
> +
> + if ( n_ins > 0 )
> + {
> +- FT_Bool debug;
> + FT_Error error;
> +
> + FT_GlyphLoader gloader = loader->gloader;
> +@@ -817,10 +816,7 @@
> + loader->exec->is_composite = is_composite;
> + loader->exec->pts = *zone;
> +
> +- debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) &&
> +- ((TT_Size)loader->size)->debug );
> +-
> +- error = TT_Run_Context( loader->exec, debug );
> ++ error = TT_Run_Context( loader->exec );
> + if ( error && loader->exec->pedantic_hinting )
> + return error;
> +
> +@@ -2116,8 +2112,7 @@
> + }
> +
> + /* query new execution context */
> +- exec = size->debug ? size->context
> +- : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
> ++ exec = size->context;
> + if ( !exec )
> + return FT_THROW( Could_Not_Find_Context );
> +
> +Index: freetype-2.5.2/src/truetype/ttinterp.c
> +===================================================================
> +--- freetype-2.5.2.orig/src/truetype/ttinterp.c 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/truetype/ttinterp.c 2015-01-23 02:55:34.552290457 +0100
> +@@ -714,12 +714,8 @@
> + /* <Return> */
> + /* TrueType error code. 0 means success. */
> + /* */
> +- /* <Note> */
> +- /* Only the glyph loader and debugger should call this function. */
> +- /* */
> + FT_LOCAL_DEF( FT_Error )
> +- TT_Run_Context( TT_ExecContext exec,
> +- FT_Bool debug )
> ++ TT_Run_Context( TT_ExecContext exec )
> + {
> + FT_Error error;
> +
> +@@ -754,16 +750,7 @@
> + exec->top = 0;
> + exec->callTop = 0;
> +
> +-#if 1
> +- FT_UNUSED( debug );
> +-
> + return exec->face->interpreter( exec );
> +-#else
> +- if ( !debug )
> +- return TT_RunIns( exec );
> +- else
> +- return FT_Err_Ok;
> +-#endif
> + }
> +
> +
> +@@ -798,30 +785,23 @@
> + {
> + TT_ExecContext exec;
> + FT_Memory memory;
> ++ FT_Error error;
> +
> ++ if ( !driver )
> ++ goto Fail;
> +
> + memory = driver->root.root.memory;
> +- exec = driver->context;
> +-
> +- if ( !driver->context )
> +- {
> +- FT_Error error;
> +-
> +-
> +- /* allocate object */
> +- if ( FT_NEW( exec ) )
> +- goto Fail;
> +-
> +- /* initialize it; in case of error this deallocates `exec' too */
> +- error = Init_Context( exec, memory );
> +- if ( error )
> +- goto Fail;
> +
> +- /* store it into the driver */
> +- driver->context = exec;
> +- }
> ++ /* allocate object */
> ++ if ( FT_NEW( exec ) )
> ++ goto Fail;
> ++
> ++ /* initialize it; in case of error this deallocates `exec' too */
> ++ error = Init_Context( exec, memory );
> ++ if ( error )
> ++ goto Fail;
> +
> +- return driver->context;
> ++ return exec;
> +
> + Fail:
> + return NULL;
> +Index: freetype-2.5.2/src/truetype/ttinterp.h
> +===================================================================
> +--- freetype-2.5.2.orig/src/truetype/ttinterp.h 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/truetype/ttinterp.h 2015-01-23 02:55:34.552290457 +0100
> +@@ -340,6 +340,7 @@
> + /* */
> + /* <Note> */
> + /* Only the glyph loader and debugger should call this function. */
> ++ /* (And right now only the glyph loader uses it.) */
> + /* */
> + FT_EXPORT( TT_ExecContext )
> + TT_New_Context( TT_Driver driver );
> +@@ -359,8 +360,7 @@
> + TT_Size ins );
> +
> + FT_LOCAL( FT_Error )
> +- TT_Run_Context( TT_ExecContext exec,
> +- FT_Bool debug );
> ++ TT_Run_Context( TT_ExecContext exec );
> + #endif /* TT_USE_BYTECODE_INTERPRETER */
> +
> +
> +Index: freetype-2.5.2/src/truetype/ttobjs.c
> +===================================================================
> +--- freetype-2.5.2.orig/src/truetype/ttobjs.c 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/truetype/ttobjs.c 2015-01-23 02:55:34.556290465 +0100
> +@@ -751,14 +751,7 @@
> + FT_Error error;
> +
> +
> +- /* debugging instances have their own context */
> +- if ( size->debug )
> +- exec = size->context;
> +- else
> +- exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
> +-
> +- if ( !exec )
> +- return FT_THROW( Could_Not_Find_Context );
> ++ exec = size->context;
> +
> + TT_Load_Context( exec, face, size );
> +
> +@@ -845,14 +838,7 @@
> + FT_Error error;
> +
> +
> +- /* debugging instances have their own context */
> +- if ( size->debug )
> +- exec = size->context;
> +- else
> +- exec = ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
> +-
> +- if ( !exec )
> +- return FT_THROW( Could_Not_Find_Context );
> ++ exec = size->context;
> +
> + TT_Load_Context( exec, face, size );
> +
> +@@ -874,12 +860,9 @@
> + {
> + error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
> +
> +- if ( !error && !size->debug )
> +- {
> +- FT_TRACE4(( "Executing `prep' table.\n" ));
> ++ FT_TRACE4(( "Executing `prep' table.\n" ));
> +
> +- error = face->interpreter( exec );
> +- }
> ++ error = face->interpreter( exec );
> + }
> + else
> + error = FT_Err_Ok;
> +@@ -924,12 +907,10 @@
> + TT_Face face = (TT_Face)ftsize->face;
> + FT_Memory memory = face->root.memory;
> +
> +-
> +- if ( size->debug )
> ++ if ( size->context )
> + {
> +- /* the debug context must be deleted by the debugger itself */
> ++ TT_Done_Context( size->context );
> + size->context = NULL;
> +- size->debug = FALSE;
> + }
> +
> + FT_FREE( size->cvt );
> +@@ -977,6 +958,8 @@
> + size->bytecode_ready = 1;
> + size->cvt_ready = 0;
> +
> ++ size->context = TT_New_Context( (TT_Driver)face->root.driver );
> ++
> + size->max_function_defs = maxp->maxFunctionDefs;
> + size->max_instruction_defs = maxp->maxInstructionDefs;
> +
> +@@ -1261,10 +1244,6 @@
> +
> + TT_Driver driver = (TT_Driver)ttdriver;
> +
> +-
> +- if ( !TT_New_Context( driver ) )
> +- return FT_THROW( Could_Not_Find_Context );
> +-
> + #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
> + driver->interpreter_version = TT_INTERPRETER_VERSION_38;
> + #else
> +@@ -1295,20 +1274,7 @@
> + FT_LOCAL_DEF( void )
> + tt_driver_done( FT_Module ttdriver ) /* TT_Driver */
> + {
> +-#ifdef TT_USE_BYTECODE_INTERPRETER
> +- TT_Driver driver = (TT_Driver)ttdriver;
> +-
> +-
> +- /* destroy the execution context */
> +- if ( driver->context )
> +- {
> +- TT_Done_Context( driver->context );
> +- driver->context = NULL;
> +- }
> +-#else
> + FT_UNUSED( ttdriver );
> +-#endif
> +-
> + }
> +
> +
> +Index: freetype-2.5.2/src/truetype/ttobjs.h
> +===================================================================
> +--- freetype-2.5.2.orig/src/truetype/ttobjs.h 2015-01-23 02:55:34.560290473 +0100
> ++++ freetype-2.5.2/src/truetype/ttobjs.h 2015-01-23 02:55:34.556290465 +0100
> +@@ -324,13 +324,6 @@
> +
> + TT_GlyphZoneRec twilight; /* The instance's twilight zone */
> +
> +- /* debugging variables */
> +-
> +- /* When using the debugger, we must keep the */
> +- /* execution context tied to the instance */
> +- /* object rather than asking it on demand. */
> +-
> +- FT_Bool debug;
> + TT_ExecContext context;
> +
> + FT_Bool bytecode_ready;
> +@@ -349,7 +342,6 @@
> + {
> + FT_DriverRec root;
> +
> +- TT_ExecContext context; /* execution context */
> + TT_GlyphZoneRec zone; /* glyph loader points zone */
> +
> + FT_UInt interpreter_version;
>
> === modified file 'debian/patches-freetype/series'
> --- debian/patches-freetype/series 2014-09-19 17:10:38 +0000
> +++ debian/patches-freetype/series 2015-01-23 02:45:23 +0000
> @@ -10,3 +10,4 @@
> 0002-Fix-Savannah-bug-42418.patch
> freetype-config.diff
> verbose-libtool.patch
> +multi-thread-violations.patch
>
--
https://code.launchpad.net/~3v1n0/ubuntu/vivid/freetype/multithread-safe/+merge/247373
Your team Ubuntu branches is subscribed to branch lp:ubuntu/freetype.
More information about the Ubuntu-reviews
mailing list