diff -u freetype-2.5.2/debian/changelog freetype-2.5.2/debian/changelog --- freetype-2.5.2/debian/changelog +++ freetype-2.5.2/debian/changelog @@ -1,3 +1,10 @@ +freetype (2.5.2-1ubuntu2.3) trusty; urgency=medium + + * Added patchset to fix multithread violations, LP: #1199571 + - debian/patches-freetype/multi-thread-violations.patch + + -- Marco Trevisan (TreviƱo) Fri, 23 Jan 2015 03:38:04 +0100 + freetype (2.5.2-1ubuntu2.2) trusty; urgency=medium * Fix incorrect Korean Fonts rendering. (LP: #1310017) diff -u freetype-2.5.2/debian/patches-freetype/series freetype-2.5.2/debian/patches-freetype/series --- freetype-2.5.2/debian/patches-freetype/series +++ freetype-2.5.2/debian/patches-freetype/series @@ -8,0 +9 @@ +multi-thread-violations.patch only in patch2: unchanged: --- freetype-2.5.2.orig/debian/patches-freetype/multi-thread-violations.patch +++ freetype-2.5.2/debian/patches-freetype/multi-thread-violations.patch @@ -0,0 +1,2105 @@ +Author: Behdad Esfahbod +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, 264b5e46 + + +Index: freetype-2.5.2/devel/ftoption.h +=================================================================== +--- freetype-2.5.2.orig/devel/ftoption.h 2015-01-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/devel/ftoption.h 2015-01-26 16:49:42.668849502 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/include/config/ftoption.h 2015-01-26 16:49:42.668849502 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/include/freetype.h 2015-01-26 16:49:42.672849504 +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. */ + /* */ + /* */ + /* 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. */ ++ /* */ + /* */ + /* 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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/include/ftimage.h 2015-01-26 16:49:42.672849504 +0100 +@@ -1179,10 +1179,10 @@ + /* FT_Raster_ResetFunc */ + /* */ + /* */ +- /* 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. */ + /* */ + /* */ +- /* 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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/include/ftrender.h 2015-01-26 16:49:42.672849504 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/include/internal/ftobjs.h 2015-01-26 16:49:42.672849504 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/autofit/afhints.c 2015-01-26 16:49:42.672849504 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/autofit/afhints.h 2015-01-26 16:49:42.672849504 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/autofit/afloader.c 2015-01-26 16:49:42.676849505 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/autofit/afloader.h 2015-01-26 16:49:42.676849505 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/autofit/afmodule.c 2015-01-26 16:49:42.676849505 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/autofit/afmodule.h 2015-01-26 16:49:42.676849505 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/base/ftobjs.c 2015-01-26 16:49:42.676849505 +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,6 +4618,8 @@ + + return FT_Err_Ok; + ++ /* Fix compilation warning */ ++ goto Fail; + Fail: + #ifdef FT_CONFIG_OPTION_PIC + ft_pic_container_destroy( library ); +@@ -4784,10 +4756,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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/base/ftoutln.c 2015-01-26 16:49:42.676849505 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/raster/ftraster.c 2015-01-26 16:49:42.680849506 +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 +- +- /*************************************************************************/ +- /* */ +- /* */ +- /* Render_Gray_Glyph */ +- /* */ +- /* */ +- /* Render a glyph with grayscaling. Sub-banding if needed. */ +- /* */ +- /* */ +- /* 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]; + +- if ( !raster || !raster->buffer || !raster->buffer_size ) ++ Long buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( Long )]; ++ ++ ++ if ( !raster ) + return FT_THROW( Not_Ini ); + + if ( !outline ) +@@ -3592,12 +3099,13 @@ + 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 ); + ++ if ( params->flags & FT_RASTER_FLAG_AA ) ++ return FT_THROW( Unsupported ); ++ + if ( !target_map ) + return FT_THROW( Invalid ); + +@@ -3611,19 +3119,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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/raster/ftrend1.c 2015-01-26 16:56:56.633016853 +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; + +@@ -194,19 +167,8 @@ + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + +- /* allocate new one, depends on pixel format */ +- if ( !( mode & FT_RENDER_MODE_MONO ) ) +- { +- /* we pad to 32 bits, only for backwards compatibility with FT 1.x */ +- pitch = FT_PAD_CEIL( width, 4 ); +- bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; +- bitmap->num_grays = 256; +- } +- else +- { +- pitch = ( ( width + 15 ) >> 4 ) << 1; +- bitmap->pixel_mode = FT_PIXEL_MODE_MONO; +- } ++ pitch = ( ( width + 15 ) >> 4 ) << 1; ++ bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + + bitmap->width = width; + bitmap->rows = height; +@@ -225,9 +187,6 @@ + params.source = outline; + params.flags = 0; + +- if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY ) +- params.flags |= FT_RASTER_FLAG_AA; +- + /* render outline into the bitmap */ + error = render->raster_render( render->raster, ¶ms ); + +Index: freetype-2.5.2/src/smooth/ftgrays.c +=================================================================== +--- freetype-2.5.2.orig/src/smooth/ftgrays.c 2015-01-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/smooth/ftgrays.c 2015-01-26 16:49:42.680849506 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/truetype/ttgload.c 2015-01-26 16:49:42.684849507 +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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/truetype/ttinterp.c 2015-01-26 16:49:42.684849507 +0100 +@@ -714,12 +714,8 @@ + /* */ + /* TrueType error code. 0 means success. */ + /* */ +- /* */ +- /* 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 + } + + +@@ -796,32 +783,26 @@ + FT_EXPORT_DEF( TT_ExecContext ) + TT_New_Context( TT_Driver driver ) + { +- TT_ExecContext exec; + FT_Memory memory; ++ FT_Error error; + ++ TT_ExecContext exec; + +- memory = driver->root.root.memory; +- exec = driver->context; +- +- if ( !driver->context ) +- { +- FT_Error error; +- +- +- /* allocate object */ +- if ( FT_NEW( exec ) ) +- goto Fail; ++ if ( !driver ) ++ goto Fail; + +- /* initialize it; in case of error this deallocates `exec' too */ +- error = Init_Context( exec, memory ); +- if ( error ) +- goto Fail; ++ memory = driver->root.root.memory; + +- /* 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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/truetype/ttinterp.h 2015-01-26 16:49:42.684849507 +0100 +@@ -340,6 +340,7 @@ + /* */ + /* */ + /* 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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/truetype/ttobjs.c 2015-01-26 16:49:42.688849509 +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 ); + +@@ -872,14 +858,11 @@ + + if ( face->cvt_program_size > 0 ) + { +- error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); ++ 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-26 16:49:42.692849510 +0100 ++++ freetype-2.5.2/src/truetype/ttobjs.h 2015-01-26 16:49:42.688849509 +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;