1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* ftgloadr.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* The FreeType glyph loader (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Copyright 2002-2006, 2010, 2013 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/ft2build.h" 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h" 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftgloadr.h" 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftmemory.h" 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftobjs.h" 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_gloader 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** G L Y P H L O A D E R *****/ 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The glyph loader is a simple object which is used to load a set of */ 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* glyphs easily. It is critical for the correct loading of composites. */ 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Ideally, one can see it as a stack of abstract `glyph' objects. */ 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* loader.base Is really the bottom of the stack. It describes a */ 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* single glyph image made of the juxtaposition of */ 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* several glyphs (those `in the stack'). */ 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* loader.current Describes the top of the stack, on which a new */ 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* glyph can be loaded. */ 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Rewind Clears the stack. */ 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Prepare Set up `loader.current' for addition of a new glyph */ 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* image. */ 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Add Add the `current' glyph image to the `base' one, */ 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and prepare for another one. */ 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The glyph loader is now a base object. Each driver used to */ 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* re-implement it in one way or the other, which wasted code and */ 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* energy. */ 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* create a new glyph loader */ 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_New( FT_Memory memory, 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader *aloader ) 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader loader = NULL; 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_NEW( loader ) ) 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->memory = memory; 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *aloader = loader; 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* rewind the glyph loader - reset counters to 0 */ 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Rewind( FT_GlyphLoader loader ) 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoad base = &loader->base; 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoad current = &loader->current; 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base->outline.n_points = 0; 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base->outline.n_contours = 0; 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base->num_subglyphs = 0; 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *current = *base; 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* reset the glyph loader, frees all allocated tables */ 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and starts from zero */ 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Reset( FT_GlyphLoader loader ) 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = loader->memory; 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( loader->base.outline.points ); 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( loader->base.outline.tags ); 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( loader->base.outline.contours ); 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( loader->base.extra_points ); 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( loader->base.subglyphs ); 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->base.extra_points2 = NULL; 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->max_points = 0; 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->max_contours = 0; 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->max_subglyphs = 0; 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Rewind( loader ); 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* delete a glyph loader */ 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Done( FT_GlyphLoader loader ) 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( loader ) 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = loader->memory; 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Reset( loader ); 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( loader ); 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* re-adjust the `current' outline fields */ 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Adjust_Points( FT_GlyphLoader loader ) 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline* base = &loader->base.outline; 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline* current = &loader->current.outline; 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current->points = base->points + base->n_points; 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current->tags = base->tags + base->n_points; 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current->contours = base->contours + base->n_contours; 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* handle extra points table - if any */ 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( loader->use_extra ) 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->current.extra_points = loader->base.extra_points + 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base->n_points; 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->current.extra_points2 = loader->base.extra_points2 + 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base->n_points; 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader ) 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = loader->memory; 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) ) 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->use_extra = 1; 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->base.extra_points2 = loader->base.extra_points + 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->max_points; 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Adjust_Points( loader ); 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* re-adjust the `current' subglyphs field */ 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader loader ) 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoad base = &loader->base; 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoad current = &loader->current; 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current->subglyphs = base->subglyphs + base->num_subglyphs; 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Ensure that we can add `n_points' and `n_contours' to our glyph. */ 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This function reallocates its outline tables if necessary. Note that */ 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* it DOESN'T change the number of points within the loader! */ 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt n_points, 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt n_contours ) 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = loader->memory; 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline* base = &loader->base.outline; 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline* current = &loader->current.outline; 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool adjust = 0; 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt new_max, old_max; 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check points & tags */ 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov new_max = base->n_points + current->n_points + n_points; 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old_max = loader->max_points; 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( new_max > old_max ) 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov new_max = FT_PAD_CEIL( new_max, 8 ); 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( new_max > FT_OUTLINE_POINTS_MAX ) 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Array_Too_Large ); 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) || 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_RENEW_ARRAY( base->tags, old_max, new_max ) ) 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( loader->use_extra ) 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_RENEW_ARRAY( loader->base.extra_points, 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old_max * 2, new_max * 2 ) ) 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ARRAY_MOVE( loader->base.extra_points + new_max, 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->base.extra_points + old_max, 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old_max ); 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->base.extra_points2 = loader->base.extra_points + new_max; 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov adjust = 1; 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->max_points = new_max; 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check contours */ 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old_max = loader->max_contours; 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov new_max = base->n_contours + current->n_contours + 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n_contours; 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( new_max > old_max ) 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov new_max = FT_PAD_CEIL( new_max, 4 ); 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( new_max > FT_OUTLINE_CONTOURS_MAX ) 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Array_Too_Large ); 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) ) 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov adjust = 1; 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->max_contours = new_max; 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( adjust ) 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Adjust_Points( loader ); 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Reset( loader ); 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Ensure that we can add `n_subglyphs' to our glyph. this function */ 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* reallocates its subglyphs table if necessary. Note that it DOES */ 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NOT change the number of subglyphs within the loader! */ 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt n_subs ) 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = loader->memory; 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt new_max, old_max; 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoad base = &loader->base; 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoad current = &loader->current; 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov new_max = base->num_subglyphs + current->num_subglyphs + n_subs; 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old_max = loader->max_subglyphs; 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( new_max > old_max ) 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov new_max = FT_PAD_CEIL( new_max, 2 ); 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) ) 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov loader->max_subglyphs = new_max; 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Adjust_Subglyphs( loader ); 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* prepare loader for the addition of a new glyph on top of the base one */ 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Prepare( FT_GlyphLoader loader ) 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoad current = &loader->current; 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current->outline.n_points = 0; 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current->outline.n_contours = 0; 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current->num_subglyphs = 0; 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Adjust_Points ( loader ); 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Adjust_Subglyphs( loader ); 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* add current glyph to the base image -- and prepare for another */ 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Add( FT_GlyphLoader loader ) 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoad base; 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoad current; 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt n_curr_contours; 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt n_base_points; 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt n; 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !loader ) 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base = &loader->base; 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current = &loader->current; 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n_curr_contours = current->outline.n_contours; 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n_base_points = base->outline.n_points; 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base->outline.n_points = 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (short)( base->outline.n_points + current->outline.n_points ); 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base->outline.n_contours = 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (short)( base->outline.n_contours + current->outline.n_contours ); 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base->num_subglyphs += current->num_subglyphs; 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* adjust contours count in newest outline */ 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < n_curr_contours; n++ ) 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current->outline.contours[n] = 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (short)( current->outline.contours[n] + n_base_points ); 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* prepare for another new glyph image */ 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Prepare( loader ); 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Error ) 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader source ) 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt num_points = source->base.outline.n_points; 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt num_contours = source->base.outline.n_contours; 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours ); 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline* out = &target->base.outline; 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline* in = &source->base.outline; 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ARRAY_COPY( out->points, in->points, 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_points ); 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ARRAY_COPY( out->tags, in->tags, 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_points ); 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ARRAY_COPY( out->contours, in->contours, 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_contours ); 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* do we need to copy the extra points? */ 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( target->use_extra && source->use_extra ) 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points, 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_points ); 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2, 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_points ); 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out->n_points = (short)num_points; 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out->n_contours = (short)num_contours; 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GlyphLoader_Adjust_Points( target ); 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 406