diff options
Diffstat (limited to 'src/base')
-rw-r--r-- | src/base/ftadvanc.c | 127 | ||||
-rw-r--r-- | src/base/ftapi.c | 121 | ||||
-rw-r--r-- | src/base/ftbase.c | 38 | ||||
-rw-r--r-- | src/base/ftbbox.c | 659 | ||||
-rw-r--r-- | src/base/ftbitmap.c | 630 | ||||
-rw-r--r-- | src/base/ftcalc.c | 825 | ||||
-rw-r--r-- | src/base/ftdbgmem.c | 998 | ||||
-rw-r--r-- | src/base/ftdebug.c | 246 | ||||
-rw-r--r-- | src/base/ftgasp.c | 61 | ||||
-rw-r--r-- | src/base/ftgloadr.c | 394 | ||||
-rw-r--r-- | src/base/ftglyph.c | 688 | ||||
-rw-r--r-- | src/base/ftinit.c | 163 | ||||
-rw-r--r-- | src/base/ftlcdfil.c | 351 | ||||
-rw-r--r-- | src/base/ftmm.c | 202 | ||||
-rw-r--r-- | src/base/ftnames.c | 94 | ||||
-rw-r--r-- | src/base/ftobjs.c | 4235 | ||||
-rw-r--r-- | src/base/ftoutln.c | 1090 | ||||
-rw-r--r-- | src/base/ftpatent.c | 281 | ||||
-rw-r--r-- | src/base/ftrfork.c | 811 | ||||
-rw-r--r-- | src/base/ftstream.c | 845 | ||||
-rw-r--r-- | src/base/ftstroke.c | 2010 | ||||
-rw-r--r-- | src/base/ftsynth.c | 159 | ||||
-rw-r--r-- | src/base/ftsystem.c | 301 | ||||
-rw-r--r-- | src/base/fttrigon.c | 546 | ||||
-rw-r--r-- | src/base/ftutil.c | 501 | ||||
-rw-r--r-- | src/base/ftwinfnt.c | 51 | ||||
-rw-r--r-- | src/base/ftxf86.c | 40 |
27 files changed, 0 insertions, 16467 deletions
diff --git a/src/base/ftadvanc.c b/src/base/ftadvanc.c deleted file mode 100644 index 626a0cf..0000000 --- a/src/base/ftadvanc.c +++ /dev/null @@ -1,127 +0,0 @@ -#include <ft2build.h> -#include FT_ADVANCES_H -#include FT_INTERNAL_OBJECTS_H - - static FT_Error - _ft_face_scale_advances( FT_Face face, - FT_Fixed* advances, - FT_UInt count, - FT_UInt flags ) - { - FT_Fixed scale; - FT_UInt nn; - - if ( (flags & FT_LOAD_NO_SCALE) ) - return FT_Err_Ok; - - if ( face->size == NULL ) - return FT_Err_Invalid_Size_Handle; - - if ( !(flags & FT_LOAD_VERTICAL_LAYOUT) ) - scale = face->size->metrics.x_scale; - else - scale = face->size->metrics.y_scale; - - /* this must be the same computation than to get linearHori/VertAdvance - * (see FT_Load_Glyph() implementation in src/base/ftobjs.c */ - for (nn = 0; nn < count; nn++) - advances[nn] = FT_MulDiv( advances[nn], scale, 64 ); - - return 0; - } - - -/* at the moment, we can perform fast advance retrieval only in - the following cases: - - - unscaled load - - unhinted load - - light-hinted load - */ -#define LOAD_ADVANCE_FAST_CHECK(flags) \ - (((flags & (FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING)) != 0) || \ - FT_LOAD_TARGET_MODE(flags) == FT_RENDER_MODE_LIGHT) - - FT_EXPORT_DEF(FT_Error) - FT_Get_Advance( FT_Face face, - FT_UInt gindex, - FT_UInt flags, - FT_Fixed *padvance ) - { - FT_Face_GetAdvancesFunc func; - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if (gindex >= (FT_UInt) face->num_glyphs ) - return FT_Err_Invalid_Glyph_Index; - - func = face->driver->clazz->get_advances; - if (func != NULL && LOAD_ADVANCE_FAST_CHECK(flags)) - { - FT_Error error; - - error = func( face, gindex, 1, flags, padvance ); - if (!error) - return _ft_face_scale_advances( face, padvance, 1, flags ); - - if (error != FT_Err_Unimplemented_Feature) - return error; - } - - return FT_Get_Advances( face, gindex, 1, flags, padvance ); - } - - - FT_EXPORT_DEF(FT_Error) - FT_Get_Advances( FT_Face face, - FT_UInt start, - FT_UInt count, - FT_UInt flags, - FT_Fixed *padvances ) - { - FT_Face_GetAdvancesFunc func; - FT_UInt num, end, nn; - FT_Error error = 0; - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - num = (FT_UInt) face->num_glyphs; - end = start + count; - if (start >= num || end < start || end > num) - return FT_Err_Invalid_Glyph_Index; - - if (count == 0) - return FT_Err_Ok; - - func = face->driver->clazz->get_advances; - if (func != NULL && LOAD_ADVANCE_FAST_CHECK(flags)) - { - error = func( face, start, count, flags, padvances ); - if (!error) goto Exit; - - if (error != FT_Err_Unimplemented_Feature) - return error; - } - - error = 0; - - if ((flags & FT_ADVANCE_FLAG_FAST_ONLY) != 0) - return FT_Err_Unimplemented_Feature; - - flags |= FT_LOAD_ADVANCE_ONLY; - for (nn = 0; nn < count; nn++) - { - error = FT_Load_Glyph( face, start+nn, flags ); - if (error) break; - - padvances[nn] = (flags & FT_LOAD_VERTICAL_LAYOUT) - ? face->glyph->advance.x - : face->glyph->advance.y; - } - if (error) return error; - - Exit: - return _ft_face_scale_advances( face, padvances, count, flags ); - } diff --git a/src/base/ftapi.c b/src/base/ftapi.c deleted file mode 100644 index 8914d1f..0000000 --- a/src/base/ftapi.c +++ /dev/null @@ -1,121 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftapi.c */ -/* */ -/* The FreeType compatibility functions (body). */ -/* */ -/* Copyright 2002 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_LIST_H -#include FT_OUTLINE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_TRUETYPE_TABLES_H -#include FT_OUTLINE_H - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** C O M P A T I B I L I T Y ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /* backwards compatibility API */ - - FT_BASE_DEF( void ) - FT_New_Memory_Stream( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Stream stream ) - { - FT_UNUSED( library ); - - FT_Stream_OpenMemory( stream, base, size ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Seek_Stream( FT_Stream stream, - FT_ULong pos ) - { - return FT_Stream_Seek( stream, pos ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Skip_Stream( FT_Stream stream, - FT_Long distance ) - { - return FT_Stream_Skip( stream, distance ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Read_Stream( FT_Stream stream, - FT_Byte* buffer, - FT_ULong count ) - { - return FT_Stream_Read( stream, buffer, count ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Read_Stream_At( FT_Stream stream, - FT_ULong pos, - FT_Byte* buffer, - FT_ULong count ) - { - return FT_Stream_ReadAt( stream, pos, buffer, count ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Extract_Frame( FT_Stream stream, - FT_ULong count, - FT_Byte** pbytes ) - { - return FT_Stream_ExtractFrame( stream, count, pbytes ); - } - - - FT_BASE_DEF( void ) - FT_Release_Frame( FT_Stream stream, - FT_Byte** pbytes ) - { - FT_Stream_ReleaseFrame( stream, pbytes ); - } - - FT_BASE_DEF( FT_Error ) - FT_Access_Frame( FT_Stream stream, - FT_ULong count ) - { - return FT_Stream_EnterFrame( stream, count ); - } - - - FT_BASE_DEF( void ) - FT_Forget_Frame( FT_Stream stream ) - { - FT_Stream_ExitFrame( stream ); - } - - -/* END */ diff --git a/src/base/ftbase.c b/src/base/ftbase.c deleted file mode 100644 index 300e02d..0000000 --- a/src/base/ftbase.c +++ /dev/null @@ -1,38 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbase.c */ -/* */ -/* Single object library component (body only). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> - -#define FT_MAKE_OPTION_SINGLE_OBJECT - -#include "ftcalc.c" -#include "ftdbgmem.c" -#include "ftgloadr.c" -#include "ftnames.c" -#include "ftobjs.c" -#include "ftoutln.c" -#include "ftrfork.c" -#include "ftstream.c" -#include "fttrigon.c" -#include "ftutil.c" - -#if defined( __APPLE__ ) && !defined ( DARWIN_NO_CARBON ) -#include "ftmac.c" -#endif - -/* END */ diff --git a/src/base/ftbbox.c b/src/base/ftbbox.c deleted file mode 100644 index 532ab13..0000000 --- a/src/base/ftbbox.c +++ /dev/null @@ -1,659 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbbox.c */ -/* */ -/* FreeType bbox computation (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2004, 2006 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used */ -/* modified and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This component has a _single_ role: to compute exact outline bounding */ - /* boxes. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_BBOX_H -#include FT_IMAGE_H -#include FT_OUTLINE_H -#include FT_INTERNAL_CALC_H - - - typedef struct TBBox_Rec_ - { - FT_Vector last; - FT_BBox bbox; - - } TBBox_Rec; - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Move_To */ - /* */ - /* <Description> */ - /* This function is used as a `move_to' and `line_to' emitter during */ - /* FT_Outline_Decompose(). It simply records the destination point */ - /* in `user->last'; no further computations are necessary since we */ - /* use the cbox as the starting bbox which must be refined. */ - /* */ - /* <Input> */ - /* to :: A pointer to the destination vector. */ - /* */ - /* <InOut> */ - /* user :: A pointer to the current walk context. */ - /* */ - /* <Return> */ - /* Always 0. Needed for the interface only. */ - /* */ - static int - BBox_Move_To( FT_Vector* to, - TBBox_Rec* user ) - { - user->last = *to; - - return 0; - } - - -#define CHECK_X( p, bbox ) \ - ( p->x < bbox.xMin || p->x > bbox.xMax ) - -#define CHECK_Y( p, bbox ) \ - ( p->y < bbox.yMin || p->y > bbox.yMax ) - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Conic_Check */ - /* */ - /* <Description> */ - /* Finds the extrema of a 1-dimensional conic Bezier curve and update */ - /* a bounding range. This version uses direct computation, as it */ - /* doesn't need square roots. */ - /* */ - /* <Input> */ - /* y1 :: The start coordinate. */ - /* */ - /* y2 :: The coordinate of the control point. */ - /* */ - /* y3 :: The end coordinate. */ - /* */ - /* <InOut> */ - /* min :: The address of the current minimum. */ - /* */ - /* max :: The address of the current maximum. */ - /* */ - static void - BBox_Conic_Check( FT_Pos y1, - FT_Pos y2, - FT_Pos y3, - FT_Pos* min, - FT_Pos* max ) - { - if ( y1 <= y3 && y2 == y1 ) /* flat arc */ - goto Suite; - - if ( y1 < y3 ) - { - if ( y2 >= y1 && y2 <= y3 ) /* ascending arc */ - goto Suite; - } - else - { - if ( y2 >= y3 && y2 <= y1 ) /* descending arc */ - { - y2 = y1; - y1 = y3; - y3 = y2; - goto Suite; - } - } - - y1 = y3 = y1 - FT_MulDiv( y2 - y1, y2 - y1, y1 - 2*y2 + y3 ); - - Suite: - if ( y1 < *min ) *min = y1; - if ( y3 > *max ) *max = y3; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Conic_To */ - /* */ - /* <Description> */ - /* This function is used as a `conic_to' emitter during */ - /* FT_Raster_Decompose(). It checks a conic Bezier curve with the */ - /* current bounding box, and computes its extrema if necessary to */ - /* update it. */ - /* */ - /* <Input> */ - /* control :: A pointer to a control point. */ - /* */ - /* to :: A pointer to the destination vector. */ - /* */ - /* <InOut> */ - /* user :: The address of the current walk context. */ - /* */ - /* <Return> */ - /* Always 0. Needed for the interface only. */ - /* */ - /* <Note> */ - /* In the case of a non-monotonous arc, we compute directly the */ - /* extremum coordinates, as it is sufficiently fast. */ - /* */ - static int - BBox_Conic_To( FT_Vector* control, - FT_Vector* to, - TBBox_Rec* user ) - { - /* we don't need to check `to' since it is always an `on' point, thus */ - /* within the bbox */ - - if ( CHECK_X( control, user->bbox ) ) - BBox_Conic_Check( user->last.x, - control->x, - to->x, - &user->bbox.xMin, - &user->bbox.xMax ); - - if ( CHECK_Y( control, user->bbox ) ) - BBox_Conic_Check( user->last.y, - control->y, - to->y, - &user->bbox.yMin, - &user->bbox.yMax ); - - user->last = *to; - - return 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Cubic_Check */ - /* */ - /* <Description> */ - /* Finds the extrema of a 1-dimensional cubic Bezier curve and */ - /* updates a bounding range. This version uses splitting because we */ - /* don't want to use square roots and extra accuracy. */ - /* */ - /* <Input> */ - /* p1 :: The start coordinate. */ - /* */ - /* p2 :: The coordinate of the first control point. */ - /* */ - /* p3 :: The coordinate of the second control point. */ - /* */ - /* p4 :: The end coordinate. */ - /* */ - /* <InOut> */ - /* min :: The address of the current minimum. */ - /* */ - /* max :: The address of the current maximum. */ - /* */ - -#if 0 - - static void - BBox_Cubic_Check( FT_Pos p1, - FT_Pos p2, - FT_Pos p3, - FT_Pos p4, - FT_Pos* min, - FT_Pos* max ) - { - FT_Pos stack[32*3 + 1], *arc; - - - arc = stack; - - arc[0] = p1; - arc[1] = p2; - arc[2] = p3; - arc[3] = p4; - - do - { - FT_Pos y1 = arc[0]; - FT_Pos y2 = arc[1]; - FT_Pos y3 = arc[2]; - FT_Pos y4 = arc[3]; - - - if ( y1 == y4 ) - { - if ( y1 == y2 && y1 == y3 ) /* flat */ - goto Test; - } - else if ( y1 < y4 ) - { - if ( y2 >= y1 && y2 <= y4 && y3 >= y1 && y3 <= y4 ) /* ascending */ - goto Test; - } - else - { - if ( y2 >= y4 && y2 <= y1 && y3 >= y4 && y3 <= y1 ) /* descending */ - { - y2 = y1; - y1 = y4; - y4 = y2; - goto Test; - } - } - - /* unknown direction -- split the arc in two */ - arc[6] = y4; - arc[1] = y1 = ( y1 + y2 ) / 2; - arc[5] = y4 = ( y4 + y3 ) / 2; - y2 = ( y2 + y3 ) / 2; - arc[2] = y1 = ( y1 + y2 ) / 2; - arc[4] = y4 = ( y4 + y2 ) / 2; - arc[3] = ( y1 + y4 ) / 2; - - arc += 3; - goto Suite; - - Test: - if ( y1 < *min ) *min = y1; - if ( y4 > *max ) *max = y4; - arc -= 3; - - Suite: - ; - } while ( arc >= stack ); - } - -#else - - static void - test_cubic_extrema( FT_Pos y1, - FT_Pos y2, - FT_Pos y3, - FT_Pos y4, - FT_Fixed u, - FT_Pos* min, - FT_Pos* max ) - { - /* FT_Pos a = y4 - 3*y3 + 3*y2 - y1; */ - FT_Pos b = y3 - 2*y2 + y1; - FT_Pos c = y2 - y1; - FT_Pos d = y1; - FT_Pos y; - FT_Fixed uu; - - FT_UNUSED ( y4 ); - - - /* The polynomial is */ - /* */ - /* P(x) = a*x^3 + 3b*x^2 + 3c*x + d , */ - /* */ - /* dP/dx = 3a*x^2 + 6b*x + 3c . */ - /* */ - /* However, we also have */ - /* */ - /* dP/dx(u) = 0 , */ - /* */ - /* which implies by subtraction that */ - /* */ - /* P(u) = b*u^2 + 2c*u + d . */ - - if ( u > 0 && u < 0x10000L ) - { - uu = FT_MulFix( u, u ); - y = d + FT_MulFix( c, 2*u ) + FT_MulFix( b, uu ); - - if ( y < *min ) *min = y; - if ( y > *max ) *max = y; - } - } - - - static void - BBox_Cubic_Check( FT_Pos y1, - FT_Pos y2, - FT_Pos y3, - FT_Pos y4, - FT_Pos* min, - FT_Pos* max ) - { - /* always compare first and last points */ - if ( y1 < *min ) *min = y1; - else if ( y1 > *max ) *max = y1; - - if ( y4 < *min ) *min = y4; - else if ( y4 > *max ) *max = y4; - - /* now, try to see if there are split points here */ - if ( y1 <= y4 ) - { - /* flat or ascending arc test */ - if ( y1 <= y2 && y2 <= y4 && y1 <= y3 && y3 <= y4 ) - return; - } - else /* y1 > y4 */ - { - /* descending arc test */ - if ( y1 >= y2 && y2 >= y4 && y1 >= y3 && y3 >= y4 ) - return; - } - - /* There are some split points. Find them. */ - { - FT_Pos a = y4 - 3*y3 + 3*y2 - y1; - FT_Pos b = y3 - 2*y2 + y1; - FT_Pos c = y2 - y1; - FT_Pos d; - FT_Fixed t; - - - /* We need to solve `ax^2+2bx+c' here, without floating points! */ - /* The trick is to normalize to a different representation in order */ - /* to use our 16.16 fixed point routines. */ - /* */ - /* We compute FT_MulFix(b,b) and FT_MulFix(a,c) after normalization. */ - /* These values must fit into a single 16.16 value. */ - /* */ - /* We normalize a, b, and c to `8.16' fixed float values to ensure */ - /* that its product is held in a `16.16' value. */ - - { - FT_ULong t1, t2; - int shift = 0; - - - /* The following computation is based on the fact that for */ - /* any value `y', if `n' is the position of the most */ - /* significant bit of `abs(y)' (starting from 0 for the */ - /* least significant bit), then `y' is in the range */ - /* */ - /* -2^n..2^n-1 */ - /* */ - /* We want to shift `a', `b', and `c' concurrently in order */ - /* to ensure that they all fit in 8.16 values, which maps */ - /* to the integer range `-2^23..2^23-1'. */ - /* */ - /* Necessarily, we need to shift `a', `b', and `c' so that */ - /* the most significant bit of its absolute values is at */ - /* _most_ at position 23. */ - /* */ - /* We begin by computing `t1' as the bitwise `OR' of the */ - /* absolute values of `a', `b', `c'. */ - - t1 = (FT_ULong)( ( a >= 0 ) ? a : -a ); - t2 = (FT_ULong)( ( b >= 0 ) ? b : -b ); - t1 |= t2; - t2 = (FT_ULong)( ( c >= 0 ) ? c : -c ); - t1 |= t2; - - /* Now we can be sure that the most significant bit of `t1' */ - /* is the most significant bit of either `a', `b', or `c', */ - /* depending on the greatest integer range of the particular */ - /* variable. */ - /* */ - /* Next, we compute the `shift', by shifting `t1' as many */ - /* times as necessary to move its MSB to position 23. This */ - /* corresponds to a value of `t1' that is in the range */ - /* 0x40_0000..0x7F_FFFF. */ - /* */ - /* Finally, we shift `a', `b', and `c' by the same amount. */ - /* This ensures that all values are now in the range */ - /* -2^23..2^23, i.e., they are now expressed as 8.16 */ - /* fixed-float numbers. This also means that we are using */ - /* 24 bits of precision to compute the zeros, independently */ - /* of the range of the original polynomial coefficients. */ - /* */ - /* This algorithm should ensure reasonably accurate values */ - /* for the zeros. Note that they are only expressed with */ - /* 16 bits when computing the extrema (the zeros need to */ - /* be in 0..1 exclusive to be considered part of the arc). */ - - if ( t1 == 0 ) /* all coefficients are 0! */ - return; - - if ( t1 > 0x7FFFFFUL ) - { - do - { - shift++; - t1 >>= 1; - - } while ( t1 > 0x7FFFFFUL ); - - /* this loses some bits of precision, but we use 24 of them */ - /* for the computation anyway */ - a >>= shift; - b >>= shift; - c >>= shift; - } - else if ( t1 < 0x400000UL ) - { - do - { - shift++; - t1 <<= 1; - - } while ( t1 < 0x400000UL ); - - a <<= shift; - b <<= shift; - c <<= shift; - } - } - - /* handle a == 0 */ - if ( a == 0 ) - { - if ( b != 0 ) - { - t = - FT_DivFix( c, b ) / 2; - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - } - } - else - { - /* solve the equation now */ - d = FT_MulFix( b, b ) - FT_MulFix( a, c ); - if ( d < 0 ) - return; - - if ( d == 0 ) - { - /* there is a single split point at -b/a */ - t = - FT_DivFix( b, a ); - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - } - else - { - /* there are two solutions; we need to filter them */ - d = FT_SqrtFixed( (FT_Int32)d ); - t = - FT_DivFix( b - d, a ); - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - - t = - FT_DivFix( b + d, a ); - test_cubic_extrema( y1, y2, y3, y4, t, min, max ); - } - } - } - } - -#endif - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* BBox_Cubic_To */ - /* */ - /* <Description> */ - /* This function is used as a `cubic_to' emitter during */ - /* FT_Raster_Decompose(). It checks a cubic Bezier curve with the */ - /* current bounding box, and computes its extrema if necessary to */ - /* update it. */ - /* */ - /* <Input> */ - /* control1 :: A pointer to the first control point. */ - /* */ - /* control2 :: A pointer to the second control point. */ - /* */ - /* to :: A pointer to the destination vector. */ - /* */ - /* <InOut> */ - /* user :: The address of the current walk context. */ - /* */ - /* <Return> */ - /* Always 0. Needed for the interface only. */ - /* */ - /* <Note> */ - /* In the case of a non-monotonous arc, we don't compute directly */ - /* extremum coordinates, we subdivide instead. */ - /* */ - static int - BBox_Cubic_To( FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to, - TBBox_Rec* user ) - { - /* we don't need to check `to' since it is always an `on' point, thus */ - /* within the bbox */ - - if ( CHECK_X( control1, user->bbox ) || - CHECK_X( control2, user->bbox ) ) - BBox_Cubic_Check( user->last.x, - control1->x, - control2->x, - to->x, - &user->bbox.xMin, - &user->bbox.xMax ); - - if ( CHECK_Y( control1, user->bbox ) || - CHECK_Y( control2, user->bbox ) ) - BBox_Cubic_Check( user->last.y, - control1->y, - control2->y, - to->y, - &user->bbox.yMin, - &user->bbox.yMax ); - - user->last = *to; - - return 0; - } - - - /* documentation is in ftbbox.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Get_BBox( FT_Outline* outline, - FT_BBox *abbox ) - { - FT_BBox cbox; - FT_BBox bbox; - FT_Vector* vec; - FT_UShort n; - - - if ( !abbox ) - return FT_Err_Invalid_Argument; - - if ( !outline ) - return FT_Err_Invalid_Outline; - - /* if outline is empty, return (0,0,0,0) */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) - { - abbox->xMin = abbox->xMax = 0; - abbox->yMin = abbox->yMax = 0; - return 0; - } - - /* We compute the control box as well as the bounding box of */ - /* all `on' points in the outline. Then, if the two boxes */ - /* coincide, we exit immediately. */ - - vec = outline->points; - bbox.xMin = bbox.xMax = cbox.xMin = cbox.xMax = vec->x; - bbox.yMin = bbox.yMax = cbox.yMin = cbox.yMax = vec->y; - vec++; - - for ( n = 1; n < outline->n_points; n++ ) - { - FT_Pos x = vec->x; - FT_Pos y = vec->y; - - - /* update control box */ - if ( x < cbox.xMin ) cbox.xMin = x; - if ( x > cbox.xMax ) cbox.xMax = x; - - if ( y < cbox.yMin ) cbox.yMin = y; - if ( y > cbox.yMax ) cbox.yMax = y; - - if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON ) - { - /* update bbox for `on' points only */ - if ( x < bbox.xMin ) bbox.xMin = x; - if ( x > bbox.xMax ) bbox.xMax = x; - - if ( y < bbox.yMin ) bbox.yMin = y; - if ( y > bbox.yMax ) bbox.yMax = y; - } - - vec++; - } - - /* test two boxes for equality */ - if ( cbox.xMin < bbox.xMin || cbox.xMax > bbox.xMax || - cbox.yMin < bbox.yMin || cbox.yMax > bbox.yMax ) - { - /* the two boxes are different, now walk over the outline to */ - /* get the Bezier arc extrema. */ - - static const FT_Outline_Funcs bbox_interface = - { - (FT_Outline_MoveTo_Func) BBox_Move_To, - (FT_Outline_LineTo_Func) BBox_Move_To, - (FT_Outline_ConicTo_Func)BBox_Conic_To, - (FT_Outline_CubicTo_Func)BBox_Cubic_To, - 0, 0 - }; - - FT_Error error; - TBBox_Rec user; - - - user.bbox = bbox; - - error = FT_Outline_Decompose( outline, &bbox_interface, &user ); - if ( error ) - return error; - - *abbox = user.bbox; - } - else - *abbox = bbox; - - return FT_Err_Ok; - } - - -/* END */ diff --git a/src/base/ftbitmap.c b/src/base/ftbitmap.c deleted file mode 100644 index 4c1cdf2..0000000 --- a/src/base/ftbitmap.c +++ /dev/null @@ -1,630 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftbitmap.c */ -/* */ -/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */ -/* bitmaps into 8bpp format (body). */ -/* */ -/* Copyright 2004, 2005, 2006, 2007 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_BITMAP_H -#include FT_INTERNAL_OBJECTS_H - - - static - const FT_Bitmap null_bitmap = { 0, 0, 0, 0, 0, 0, 0, 0 }; - - - /* documentation is in ftbitmap.h */ - - FT_EXPORT_DEF( void ) - FT_Bitmap_New( FT_Bitmap *abitmap ) - { - *abitmap = null_bitmap; - } - - - /* documentation is in ftbitmap.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Bitmap_Copy( FT_Library library, - const FT_Bitmap *source, - FT_Bitmap *target) - { - FT_Memory memory = library->memory; - FT_Error error = FT_Err_Ok; - FT_Int pitch = source->pitch; - FT_ULong size; - - - if ( source == target ) - return FT_Err_Ok; - - if ( source->buffer == NULL ) - { - *target = *source; - - return FT_Err_Ok; - } - - if ( pitch < 0 ) - pitch = -pitch; - size = (FT_ULong)( pitch * source->rows ); - - if ( target->buffer ) - { - FT_Int target_pitch = target->pitch; - FT_ULong target_size; - - - if ( target_pitch < 0 ) - target_pitch = -target_pitch; - target_size = (FT_ULong)( target_pitch * target->rows ); - - if ( target_size != size ) - (void)FT_QREALLOC( target->buffer, target_size, size ); - } - else - (void)FT_QALLOC( target->buffer, size ); - - if ( !error ) - { - unsigned char *p; - - - p = target->buffer; - *target = *source; - target->buffer = p; - - FT_MEM_COPY( target->buffer, source->buffer, size ); - } - - return error; - } - - - static FT_Error - ft_bitmap_assure_buffer( FT_Memory memory, - FT_Bitmap* bitmap, - FT_UInt xpixels, - FT_UInt ypixels ) - { - FT_Error error; - int pitch; - int new_pitch; - FT_UInt bpp; - FT_Int i, width, height; - unsigned char* buffer; - - - width = bitmap->width; - height = bitmap->rows; - pitch = bitmap->pitch; - if ( pitch < 0 ) - pitch = -pitch; - - switch ( bitmap->pixel_mode ) - { - case FT_PIXEL_MODE_MONO: - bpp = 1; - new_pitch = ( width + xpixels + 7 ) >> 3; - break; - case FT_PIXEL_MODE_GRAY2: - bpp = 2; - new_pitch = ( width + xpixels + 3 ) >> 2; - break; - case FT_PIXEL_MODE_GRAY4: - bpp = 4; - new_pitch = ( width + xpixels + 1 ) >> 1; - break; - case FT_PIXEL_MODE_GRAY: - case FT_PIXEL_MODE_LCD: - case FT_PIXEL_MODE_LCD_V: - bpp = 8; - new_pitch = ( width + xpixels ); - break; - default: - return FT_Err_Invalid_Glyph_Format; - } - - /* if no need to allocate memory */ - if ( ypixels == 0 && new_pitch <= pitch ) - { - /* zero the padding */ - FT_Int bit_width = pitch * 8; - FT_Int bit_last = ( width + xpixels ) * bpp; - - - if ( bit_last < bit_width ) - { - FT_Byte* line = bitmap->buffer + ( bit_last >> 3 ); - FT_Byte* end = bitmap->buffer + pitch; - FT_Int shift = bit_last & 7; - FT_UInt mask = 0xFF00U >> shift; - FT_Int count = height; - - - for ( ; count > 0; count--, line += pitch, end += pitch ) - { - FT_Byte* write = line; - - - if ( shift > 0 ) - { - write[0] = (FT_Byte)( write[0] & mask ); - write++; - } - if ( write < end ) - FT_MEM_ZERO( write, end-write ); - } - } - - return FT_Err_Ok; - } - - if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) ) - return error; - - if ( bitmap->pitch > 0 ) - { - FT_Int len = ( width * bpp + 7 ) >> 3; - - - for ( i = 0; i < bitmap->rows; i++ ) - FT_MEM_COPY( buffer + new_pitch * ( ypixels + i ), - bitmap->buffer + pitch * i, len ); - } - else - { - FT_Int len = ( width * bpp + 7 ) >> 3; - - - for ( i = 0; i < bitmap->rows; i++ ) - FT_MEM_COPY( buffer + new_pitch * i, - bitmap->buffer + pitch * i, len ); - } - - FT_FREE( bitmap->buffer ); - bitmap->buffer = buffer; - - if ( bitmap->pitch < 0 ) - new_pitch = -new_pitch; - - /* set pitch only, width and height are left untouched */ - bitmap->pitch = new_pitch; - - return FT_Err_Ok; - } - - - /* documentation is in ftbitmap.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Bitmap_Embolden( FT_Library library, - FT_Bitmap* bitmap, - FT_Pos xStrength, - FT_Pos yStrength ) - { - FT_Error error; - unsigned char* p; - FT_Int i, x, y, pitch; - FT_Int xstr, ystr; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !bitmap || !bitmap->buffer ) - return FT_Err_Invalid_Argument; - - xstr = FT_PIX_ROUND( xStrength ) >> 6; - ystr = FT_PIX_ROUND( yStrength ) >> 6; - - if ( xstr == 0 && ystr == 0 ) - return FT_Err_Ok; - else if ( xstr < 0 || ystr < 0 ) - return FT_Err_Invalid_Argument; - - switch ( bitmap->pixel_mode ) - { - case FT_PIXEL_MODE_GRAY2: - case FT_PIXEL_MODE_GRAY4: - { - FT_Bitmap tmp; - FT_Int align; - - - if ( bitmap->pixel_mode == FT_PIXEL_MODE_GRAY2 ) - align = ( bitmap->width + xstr + 3 ) / 4; - else - align = ( bitmap->width + xstr + 1 ) / 2; - - FT_Bitmap_New( &tmp ); - - error = FT_Bitmap_Convert( library, bitmap, &tmp, align ); - if ( error ) - return error; - - FT_Bitmap_Done( library, bitmap ); - *bitmap = tmp; - } - break; - - case FT_PIXEL_MODE_MONO: - if ( xstr > 8 ) - xstr = 8; - break; - - case FT_PIXEL_MODE_LCD: - xstr *= 3; - break; - - case FT_PIXEL_MODE_LCD_V: - ystr *= 3; - break; - } - - error = ft_bitmap_assure_buffer( library->memory, bitmap, xstr, ystr ); - if ( error ) - return error; - - pitch = bitmap->pitch; - if ( pitch > 0 ) - p = bitmap->buffer + pitch * ystr; - else - { - pitch = -pitch; - p = bitmap->buffer + pitch * ( bitmap->rows - 1 ); - } - - /* for each row */ - for ( y = 0; y < bitmap->rows ; y++ ) - { - /* - * Horizontally: - * - * From the last pixel on, make each pixel or'ed with the - * `xstr' pixels before it. - */ - for ( x = pitch - 1; x >= 0; x-- ) - { - unsigned char tmp; - - - tmp = p[x]; - for ( i = 1; i <= xstr; i++ ) - { - if ( bitmap->pixel_mode == FT_PIXEL_MODE_MONO ) - { - p[x] |= tmp >> i; - - /* the maximum value of 8 for `xstr' comes from here */ - if ( x > 0 ) - p[x] |= p[x - 1] << ( 8 - i ); - -#if 0 - if ( p[x] == 0xff ) - break; -#endif - } - else - { - if ( x - i >= 0 ) - { - if ( p[x] + p[x - i] > bitmap->num_grays - 1 ) - { - p[x] = (unsigned char)(bitmap->num_grays - 1); - break; - } - else - { - p[x] = (unsigned char)(p[x] + p[x-i]); - if ( p[x] == bitmap->num_grays - 1 ) - break; - } - } - else - break; - } - } - } - - /* - * Vertically: - * - * Make the above `ystr' rows or'ed with it. - */ - for ( x = 1; x <= ystr; x++ ) - { - unsigned char* q; - - - q = p - bitmap->pitch * x; - for ( i = 0; i < pitch; i++ ) - q[i] |= p[i]; - } - - p += bitmap->pitch; - } - - bitmap->width += xstr; - bitmap->rows += ystr; - - return FT_Err_Ok; - } - - - /* documentation is in ftbitmap.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Bitmap_Convert( FT_Library library, - const FT_Bitmap *source, - FT_Bitmap *target, - FT_Int alignment ) - { - FT_Error error = FT_Err_Ok; - FT_Memory memory; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - memory = library->memory; - - switch ( source->pixel_mode ) - { - case FT_PIXEL_MODE_MONO: - case FT_PIXEL_MODE_GRAY: - case FT_PIXEL_MODE_GRAY2: - case FT_PIXEL_MODE_GRAY4: - { - FT_Int pad; - FT_Long old_size; - - - old_size = target->rows * target->pitch; - if ( old_size < 0 ) - old_size = -old_size; - - target->pixel_mode = FT_PIXEL_MODE_GRAY; - target->rows = source->rows; - target->width = source->width; - - pad = 0; - if ( alignment > 0 ) - { - pad = source->width % alignment; - if ( pad != 0 ) - pad = alignment - pad; - } - - target->pitch = source->width + pad; - - if ( target->rows * target->pitch > old_size && - FT_QREALLOC( target->buffer, - old_size, target->rows * target->pitch ) ) - return error; - } - break; - - default: - error = FT_Err_Invalid_Argument; - } - - switch ( source->pixel_mode ) - { - case FT_PIXEL_MODE_MONO: - { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; - - - target->num_grays = 2; - - for ( i = source->rows; i > 0; i-- ) - { - FT_Byte* ss = s; - FT_Byte* tt = t; - FT_Int j; - - - /* get the full bytes */ - for ( j = source->width >> 3; j > 0; j-- ) - { - FT_Int val = ss[0]; /* avoid a byte->int cast on each line */ - - - tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7 ); - tt[1] = (FT_Byte)( ( val & 0x40 ) >> 6 ); - tt[2] = (FT_Byte)( ( val & 0x20 ) >> 5 ); - tt[3] = (FT_Byte)( ( val & 0x10 ) >> 4 ); - tt[4] = (FT_Byte)( ( val & 0x08 ) >> 3 ); - tt[5] = (FT_Byte)( ( val & 0x04 ) >> 2 ); - tt[6] = (FT_Byte)( ( val & 0x02 ) >> 1 ); - tt[7] = (FT_Byte)( val & 0x01 ); - - tt += 8; - ss += 1; - } - - /* get remaining pixels (if any) */ - j = source->width & 7; - if ( j > 0 ) - { - FT_Int val = *ss; - - - for ( ; j > 0; j-- ) - { - tt[0] = (FT_Byte)( ( val & 0x80 ) >> 7); - val <<= 1; - tt += 1; - } - } - - s += source->pitch; - t += target->pitch; - } - } - break; - - - case FT_PIXEL_MODE_GRAY: - { - FT_Int width = source->width; - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int s_pitch = source->pitch; - FT_Int t_pitch = target->pitch; - FT_Int i; - - - target->num_grays = 256; - - for ( i = source->rows; i > 0; i-- ) - { - FT_ARRAY_COPY( t, s, width ); - - s += s_pitch; - t += t_pitch; - } - } - break; - - - case FT_PIXEL_MODE_GRAY2: - { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; - - - target->num_grays = 4; - - for ( i = source->rows; i > 0; i-- ) - { - FT_Byte* ss = s; - FT_Byte* tt = t; - FT_Int j; - - - /* get the full bytes */ - for ( j = source->width >> 2; j > 0; j-- ) - { - FT_Int val = ss[0]; - - - tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 ); - tt[1] = (FT_Byte)( ( val & 0x30 ) >> 4 ); - tt[2] = (FT_Byte)( ( val & 0x0C ) >> 2 ); - tt[3] = (FT_Byte)( ( val & 0x03 ) ); - - ss += 1; - tt += 4; - } - - j = source->width & 3; - if ( j > 0 ) - { - FT_Int val = ss[0]; - - - for ( ; j > 0; j-- ) - { - tt[0] = (FT_Byte)( ( val & 0xC0 ) >> 6 ); - val <<= 2; - tt += 1; - } - } - - s += source->pitch; - t += target->pitch; - } - } - break; - - - case FT_PIXEL_MODE_GRAY4: - { - FT_Byte* s = source->buffer; - FT_Byte* t = target->buffer; - FT_Int i; - - - target->num_grays = 16; - - for ( i = source->rows; i > 0; i-- ) - { - FT_Byte* ss = s; - FT_Byte* tt = t; - FT_Int j; - - - /* get the full bytes */ - for ( j = source->width >> 1; j > 0; j-- ) - { - FT_Int val = ss[0]; - - - tt[0] = (FT_Byte)( ( val & 0xF0 ) >> 4 ); - tt[1] = (FT_Byte)( ( val & 0x0F ) ); - - ss += 1; - tt += 2; - } - - if ( source->width & 1 ) - tt[0] = (FT_Byte)( ( ss[0] & 0xF0 ) >> 4 ); - - s += source->pitch; - t += target->pitch; - } - } - break; - - - default: - ; - } - - return error; - } - - - /* documentation is in ftbitmap.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Bitmap_Done( FT_Library library, - FT_Bitmap *bitmap ) - { - FT_Memory memory; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !bitmap ) - return FT_Err_Invalid_Argument; - - memory = library->memory; - - FT_FREE( bitmap->buffer ); - *bitmap = null_bitmap; - - return FT_Err_Ok; - } - - -/* END */ diff --git a/src/base/ftcalc.c b/src/base/ftcalc.c deleted file mode 100644 index 9193c32..0000000 --- a/src/base/ftcalc.c +++ /dev/null @@ -1,825 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftcalc.c */ -/* */ -/* Arithmetic computations (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* Support for 1-complement arithmetic has been totally dropped in this */ - /* release. You can still write your own code if you need it. */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Implementing basic computation routines. */ - /* */ - /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */ - /* and FT_FloorFix() are declared in freetype.h. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_CALC_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_OBJECTS_H - -#ifdef FT_MULFIX_INLINED -#undef FT_MulFix -#endif - -/* we need to define a 64-bits data type here */ - -#ifdef FT_LONG64 - - typedef FT_INT64 FT_Int64; - -#else - - typedef struct FT_Int64_ - { - FT_UInt32 lo; - FT_UInt32 hi; - - } FT_Int64; - -#endif /* FT_LONG64 */ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_calc - - - /* The following three functions are available regardless of whether */ - /* FT_LONG64 is defined. */ - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_RoundFix( FT_Fixed a ) - { - return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL - : -((-a + 0x8000L ) & ~0xFFFFL ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_CeilFix( FT_Fixed a ) - { - return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL - : -((-a + 0xFFFFL ) & ~0xFFFFL ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_FloorFix( FT_Fixed a ) - { - return ( a >= 0 ) ? a & ~0xFFFFL - : -((-a) & ~0xFFFFL ); - } - - -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - - /* documentation is in ftcalc.h */ - - FT_EXPORT_DEF( FT_Int32 ) - FT_Sqrt32( FT_Int32 x ) - { - FT_ULong val, root, newroot, mask; - - - root = 0; - mask = 0x40000000L; - val = (FT_ULong)x; - - do - { - newroot = root + mask; - if ( newroot <= val ) - { - val -= newroot; - root = newroot + mask; - } - - root >>= 1; - mask >>= 2; - - } while ( mask != 0 ); - - return root; - } - -#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ - - -#ifdef FT_LONG64 - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ) - { - FT_Int s; - FT_Long d; - - - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } - - d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c - : 0x7FFFFFFFL ); - - return ( s > 0 ) ? d : -d; - } - - -#ifdef TT_USE_BYTECODE_INTERPRETER - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( FT_Long ) - FT_MulDiv_No_Round( FT_Long a, - FT_Long b, - FT_Long c ) - { - FT_Int s; - FT_Long d; - - - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - if ( c < 0 ) { c = -c; s = -s; } - - d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c - : 0x7FFFFFFFL ); - - return ( s > 0 ) ? d : -d; - } - -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ) - { -#ifdef FT_MULFIX_ASSEMBLER - return FT_MULFIX_ASSEMBLER(a,b); -#else - FT_Int s = 1; - FT_Long c; - - - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - - c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); - return ( s > 0 ) ? c : -c ; -#endif - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_DivFix( FT_Long a, - FT_Long b ) - { - FT_Int32 s; - FT_UInt32 q; - - s = 1; - if ( a < 0 ) { a = -a; s = -1; } - if ( b < 0 ) { b = -b; s = -s; } - - if ( b == 0 ) - /* check for division by 0 */ - q = 0x7FFFFFFFL; - else - /* compute result directly */ - q = (FT_UInt32)( ( ( (FT_Int64)a << 16 ) + ( b >> 1 ) ) / b ); - - return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); - } - - -#else /* !FT_LONG64 */ - - - static void - ft_multo64( FT_UInt32 x, - FT_UInt32 y, - FT_Int64 *z ) - { - FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; - - - lo1 = x & 0x0000FFFFU; hi1 = x >> 16; - lo2 = y & 0x0000FFFFU; hi2 = y >> 16; - - lo = lo1 * lo2; - i1 = lo1 * hi2; - i2 = lo2 * hi1; - hi = hi1 * hi2; - - /* Check carry overflow of i1 + i2 */ - i1 += i2; - hi += (FT_UInt32)( i1 < i2 ) << 16; - - hi += i1 >> 16; - i1 = i1 << 16; - - /* Check carry overflow of i1 + lo */ - lo += i1; - hi += ( lo < i1 ); - - z->lo = lo; - z->hi = hi; - } - - - static FT_UInt32 - ft_div64by32( FT_UInt32 hi, - FT_UInt32 lo, - FT_UInt32 y ) - { - FT_UInt32 r, q; - FT_Int i; - - - q = 0; - r = hi; - - if ( r >= y ) - return (FT_UInt32)0x7FFFFFFFL; - - i = 32; - do - { - r <<= 1; - q <<= 1; - r |= lo >> 31; - - if ( r >= (FT_UInt32)y ) - { - r -= y; - q |= 1; - } - lo <<= 1; - } while ( --i ); - - return q; - } - - - static void - FT_Add64( FT_Int64* x, - FT_Int64* y, - FT_Int64 *z ) - { - register FT_UInt32 lo, hi; - - - lo = x->lo + y->lo; - hi = x->hi + y->hi + ( lo < x->lo ); - - z->lo = lo; - z->hi = hi; - } - - - /* documentation is in freetype.h */ - - /* The FT_MulDiv function has been optimized thanks to ideas from */ - /* Graham Asher. The trick is to optimize computation when everything */ - /* fits within 32-bits (a rather common case). */ - /* */ - /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */ - /* */ - /* 46340 is FLOOR(SQRT(2^31-1)). */ - /* */ - /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */ - /* */ - /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */ - /* */ - /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */ - /* */ - /* and 2*0x157F0 = 176096 */ - /* */ - - FT_EXPORT_DEF( FT_Long ) - FT_MulDiv( FT_Long a, - FT_Long b, - FT_Long c ) - { - long s; - - - if ( a == 0 || b == c ) - return a; - - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - s ^= c; c = FT_ABS( c ); - - if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) - a = ( a * b + ( c >> 1 ) ) / c; - - else if ( c > 0 ) - { - FT_Int64 temp, temp2; - - - ft_multo64( a, b, &temp ); - - temp2.hi = 0; - temp2.lo = (FT_UInt32)(c >> 1); - FT_Add64( &temp, &temp2, &temp ); - a = ft_div64by32( temp.hi, temp.lo, c ); - } - else - a = 0x7FFFFFFFL; - - return ( s < 0 ? -a : a ); - } - - -#ifdef TT_USE_BYTECODE_INTERPRETER - - FT_BASE_DEF( FT_Long ) - FT_MulDiv_No_Round( FT_Long a, - FT_Long b, - FT_Long c ) - { - long s; - - - if ( a == 0 || b == c ) - return a; - - s = a; a = FT_ABS( a ); - s ^= b; b = FT_ABS( b ); - s ^= c; c = FT_ABS( c ); - - if ( a <= 46340L && b <= 46340L && c > 0 ) - a = a * b / c; - - else if ( c > 0 ) - { - FT_Int64 temp; - - - ft_multo64( a, b, &temp ); - a = ft_div64by32( temp.hi, temp.lo, c ); - } - else - a = 0x7FFFFFFFL; - - return ( s < 0 ? -a : a ); - } - -#endif /* TT_USE_BYTECODE_INTERPRETER */ - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_MulFix( FT_Long a, - FT_Long b ) - { -#ifdef FT_MULFIX_ASSEMBLER - return FT_MULFIX_ASSEMBLER(a,b); -#else - FT_Long sa, sb; - FT_ULong ua, ub; - - - if ( a == 0 || b == 0x10000L ) - return a; - - sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); - a = ( a ^ sa ) - sa; - sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); - b = ( b ^ sb ) - sb; - - ua = (FT_ULong)a; - ub = (FT_ULong)b; - - if ( ua <= 2048 && ub <= 1048576L ) - ua = ( ua * ub + 0x8000U ) >> 16; - else - { - FT_ULong al = ua & 0xFFFFU; - - - ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + - ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); - } - - sa ^= sb, - ua = (FT_ULong)(( ua ^ sa ) - sa); - - return (FT_Long)ua; -#endif - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_DivFix( FT_Long a, - FT_Long b ) - { - FT_Int32 s; - FT_UInt32 q; - - - s = a; a = FT_ABS(a); - s ^= b; b = FT_ABS(b); - - if ( b == 0 ) - { - /* check for division by 0 */ - q = 0x7FFFFFFFL; - } - else if ( ( a >> 16 ) == 0 ) - { - /* compute result directly */ - q = (FT_UInt32)( (a << 16) + (b >> 1) ) / (FT_UInt32)b; - } - else - { - /* we need more bits; we have to do it by hand */ - FT_Int64 temp, temp2; - - temp.hi = (FT_Int32) (a >> 16); - temp.lo = (FT_UInt32)(a << 16); - temp2.hi = 0; - temp2.lo = (FT_UInt32)( b >> 1 ); - FT_Add64( &temp, &temp2, &temp ); - q = ft_div64by32( temp.hi, temp.lo, b ); - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - -#if 0 - - /* documentation is in ftcalc.h */ - - FT_EXPORT_DEF( void ) - FT_MulTo64( FT_Int32 x, - FT_Int32 y, - FT_Int64 *z ) - { - FT_Int32 s; - - - s = x; x = FT_ABS( x ); - s ^= y; y = FT_ABS( y ); - - ft_multo64( x, y, z ); - - if ( s < 0 ) - { - z->lo = (FT_UInt32)-(FT_Int32)z->lo; - z->hi = ~z->hi + !( z->lo ); - } - } - - - /* apparently, the second version of this code is not compiled correctly */ - /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */ - -#if 1 - - FT_EXPORT_DEF( FT_Int32 ) - FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q, r, i, lo; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !x->lo; - } - s ^= y; y = FT_ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = x->lo / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - r = x->hi; - lo = x->lo; - - if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */ - return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL ); - /* Return Max/Min Int32 if division overflow. */ - /* This includes division by zero! */ - q = 0; - for ( i = 0; i < 32; i++ ) - { - r <<= 1; - q <<= 1; - r |= lo >> 31; - - if ( r >= (FT_UInt32)y ) - { - r -= y; - q |= 1; - } - lo <<= 1; - } - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - -#else /* 0 */ - - FT_EXPORT_DEF( FT_Int32 ) - FT_Div64by32( FT_Int64* x, - FT_Int32 y ) - { - FT_Int32 s; - FT_UInt32 q; - - - s = x->hi; - if ( s < 0 ) - { - x->lo = (FT_UInt32)-(FT_Int32)x->lo; - x->hi = ~x->hi + !x->lo; - } - s ^= y; y = FT_ABS( y ); - - /* Shortcut */ - if ( x->hi == 0 ) - { - if ( y > 0 ) - q = ( x->lo + ( y >> 1 ) ) / y; - else - q = 0x7FFFFFFFL; - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - - q = ft_div64by32( x->hi, x->lo, y ); - - return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); - } - -#endif /* 0 */ - -#endif /* 0 */ - - -#endif /* FT_LONG64 */ - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( void ) - FT_Matrix_Multiply_Scaled( const FT_Matrix* a, - FT_Matrix *b, - FT_Long scaling ) - { - FT_Fixed xx, xy, yx, yy; - - FT_Long val = 0x10000L * scaling; - - - if ( !a || !b ) - return; - - xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); - xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); - yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); - yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); - - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( void ) - FT_Vector_Transform_Scaled( FT_Vector* vector, - const FT_Matrix* matrix, - FT_Long scaling ) - { - FT_Pos xz, yz; - - FT_Long val = 0x10000L * scaling; - - - if ( !vector || !matrix ) - return; - - xz = FT_MulDiv( vector->x, matrix->xx, val ) + - FT_MulDiv( vector->y, matrix->xy, val ); - - yz = FT_MulDiv( vector->x, matrix->yx, val ) + - FT_MulDiv( vector->y, matrix->yy, val ); - - vector->x = xz; - vector->y = yz; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( FT_Int32 ) - FT_SqrtFixed( FT_Int32 x ) - { - FT_UInt32 root, rem_hi, rem_lo, test_div; - FT_Int count; - - - root = 0; - - if ( x > 0 ) - { - rem_hi = 0; - rem_lo = x; - count = 24; - do - { - rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 ); - rem_lo <<= 2; - root <<= 1; - test_div = ( root << 1 ) + 1; - - if ( rem_hi >= test_div ) - { - rem_hi -= test_div; - root += 1; - } - } while ( --count ); - } - - return (FT_Int32)root; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( FT_Int ) - ft_corner_orientation( FT_Pos in_x, - FT_Pos in_y, - FT_Pos out_x, - FT_Pos out_y ) - { - FT_Int result; - - - /* deal with the trivial cases quickly */ - if ( in_y == 0 ) - { - if ( in_x >= 0 ) - result = out_y; - else - result = -out_y; - } - else if ( in_x == 0 ) - { - if ( in_y >= 0 ) - result = -out_x; - else - result = out_x; - } - else if ( out_y == 0 ) - { - if ( out_x >= 0 ) - result = in_y; - else - result = -in_y; - } - else if ( out_x == 0 ) - { - if ( out_y >= 0 ) - result = -in_x; - else - result = in_x; - } - else /* general case */ - { -#ifdef FT_LONG64 - - FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x; - - - if ( delta == 0 ) - result = 0; - else - result = 1 - 2 * ( delta < 0 ); - -#else - - FT_Int64 z1, z2; - - - ft_multo64( in_x, out_y, &z1 ); - ft_multo64( in_y, out_x, &z2 ); - - if ( z1.hi > z2.hi ) - result = +1; - else if ( z1.hi < z2.hi ) - result = -1; - else if ( z1.lo > z2.lo ) - result = +1; - else if ( z1.lo < z2.lo ) - result = -1; - else - result = 0; - -#endif - } - - return result; - } - - - /* documentation is in ftcalc.h */ - - FT_BASE_DEF( FT_Int ) - ft_corner_is_flat( FT_Pos in_x, - FT_Pos in_y, - FT_Pos out_x, - FT_Pos out_y ) - { - FT_Pos ax = in_x; - FT_Pos ay = in_y; - - FT_Pos d_in, d_out, d_corner; - - - if ( ax < 0 ) - ax = -ax; - if ( ay < 0 ) - ay = -ay; - d_in = ax + ay; - - ax = out_x; - if ( ax < 0 ) - ax = -ax; - ay = out_y; - if ( ay < 0 ) - ay = -ay; - d_out = ax + ay; - - ax = out_x + in_x; - if ( ax < 0 ) - ax = -ax; - ay = out_y + in_y; - if ( ay < 0 ) - ay = -ay; - d_corner = ax + ay; - - return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); - } - - -/* END */ diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c deleted file mode 100644 index 52a5c20..0000000 --- a/src/base/ftdbgmem.c +++ /dev/null @@ -1,998 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftdbgmem.c */ -/* */ -/* Memory debugger (body). */ -/* */ -/* Copyright 2001, 2002, 2003, 2004, 2005, 2006 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_MEMORY_H -#include FT_SYSTEM_H -#include FT_ERRORS_H -#include FT_TYPES_H - - -#ifdef FT_DEBUG_MEMORY - -#define KEEPALIVE /* `Keep alive' means that freed blocks aren't released - * to the heap. This is useful to detect double-frees - * or weird heap corruption, but it uses large amounts of - * memory, however. - */ - -#include <stdio.h> -#include <stdlib.h> - - FT_BASE_DEF( const char* ) _ft_debug_file = 0; - FT_BASE_DEF( long ) _ft_debug_lineno = 0; - - extern void - FT_DumpMemory( FT_Memory memory ); - - - typedef struct FT_MemSourceRec_* FT_MemSource; - typedef struct FT_MemNodeRec_* FT_MemNode; - typedef struct FT_MemTableRec_* FT_MemTable; - - -#define FT_MEM_VAL( addr ) ((FT_ULong)(FT_Pointer)( addr )) - - /* - * This structure holds statistics for a single allocation/release - * site. This is useful to know where memory operations happen the - * most. - */ - typedef struct FT_MemSourceRec_ - { - const char* file_name; - long line_no; - - FT_Long cur_blocks; /* current number of allocated blocks */ - FT_Long max_blocks; /* max. number of allocated blocks */ - FT_Long all_blocks; /* total number of blocks allocated */ - - FT_Long cur_size; /* current cumulative allocated size */ - FT_Long max_size; /* maximum cumulative allocated size */ - FT_Long all_size; /* total cumulative allocated size */ - - FT_Long cur_max; /* current maximum allocated size */ - - FT_UInt32 hash; - FT_MemSource link; - - } FT_MemSourceRec; - - - /* - * We don't need a resizable array for the memory sources, because - * their number is pretty limited within FreeType. - */ -#define FT_MEM_SOURCE_BUCKETS 128 - - /* - * This structure holds information related to a single allocated - * memory block. If KEEPALIVE is defined, blocks that are freed by - * FreeType are never released to the system. Instead, their `size' - * field is set to -size. This is mainly useful to detect double frees, - * at the price of large memory footprint during execution. - */ - typedef struct FT_MemNodeRec_ - { - FT_Byte* address; - FT_Long size; /* < 0 if the block was freed */ - - FT_MemSource source; - -#ifdef KEEPALIVE - const char* free_file_name; - FT_Long free_line_no; -#endif - - FT_MemNode link; - - } FT_MemNodeRec; - - - /* - * The global structure, containing compound statistics and all hash - * tables. - */ - typedef struct FT_MemTableRec_ - { - FT_ULong size; - FT_ULong nodes; - FT_MemNode* buckets; - - FT_ULong alloc_total; - FT_ULong alloc_current; - FT_ULong alloc_max; - FT_ULong alloc_count; - - FT_Bool bound_total; - FT_ULong alloc_total_max; - - FT_Bool bound_count; - FT_ULong alloc_count_max; - - FT_MemSource sources[FT_MEM_SOURCE_BUCKETS]; - - FT_Bool keep_alive; - - FT_Memory memory; - FT_Pointer memory_user; - FT_Alloc_Func alloc; - FT_Free_Func free; - FT_Realloc_Func realloc; - - } FT_MemTableRec; - - -#define FT_MEM_SIZE_MIN 7 -#define FT_MEM_SIZE_MAX 13845163 - -#define FT_FILENAME( x ) ((x) ? (x) : "unknown file") - - - /* - * Prime numbers are ugly to handle. It would be better to implement - * L-Hashing, which is 10% faster and doesn't require divisions. - */ - static const FT_UInt ft_mem_primes[] = - { - 7, - 11, - 19, - 37, - 73, - 109, - 163, - 251, - 367, - 557, - 823, - 1237, - 1861, - 2777, - 4177, - 6247, - 9371, - 14057, - 21089, - 31627, - 47431, - 71143, - 106721, - 160073, - 240101, - 360163, - 540217, - 810343, - 1215497, - 1823231, - 2734867, - 4102283, - 6153409, - 9230113, - 13845163, - }; - - - static FT_ULong - ft_mem_closest_prime( FT_ULong num ) - { - FT_UInt i; - - - for ( i = 0; - i < sizeof ( ft_mem_primes ) / sizeof ( ft_mem_primes[0] ); i++ ) - if ( ft_mem_primes[i] > num ) - return ft_mem_primes[i]; - - return FT_MEM_SIZE_MAX; - } - - - extern void - ft_mem_debug_panic( const char* fmt, - ... ) - { - va_list ap; - - - printf( "FreeType.Debug: " ); - - va_start( ap, fmt ); - vprintf( fmt, ap ); - va_end( ap ); - - printf( "\n" ); - exit( EXIT_FAILURE ); - } - - - static FT_Pointer - ft_mem_table_alloc( FT_MemTable table, - FT_Long size ) - { - FT_Memory memory = table->memory; - FT_Pointer block; - - - memory->user = table->memory_user; - block = table->alloc( memory, size ); - memory->user = table; - - return block; - } - - - static void - ft_mem_table_free( FT_MemTable table, - FT_Pointer block ) - { - FT_Memory memory = table->memory; - - - memory->user = table->memory_user; - table->free( memory, block ); - memory->user = table; - } - - - static void - ft_mem_table_resize( FT_MemTable table ) - { - FT_ULong new_size; - - - new_size = ft_mem_closest_prime( table->nodes ); - if ( new_size != table->size ) - { - FT_MemNode* new_buckets; - FT_ULong i; - - - new_buckets = (FT_MemNode *) - ft_mem_table_alloc( table, - new_size * sizeof ( FT_MemNode ) ); - if ( new_buckets == NULL ) - return; - - FT_ARRAY_ZERO( new_buckets, new_size ); - - for ( i = 0; i < table->size; i++ ) - { - FT_MemNode node, next, *pnode; - FT_ULong hash; - - - node = table->buckets[i]; - while ( node ) - { - next = node->link; - hash = FT_MEM_VAL( node->address ) % new_size; - pnode = new_buckets + hash; - - node->link = pnode[0]; - pnode[0] = node; - - node = next; - } - } - - if ( table->buckets ) - ft_mem_table_free( table, table->buckets ); - - table->buckets = new_buckets; - table->size = new_size; - } - } - - - static FT_MemTable - ft_mem_table_new( FT_Memory memory ) - { - FT_MemTable table; - - - table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); - if ( table == NULL ) - goto Exit; - - FT_ZERO( table ); - - table->size = FT_MEM_SIZE_MIN; - table->nodes = 0; - - table->memory = memory; - - table->memory_user = memory->user; - - table->alloc = memory->alloc; - table->realloc = memory->realloc; - table->free = memory->free; - - table->buckets = (FT_MemNode *) - memory->alloc( memory, - table->size * sizeof ( FT_MemNode ) ); - if ( table->buckets ) - FT_ARRAY_ZERO( table->buckets, table->size ); - else - { - memory->free( memory, table ); - table = NULL; - } - - Exit: - return table; - } - - - static void - ft_mem_table_destroy( FT_MemTable table ) - { - FT_ULong i; - - - FT_DumpMemory( table->memory ); - - if ( table ) - { - FT_Long leak_count = 0; - FT_ULong leaks = 0; - - - /* remove all blocks from the table, revealing leaked ones */ - for ( i = 0; i < table->size; i++ ) - { - FT_MemNode *pnode = table->buckets + i, next, node = *pnode; - - - while ( node ) - { - next = node->link; - node->link = 0; - - if ( node->size > 0 ) - { - printf( - "leaked memory block at address %p, size %8ld in (%s:%ld)\n", - node->address, node->size, - FT_FILENAME( node->source->file_name ), - node->source->line_no ); - - leak_count++; - leaks += node->size; - - ft_mem_table_free( table, node->address ); - } - - node->address = NULL; - node->size = 0; - - ft_mem_table_free( table, node ); - node = next; - } - table->buckets[i] = 0; - } - - ft_mem_table_free( table, table->buckets ); - table->buckets = NULL; - - table->size = 0; - table->nodes = 0; - - /* remove all sources */ - for ( i = 0; i < FT_MEM_SOURCE_BUCKETS; i++ ) - { - FT_MemSource source, next; - - - for ( source = table->sources[i]; source != NULL; source = next ) - { - next = source->link; - ft_mem_table_free( table, source ); - } - - table->sources[i] = NULL; - } - - printf( - "FreeType: total memory allocations = %ld\n", table->alloc_total ); - printf( - "FreeType: maximum memory footprint = %ld\n", table->alloc_max ); - - ft_mem_table_free( table, table ); - - if ( leak_count > 0 ) - ft_mem_debug_panic( - "FreeType: %ld bytes of memory leaked in %ld blocks\n", - leaks, leak_count ); - - printf( "FreeType: No memory leaks detected!\n" ); - } - } - - - static FT_MemNode* - ft_mem_table_get_nodep( FT_MemTable table, - FT_Byte* address ) - { - FT_ULong hash; - FT_MemNode *pnode, node; - - - hash = FT_MEM_VAL( address ); - pnode = table->buckets + ( hash % table->size ); - - for (;;) - { - node = pnode[0]; - if ( !node ) - break; - - if ( node->address == address ) - break; - - pnode = &node->link; - } - return pnode; - } - - - static FT_MemSource - ft_mem_table_get_source( FT_MemTable table ) - { - FT_UInt32 hash; - FT_MemSource node, *pnode; - - - /* cast to FT_PtrDist first since void* can be larger */ - /* than FT_UInt32 and GCC 4.1.1 emits a warning */ - hash = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file + - (FT_UInt32)( 5 * _ft_debug_lineno ); - pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS]; - - for ( ;; ) - { - node = *pnode; - if ( node == NULL ) - break; - - if ( node->file_name == _ft_debug_file && - node->line_no == _ft_debug_lineno ) - goto Exit; - - pnode = &node->link; - } - - node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) ); - if ( node == NULL ) - ft_mem_debug_panic( - "not enough memory to perform memory debugging\n" ); - - node->file_name = _ft_debug_file; - node->line_no = _ft_debug_lineno; - - node->cur_blocks = 0; - node->max_blocks = 0; - node->all_blocks = 0; - - node->cur_size = 0; - node->max_size = 0; - node->all_size = 0; - - node->cur_max = 0; - - node->link = NULL; - node->hash = hash; - *pnode = node; - - Exit: - return node; - } - - - static void - ft_mem_table_set( FT_MemTable table, - FT_Byte* address, - FT_ULong size, - FT_Long delta ) - { - FT_MemNode *pnode, node; - - - if ( table ) - { - FT_MemSource source; - - - pnode = ft_mem_table_get_nodep( table, address ); - node = *pnode; - if ( node ) - { - if ( node->size < 0 ) - { - /* This block was already freed. Our memory is now completely */ - /* corrupted! */ - /* This can only happen in keep-alive mode. */ - ft_mem_debug_panic( - "memory heap corrupted (allocating freed block)" ); - } - else - { - /* This block was already allocated. This means that our memory */ - /* is also corrupted! */ - ft_mem_debug_panic( - "memory heap corrupted (re-allocating allocated block at" - " %p, of size %ld)\n" - "org=%s:%d new=%s:%d\n", - node->address, node->size, - FT_FILENAME( node->source->file_name ), node->source->line_no, - FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); - } - } - - /* we need to create a new node in this table */ - node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); - if ( node == NULL ) - ft_mem_debug_panic( "not enough memory to run memory tests" ); - - node->address = address; - node->size = size; - node->source = source = ft_mem_table_get_source( table ); - - if ( delta == 0 ) - { - /* this is an allocation */ - source->all_blocks++; - source->cur_blocks++; - if ( source->cur_blocks > source->max_blocks ) - source->max_blocks = source->cur_blocks; - } - - if ( size > (FT_ULong)source->cur_max ) - source->cur_max = size; - - if ( delta != 0 ) - { - /* we are growing or shrinking a reallocated block */ - source->cur_size += delta; - table->alloc_current += delta; - } - else - { - /* we are allocating a new block */ - source->cur_size += size; - table->alloc_current += size; - } - - source->all_size += size; - - if ( source->cur_size > source->max_size ) - source->max_size = source->cur_size; - - node->free_file_name = NULL; - node->free_line_no = 0; - - node->link = pnode[0]; - - pnode[0] = node; - table->nodes++; - - table->alloc_total += size; - - if ( table->alloc_current > table->alloc_max ) - table->alloc_max = table->alloc_current; - - if ( table->nodes * 3 < table->size || - table->size * 3 < table->nodes ) - ft_mem_table_resize( table ); - } - } - - - static void - ft_mem_table_remove( FT_MemTable table, - FT_Byte* address, - FT_Long delta ) - { - if ( table ) - { - FT_MemNode *pnode, node; - - - pnode = ft_mem_table_get_nodep( table, address ); - node = *pnode; - if ( node ) - { - FT_MemSource source; - - - if ( node->size < 0 ) - ft_mem_debug_panic( - "freeing memory block at %p more than once at (%s:%ld)\n" - "block allocated at (%s:%ld) and released at (%s:%ld)", - address, - FT_FILENAME( _ft_debug_file ), _ft_debug_lineno, - FT_FILENAME( node->source->file_name ), node->source->line_no, - FT_FILENAME( node->free_file_name ), node->free_line_no ); - - /* scramble the node's content for additional safety */ - FT_MEM_SET( address, 0xF3, node->size ); - - if ( delta == 0 ) - { - source = node->source; - - source->cur_blocks--; - source->cur_size -= node->size; - - table->alloc_current -= node->size; - } - - if ( table->keep_alive ) - { - /* we simply invert the node's size to indicate that the node */ - /* was freed. */ - node->size = -node->size; - node->free_file_name = _ft_debug_file; - node->free_line_no = _ft_debug_lineno; - } - else - { - table->nodes--; - - *pnode = node->link; - - node->size = 0; - node->source = NULL; - - ft_mem_table_free( table, node ); - - if ( table->nodes * 3 < table->size || - table->size * 3 < table->nodes ) - ft_mem_table_resize( table ); - } - } - else - ft_mem_debug_panic( - "trying to free unknown block at %p in (%s:%ld)\n", - address, - FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); - } - } - - - extern FT_Pointer - ft_mem_debug_alloc( FT_Memory memory, - FT_Long size ) - { - FT_MemTable table = (FT_MemTable)memory->user; - FT_Byte* block; - - - if ( size <= 0 ) - ft_mem_debug_panic( "negative block size allocation (%ld)", size ); - - /* return NULL if the maximum number of allocations was reached */ - if ( table->bound_count && - table->alloc_count >= table->alloc_count_max ) - return NULL; - - /* return NULL if this allocation would overflow the maximum heap size */ - if ( table->bound_total && - table->alloc_total_max - table->alloc_current > (FT_ULong)size ) - return NULL; - - block = (FT_Byte *)ft_mem_table_alloc( table, size ); - if ( block ) - { - ft_mem_table_set( table, block, (FT_ULong)size, 0 ); - - table->alloc_count++; - } - - _ft_debug_file = "<unknown>"; - _ft_debug_lineno = 0; - - return (FT_Pointer)block; - } - - - extern void - ft_mem_debug_free( FT_Memory memory, - FT_Pointer block ) - { - FT_MemTable table = (FT_MemTable)memory->user; - - - if ( block == NULL ) - ft_mem_debug_panic( "trying to free NULL in (%s:%ld)", - FT_FILENAME( _ft_debug_file ), - _ft_debug_lineno ); - - ft_mem_table_remove( table, (FT_Byte*)block, 0 ); - - if ( !table->keep_alive ) - ft_mem_table_free( table, block ); - - table->alloc_count--; - - _ft_debug_file = "<unknown>"; - _ft_debug_lineno = 0; - } - - - extern FT_Pointer - ft_mem_debug_realloc( FT_Memory memory, - FT_Long cur_size, - FT_Long new_size, - FT_Pointer block ) - { - FT_MemTable table = (FT_MemTable)memory->user; - FT_MemNode node, *pnode; - FT_Pointer new_block; - FT_Long delta; - - const char* file_name = FT_FILENAME( _ft_debug_file ); - FT_Long line_no = _ft_debug_lineno; - - - /* unlikely, but possible */ - if ( new_size == cur_size ) - return block; - - /* the following is valid according to ANSI C */ -#if 0 - if ( block == NULL || cur_size == 0 ) - ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)", - file_name, line_no ); -#endif - - /* while the following is allowed in ANSI C also, we abort since */ - /* such case should be handled by FreeType. */ - if ( new_size <= 0 ) - ft_mem_debug_panic( - "trying to reallocate %p to size 0 (current is %ld) in (%s:%ld)", - block, cur_size, file_name, line_no ); - - /* check `cur_size' value */ - pnode = ft_mem_table_get_nodep( table, (FT_Byte*)block ); - node = *pnode; - if ( !node ) - ft_mem_debug_panic( - "trying to reallocate unknown block at %p in (%s:%ld)", - block, file_name, line_no ); - - if ( node->size <= 0 ) - ft_mem_debug_panic( - "trying to reallocate freed block at %p in (%s:%ld)", - block, file_name, line_no ); - - if ( node->size != cur_size ) - ft_mem_debug_panic( "invalid ft_realloc request for %p. cur_size is " - "%ld instead of %ld in (%s:%ld)", - block, cur_size, node->size, file_name, line_no ); - - /* return NULL if the maximum number of allocations was reached */ - if ( table->bound_count && - table->alloc_count >= table->alloc_count_max ) - return NULL; - - delta = (FT_Long)( new_size - cur_size ); - - /* return NULL if this allocation would overflow the maximum heap size */ - if ( delta > 0 && - table->bound_total && - table->alloc_current + (FT_ULong)delta > table->alloc_total_max ) - return NULL; - - new_block = (FT_Byte *)ft_mem_table_alloc( table, new_size ); - if ( new_block == NULL ) - return NULL; - - ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta ); - - ft_memcpy( new_block, block, cur_size < new_size ? cur_size : new_size ); - - ft_mem_table_remove( table, (FT_Byte*)block, delta ); - - _ft_debug_file = "<unknown>"; - _ft_debug_lineno = 0; - - if ( !table->keep_alive ) - ft_mem_table_free( table, block ); - - return new_block; - } - - - extern FT_Int - ft_mem_debug_init( FT_Memory memory ) - { - FT_MemTable table; - FT_Int result = 0; - - - if ( getenv( "FT2_DEBUG_MEMORY" ) ) - { - table = ft_mem_table_new( memory ); - if ( table ) - { - const char* p; - - - memory->user = table; - memory->alloc = ft_mem_debug_alloc; - memory->realloc = ft_mem_debug_realloc; - memory->free = ft_mem_debug_free; - - p = getenv( "FT2_ALLOC_TOTAL_MAX" ); - if ( p != NULL ) - { - FT_Long total_max = ft_atol( p ); - - - if ( total_max > 0 ) - { - table->bound_total = 1; - table->alloc_total_max = (FT_ULong)total_max; - } - } - - p = getenv( "FT2_ALLOC_COUNT_MAX" ); - if ( p != NULL ) - { - FT_Long total_count = ft_atol( p ); - - - if ( total_count > 0 ) - { - table->bound_count = 1; - table->alloc_count_max = (FT_ULong)total_count; - } - } - - p = getenv( "FT2_KEEP_ALIVE" ); - if ( p != NULL ) - { - FT_Long keep_alive = ft_atol( p ); - - - if ( keep_alive > 0 ) - table->keep_alive = 1; - } - - result = 1; - } - } - return result; - } - - - extern void - ft_mem_debug_done( FT_Memory memory ) - { - FT_MemTable table = (FT_MemTable)memory->user; - - - if ( table ) - { - memory->free = table->free; - memory->realloc = table->realloc; - memory->alloc = table->alloc; - - ft_mem_table_destroy( table ); - memory->user = NULL; - } - } - - - - static int - ft_mem_source_compare( const void* p1, - const void* p2 ) - { - FT_MemSource s1 = *(FT_MemSource*)p1; - FT_MemSource s2 = *(FT_MemSource*)p2; - - - if ( s2->max_size > s1->max_size ) - return 1; - else if ( s2->max_size < s1->max_size ) - return -1; - else - return 0; - } - - - extern void - FT_DumpMemory( FT_Memory memory ) - { - FT_MemTable table = (FT_MemTable)memory->user; - - - if ( table ) - { - FT_MemSource* bucket = table->sources; - FT_MemSource* limit = bucket + FT_MEM_SOURCE_BUCKETS; - FT_MemSource* sources; - FT_UInt nn, count; - const char* fmt; - - - count = 0; - for ( ; bucket < limit; bucket++ ) - { - FT_MemSource source = *bucket; - - - for ( ; source; source = source->link ) - count++; - } - - sources = (FT_MemSource*)ft_mem_table_alloc( - table, sizeof ( *sources ) * count ); - - count = 0; - for ( bucket = table->sources; bucket < limit; bucket++ ) - { - FT_MemSource source = *bucket; - - - for ( ; source; source = source->link ) - sources[count++] = source; - } - - ft_qsort( sources, count, sizeof ( *sources ), ft_mem_source_compare ); - - printf( "FreeType Memory Dump: " - "current=%ld max=%ld total=%ld count=%ld\n", - table->alloc_current, table->alloc_max, - table->alloc_total, table->alloc_count ); - printf( " block block sizes sizes sizes source\n" ); - printf( " count high sum highsum max location\n" ); - printf( "-------------------------------------------------\n" ); - - fmt = "%6ld %6ld %8ld %8ld %8ld %s:%d\n"; - - for ( nn = 0; nn < count; nn++ ) - { - FT_MemSource source = sources[nn]; - - - printf( fmt, - source->cur_blocks, source->max_blocks, - source->cur_size, source->max_size, source->cur_max, - FT_FILENAME( source->file_name ), - source->line_no ); - } - printf( "------------------------------------------------\n" ); - - ft_mem_table_free( table, sources ); - } - } - -#else /* !FT_DEBUG_MEMORY */ - - /* ANSI C doesn't like empty source files */ - const FT_Byte _debug_mem_dummy = 0; - -#endif /* !FT_DEBUG_MEMORY */ - - -/* END */ diff --git a/src/base/ftdebug.c b/src/base/ftdebug.c deleted file mode 100644 index 356c8c2..0000000 --- a/src/base/ftdebug.c +++ /dev/null @@ -1,246 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftdebug.c */ -/* */ -/* Debugging and logging component (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2004, 2008 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* This component contains various macros and functions used to ease the */ - /* debugging of the FreeType engine. Its main purpose is in assertion */ - /* checking, tracing, and error detection. */ - /* */ - /* There are now three debugging modes: */ - /* */ - /* - trace mode */ - /* */ - /* Error and trace messages are sent to the log file (which can be the */ - /* standard error output). */ - /* */ - /* - error mode */ - /* */ - /* Only error messages are generated. */ - /* */ - /* - release mode: */ - /* */ - /* No error message is sent or generated. The code is free from any */ - /* debugging parts. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_INTERNAL_DEBUG_H - - -#if defined( FT_DEBUG_LEVEL_ERROR ) - - /* documentation is in ftdebug.h */ - - FT_BASE_DEF( void ) - FT_Message( const char* fmt, ... ) - { - va_list ap; - - - va_start( ap, fmt ); - vfprintf( stderr, fmt, ap ); - va_end( ap ); - } - - - /* documentation is in ftdebug.h */ - - FT_BASE_DEF( void ) - FT_Panic( const char* fmt, ... ) - { - va_list ap; - - - va_start( ap, fmt ); - vfprintf( stderr, fmt, ap ); - va_end( ap ); - - exit( EXIT_FAILURE ); - } - -#endif /* FT_DEBUG_LEVEL_ERROR */ - - - -#ifdef FT_DEBUG_LEVEL_TRACE - - /* array of trace levels, initialized to 0 */ - int ft_trace_levels[trace_count]; - - - /* define array of trace toggle names */ -#define FT_TRACE_DEF( x ) #x , - - static const char* ft_trace_toggles[trace_count + 1] = - { -#include FT_INTERNAL_TRACE_H - NULL - }; - -#undef FT_TRACE_DEF - - - /* documentation is in ftdebug.h */ - - FT_BASE_DEF( FT_Int ) - FT_Trace_Get_Count( void ) - { - return trace_count; - } - - - /* documentation is in ftdebug.h */ - - FT_BASE_DEF( const char * ) - FT_Trace_Get_Name( FT_Int idx ) - { - int max = FT_Trace_Get_Count(); - - - if ( idx < max ) - return ft_trace_toggles[idx]; - else - return NULL; - } - - - /*************************************************************************/ - /* */ - /* Initialize the tracing sub-system. This is done by retrieving the */ - /* value of the `FT2_DEBUG' environment variable. It must be a list of */ - /* toggles, separated by spaces, `;', or `,'. Example: */ - /* */ - /* export FT2_DEBUG="any:3 memory:7 stream:5" */ - /* */ - /* This requests that all levels be set to 3, except the trace level for */ - /* the memory and stream components which are set to 7 and 5, */ - /* respectively. */ - /* */ - /* See the file <include/freetype/internal/fttrace.h> for details of the */ - /* available toggle names. */ - /* */ - /* The level must be between 0 and 7; 0 means quiet (except for serious */ - /* runtime errors), and 7 means _very_ verbose. */ - /* */ - FT_BASE_DEF( void ) - ft_debug_init( void ) - { - const char* ft2_debug = getenv( "FT2_DEBUG" ); - - - if ( ft2_debug ) - { - const char* p = ft2_debug; - const char* q; - - - for ( ; *p; p++ ) - { - /* skip leading whitespace and separators */ - if ( *p == ' ' || *p == '\t' || *p == ',' || *p == ';' || *p == '=' ) - continue; - - /* read toggle name, followed by ':' */ - q = p; - while ( *p && *p != ':' ) - p++; - - if ( *p == ':' && p > q ) - { - FT_Int n, i, len = (FT_Int)( p - q ); - FT_Int level = -1, found = -1; - - - for ( n = 0; n < trace_count; n++ ) - { - const char* toggle = ft_trace_toggles[n]; - - - for ( i = 0; i < len; i++ ) - { - if ( toggle[i] != q[i] ) - break; - } - - if ( i == len && toggle[i] == 0 ) - { - found = n; - break; - } - } - - /* read level */ - p++; - if ( *p ) - { - level = *p++ - '0'; - if ( level < 0 || level > 7 ) - level = -1; - } - - if ( found >= 0 && level >= 0 ) - { - if ( found == trace_any ) - { - /* special case for `any' */ - for ( n = 0; n < trace_count; n++ ) - ft_trace_levels[n] = level; - } - else - ft_trace_levels[found] = level; - } - } - } - } - } - - -#else /* !FT_DEBUG_LEVEL_TRACE */ - - - FT_BASE_DEF( void ) - ft_debug_init( void ) - { - /* nothing */ - } - - - FT_BASE_DEF( FT_Int ) - FT_Trace_Get_Count( void ) - { - return 0; - } - - - FT_BASE_DEF( const char * ) - FT_Trace_Get_Name( FT_Int idx ) - { - FT_UNUSED( idx ); - - return NULL; - } - - -#endif /* !FT_DEBUG_LEVEL_TRACE */ - - -/* END */ diff --git a/src/base/ftgasp.c b/src/base/ftgasp.c deleted file mode 100644 index 8485d29..0000000 --- a/src/base/ftgasp.c +++ /dev/null @@ -1,61 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgasp.c */ -/* */ -/* Access of TrueType's `gasp' table (body). */ -/* */ -/* Copyright 2007 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_GASP_H -#include FT_INTERNAL_TRUETYPE_TYPES_H - - - FT_EXPORT_DEF( FT_Int ) - FT_Get_Gasp( FT_Face face, - FT_UInt ppem ) - { - FT_Int result = FT_GASP_NO_TABLE; - - - if ( face && FT_IS_SFNT( face ) ) - { - TT_Face ttface = (TT_Face)face; - - - if ( ttface->gasp.numRanges > 0 ) - { - TT_GaspRange range = ttface->gasp.gaspRanges; - TT_GaspRange range_end = range + ttface->gasp.numRanges; - - - while ( ppem > range->maxPPEM ) - { - range++; - if ( range >= range_end ) - goto Exit; - } - - result = range->gaspFlag; - - /* ensure that we don't have spurious bits */ - if ( ttface->gasp.version == 0 ) - result &= 3; - } - } - Exit: - return result; - } - - -/* END */ diff --git a/src/base/ftgloadr.c b/src/base/ftgloadr.c deleted file mode 100644 index ab52621..0000000 --- a/src/base/ftgloadr.c +++ /dev/null @@ -1,394 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftgloadr.c */ -/* */ -/* The FreeType glyph loader (body). */ -/* */ -/* Copyright 2002, 2003, 2004, 2005, 2006 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_GLYPH_LOADER_H -#include FT_INTERNAL_MEMORY_H -#include FT_INTERNAL_OBJECTS_H - -#undef FT_COMPONENT -#define FT_COMPONENT trace_gloader - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** *****/ - /***** G L Y P H L O A D E R *****/ - /***** *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* The glyph loader is a simple object which is used to load a set of */ - /* glyphs easily. It is critical for the correct loading of composites. */ - /* */ - /* Ideally, one can see it as a stack of abstract `glyph' objects. */ - /* */ - /* loader.base Is really the bottom of the stack. It describes a */ - /* single glyph image made of the juxtaposition of */ - /* several glyphs (those `in the stack'). */ - /* */ - /* loader.current Describes the top of the stack, on which a new */ - /* glyph can be loaded. */ - /* */ - /* Rewind Clears the stack. */ - /* Prepare Set up `loader.current' for addition of a new glyph */ - /* image. */ - /* Add Add the `current' glyph image to the `base' one, */ - /* and prepare for another one. */ - /* */ - /* The glyph loader is now a base object. Each driver used to */ - /* re-implement it in one way or the other, which wasted code and */ - /* energy. */ - /* */ - /*************************************************************************/ - - - /* create a new glyph loader */ - FT_BASE_DEF( FT_Error ) - FT_GlyphLoader_New( FT_Memory memory, - FT_GlyphLoader *aloader ) - { - FT_GlyphLoader loader; - FT_Error error; - - - if ( !FT_NEW( loader ) ) - { - loader->memory = memory; - *aloader = loader; - } - return error; - } - - - /* rewind the glyph loader - reset counters to 0 */ - FT_BASE_DEF( void ) - FT_GlyphLoader_Rewind( FT_GlyphLoader loader ) - { - FT_GlyphLoad base = &loader->base; - FT_GlyphLoad current = &loader->current; - - - base->outline.n_points = 0; - base->outline.n_contours = 0; - base->num_subglyphs = 0; - - *current = *base; - } - - - /* reset the glyph loader, frees all allocated tables */ - /* and starts from zero */ - FT_BASE_DEF( void ) - FT_GlyphLoader_Reset( FT_GlyphLoader loader ) - { - FT_Memory memory = loader->memory; - - - FT_FREE( loader->base.outline.points ); - FT_FREE( loader->base.outline.tags ); - FT_FREE( loader->base.outline.contours ); - FT_FREE( loader->base.extra_points ); - FT_FREE( loader->base.subglyphs ); - - loader->base.extra_points2 = NULL; - - loader->max_points = 0; - loader->max_contours = 0; - loader->max_subglyphs = 0; - - FT_GlyphLoader_Rewind( loader ); - } - - - /* delete a glyph loader */ - FT_BASE_DEF( void ) - FT_GlyphLoader_Done( FT_GlyphLoader loader ) - { - if ( loader ) - { - FT_Memory memory = loader->memory; - - - FT_GlyphLoader_Reset( loader ); - FT_FREE( loader ); - } - } - - - /* re-adjust the `current' outline fields */ - static void - FT_GlyphLoader_Adjust_Points( FT_GlyphLoader loader ) - { - FT_Outline* base = &loader->base.outline; - FT_Outline* current = &loader->current.outline; - - - current->points = base->points + base->n_points; - current->tags = base->tags + base->n_points; - current->contours = base->contours + base->n_contours; - - /* handle extra points table - if any */ - if ( loader->use_extra ) - { - loader->current.extra_points = loader->base.extra_points + - base->n_points; - - loader->current.extra_points2 = loader->base.extra_points2 + - base->n_points; - } - } - - - FT_BASE_DEF( FT_Error ) - FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader ) - { - FT_Error error; - FT_Memory memory = loader->memory; - - - if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) ) - { - loader->use_extra = 1; - loader->base.extra_points2 = loader->base.extra_points + - loader->max_points; - - FT_GlyphLoader_Adjust_Points( loader ); - } - return error; - } - - - /* re-adjust the `current' subglyphs field */ - static void - FT_GlyphLoader_Adjust_Subglyphs( FT_GlyphLoader loader ) - { - FT_GlyphLoad base = &loader->base; - FT_GlyphLoad current = &loader->current; - - - current->subglyphs = base->subglyphs + base->num_subglyphs; - } - - - /* Ensure that we can add `n_points' and `n_contours' to our glyph. */ - /* This function reallocates its outline tables if necessary. Note that */ - /* it DOESN'T change the number of points within the loader! */ - /* */ - FT_BASE_DEF( FT_Error ) - FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, - FT_UInt n_points, - FT_UInt n_contours ) - { - FT_Memory memory = loader->memory; - FT_Error error = FT_Err_Ok; - FT_Outline* base = &loader->base.outline; - FT_Outline* current = &loader->current.outline; - FT_Bool adjust = 0; - - FT_UInt new_max, old_max; - - - /* check points & tags */ - new_max = base->n_points + current->n_points + n_points; - old_max = loader->max_points; - - if ( new_max > old_max ) - { - new_max = FT_PAD_CEIL( new_max, 8 ); - - if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) || - FT_RENEW_ARRAY( base->tags, old_max, new_max ) ) - goto Exit; - - if ( loader->use_extra ) - { - if ( FT_RENEW_ARRAY( loader->base.extra_points, - old_max * 2, new_max * 2 ) ) - goto Exit; - - FT_ARRAY_MOVE( loader->base.extra_points + new_max, - loader->base.extra_points + old_max, - old_max ); - - loader->base.extra_points2 = loader->base.extra_points + new_max; - } - - adjust = 1; - loader->max_points = new_max; - } - - /* check contours */ - old_max = loader->max_contours; - new_max = base->n_contours + current->n_contours + - n_contours; - if ( new_max > old_max ) - { - new_max = FT_PAD_CEIL( new_max, 4 ); - if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) ) - goto Exit; - - adjust = 1; - loader->max_contours = new_max; - } - - if ( adjust ) - FT_GlyphLoader_Adjust_Points( loader ); - - Exit: - return error; - } - - - /* Ensure that we can add `n_subglyphs' to our glyph. this function */ - /* reallocates its subglyphs table if necessary. Note that it DOES */ - /* NOT change the number of subglyphs within the loader! */ - /* */ - FT_BASE_DEF( FT_Error ) - FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, - FT_UInt n_subs ) - { - FT_Memory memory = loader->memory; - FT_Error error = FT_Err_Ok; - FT_UInt new_max, old_max; - - FT_GlyphLoad base = &loader->base; - FT_GlyphLoad current = &loader->current; - - - new_max = base->num_subglyphs + current->num_subglyphs + n_subs; - old_max = loader->max_subglyphs; - if ( new_max > old_max ) - { - new_max = FT_PAD_CEIL( new_max, 2 ); - if ( FT_RENEW_ARRAY( base->subglyphs, old_max, new_max ) ) - goto Exit; - - loader->max_subglyphs = new_max; - - FT_GlyphLoader_Adjust_Subglyphs( loader ); - } - - Exit: - return error; - } - - - /* prepare loader for the addition of a new glyph on top of the base one */ - FT_BASE_DEF( void ) - FT_GlyphLoader_Prepare( FT_GlyphLoader loader ) - { - FT_GlyphLoad current = &loader->current; - - - current->outline.n_points = 0; - current->outline.n_contours = 0; - current->num_subglyphs = 0; - - FT_GlyphLoader_Adjust_Points ( loader ); - FT_GlyphLoader_Adjust_Subglyphs( loader ); - } - - - /* add current glyph to the base image - and prepare for another */ - FT_BASE_DEF( void ) - FT_GlyphLoader_Add( FT_GlyphLoader loader ) - { - FT_GlyphLoad base; - FT_GlyphLoad current; - - FT_UInt n_curr_contours; - FT_UInt n_base_points; - FT_UInt n; - - - if ( !loader ) - return; - - base = &loader->base; - current = &loader->current; - - n_curr_contours = current->outline.n_contours; - n_base_points = base->outline.n_points; - - base->outline.n_points = - (short)( base->outline.n_points + current->outline.n_points ); - base->outline.n_contours = - (short)( base->outline.n_contours + current->outline.n_contours ); - - base->num_subglyphs += current->num_subglyphs; - - /* adjust contours count in newest outline */ - for ( n = 0; n < n_curr_contours; n++ ) - current->outline.contours[n] = - (short)( current->outline.contours[n] + n_base_points ); - - /* prepare for another new glyph image */ - FT_GlyphLoader_Prepare( loader ); - } - - - FT_BASE_DEF( FT_Error ) - FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, - FT_GlyphLoader source ) - { - FT_Error error; - FT_UInt num_points = source->base.outline.n_points; - FT_UInt num_contours = source->base.outline.n_contours; - - - error = FT_GlyphLoader_CheckPoints( target, num_points, num_contours ); - if ( !error ) - { - FT_Outline* out = &target->base.outline; - FT_Outline* in = &source->base.outline; - - - FT_ARRAY_COPY( out->points, in->points, - num_points ); - FT_ARRAY_COPY( out->tags, in->tags, - num_points ); - FT_ARRAY_COPY( out->contours, in->contours, - num_contours ); - - /* do we need to copy the extra points? */ - if ( target->use_extra && source->use_extra ) - { - FT_ARRAY_COPY( target->base.extra_points, source->base.extra_points, - num_points ); - FT_ARRAY_COPY( target->base.extra_points2, source->base.extra_points2, - num_points ); - } - - out->n_points = (short)num_points; - out->n_contours = (short)num_contours; - - FT_GlyphLoader_Adjust_Points( target ); - } - - return error; - } - - -/* END */ diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c deleted file mode 100644 index db0e79f..0000000 --- a/src/base/ftglyph.c +++ /dev/null @@ -1,688 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftglyph.c */ -/* */ -/* FreeType convenience functions to handle glyphs (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2007 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This file contains the definition of several convenience functions */ - /* that can be used by client applications to easily retrieve glyph */ - /* bitmaps and outlines from a given face. */ - /* */ - /* These functions should be optional if you are writing a font server */ - /* or text layout engine on top of FreeType. However, they are pretty */ - /* handy for many other simple uses of the library. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_GLYPH_H -#include FT_OUTLINE_H -#include FT_BITMAP_H -#include FT_INTERNAL_OBJECTS_H - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_glyph - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** Convenience functions ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( void ) - FT_Matrix_Multiply( const FT_Matrix* a, - FT_Matrix *b ) - { - FT_Fixed xx, xy, yx, yy; - - - if ( !a || !b ) - return; - - xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); - xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); - yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); - yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); - - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Matrix_Invert( FT_Matrix* matrix ) - { - FT_Pos delta, xx, yy; - - - if ( !matrix ) - return FT_Err_Invalid_Argument; - - /* compute discriminant */ - delta = FT_MulFix( matrix->xx, matrix->yy ) - - FT_MulFix( matrix->xy, matrix->yx ); - - if ( !delta ) - return FT_Err_Invalid_Argument; /* matrix can't be inverted */ - - matrix->xy = - FT_DivFix( matrix->xy, delta ); - matrix->yx = - FT_DivFix( matrix->yx, delta ); - - xx = matrix->xx; - yy = matrix->yy; - - matrix->xx = FT_DivFix( yy, delta ); - matrix->yy = FT_DivFix( xx, delta ); - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** FT_BitmapGlyph support ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - FT_CALLBACK_DEF( FT_Error ) - ft_bitmap_glyph_init( FT_Glyph bitmap_glyph, - FT_GlyphSlot slot ) - { - FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; - FT_Error error = FT_Err_Ok; - FT_Library library = FT_GLYPH( glyph )->library; - - - if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) - { - error = FT_Err_Invalid_Glyph_Format; - goto Exit; - } - - glyph->left = slot->bitmap_left; - glyph->top = slot->bitmap_top; - - /* do lazy copying whenever possible */ - if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) - { - glyph->bitmap = slot->bitmap; - slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; - } - else - { - FT_Bitmap_New( &glyph->bitmap ); - error = FT_Bitmap_Copy( library, &slot->bitmap, &glyph->bitmap ); - } - - Exit: - return error; - } - - - FT_CALLBACK_DEF( FT_Error ) - ft_bitmap_glyph_copy( FT_Glyph bitmap_source, - FT_Glyph bitmap_target ) - { - FT_Library library = bitmap_source->library; - FT_BitmapGlyph source = (FT_BitmapGlyph)bitmap_source; - FT_BitmapGlyph target = (FT_BitmapGlyph)bitmap_target; - - - target->left = source->left; - target->top = source->top; - - return FT_Bitmap_Copy( library, &source->bitmap, &target->bitmap ); - } - - - FT_CALLBACK_DEF( void ) - ft_bitmap_glyph_done( FT_Glyph bitmap_glyph ) - { - FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; - FT_Library library = FT_GLYPH( glyph )->library; - - - FT_Bitmap_Done( library, &glyph->bitmap ); - } - - - FT_CALLBACK_DEF( void ) - ft_bitmap_glyph_bbox( FT_Glyph bitmap_glyph, - FT_BBox* cbox ) - { - FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; - - - cbox->xMin = glyph->left << 6; - cbox->xMax = cbox->xMin + ( glyph->bitmap.width << 6 ); - cbox->yMax = glyph->top << 6; - cbox->yMin = cbox->yMax - ( glyph->bitmap.rows << 6 ); - } - - - FT_CALLBACK_TABLE_DEF - const FT_Glyph_Class ft_bitmap_glyph_class = - { - sizeof ( FT_BitmapGlyphRec ), - FT_GLYPH_FORMAT_BITMAP, - - ft_bitmap_glyph_init, - ft_bitmap_glyph_done, - ft_bitmap_glyph_copy, - 0, /* FT_Glyph_TransformFunc */ - ft_bitmap_glyph_bbox, - 0 /* FT_Glyph_PrepareFunc */ - }; - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** FT_OutlineGlyph support ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_CALLBACK_DEF( FT_Error ) - ft_outline_glyph_init( FT_Glyph outline_glyph, - FT_GlyphSlot slot ) - { - FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; - FT_Error error = FT_Err_Ok; - FT_Library library = FT_GLYPH( glyph )->library; - FT_Outline* source = &slot->outline; - FT_Outline* target = &glyph->outline; - - - /* check format in glyph slot */ - if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) - { - error = FT_Err_Invalid_Glyph_Format; - goto Exit; - } - - /* allocate new outline */ - error = FT_Outline_New( library, source->n_points, source->n_contours, - &glyph->outline ); - if ( error ) - goto Exit; - - FT_Outline_Copy( source, target ); - - Exit: - return error; - } - - - FT_CALLBACK_DEF( void ) - ft_outline_glyph_done( FT_Glyph outline_glyph ) - { - FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; - - - FT_Outline_Done( FT_GLYPH( glyph )->library, &glyph->outline ); - } - - - FT_CALLBACK_DEF( FT_Error ) - ft_outline_glyph_copy( FT_Glyph outline_source, - FT_Glyph outline_target ) - { - FT_OutlineGlyph source = (FT_OutlineGlyph)outline_source; - FT_OutlineGlyph target = (FT_OutlineGlyph)outline_target; - FT_Error error; - FT_Library library = FT_GLYPH( source )->library; - - - error = FT_Outline_New( library, source->outline.n_points, - source->outline.n_contours, &target->outline ); - if ( !error ) - FT_Outline_Copy( &source->outline, &target->outline ); - - return error; - } - - - FT_CALLBACK_DEF( void ) - ft_outline_glyph_transform( FT_Glyph outline_glyph, - const FT_Matrix* matrix, - const FT_Vector* delta ) - { - FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; - - - if ( matrix ) - FT_Outline_Transform( &glyph->outline, matrix ); - - if ( delta ) - FT_Outline_Translate( &glyph->outline, delta->x, delta->y ); - } - - - FT_CALLBACK_DEF( void ) - ft_outline_glyph_bbox( FT_Glyph outline_glyph, - FT_BBox* bbox ) - { - FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; - - - FT_Outline_Get_CBox( &glyph->outline, bbox ); - } - - - FT_CALLBACK_DEF( FT_Error ) - ft_outline_glyph_prepare( FT_Glyph outline_glyph, - FT_GlyphSlot slot ) - { - FT_OutlineGlyph glyph = (FT_OutlineGlyph)outline_glyph; - - - slot->format = FT_GLYPH_FORMAT_OUTLINE; - slot->outline = glyph->outline; - slot->outline.flags &= ~FT_OUTLINE_OWNER; - - return FT_Err_Ok; - } - - - FT_CALLBACK_TABLE_DEF - const FT_Glyph_Class ft_outline_glyph_class = - { - sizeof ( FT_OutlineGlyphRec ), - FT_GLYPH_FORMAT_OUTLINE, - - ft_outline_glyph_init, - ft_outline_glyph_done, - ft_outline_glyph_copy, - ft_outline_glyph_transform, - ft_outline_glyph_bbox, - ft_outline_glyph_prepare - }; - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** FT_Glyph class and API ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - static FT_Error - ft_new_glyph( FT_Library library, - const FT_Glyph_Class* clazz, - FT_Glyph* aglyph ) - { - FT_Memory memory = library->memory; - FT_Error error; - FT_Glyph glyph; - - - *aglyph = 0; - - if ( !FT_ALLOC( glyph, clazz->glyph_size ) ) - { - glyph->library = library; - glyph->clazz = clazz; - glyph->format = clazz->glyph_format; - - *aglyph = glyph; - } - - return error; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Glyph_Copy( FT_Glyph source, - FT_Glyph *target ) - { - FT_Glyph copy; - FT_Error error; - const FT_Glyph_Class* clazz; - - - /* check arguments */ - if ( !target ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - *target = 0; - - if ( !source || !source->clazz ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - clazz = source->clazz; - error = ft_new_glyph( source->library, clazz, © ); - if ( error ) - goto Exit; - - copy->advance = source->advance; - copy->format = source->format; - - if ( clazz->glyph_copy ) - error = clazz->glyph_copy( source, copy ); - - if ( error ) - FT_Done_Glyph( copy ); - else - *target = copy; - - Exit: - return error; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Glyph( FT_GlyphSlot slot, - FT_Glyph *aglyph ) - { - FT_Library library; - FT_Error error; - FT_Glyph glyph; - - const FT_Glyph_Class* clazz = 0; - - - if ( !slot ) - return FT_Err_Invalid_Slot_Handle; - - library = slot->library; - - if ( !aglyph ) - return FT_Err_Invalid_Argument; - - /* if it is a bitmap, that's easy :-) */ - if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) - clazz = &ft_bitmap_glyph_class; - - /* it it is an outline too */ - else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - clazz = &ft_outline_glyph_class; - - else - { - /* try to find a renderer that supports the glyph image format */ - FT_Renderer render = FT_Lookup_Renderer( library, slot->format, 0 ); - - - if ( render ) - clazz = &render->glyph_class; - } - - if ( !clazz ) - { - error = FT_Err_Invalid_Glyph_Format; - goto Exit; - } - - /* create FT_Glyph object */ - error = ft_new_glyph( library, clazz, &glyph ); - if ( error ) - goto Exit; - - /* copy advance while converting it to 16.16 format */ - glyph->advance.x = slot->advance.x << 10; - glyph->advance.y = slot->advance.y << 10; - - /* now import the image from the glyph slot */ - error = clazz->glyph_init( glyph, slot ); - - /* if an error occurred, destroy the glyph */ - if ( error ) - FT_Done_Glyph( glyph ); - else - *aglyph = glyph; - - Exit: - return error; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Glyph_Transform( FT_Glyph glyph, - FT_Matrix* matrix, - FT_Vector* delta ) - { - const FT_Glyph_Class* clazz; - FT_Error error = FT_Err_Ok; - - - if ( !glyph || !glyph->clazz ) - error = FT_Err_Invalid_Argument; - else - { - clazz = glyph->clazz; - if ( clazz->glyph_transform ) - { - /* transform glyph image */ - clazz->glyph_transform( glyph, matrix, delta ); - - /* transform advance vector */ - if ( matrix ) - FT_Vector_Transform( &glyph->advance, matrix ); - } - else - error = FT_Err_Invalid_Glyph_Format; - } - return error; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( void ) - FT_Glyph_Get_CBox( FT_Glyph glyph, - FT_UInt bbox_mode, - FT_BBox *acbox ) - { - const FT_Glyph_Class* clazz; - - - if ( !acbox ) - return; - - acbox->xMin = acbox->yMin = acbox->xMax = acbox->yMax = 0; - - if ( !glyph || !glyph->clazz ) - return; - else - { - clazz = glyph->clazz; - if ( !clazz->glyph_bbox ) - return; - else - { - /* retrieve bbox in 26.6 coordinates */ - clazz->glyph_bbox( glyph, acbox ); - - /* perform grid fitting if needed */ - if ( bbox_mode == FT_GLYPH_BBOX_GRIDFIT || - bbox_mode == FT_GLYPH_BBOX_PIXELS ) - { - acbox->xMin = FT_PIX_FLOOR( acbox->xMin ); - acbox->yMin = FT_PIX_FLOOR( acbox->yMin ); - acbox->xMax = FT_PIX_CEIL( acbox->xMax ); - acbox->yMax = FT_PIX_CEIL( acbox->yMax ); - } - - /* convert to integer pixels if needed */ - if ( bbox_mode == FT_GLYPH_BBOX_TRUNCATE || - bbox_mode == FT_GLYPH_BBOX_PIXELS ) - { - acbox->xMin >>= 6; - acbox->yMin >>= 6; - acbox->xMax >>= 6; - acbox->yMax >>= 6; - } - } - } - return; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, - FT_Render_Mode render_mode, - FT_Vector* origin, - FT_Bool destroy ) - { - FT_GlyphSlotRec dummy; - FT_GlyphSlot_InternalRec dummy_internal; - FT_Error error = FT_Err_Ok; - FT_Glyph glyph; - FT_BitmapGlyph bitmap = NULL; - - const FT_Glyph_Class* clazz; - - - /* check argument */ - if ( !the_glyph ) - goto Bad; - - /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ - /* then calling FT_Render_Glyph_Internal() */ - - glyph = *the_glyph; - if ( !glyph ) - goto Bad; - - clazz = glyph->clazz; - - /* when called with a bitmap glyph, do nothing and return successfully */ - if ( clazz == &ft_bitmap_glyph_class ) - goto Exit; - - if ( !clazz || !clazz->glyph_prepare ) - goto Bad; - - FT_MEM_ZERO( &dummy, sizeof ( dummy ) ); - FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) ); - dummy.internal = &dummy_internal; - dummy.library = glyph->library; - dummy.format = clazz->glyph_format; - - /* create result bitmap glyph */ - error = ft_new_glyph( glyph->library, &ft_bitmap_glyph_class, - (FT_Glyph*)(void*)&bitmap ); - if ( error ) - goto Exit; - -#if 1 - /* if `origin' is set, translate the glyph image */ - if ( origin ) - FT_Glyph_Transform( glyph, 0, origin ); -#else - FT_UNUSED( origin ); -#endif - - /* prepare dummy slot for rendering */ - error = clazz->glyph_prepare( glyph, &dummy ); - if ( !error ) - error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode ); - -#if 1 - if ( !destroy && origin ) - { - FT_Vector v; - - - v.x = -origin->x; - v.y = -origin->y; - FT_Glyph_Transform( glyph, 0, &v ); - } -#endif - - if ( error ) - goto Exit; - - /* in case of success, copy the bitmap to the glyph bitmap */ - error = ft_bitmap_glyph_init( (FT_Glyph)bitmap, &dummy ); - if ( error ) - goto Exit; - - /* copy advance */ - bitmap->root.advance = glyph->advance; - - if ( destroy ) - FT_Done_Glyph( glyph ); - - *the_glyph = FT_GLYPH( bitmap ); - - Exit: - if ( error && bitmap ) - FT_Done_Glyph( FT_GLYPH( bitmap ) ); - - return error; - - Bad: - error = FT_Err_Invalid_Argument; - goto Exit; - } - - - /* documentation is in ftglyph.h */ - - FT_EXPORT_DEF( void ) - FT_Done_Glyph( FT_Glyph glyph ) - { - if ( glyph ) - { - FT_Memory memory = glyph->library->memory; - const FT_Glyph_Class* clazz = glyph->clazz; - - - if ( clazz->glyph_done ) - clazz->glyph_done( glyph ); - - FT_FREE( glyph ); - } - } - - -/* END */ diff --git a/src/base/ftinit.c b/src/base/ftinit.c deleted file mode 100644 index 7af19c3..0000000 --- a/src/base/ftinit.c +++ /dev/null @@ -1,163 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftinit.c */ -/* */ -/* FreeType initialization layer (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2005, 2007 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* The purpose of this file is to implement the following two */ - /* functions: */ - /* */ - /* FT_Add_Default_Modules(): */ - /* This function is used to add the set of default modules to a */ - /* fresh new library object. The set is taken from the header file */ - /* `freetype/config/ftmodule.h'. See the document `FreeType 2.0 */ - /* Build System' for more information. */ - /* */ - /* FT_Init_FreeType(): */ - /* This function creates a system object for the current platform, */ - /* builds a library out of it, then calls FT_Default_Drivers(). */ - /* */ - /* Note that even if FT_Init_FreeType() uses the implementation of the */ - /* system object defined at build time, client applications are still */ - /* able to provide their own `ftsystem.c'. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_MODULE_H - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_init - -#undef FT_USE_MODULE -#ifdef __cplusplus -#define FT_USE_MODULE( x ) extern "C" const FT_Module_Class x; -#else -#define FT_USE_MODULE( x ) extern const FT_Module_Class x; -#endif - - -#include FT_CONFIG_MODULES_H - - -#undef FT_USE_MODULE -#define FT_USE_MODULE( x ) (const FT_Module_Class*)&(x), - - static - const FT_Module_Class* const ft_default_modules[] = - { -#include FT_CONFIG_MODULES_H - 0 - }; - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( void ) - FT_Add_Default_Modules( FT_Library library ) - { - FT_Error error; - const FT_Module_Class* const* cur; - - - /* test for valid `library' delayed to FT_Add_Module() */ - - cur = ft_default_modules; - while ( *cur ) - { - error = FT_Add_Module( library, *cur ); - /* notify errors, but don't stop */ - if ( error ) - { - FT_ERROR(( "FT_Add_Default_Module: Cannot install `%s', error = 0x%x\n", - (*cur)->module_name, error )); - } - cur++; - } - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Init_FreeType( FT_Library *alibrary ) - { - FT_Error error; - FT_Memory memory; - - - /* First of all, allocate a new system object -- this function is part */ - /* of the system-specific component, i.e. `ftsystem.c'. */ - - memory = FT_New_Memory(); - if ( !memory ) - { - FT_ERROR(( "FT_Init_FreeType: cannot find memory manager\n" )); - return FT_Err_Unimplemented_Feature; - } - - /* build a library out of it, then fill it with the set of */ - /* default drivers. */ - - error = FT_New_Library( memory, alibrary ); - if ( error ) - FT_Done_Memory( memory ); - else - { - (*alibrary)->version_major = FREETYPE_MAJOR; - (*alibrary)->version_minor = FREETYPE_MINOR; - (*alibrary)->version_patch = FREETYPE_PATCH; - - FT_Add_Default_Modules( *alibrary ); - } - - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Done_FreeType( FT_Library library ) - { - if ( library ) - { - FT_Memory memory = library->memory; - - - /* Discard the library object */ - FT_Done_Library( library ); - - /* discard memory manager */ - FT_Done_Memory( memory ); - } - - return FT_Err_Ok; - } - - -/* END */ diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c deleted file mode 100644 index 5f1fa0b..0000000 --- a/src/base/ftlcdfil.c +++ /dev/null @@ -1,351 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftlcdfil.c */ -/* */ -/* FreeType API for color filtering of subpixel bitmap glyphs (body). */ -/* */ -/* Copyright 2006, 2008 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_LCD_FILTER_H -#include FT_IMAGE_H -#include FT_INTERNAL_OBJECTS_H - - -#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - -/* define USE_LEGACY to implement the legacy filter */ -#define USE_LEGACY - - /* FIR filter used by the default and light filters */ - static void - _ft_lcd_filter_fir( FT_Bitmap* bitmap, - FT_Render_Mode mode, - FT_Library library ) - { - FT_Byte* weights = library->lcd_weights; - FT_UInt width = (FT_UInt)bitmap->width; - FT_UInt height = (FT_UInt)bitmap->rows; - - - /* horizontal in-place FIR filter */ - if ( mode == FT_RENDER_MODE_LCD && width >= 4 ) - { - FT_Byte* line = bitmap->buffer; - - - for ( ; height > 0; height--, line += bitmap->pitch ) - { - FT_UInt fir[5]; - FT_UInt val1, xx; - - - val1 = line[0]; - fir[0] = weights[2] * val1; - fir[1] = weights[3] * val1; - fir[2] = weights[4] * val1; - fir[3] = 0; - fir[4] = 0; - - val1 = line[1]; - fir[0] += weights[1] * val1; - fir[1] += weights[2] * val1; - fir[2] += weights[3] * val1; - fir[3] += weights[4] * val1; - - for ( xx = 2; xx < width; xx++ ) - { - FT_UInt val, pix; - - - val = line[xx]; - pix = fir[0] + weights[0] * val; - fir[0] = fir[1] + weights[1] * val; - fir[1] = fir[2] + weights[2] * val; - fir[2] = fir[3] + weights[3] * val; - fir[3] = weights[4] * val; - - pix >>= 8; - pix |= -( pix >> 8 ); - line[xx - 2] = (FT_Byte)pix; - } - - { - FT_UInt pix; - - - pix = fir[0] >> 8; - pix |= -( pix >> 8 ); - line[xx - 2] = (FT_Byte)pix; - - pix = fir[1] >> 8; - pix |= -( pix >> 8 ); - line[xx - 1] = (FT_Byte)pix; - } - } - } - - /* vertical in-place FIR filter */ - else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 ) - { - FT_Byte* column = bitmap->buffer; - FT_Int pitch = bitmap->pitch; - - - for ( ; width > 0; width--, column++ ) - { - FT_Byte* col = column; - FT_UInt fir[5]; - FT_UInt val1, yy; - - - val1 = col[0]; - fir[0] = weights[2] * val1; - fir[1] = weights[3] * val1; - fir[2] = weights[4] * val1; - fir[3] = 0; - fir[4] = 0; - col += pitch; - - val1 = col[0]; - fir[0] += weights[1] * val1; - fir[1] += weights[2] * val1; - fir[2] += weights[3] * val1; - fir[3] += weights[4] * val1; - col += pitch; - - for ( yy = 2; yy < height; yy++ ) - { - FT_UInt val, pix; - - - val = col[0]; - pix = fir[0] + weights[0] * val; - fir[0] = fir[1] + weights[1] * val; - fir[1] = fir[2] + weights[2] * val; - fir[2] = fir[3] + weights[3] * val; - fir[3] = weights[4] * val; - - pix >>= 8; - pix |= -( pix >> 8 ); - col[-2 * pitch] = (FT_Byte)pix; - col += pitch; - } - - { - FT_UInt pix; - - - pix = fir[0] >> 8; - pix |= -( pix >> 8 ); - col[-2 * pitch] = (FT_Byte)pix; - - pix = fir[1] >> 8; - pix |= -( pix >> 8 ); - col[-pitch] = (FT_Byte)pix; - } - } - } - } - - -#ifdef USE_LEGACY - - /* intra-pixel filter used by the legacy filter */ - static void - _ft_lcd_filter_legacy( FT_Bitmap* bitmap, - FT_Render_Mode mode, - FT_Library library ) - { - FT_UInt width = (FT_UInt)bitmap->width; - FT_UInt height = (FT_UInt)bitmap->rows; - FT_Int pitch = bitmap->pitch; - - static const int filters[3][3] = - { - { 65538 * 9/13, 65538 * 1/6, 65538 * 1/13 }, - { 65538 * 3/13, 65538 * 4/6, 65538 * 3/13 }, - { 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 } - }; - - FT_UNUSED( library ); - - - /* horizontal in-place intra-pixel filter */ - if ( mode == FT_RENDER_MODE_LCD && width >= 3 ) - { - FT_Byte* line = bitmap->buffer; - - - for ( ; height > 0; height--, line += pitch ) - { - FT_UInt xx; - - - for ( xx = 0; xx < width; xx += 3 ) - { - FT_UInt r = 0; - FT_UInt g = 0; - FT_UInt b = 0; - FT_UInt p; - - - p = line[xx]; - r += filters[0][0] * p; - g += filters[0][1] * p; - b += filters[0][2] * p; - - p = line[xx + 1]; - r += filters[1][0] * p; - g += filters[1][1] * p; - b += filters[1][2] * p; - - p = line[xx + 2]; - r += filters[2][0] * p; - g += filters[2][1] * p; - b += filters[2][2] * p; - - line[xx] = (FT_Byte)( r / 65536 ); - line[xx + 1] = (FT_Byte)( g / 65536 ); - line[xx + 2] = (FT_Byte)( b / 65536 ); - } - } - } - else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 ) - { - FT_Byte* column = bitmap->buffer; - - - for ( ; width > 0; width--, column++ ) - { - FT_Byte* col = column; - FT_Byte* col_end = col + height * pitch; - - - for ( ; col < col_end; col += 3 * pitch ) - { - FT_UInt r = 0; - FT_UInt g = 0; - FT_UInt b = 0; - FT_UInt p; - - - p = col[0]; - r += filters[0][0] * p; - g += filters[0][1] * p; - b += filters[0][2] * p; - - p = col[pitch]; - r += filters[1][0] * p; - g += filters[1][1] * p; - b += filters[1][2] * p; - - p = col[pitch * 2]; - r += filters[2][0] * p; - g += filters[2][1] * p; - b += filters[2][2] * p; - - col[0] = (FT_Byte)( r / 65536 ); - col[pitch] = (FT_Byte)( g / 65536 ); - col[2 * pitch] = (FT_Byte)( b / 65536 ); - } - } - } - } - -#endif /* USE_LEGACY */ - - - FT_EXPORT( FT_Error ) - FT_Library_SetLcdFilter( FT_Library library, - FT_LcdFilter filter ) - { - static const FT_Byte light_filter[5] = - { 0, 85, 86, 85, 0 }; - /* the values here sum up to a value larger than 256, */ - /* providing a cheap gamma correction */ - static const FT_Byte default_filter[5] = - { 0x10, 0x40, 0x70, 0x40, 0x10 }; - - - if ( library == NULL ) - return FT_Err_Invalid_Argument; - - switch ( filter ) - { - case FT_LCD_FILTER_NONE: - library->lcd_filter_func = NULL; - library->lcd_extra = 0; - break; - - case FT_LCD_FILTER_DEFAULT: -#if defined( FT_FORCE_LEGACY_LCD_FILTER ) - - library->lcd_filter_func = _ft_lcd_filter_legacy; - library->lcd_extra = 0; - -#elif defined( FT_FORCE_LIGHT_LCD_FILTER ) - - memcpy( library->lcd_weights, light_filter, 5 ); - library->lcd_filter_func = _ft_lcd_filter_fir; - library->lcd_extra = 2; - -#else - - memcpy( library->lcd_weights, default_filter, 5 ); - library->lcd_filter_func = _ft_lcd_filter_fir; - library->lcd_extra = 2; - -#endif - - break; - - case FT_LCD_FILTER_LIGHT: - memcpy( library->lcd_weights, light_filter, 5 ); - library->lcd_filter_func = _ft_lcd_filter_fir; - library->lcd_extra = 2; - break; - -#ifdef USE_LEGACY - - case FT_LCD_FILTER_LEGACY: - library->lcd_filter_func = _ft_lcd_filter_legacy; - library->lcd_extra = 0; - break; - -#endif - - default: - return FT_Err_Invalid_Argument; - } - - library->lcd_filter = filter; - return 0; - } - -#else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - - FT_EXPORT( FT_Error ) - FT_Library_SetLcdFilter( FT_Library library, - FT_LcdFilter filter ) - { - FT_UNUSED( library ); - FT_UNUSED( filter ); - - return FT_Err_Unimplemented_Feature; - } - -#endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - - -/* END */ diff --git a/src/base/ftmm.c b/src/base/ftmm.c deleted file mode 100644 index 586d5e8..0000000 --- a/src/base/ftmm.c +++ /dev/null @@ -1,202 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftmm.c */ -/* */ -/* Multiple Master font support (body). */ -/* */ -/* Copyright 1996-2001, 2003, 2004 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_MULTIPLE_MASTERS_H -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_MULTIPLE_MASTERS_H - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_mm - - - static FT_Error - ft_face_get_mm_service( FT_Face face, - FT_Service_MultiMasters *aservice ) - { - FT_Error error; - - - *aservice = NULL; - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - error = FT_Err_Invalid_Argument; - - if ( FT_HAS_MULTIPLE_MASTERS( face ) ) - { - FT_FACE_LOOKUP_SERVICE( face, - *aservice, - MULTI_MASTERS ); - - if ( aservice ) - error = FT_Err_Ok; - } - - return error; - } - - - /* documentation is in ftmm.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Multi_Master( FT_Face face, - FT_Multi_Master *amaster ) - { - FT_Error error; - FT_Service_MultiMasters service; - - - error = ft_face_get_mm_service( face, &service ); - if ( !error ) - { - error = FT_Err_Invalid_Argument; - if ( service->get_mm ) - error = service->get_mm( face, amaster ); - } - - return error; - } - - - /* documentation is in ftmm.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_MM_Var( FT_Face face, - FT_MM_Var* *amaster ) - { - FT_Error error; - FT_Service_MultiMasters service; - - - error = ft_face_get_mm_service( face, &service ); - if ( !error ) - { - error = FT_Err_Invalid_Argument; - if ( service->get_mm_var ) - error = service->get_mm_var( face, amaster ); - } - - return error; - } - - - /* documentation is in ftmm.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_MM_Design_Coordinates( FT_Face face, - FT_UInt num_coords, - FT_Long* coords ) - { - FT_Error error; - FT_Service_MultiMasters service; - - - error = ft_face_get_mm_service( face, &service ); - if ( !error ) - { - error = FT_Err_Invalid_Argument; - if ( service->set_mm_design ) - error = service->set_mm_design( face, num_coords, coords ); - } - - return error; - } - - - /* documentation is in ftmm.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_Var_Design_Coordinates( FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - FT_Error error; - FT_Service_MultiMasters service; - - - error = ft_face_get_mm_service( face, &service ); - if ( !error ) - { - error = FT_Err_Invalid_Argument; - if ( service->set_var_design ) - error = service->set_var_design( face, num_coords, coords ); - } - - return error; - } - - - /* documentation is in ftmm.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_MM_Blend_Coordinates( FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - FT_Error error; - FT_Service_MultiMasters service; - - - error = ft_face_get_mm_service( face, &service ); - if ( !error ) - { - error = FT_Err_Invalid_Argument; - if ( service->set_mm_blend ) - error = service->set_mm_blend( face, num_coords, coords ); - } - - return error; - } - - - /* documentation is in ftmm.h */ - - /* This is exactly the same as the previous function. It exists for */ - /* orthogonality. */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_Var_Blend_Coordinates( FT_Face face, - FT_UInt num_coords, - FT_Fixed* coords ) - { - FT_Error error; - FT_Service_MultiMasters service; - - - error = ft_face_get_mm_service( face, &service ); - if ( !error ) - { - error = FT_Err_Invalid_Argument; - if ( service->set_mm_blend ) - error = service->set_mm_blend( face, num_coords, coords ); - } - - return error; - } - - -/* END */ diff --git a/src/base/ftnames.c b/src/base/ftnames.c deleted file mode 100644 index 7fde5c4..0000000 --- a/src/base/ftnames.c +++ /dev/null @@ -1,94 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftnames.c */ -/* */ -/* Simple interface to access SFNT name tables (which are used */ -/* to hold font names, copyright info, notices, etc.) (body). */ -/* */ -/* This is _not_ used to retrieve glyph names! */ -/* */ -/* Copyright 1996-2001, 2002 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_SFNT_NAMES_H -#include FT_INTERNAL_TRUETYPE_TYPES_H -#include FT_INTERNAL_STREAM_H - - -#ifdef TT_CONFIG_OPTION_SFNT_NAMES - - - /* documentation is in ftnames.h */ - - FT_EXPORT_DEF( FT_UInt ) - FT_Get_Sfnt_Name_Count( FT_Face face ) - { - return (face && FT_IS_SFNT( face )) ? ((TT_Face)face)->num_names : 0; - } - - - /* documentation is in ftnames.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Sfnt_Name( FT_Face face, - FT_UInt idx, - FT_SfntName *aname ) - { - FT_Error error = FT_Err_Invalid_Argument; - - - if ( aname && face && FT_IS_SFNT( face ) ) - { - TT_Face ttface = (TT_Face)face; - - - if ( idx < (FT_UInt)ttface->num_names ) - { - TT_NameEntryRec* entry = ttface->name_table.names + idx; - - - /* load name on demand */ - if ( entry->stringLength > 0 && entry->string == NULL ) - { - FT_Memory memory = face->memory; - FT_Stream stream = face->stream; - - - if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || - FT_STREAM_SEEK( entry->stringOffset ) || - FT_STREAM_READ( entry->string, entry->stringLength ) ) - { - FT_FREE( entry->string ); - entry->stringLength = 0; - } - } - - aname->platform_id = entry->platformID; - aname->encoding_id = entry->encodingID; - aname->language_id = entry->languageID; - aname->name_id = entry->nameID; - aname->string = (FT_Byte*)entry->string; - aname->string_len = entry->stringLength; - - error = FT_Err_Ok; - } - } - - return error; - } - - -#endif /* TT_CONFIG_OPTION_SFNT_NAMES */ - - -/* END */ diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c deleted file mode 100644 index f167b2f..0000000 --- a/src/base/ftobjs.c +++ /dev/null @@ -1,4235 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftobjs.c */ -/* */ -/* The FreeType private base classes (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_LIST_H -#include FT_OUTLINE_H -#include FT_INTERNAL_VALIDATE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_RFORK_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ -#include FT_TRUETYPE_TABLES_H -#include FT_TRUETYPE_IDS_H -#include FT_OUTLINE_H - -#include FT_SERVICE_SFNT_H -#include FT_SERVICE_POSTSCRIPT_NAME_H -#include FT_SERVICE_GLYPH_DICT_H -#include FT_SERVICE_TT_CMAP_H -#include FT_SERVICE_KERNING_H -#include FT_SERVICE_TRUETYPE_ENGINE_H - -#ifdef ANDROID_FONT_HACK -#include <unistd.h> -#include <fcntl.h> -#endif - -#define GRID_FIT_METRICS - - FT_BASE_DEF( FT_Pointer ) - ft_service_list_lookup( FT_ServiceDesc service_descriptors, - const char* service_id ) - { - FT_Pointer result = NULL; - FT_ServiceDesc desc = service_descriptors; - - - if ( desc && service_id ) - { - for ( ; desc->serv_id != NULL; desc++ ) - { - if ( ft_strcmp( desc->serv_id, service_id ) == 0 ) - { - result = (FT_Pointer)desc->serv_data; - break; - } - } - } - - return result; - } - - - FT_BASE_DEF( void ) - ft_validator_init( FT_Validator valid, - const FT_Byte* base, - const FT_Byte* limit, - FT_ValidationLevel level ) - { - valid->base = base; - valid->limit = limit; - valid->level = level; - valid->error = FT_Err_Ok; - } - - - FT_BASE_DEF( FT_Int ) - ft_validator_run( FT_Validator valid ) - { - /* This function doesn't work! None should call it. */ - FT_UNUSED( valid ); - - return -1; - } - - - FT_BASE_DEF( void ) - ft_validator_error( FT_Validator valid, - FT_Error error ) - { - /* since the cast below also disables the compiler's */ - /* type check, we introduce a dummy variable, which */ - /* will be optimized away */ - volatile ft_jmp_buf* jump_buffer = &valid->jump_buffer; - - - valid->error = error; - - /* throw away volatileness; use `jump_buffer' or the */ - /* compiler may warn about an unused local variable */ - ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** S T R E A M ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* create a new input stream from an FT_Open_Args structure */ - /* */ - FT_BASE_DEF( FT_Error ) - FT_Stream_New( FT_Library library, - const FT_Open_Args* args, - FT_Stream *astream ) - { - FT_Error error; - FT_Memory memory; - FT_Stream stream; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !args ) - return FT_Err_Invalid_Argument; - - *astream = 0; - memory = library->memory; - - if ( FT_NEW( stream ) ) - goto Exit; - - stream->memory = memory; - - if ( args->flags & FT_OPEN_MEMORY ) - { - /* create a memory-based stream */ - FT_Stream_OpenMemory( stream, - (const FT_Byte*)args->memory_base, - args->memory_size ); - } - else if ( args->flags & FT_OPEN_PATHNAME ) - { - /* create a normal system stream */ - error = FT_Stream_Open( stream, args->pathname ); - stream->pathname.pointer = args->pathname; - } - else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream ) - { - /* use an existing, user-provided stream */ - - /* in this case, we do not need to allocate a new stream object */ - /* since the caller is responsible for closing it himself */ - FT_FREE( stream ); - stream = args->stream; - } - else - error = FT_Err_Invalid_Argument; - - if ( error ) - FT_FREE( stream ); - else - stream->memory = memory; /* just to be certain */ - - *astream = stream; - - Exit: - return error; - } - - - FT_BASE_DEF( void ) - FT_Stream_Free( FT_Stream stream, - FT_Int external ) - { - if ( stream ) - { - FT_Memory memory = stream->memory; - - - FT_Stream_Close( stream ); - - if ( !external ) - FT_FREE( stream ); - } - } - - -#undef FT_COMPONENT -#define FT_COMPONENT trace_objs - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - static FT_Error - ft_glyphslot_init( FT_GlyphSlot slot ) - { - FT_Driver driver = slot->face->driver; - FT_Driver_Class clazz = driver->clazz; - FT_Memory memory = driver->root.memory; - FT_Error error = FT_Err_Ok; - FT_Slot_Internal internal; - - - slot->library = driver->root.library; - - if ( FT_NEW( internal ) ) - goto Exit; - - slot->internal = internal; - - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - error = FT_GlyphLoader_New( memory, &internal->loader ); - - if ( !error && clazz->init_slot ) - error = clazz->init_slot( slot ); - - Exit: - return error; - } - - - FT_BASE_DEF( void ) - ft_glyphslot_free_bitmap( FT_GlyphSlot slot ) - { - if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) - { - FT_Memory memory = FT_FACE_MEMORY( slot->face ); - - - FT_FREE( slot->bitmap.buffer ); - slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; - } - else - { - /* assume that the bitmap buffer was stolen or not */ - /* allocated from the heap */ - slot->bitmap.buffer = NULL; - } - } - - - FT_BASE_DEF( void ) - ft_glyphslot_set_bitmap( FT_GlyphSlot slot, - FT_Byte* buffer ) - { - ft_glyphslot_free_bitmap( slot ); - - slot->bitmap.buffer = buffer; - - FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 ); - } - - - FT_BASE_DEF( FT_Error ) - ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, - FT_ULong size ) - { - FT_Memory memory = FT_FACE_MEMORY( slot->face ); - FT_Error error; - - - if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) - FT_FREE( slot->bitmap.buffer ); - else - slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - - (void)FT_ALLOC( slot->bitmap.buffer, size ); - return error; - } - - - static void - ft_glyphslot_clear( FT_GlyphSlot slot ) - { - /* free bitmap if needed */ - ft_glyphslot_free_bitmap( slot ); - - /* clear all public fields in the glyph slot */ - FT_ZERO( &slot->metrics ); - FT_ZERO( &slot->outline ); - - slot->bitmap.width = 0; - slot->bitmap.rows = 0; - slot->bitmap.pitch = 0; - slot->bitmap.pixel_mode = 0; - /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */ - - slot->bitmap_left = 0; - slot->bitmap_top = 0; - slot->num_subglyphs = 0; - slot->subglyphs = 0; - slot->control_data = 0; - slot->control_len = 0; - slot->other = 0; - slot->format = FT_GLYPH_FORMAT_NONE; - - slot->linearHoriAdvance = 0; - slot->linearVertAdvance = 0; - slot->lsb_delta = 0; - slot->rsb_delta = 0; - } - - - static void - ft_glyphslot_done( FT_GlyphSlot slot ) - { - FT_Driver driver = slot->face->driver; - FT_Driver_Class clazz = driver->clazz; - FT_Memory memory = driver->root.memory; - - - if ( clazz->done_slot ) - clazz->done_slot( slot ); - - /* free bitmap buffer if needed */ - ft_glyphslot_free_bitmap( slot ); - - /* free glyph loader */ - if ( FT_DRIVER_USES_OUTLINES( driver ) ) - { - FT_GlyphLoader_Done( slot->internal->loader ); - slot->internal->loader = 0; - } - - FT_FREE( slot->internal ); - } - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( FT_Error ) - FT_New_GlyphSlot( FT_Face face, - FT_GlyphSlot *aslot ) - { - FT_Error error; - FT_Driver driver; - FT_Driver_Class clazz; - FT_Memory memory; - FT_GlyphSlot slot; - - - if ( !face || !face->driver ) - return FT_Err_Invalid_Argument; - - driver = face->driver; - clazz = driver->clazz; - memory = driver->root.memory; - - FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" )); - if ( !FT_ALLOC( slot, clazz->slot_object_size ) ) - { - slot->face = face; - - error = ft_glyphslot_init( slot ); - if ( error ) - { - ft_glyphslot_done( slot ); - FT_FREE( slot ); - goto Exit; - } - - slot->next = face->glyph; - face->glyph = slot; - - if ( aslot ) - *aslot = slot; - } - else if ( aslot ) - *aslot = 0; - - - Exit: - FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); - return error; - } - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( void ) - FT_Done_GlyphSlot( FT_GlyphSlot slot ) - { - if ( slot ) - { - FT_Driver driver = slot->face->driver; - FT_Memory memory = driver->root.memory; - FT_GlyphSlot prev; - FT_GlyphSlot cur; - - - /* Remove slot from its parent face's list */ - prev = NULL; - cur = slot->face->glyph; - - while ( cur ) - { - if ( cur == slot ) - { - if ( !prev ) - slot->face->glyph = cur->next; - else - prev->next = cur->next; - - ft_glyphslot_done( slot ); - FT_FREE( slot ); - break; - } - prev = cur; - cur = cur->next; - } - } - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( void ) - FT_Set_Transform( FT_Face face, - FT_Matrix* matrix, - FT_Vector* delta ) - { - FT_Face_Internal internal; - - - if ( !face ) - return; - - internal = face->internal; - - internal->transform_flags = 0; - - if ( !matrix ) - { - internal->transform_matrix.xx = 0x10000L; - internal->transform_matrix.xy = 0; - internal->transform_matrix.yx = 0; - internal->transform_matrix.yy = 0x10000L; - matrix = &internal->transform_matrix; - } - else - internal->transform_matrix = *matrix; - - /* set transform_flags bit flag 0 if `matrix' isn't the identity */ - if ( ( matrix->xy | matrix->yx ) || - matrix->xx != 0x10000L || - matrix->yy != 0x10000L ) - internal->transform_flags |= 1; - - if ( !delta ) - { - internal->transform_delta.x = 0; - internal->transform_delta.y = 0; - delta = &internal->transform_delta; - } - else - internal->transform_delta = *delta; - - /* set transform_flags bit flag 1 if `delta' isn't the null vector */ - if ( delta->x | delta->y ) - internal->transform_flags |= 2; - } - - - static FT_Renderer - ft_lookup_glyph_renderer( FT_GlyphSlot slot ); - - -#ifdef GRID_FIT_METRICS - static void - ft_glyphslot_grid_fit_metrics( FT_GlyphSlot slot, - FT_Bool vertical ) - { - FT_Glyph_Metrics* metrics = &slot->metrics; - FT_Pos right, bottom; - - - if ( vertical ) - { - metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); - metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); - - right = FT_PIX_CEIL( metrics->vertBearingX + metrics->width ); - bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height ); - - metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); - metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); - - metrics->width = right - metrics->vertBearingX; - metrics->height = bottom - metrics->vertBearingY; - } - else - { - metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); - metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); - - right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width ); - bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height ); - - metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); - metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); - - metrics->width = right - metrics->horiBearingX; - metrics->height = metrics->horiBearingY - bottom; - } - - metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); - metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); - } -#endif /* GRID_FIT_METRICS */ - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Load_Glyph( FT_Face face, - FT_UInt glyph_index, - FT_Int32 load_flags ) - { - FT_Error error; - FT_Driver driver; - FT_GlyphSlot slot; - FT_Library library; - FT_Bool autohint = 0; - FT_Module hinter; - - - if ( !face || !face->size || !face->glyph ) - return FT_Err_Invalid_Face_Handle; - - /* The validity test for `glyph_index' is performed by the */ - /* font drivers. */ - - slot = face->glyph; - ft_glyphslot_clear( slot ); - - driver = face->driver; - library = driver->root.library; - hinter = library->auto_hinter; - - /* resolve load flags dependencies */ - - if ( load_flags & FT_LOAD_NO_RECURSE ) - load_flags |= FT_LOAD_NO_SCALE | - FT_LOAD_IGNORE_TRANSFORM; - - if ( load_flags & FT_LOAD_NO_SCALE ) - { - load_flags |= FT_LOAD_NO_HINTING | - FT_LOAD_NO_BITMAP; - - load_flags &= ~FT_LOAD_RENDER; - } -#ifdef ANDROID_FONT_HACK - else - { - static int hack_mode; - - if (hack_mode == 0) { - do { - int fd = open("/data/misc/font-hack", O_RDONLY); - char buff[2]; - int ret; - - hack_mode = 1; /*means light node by default */ - if (fd < 0) - break; - - ret = read(fd, buff, 1); - if (ret == 1) - hack_mode = 1 + (buff[0] - '0'); - - close(fd); - } while (0); - } - - switch (hack_mode) - { - case 1: - load_flags &= 0xfff0ffff; - load_flags |= FT_LOAD_TARGET_LIGHT; - break; - } - } -#endif - - /* - * Determine whether we need to auto-hint or not. - * The general rules are: - * - * - Do only auto-hinting if we have a hinter module, - * a scalable font format dealing with outlines, - * and no transforms except simple slants. - * - * - Then, autohint if FT_LOAD_FORCE_AUTOHINT is set - * or if we don't have a native font hinter. - * - * - Otherwise, auto-hint for LIGHT hinting mode. - * - * - Exception: The font requires the unpatented - * bytecode interpreter to load properly. - */ - - autohint = 0; - if ( hinter && - ( load_flags & FT_LOAD_NO_HINTING ) == 0 && - ( load_flags & FT_LOAD_NO_AUTOHINT ) == 0 && - FT_DRIVER_IS_SCALABLE( driver ) && - FT_DRIVER_USES_OUTLINES( driver ) && - face->internal->transform_matrix.yy > 0 && - face->internal->transform_matrix.yx == 0 ) - { - if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) != 0 || - !FT_DRIVER_HAS_HINTER( driver ) ) - autohint = 1; - else - { - FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); - - - if ( mode == FT_RENDER_MODE_LIGHT || - face->internal->ignore_unpatented_hinter ) - autohint = 1; - } - } - - if ( autohint ) - { - FT_AutoHinter_Service hinting; - - - /* try to load embedded bitmaps first if available */ - /* */ - /* XXX: This is really a temporary hack that should disappear */ - /* promptly with FreeType 2.1! */ - /* */ - if ( FT_HAS_FIXED_SIZES( face ) && - ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) - { - error = driver->clazz->load_glyph( slot, face->size, - glyph_index, - load_flags | FT_LOAD_SBITS_ONLY ); - - if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP ) - goto Load_Ok; - } - - { - FT_Face_Internal internal = face->internal; - FT_Int transform_flags = internal->transform_flags; - - - /* since the auto-hinter calls FT_Load_Glyph by itself, */ - /* make sure that glyphs aren't transformed */ - internal->transform_flags = 0; - - /* load auto-hinted outline */ - hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface; - - error = hinting->load_glyph( (FT_AutoHinter)hinter, - slot, face->size, - glyph_index, load_flags ); - - internal->transform_flags = transform_flags; - } - } - else - { - error = driver->clazz->load_glyph( slot, - face->size, - glyph_index, - load_flags ); - if ( error ) - goto Exit; - - if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - { - /* check that the loaded outline is correct */ - error = FT_Outline_Check( &slot->outline ); - if ( error ) - goto Exit; - -#ifdef GRID_FIT_METRICS - if ( !( load_flags & FT_LOAD_NO_HINTING ) ) - ft_glyphslot_grid_fit_metrics( slot, - FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) ); -#endif - } - } - - Load_Ok: - /* compute the advance */ - if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) - { - slot->advance.x = 0; - slot->advance.y = slot->metrics.vertAdvance; - } - else - { - slot->advance.x = slot->metrics.horiAdvance; - slot->advance.y = 0; - } - - /* compute the linear advance in 16.16 pixels */ - if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) ) - { - FT_Size_Metrics* metrics = &face->size->metrics; - - - /* it's tricky! */ - slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance, - metrics->x_scale, 64 ); - - slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance, - metrics->y_scale, 64 ); - } - - if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 ) - { - FT_Face_Internal internal = face->internal; - - - /* now, transform the glyph image if needed */ - if ( internal->transform_flags ) - { - /* get renderer */ - FT_Renderer renderer = ft_lookup_glyph_renderer( slot ); - - - if ( renderer ) - error = renderer->clazz->transform_glyph( - renderer, slot, - &internal->transform_matrix, - &internal->transform_delta ); - /* transform advance */ - FT_Vector_Transform( &slot->advance, &internal->transform_matrix ); - } - } - - /* do we need to render the image now? */ - if ( !error && - slot->format != FT_GLYPH_FORMAT_BITMAP && - slot->format != FT_GLYPH_FORMAT_COMPOSITE && - load_flags & FT_LOAD_RENDER ) - { - FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); - - - if ( mode == FT_RENDER_MODE_NORMAL && - (load_flags & FT_LOAD_MONOCHROME ) ) - mode = FT_RENDER_MODE_MONO; - - error = FT_Render_Glyph( slot, mode ); - } - - Exit: - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Load_Char( FT_Face face, - FT_ULong char_code, - FT_Int32 load_flags ) - { - FT_UInt glyph_index; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - glyph_index = (FT_UInt)char_code; - if ( face->charmap ) - glyph_index = FT_Get_Char_Index( face, char_code ); - - return FT_Load_Glyph( face, glyph_index, load_flags ); - } - - - /* destructor for sizes list */ - static void - destroy_size( FT_Memory memory, - FT_Size size, - FT_Driver driver ) - { - /* finalize client-specific data */ - if ( size->generic.finalizer ) - size->generic.finalizer( size ); - - /* finalize format-specific stuff */ - if ( driver->clazz->done_size ) - driver->clazz->done_size( size ); - - FT_FREE( size->internal ); - FT_FREE( size ); - } - - - static void - ft_cmap_done_internal( FT_CMap cmap ); - - - static void - destroy_charmaps( FT_Face face, - FT_Memory memory ) - { - FT_Int n; - - - if ( !face ) - return; - - for ( n = 0; n < face->num_charmaps; n++ ) - { - FT_CMap cmap = FT_CMAP( face->charmaps[n] ); - - - ft_cmap_done_internal( cmap ); - - face->charmaps[n] = NULL; - } - - FT_FREE( face->charmaps ); - face->num_charmaps = 0; - } - - - /* destructor for faces list */ - static void - destroy_face( FT_Memory memory, - FT_Face face, - FT_Driver driver ) - { - FT_Driver_Class clazz = driver->clazz; - - - /* discard auto-hinting data */ - if ( face->autohint.finalizer ) - face->autohint.finalizer( face->autohint.data ); - - /* Discard glyph slots for this face. */ - /* Beware! FT_Done_GlyphSlot() changes the field `face->glyph' */ - while ( face->glyph ) - FT_Done_GlyphSlot( face->glyph ); - - /* discard all sizes for this face */ - FT_List_Finalize( &face->sizes_list, - (FT_List_Destructor)destroy_size, - memory, - driver ); - face->size = 0; - - /* now discard client data */ - if ( face->generic.finalizer ) - face->generic.finalizer( face ); - - /* discard charmaps */ - destroy_charmaps( face, memory ); - - /* finalize format-specific stuff */ - if ( clazz->done_face ) - clazz->done_face( face ); - - /* close the stream for this face if needed */ - FT_Stream_Free( - face->stream, - ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); - - face->stream = 0; - - /* get rid of it */ - if ( face->internal ) - { - FT_FREE( face->internal ); - } - FT_FREE( face ); - } - - - static void - Destroy_Driver( FT_Driver driver ) - { - FT_List_Finalize( &driver->faces_list, - (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 ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* find_unicode_charmap */ - /* */ - /* <Description> */ - /* This function finds a Unicode charmap, if there is one. */ - /* And if there is more than one, it tries to favour the more */ - /* extensive one, i.e., one that supports UCS-4 against those which */ - /* are limited to the BMP (said UCS-2 encoding.) */ - /* */ - /* This function is called from open_face() (just below), and also */ - /* from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ). */ - /* */ - static FT_Error - find_unicode_charmap( FT_Face face ) - { - FT_CharMap* first; - FT_CharMap* cur; - - - /* caller should have already checked that `face' is valid */ - FT_ASSERT( face ); - - first = face->charmaps; - - if ( !first ) - return FT_Err_Invalid_CharMap_Handle; - - /* - * The original TrueType specification(s) only specified charmap - * formats that are capable of mapping 8 or 16 bit character codes to - * glyph indices. - * - * However, recent updates to the Apple and OpenType specifications - * introduced new formats that are capable of mapping 32-bit character - * codes as well. And these are already used on some fonts, mainly to - * map non-BMP Asian ideographs as defined in Unicode. - * - * For compatibility purposes, these fonts generally come with - * *several* Unicode charmaps: - * - * - One of them in the "old" 16-bit format, that cannot access - * all glyphs in the font. - * - * - Another one in the "new" 32-bit format, that can access all - * the glyphs. - * - * This function has been written to always favor a 32-bit charmap - * when found. Otherwise, a 16-bit one is returned when found. - */ - - /* Since the `interesting' table, with IDs (3,10), is normally the */ - /* last one, we loop backwards. This loses with type1 fonts with */ - /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP */ - /* chars (.01% ?), and this is the same about 99.99% of the time! */ - - cur = first + face->num_charmaps; /* points after the last one */ - - for ( ; --cur >= first; ) - { - if ( cur[0]->encoding == FT_ENCODING_UNICODE ) - { - /* XXX If some new encodings to represent UCS-4 are added, */ - /* they should be added here. */ - if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT && - cur[0]->encoding_id == TT_MS_ID_UCS_4 ) || - ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && - cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32 ) ) - { - face->charmap = cur[0]; - return FT_Err_Ok; - } - } - } - - /* We do not have any UCS-4 charmap. */ - /* Do the loop again and search for UCS-2 charmaps. */ - cur = first + face->num_charmaps; - - for ( ; --cur >= first; ) - { - if ( cur[0]->encoding == FT_ENCODING_UNICODE ) - { - face->charmap = cur[0]; - return FT_Err_Ok; - } - } - - return FT_Err_Invalid_CharMap_Handle; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* find_variant_selector_charmap */ - /* */ - /* <Description> */ - /* This function finds the variant selector charmap, if there is one. */ - /* There can only be one (platform=0, specific=5, format=14). */ - /* */ - static FT_CharMap - find_variant_selector_charmap( FT_Face face ) - { - FT_CharMap* first; - FT_CharMap* end; - FT_CharMap* cur; - - - /* caller should have already checked that `face' is valid */ - FT_ASSERT( face ); - - first = face->charmaps; - - if ( !first ) - return NULL; - - end = first + face->num_charmaps; /* points after the last one */ - - for ( cur = first; cur < end; ++cur ) - { - if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && - cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && - FT_Get_CMap_Format( cur[0] ) == 14 ) - return cur[0]; - } - - return NULL; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* open_face */ - /* */ - /* <Description> */ - /* This function does some work for FT_Open_Face(). */ - /* */ - static FT_Error - open_face( FT_Driver driver, - FT_Stream stream, - FT_Long face_index, - FT_Int num_params, - FT_Parameter* params, - FT_Face *aface ) - { - FT_Memory memory; - FT_Driver_Class clazz; - FT_Face face = 0; - FT_Error error, error2; - FT_Face_Internal internal = NULL; - - - clazz = driver->clazz; - memory = driver->root.memory; - - /* allocate the face object and perform basic initialization */ - if ( FT_ALLOC( face, clazz->face_object_size ) ) - goto Fail; - - if ( FT_NEW( internal ) ) - goto Fail; - - face->internal = internal; - - face->driver = driver; - face->memory = memory; - face->stream = stream; - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - { - int i; - - - face->internal->incremental_interface = 0; - for ( i = 0; i < num_params && !face->internal->incremental_interface; - i++ ) - if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL ) - face->internal->incremental_interface = - (FT_Incremental_Interface)params[i].data; - } -#endif - - if ( clazz->init_face ) - error = clazz->init_face( stream, - face, - (FT_Int)face_index, - num_params, - params ); - if ( error ) - goto Fail; - - /* select Unicode charmap by default */ - error2 = find_unicode_charmap( face ); - - /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */ - /* is returned. */ - - /* no error should happen, but we want to play safe */ - if ( error2 && error2 != FT_Err_Invalid_CharMap_Handle ) - { - error = error2; - goto Fail; - } - - *aface = face; - - Fail: - if ( error ) - { - destroy_charmaps( face, memory ); - if ( clazz->done_face ) - clazz->done_face( face ); - FT_FREE( internal ); - FT_FREE( face ); - *aface = 0; - } - - return error; - } - - - /* there's a Mac-specific extended implementation of FT_New_Face() */ - /* in src/base/ftmac.c */ - -#ifndef FT_MACINTOSH - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_New_Face( FT_Library library, - const char* pathname, - FT_Long face_index, - FT_Face *aface ) - { - FT_Open_Args args; - - - /* test for valid `library' and `aface' delayed to FT_Open_Face() */ - if ( !pathname ) - return FT_Err_Invalid_Argument; - - args.flags = FT_OPEN_PATHNAME; - args.pathname = (char*)pathname; - - return FT_Open_Face( library, &args, face_index, aface ); - } - -#endif /* !FT_MACINTOSH */ - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_New_Memory_Face( FT_Library library, - const FT_Byte* file_base, - FT_Long file_size, - FT_Long face_index, - FT_Face *aface ) - { - FT_Open_Args args; - - - /* test for valid `library' and `face' delayed to FT_Open_Face() */ - if ( !file_base ) - return FT_Err_Invalid_Argument; - - args.flags = FT_OPEN_MEMORY; - args.memory_base = file_base; - args.memory_size = file_size; - - return FT_Open_Face( library, &args, face_index, aface ); - } - - -#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) - - /* The behavior here is very similar to that in base/ftmac.c, but it */ - /* is designed to work on non-mac systems, so no mac specific calls. */ - /* */ - /* We look at the file and determine if it is a mac dfont file or a mac */ - /* resource file, or a macbinary file containing a mac resource file. */ - /* */ - /* Unlike ftmac I'm not going to look at a `FOND'. I don't really see */ - /* the point, especially since there may be multiple `FOND' resources. */ - /* Instead I'll just look for `sfnt' and `POST' resources, ordered as */ - /* they occur in the file. */ - /* */ - /* Note that multiple `POST' resources do not mean multiple postscript */ - /* fonts; they all get jammed together to make what is essentially a */ - /* pfb file. */ - /* */ - /* We aren't interested in `NFNT' or `FONT' bitmap resources. */ - /* */ - /* As soon as we get an `sfnt' load it into memory and pass it off to */ - /* FT_Open_Face. */ - /* */ - /* If we have a (set of) `POST' resources, massage them into a (memory) */ - /* pfb file and pass that to FT_Open_Face. (As with ftmac.c I'm not */ - /* going to try to save the kerning info. After all that lives in the */ - /* `FOND' which isn't in the file containing the `POST' resources so */ - /* we don't really have access to it. */ - - - /* Finalizer for a memory stream; gets called by FT_Done_Face(). - It frees the memory it uses. */ - /* from ftmac.c */ - static void - memory_stream_close( FT_Stream stream ) - { - FT_Memory memory = stream->memory; - - - FT_FREE( stream->base ); - - stream->size = 0; - stream->base = 0; - stream->close = 0; - } - - - /* Create a new memory stream from a buffer and a size. */ - /* from ftmac.c */ - static FT_Error - new_memory_stream( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Stream_CloseFunc close, - FT_Stream *astream ) - { - FT_Error error; - FT_Memory memory; - FT_Stream stream; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !base ) - return FT_Err_Invalid_Argument; - - *astream = 0; - memory = library->memory; - if ( FT_NEW( stream ) ) - goto Exit; - - FT_Stream_OpenMemory( stream, base, size ); - - stream->close = close; - - *astream = stream; - - Exit: - return error; - } - - - /* Create a new FT_Face given a buffer and a driver name. */ - /* from ftmac.c */ - static FT_Error - open_face_from_buffer( FT_Library library, - FT_Byte* base, - FT_ULong size, - FT_Long face_index, - const char* driver_name, - FT_Face *aface ) - { - FT_Open_Args args; - FT_Error error; - FT_Stream stream = NULL; - FT_Memory memory = library->memory; - - - error = new_memory_stream( library, - base, - size, - memory_stream_close, - &stream ); - if ( error ) - { - FT_FREE( base ); - return error; - } - - args.flags = FT_OPEN_STREAM; - args.stream = stream; - if ( driver_name ) - { - args.flags = args.flags | FT_OPEN_DRIVER; - args.driver = FT_Get_Module( library, driver_name ); - } - - error = FT_Open_Face( library, &args, face_index, aface ); - - if ( error == FT_Err_Ok ) - (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; - else - { - FT_Stream_Close( stream ); - FT_FREE( stream ); - } - - return error; - } - - - /* The resource header says we've got resource_cnt `POST' (type1) */ - /* resources in this file. They all need to be coalesced into */ - /* one lump which gets passed on to the type1 driver. */ - /* Here can be only one PostScript font in a file so face_index */ - /* must be 0 (or -1). */ - /* */ - static FT_Error - Mac_Read_POST_Resource( FT_Library library, - FT_Stream stream, - FT_Long *offsets, - FT_Long resource_cnt, - FT_Long face_index, - FT_Face *aface ) - { - FT_Error error = FT_Err_Cannot_Open_Resource; - FT_Memory memory = library->memory; - FT_Byte* pfb_data; - int i, type, flags; - FT_Long len; - FT_Long pfb_len, pfb_pos, pfb_lenpos; - FT_Long rlen, temp; - - - if ( face_index == -1 ) - face_index = 0; - if ( face_index != 0 ) - return error; - - /* Find the length of all the POST resources, concatenated. Assume */ - /* worst case (each resource in its own section). */ - pfb_len = 0; - for ( i = 0; i < resource_cnt; ++i ) - { - error = FT_Stream_Seek( stream, offsets[i] ); - if ( error ) - goto Exit; - if ( FT_READ_LONG( temp ) ) - goto Exit; - pfb_len += temp + 6; - } - - if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) - goto Exit; - - pfb_data[0] = 0x80; - pfb_data[1] = 1; /* Ascii section */ - pfb_data[2] = 0; /* 4-byte length, fill in later */ - pfb_data[3] = 0; - pfb_data[4] = 0; - pfb_data[5] = 0; - pfb_pos = 6; - pfb_lenpos = 2; - - len = 0; - type = 1; - for ( i = 0; i < resource_cnt; ++i ) - { - error = FT_Stream_Seek( stream, offsets[i] ); - if ( error ) - goto Exit2; - if ( FT_READ_LONG( rlen ) ) - goto Exit; - if ( FT_READ_USHORT( flags ) ) - goto Exit; - rlen -= 2; /* the flags are part of the resource */ - if ( ( flags >> 8 ) == type ) - len += rlen; - else - { - pfb_data[pfb_lenpos ] = (FT_Byte)( len ); - pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); - pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); - pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 ); - - if ( ( flags >> 8 ) == 5 ) /* End of font mark */ - break; - - pfb_data[pfb_pos++] = 0x80; - - type = flags >> 8; - len = rlen; - - pfb_data[pfb_pos++] = (FT_Byte)type; - pfb_lenpos = pfb_pos; - pfb_data[pfb_pos++] = 0; /* 4-byte length, fill in later */ - pfb_data[pfb_pos++] = 0; - pfb_data[pfb_pos++] = 0; - pfb_data[pfb_pos++] = 0; - } - - error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); - pfb_pos += rlen; - } - - pfb_data[pfb_pos++] = 0x80; - pfb_data[pfb_pos++] = 3; - - pfb_data[pfb_lenpos ] = (FT_Byte)( len ); - pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); - pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); - pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 ); - - return open_face_from_buffer( library, - pfb_data, - pfb_pos, - face_index, - "type1", - aface ); - - Exit2: - FT_FREE( pfb_data ); - - Exit: - return error; - } - - - /* The resource header says we've got resource_cnt `sfnt' */ - /* (TrueType/OpenType) resources in this file. Look through */ - /* them for the one indicated by face_index, load it into mem, */ - /* pass it on the the truetype driver and return it. */ - /* */ - static FT_Error - Mac_Read_sfnt_Resource( FT_Library library, - FT_Stream stream, - FT_Long *offsets, - FT_Long resource_cnt, - FT_Long face_index, - FT_Face *aface ) - { - FT_Memory memory = library->memory; - FT_Byte* sfnt_data; - FT_Error error; - FT_Long flag_offset; - FT_Long rlen; - int is_cff; - FT_Long face_index_in_resource = 0; - - - if ( face_index == -1 ) - face_index = 0; - if ( face_index >= resource_cnt ) - return FT_Err_Cannot_Open_Resource; - - flag_offset = offsets[face_index]; - error = FT_Stream_Seek( stream, flag_offset ); - if ( error ) - goto Exit; - - if ( FT_READ_LONG( rlen ) ) - goto Exit; - if ( rlen == -1 ) - return FT_Err_Cannot_Open_Resource; - - if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) ) - return error; - error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen ); - if ( error ) - goto Exit; - - is_cff = rlen > 4 && sfnt_data[0] == 'O' && - sfnt_data[1] == 'T' && - sfnt_data[2] == 'T' && - sfnt_data[3] == 'O'; - - error = open_face_from_buffer( library, - sfnt_data, - rlen, - face_index_in_resource, - is_cff ? "cff" : "truetype", - aface ); - - Exit: - return error; - } - - - /* Check for a valid resource fork header, or a valid dfont */ - /* header. In a resource fork the first 16 bytes are repeated */ - /* at the location specified by bytes 4-7. In a dfont bytes */ - /* 4-7 point to 16 bytes of zeroes instead. */ - /* */ - static FT_Error - IsMacResource( FT_Library library, - FT_Stream stream, - FT_Long resource_offset, - FT_Long face_index, - FT_Face *aface ) - { - FT_Memory memory = library->memory; - FT_Error error; - FT_Long map_offset, rdara_pos; - FT_Long *data_offsets; - FT_Long count; - - - error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset, - &map_offset, &rdara_pos ); - if ( error ) - return error; - - error = FT_Raccess_Get_DataOffsets( library, stream, - map_offset, rdara_pos, - FT_MAKE_TAG( 'P', 'O', 'S', 'T' ), - &data_offsets, &count ); - if ( !error ) - { - error = Mac_Read_POST_Resource( library, stream, data_offsets, count, - face_index, aface ); - FT_FREE( data_offsets ); - /* POST exists in an LWFN providing a single face */ - if ( !error ) - (*aface)->num_faces = 1; - return error; - } - - error = FT_Raccess_Get_DataOffsets( library, stream, - map_offset, rdara_pos, - FT_MAKE_TAG( 's', 'f', 'n', 't' ), - &data_offsets, &count ); - if ( !error ) - { - FT_Long face_index_internal = face_index % count; - - - error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count, - face_index_internal, aface ); - FT_FREE( data_offsets ); - if ( !error ) - (*aface)->num_faces = count; - } - - return error; - } - - - /* Check for a valid macbinary header, and if we find one */ - /* check that the (flattened) resource fork in it is valid. */ - /* */ - static FT_Error - IsMacBinary( FT_Library library, - FT_Stream stream, - FT_Long face_index, - FT_Face *aface ) - { - unsigned char header[128]; - FT_Error error; - FT_Long dlen, offset; - - - if ( NULL == stream ) - return FT_Err_Invalid_Stream_Operation; - - error = FT_Stream_Seek( stream, 0 ); - if ( error ) - goto Exit; - - error = FT_Stream_Read( stream, (FT_Byte*)header, 128 ); - if ( error ) - goto Exit; - - if ( header[ 0] != 0 || - header[74] != 0 || - header[82] != 0 || - header[ 1] == 0 || - header[ 1] > 33 || - header[63] != 0 || - header[2 + header[1]] != 0 ) - return FT_Err_Unknown_File_Format; - - dlen = ( header[0x53] << 24 ) | - ( header[0x54] << 16 ) | - ( header[0x55] << 8 ) | - header[0x56]; -#if 0 - rlen = ( header[0x57] << 24 ) | - ( header[0x58] << 16 ) | - ( header[0x59] << 8 ) | - header[0x5a]; -#endif /* 0 */ - offset = 128 + ( ( dlen + 127 ) & ~127 ); - - return IsMacResource( library, stream, offset, face_index, aface ); - - Exit: - return error; - } - - - static FT_Error - load_face_in_embedded_rfork( FT_Library library, - FT_Stream stream, - FT_Long face_index, - FT_Face *aface, - const FT_Open_Args *args ) - { - -#undef FT_COMPONENT -#define FT_COMPONENT trace_raccess - - FT_Memory memory = library->memory; - FT_Error error = FT_Err_Unknown_File_Format; - int i; - - char * file_names[FT_RACCESS_N_RULES]; - FT_Long offsets[FT_RACCESS_N_RULES]; - FT_Error errors[FT_RACCESS_N_RULES]; - - FT_Open_Args args2; - FT_Stream stream2; - - - FT_Raccess_Guess( library, stream, - args->pathname, file_names, offsets, errors ); - - for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) - { - if ( errors[i] ) - { - FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i )); - continue; - } - - args2.flags = FT_OPEN_PATHNAME; - args2.pathname = file_names[i] ? file_names[i] : args->pathname; - - FT_TRACE3(( "Try rule %d: %s (offset=%d) ...", - i, args2.pathname, offsets[i] )); - - error = FT_Stream_New( library, &args2, &stream2 ); - if ( error ) - { - FT_TRACE3(( "failed\n" )); - continue; - } - - error = IsMacResource( library, stream2, offsets[i], - face_index, aface ); - FT_Stream_Free( stream2, 0 ); - - FT_TRACE3(( "%s\n", error ? "failed": "successful" )); - - if ( !error ) - break; - } - - for (i = 0; i < FT_RACCESS_N_RULES; i++) - { - if ( file_names[i] ) - FT_FREE( file_names[i] ); - } - - /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */ - if ( error ) - error = FT_Err_Unknown_File_Format; - - return error; - -#undef FT_COMPONENT -#define FT_COMPONENT trace_objs - - } - - - /* Check for some macintosh formats. */ - /* Is this a macbinary file? If so look at the resource fork. */ - /* Is this a mac dfont file? */ - /* Is this an old style resource fork? (in data) */ - /* Else call load_face_in_embedded_rfork to try extra rules */ - /* (defined in `ftrfork.c'). */ - /* */ - static FT_Error - load_mac_face( FT_Library library, - FT_Stream stream, - FT_Long face_index, - FT_Face *aface, - const FT_Open_Args *args ) - { - FT_Error error; - FT_UNUSED( args ); - - - error = IsMacBinary( library, stream, face_index, aface ); - if ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format ) - { - -#undef FT_COMPONENT -#define FT_COMPONENT trace_raccess - - FT_TRACE3(( "Try as dfont: %s ...", args->pathname )); - - error = IsMacResource( library, stream, 0, face_index, aface ); - - FT_TRACE3(( "%s\n", error ? "failed" : "successful" )); - -#undef FT_COMPONENT -#define FT_COMPONENT trace_objs - - } - - if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format || - FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) && - ( args->flags & FT_OPEN_PATHNAME ) ) - error = load_face_in_embedded_rfork( library, stream, - face_index, aface, args ); - return error; - } - -#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Open_Face( FT_Library library, - const FT_Open_Args* args, - FT_Long face_index, - FT_Face *aface ) - { - FT_Error error; - FT_Driver driver; - FT_Memory memory; - FT_Stream stream; - FT_Face face = 0; - FT_ListNode node = 0; - FT_Bool external_stream; - FT_Module* cur; - FT_Module* limit; - - - /* test for valid `library' delayed to */ - /* FT_Stream_New() */ - - if ( ( !aface && face_index >= 0 ) || !args ) - return FT_Err_Invalid_Argument; - - external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) && - args->stream ); - - /* create input stream */ - error = FT_Stream_New( library, args, &stream ); - if ( error ) - goto Fail3; - - memory = library->memory; - - /* If the font driver is specified in the `args' structure, use */ - /* it. Otherwise, we scan the list of registered drivers. */ - if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver ) - { - driver = FT_DRIVER( args->driver ); - - /* not all modules are drivers, so check... */ - if ( FT_MODULE_IS_DRIVER( driver ) ) - { - FT_Int num_params = 0; - FT_Parameter* params = 0; - - - if ( args->flags & FT_OPEN_PARAMS ) - { - num_params = args->num_params; - params = args->params; - } - - error = open_face( driver, stream, face_index, - num_params, params, &face ); - if ( !error ) - goto Success; - } - else - error = FT_Err_Invalid_Handle; - - FT_Stream_Free( stream, external_stream ); - goto Fail; - } - else - { - /* check each font driver for an appropriate format */ - cur = library->modules; - limit = cur + library->num_modules; - - - for ( ; cur < limit; cur++ ) - { - /* not all modules are font drivers, so check... */ - if ( FT_MODULE_IS_DRIVER( cur[0] ) ) - { - FT_Int num_params = 0; - FT_Parameter* params = 0; - - - driver = FT_DRIVER( cur[0] ); - - if ( args->flags & FT_OPEN_PARAMS ) - { - num_params = args->num_params; - params = args->params; - } - - error = open_face( driver, stream, face_index, - num_params, params, &face ); - if ( !error ) - goto Success; - - if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format ) - goto Fail3; - } - } - - Fail3: - /* If we are on the mac, and we get an FT_Err_Invalid_Stream_Operation */ - /* it may be because we have an empty data fork, so we need to check */ - /* the resource fork. */ - if ( FT_ERROR_BASE( error ) != FT_Err_Cannot_Open_Stream && - FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format && - FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation ) - goto Fail2; - -#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) - error = load_mac_face( library, stream, face_index, aface, args ); - if ( !error ) - { - /* We don't want to go to Success here. We've already done that. */ - /* On the other hand, if we succeeded we still need to close this */ - /* stream (we opened a different stream which extracted the */ - /* interesting information out of this stream here. That stream */ - /* will still be open and the face will point to it). */ - FT_Stream_Free( stream, external_stream ); - return error; - } - - if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format ) - goto Fail2; -#endif /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */ - - /* no driver is able to handle this format */ - error = FT_Err_Unknown_File_Format; - - Fail2: - FT_Stream_Free( stream, external_stream ); - goto Fail; - } - - Success: - FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" )); - - /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */ - if ( external_stream ) - face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM; - - /* add the face object to its driver's list */ - if ( FT_NEW( node ) ) - goto Fail; - - node->data = face; - /* don't assume driver is the same as face->driver, so use */ - /* face->driver instead. */ - FT_List_Add( &face->driver->faces_list, node ); - - /* now allocate a glyph slot object for the face */ - FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" )); - - if ( face_index >= 0 ) - { - error = FT_New_GlyphSlot( face, NULL ); - if ( error ) - goto Fail; - - /* finally, allocate a size object for the face */ - { - FT_Size size; - - - FT_TRACE4(( "FT_Open_Face: Creating size object\n" )); - - error = FT_New_Size( face, &size ); - if ( error ) - goto Fail; - - face->size = size; - } - } - - /* some checks */ - - if ( FT_IS_SCALABLE( face ) ) - { - if ( face->height < 0 ) - face->height = (FT_Short)-face->height; - - if ( !FT_HAS_VERTICAL( face ) ) - face->max_advance_height = (FT_Short)face->height; - } - - if ( FT_HAS_FIXED_SIZES( face ) ) - { - FT_Int i; - - - for ( i = 0; i < face->num_fixed_sizes; i++ ) - { - FT_Bitmap_Size* bsize = face->available_sizes + i; - - - if ( bsize->height < 0 ) - bsize->height = (FT_Short)-bsize->height; - if ( bsize->x_ppem < 0 ) - bsize->x_ppem = (FT_Short)-bsize->x_ppem; - if ( bsize->y_ppem < 0 ) - bsize->y_ppem = -bsize->y_ppem; - } - } - - /* initialize internal face data */ - { - FT_Face_Internal internal = face->internal; - - - internal->transform_matrix.xx = 0x10000L; - internal->transform_matrix.xy = 0; - internal->transform_matrix.yx = 0; - internal->transform_matrix.yy = 0x10000L; - - internal->transform_delta.x = 0; - internal->transform_delta.y = 0; - } - - if ( aface ) - *aface = face; - else - FT_Done_Face( face ); - - goto Exit; - - Fail: - FT_Done_Face( face ); - - Exit: - FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); - - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Attach_File( FT_Face face, - const char* filepathname ) - { - FT_Open_Args open; - - - /* test for valid `face' delayed to FT_Attach_Stream() */ - - if ( !filepathname ) - return FT_Err_Invalid_Argument; - - open.stream = NULL; - open.flags = FT_OPEN_PATHNAME; - open.pathname = (char*)filepathname; - - return FT_Attach_Stream( face, &open ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Attach_Stream( FT_Face face, - FT_Open_Args* parameters ) - { - FT_Stream stream; - FT_Error error; - FT_Driver driver; - - FT_Driver_Class clazz; - - - /* test for valid `parameters' delayed to FT_Stream_New() */ - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - driver = face->driver; - if ( !driver ) - return FT_Err_Invalid_Driver_Handle; - - error = FT_Stream_New( driver->root.library, parameters, &stream ); - if ( error ) - goto Exit; - - /* we implement FT_Attach_Stream in each driver through the */ - /* `attach_file' interface */ - - error = FT_Err_Unimplemented_Feature; - clazz = driver->clazz; - if ( clazz->attach_file ) - error = clazz->attach_file( face, stream ); - - /* close the attached stream */ - FT_Stream_Free( stream, - (FT_Bool)( parameters->stream && - ( parameters->flags & FT_OPEN_STREAM ) ) ); - - Exit: - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Done_Face( FT_Face face ) - { - FT_Error error; - FT_Driver driver; - FT_Memory memory; - FT_ListNode node; - - - error = FT_Err_Invalid_Face_Handle; - if ( face && face->driver ) - { - driver = face->driver; - memory = driver->root.memory; - - /* find face in driver's list */ - node = FT_List_Find( &driver->faces_list, face ); - if ( node ) - { - /* remove face object from the driver's list */ - FT_List_Remove( &driver->faces_list, node ); - FT_FREE( node ); - - /* now destroy the object proper */ - destroy_face( memory, face, driver ); - error = FT_Err_Ok; - } - } - return error; - } - - - /* documentation is in ftobjs.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_New_Size( FT_Face face, - FT_Size *asize ) - { - FT_Error error; - FT_Memory memory; - FT_Driver driver; - FT_Driver_Class clazz; - - FT_Size size = 0; - FT_ListNode node = 0; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if ( !asize ) - return FT_Err_Invalid_Size_Handle; - - if ( !face->driver ) - return FT_Err_Invalid_Driver_Handle; - - *asize = 0; - - driver = face->driver; - clazz = driver->clazz; - memory = face->memory; - - /* Allocate new size object and perform basic initialisation */ - if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) ) - goto Exit; - - size->face = face; - - /* for now, do not use any internal fields in size objects */ - size->internal = 0; - - if ( clazz->init_size ) - error = clazz->init_size( size ); - - /* in case of success, add to the face's list */ - if ( !error ) - { - *asize = size; - node->data = size; - FT_List_Add( &face->sizes_list, node ); - } - - Exit: - if ( error ) - { - FT_FREE( node ); - FT_FREE( size ); - } - - return error; - } - - - /* documentation is in ftobjs.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Done_Size( FT_Size size ) - { - FT_Error error; - FT_Driver driver; - FT_Memory memory; - FT_Face face; - FT_ListNode node; - - - if ( !size ) - return FT_Err_Invalid_Size_Handle; - - face = size->face; - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - driver = face->driver; - if ( !driver ) - return FT_Err_Invalid_Driver_Handle; - - memory = driver->root.memory; - - error = FT_Err_Ok; - node = FT_List_Find( &face->sizes_list, size ); - if ( node ) - { - FT_List_Remove( &face->sizes_list, node ); - FT_FREE( node ); - - if ( face->size == size ) - { - face->size = 0; - if ( face->sizes_list.head ) - face->size = (FT_Size)(face->sizes_list.head->data); - } - - destroy_size( memory, size, driver ); - } - else - error = FT_Err_Invalid_Size_Handle; - - return error; - } - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( FT_Error ) - FT_Match_Size( FT_Face face, - FT_Size_Request req, - FT_Bool ignore_width, - FT_ULong* size_index ) - { - FT_Int i; - FT_Long w, h; - - - if ( !FT_HAS_FIXED_SIZES( face ) ) - return FT_Err_Invalid_Face_Handle; - - /* FT_Bitmap_Size doesn't provide enough info... */ - if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) - return FT_Err_Unimplemented_Feature; - - w = FT_REQUEST_WIDTH ( req ); - h = FT_REQUEST_HEIGHT( req ); - - if ( req->width && !req->height ) - h = w; - else if ( !req->width && req->height ) - w = h; - - w = FT_PIX_ROUND( w ); - h = FT_PIX_ROUND( h ); - - for ( i = 0; i < face->num_fixed_sizes; i++ ) - { - FT_Bitmap_Size* bsize = face->available_sizes + i; - - - if ( h != FT_PIX_ROUND( bsize->y_ppem ) ) - continue; - - if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width ) - { - if ( size_index ) - *size_index = (FT_ULong)i; - - return FT_Err_Ok; - } - } - - return FT_Err_Invalid_Pixel_Size; - } - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( void ) - ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, - FT_Pos advance ) - { - /* the factor 1.2 is a heuristical value */ - if ( !advance ) - advance = metrics->height * 12 / 10; - - metrics->vertBearingX = -( metrics->width / 2 ); - metrics->vertBearingY = ( advance - metrics->height ) / 2; - metrics->vertAdvance = advance; - } - - - static void - ft_recompute_scaled_metrics( FT_Face face, - FT_Size_Metrics* metrics ) - { - /* Compute root ascender, descender, test height, and max_advance */ - -#ifdef GRID_FIT_METRICS - metrics->ascender = FT_PIX_CEIL( FT_MulFix( face->ascender, - metrics->y_scale ) ); - - metrics->descender = FT_PIX_FLOOR( FT_MulFix( face->descender, - metrics->y_scale ) ); - - metrics->height = FT_PIX_ROUND( FT_MulFix( face->height, - metrics->y_scale ) ); - - metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width, - metrics->x_scale ) ); -#else /* !GRID_FIT_METRICS */ - metrics->ascender = FT_MulFix( face->ascender, - metrics->y_scale ); - - metrics->descender = FT_MulFix( face->descender, - metrics->y_scale ); - - metrics->height = FT_MulFix( face->height, - metrics->y_scale ); - - metrics->max_advance = FT_MulFix( face->max_advance_width, - metrics->x_scale ); -#endif /* !GRID_FIT_METRICS */ - } - - - FT_BASE_DEF( void ) - FT_Select_Metrics( FT_Face face, - FT_ULong strike_index ) - { - FT_Size_Metrics* metrics; - FT_Bitmap_Size* bsize; - - - metrics = &face->size->metrics; - bsize = face->available_sizes + strike_index; - - metrics->x_ppem = (FT_UShort)( ( bsize->x_ppem + 32 ) >> 6 ); - metrics->y_ppem = (FT_UShort)( ( bsize->y_ppem + 32 ) >> 6 ); - - if ( FT_IS_SCALABLE( face ) ) - { - metrics->x_scale = FT_DivFix( bsize->x_ppem, - face->units_per_EM ); - metrics->y_scale = FT_DivFix( bsize->y_ppem, - face->units_per_EM ); - - ft_recompute_scaled_metrics( face, metrics ); - } - else - { - metrics->x_scale = 1L << 22; - metrics->y_scale = 1L << 22; - metrics->ascender = bsize->y_ppem; - metrics->descender = 0; - metrics->height = bsize->height << 6; - metrics->max_advance = bsize->x_ppem; - } - } - - - FT_BASE_DEF( void ) - FT_Request_Metrics( FT_Face face, - FT_Size_Request req ) - { - FT_Size_Metrics* metrics; - - - metrics = &face->size->metrics; - - if ( FT_IS_SCALABLE( face ) ) - { - FT_Long w = 0, h = 0, scaled_w = 0, scaled_h = 0; - - - switch ( req->type ) - { - case FT_SIZE_REQUEST_TYPE_NOMINAL: - w = h = face->units_per_EM; - break; - - case FT_SIZE_REQUEST_TYPE_REAL_DIM: - w = h = face->ascender - face->descender; - break; - - case FT_SIZE_REQUEST_TYPE_BBOX: - w = face->bbox.xMax - face->bbox.xMin; - h = face->bbox.yMax - face->bbox.yMin; - break; - - case FT_SIZE_REQUEST_TYPE_CELL: - w = face->max_advance_width; - h = face->ascender - face->descender; - break; - - case FT_SIZE_REQUEST_TYPE_SCALES: - metrics->x_scale = (FT_Fixed)req->width; - metrics->y_scale = (FT_Fixed)req->height; - if ( !metrics->x_scale ) - metrics->x_scale = metrics->y_scale; - else if ( !metrics->y_scale ) - metrics->y_scale = metrics->x_scale; - goto Calculate_Ppem; - - case FT_SIZE_REQUEST_TYPE_MAX: - break; - } - - /* to be on the safe side */ - if ( w < 0 ) - w = -w; - - if ( h < 0 ) - h = -h; - - scaled_w = FT_REQUEST_WIDTH ( req ); - scaled_h = FT_REQUEST_HEIGHT( req ); - - /* determine scales */ - if ( req->width ) - { - metrics->x_scale = FT_DivFix( scaled_w, w ); - - if ( req->height ) - { - metrics->y_scale = FT_DivFix( scaled_h, h ); - - if ( req->type == FT_SIZE_REQUEST_TYPE_CELL ) - { - if ( metrics->y_scale > metrics->x_scale ) - metrics->y_scale = metrics->x_scale; - else - metrics->x_scale = metrics->y_scale; - } - } - else - { - metrics->y_scale = metrics->x_scale; - scaled_h = FT_MulDiv( scaled_w, h, w ); - } - } - else - { - metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h ); - scaled_w = FT_MulDiv( scaled_h, w, h ); - } - - Calculate_Ppem: - /* calculate the ppems */ - if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL ) - { - scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale ); - scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale ); - } - - metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 ); - metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 ); - - ft_recompute_scaled_metrics( face, metrics ); - } - else - { - FT_ZERO( metrics ); - metrics->x_scale = 1L << 22; - metrics->y_scale = 1L << 22; - } - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Select_Size( FT_Face face, - FT_Int strike_index ) - { - FT_Driver_Class clazz; - - - if ( !face || !FT_HAS_FIXED_SIZES( face ) ) - return FT_Err_Invalid_Face_Handle; - - if ( strike_index < 0 || strike_index >= face->num_fixed_sizes ) - return FT_Err_Invalid_Argument; - - clazz = face->driver->clazz; - - if ( clazz->select_size ) - return clazz->select_size( face->size, (FT_ULong)strike_index ); - - FT_Select_Metrics( face, (FT_ULong)strike_index ); - - return FT_Err_Ok; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Request_Size( FT_Face face, - FT_Size_Request req ) - { - FT_Driver_Class clazz; - FT_ULong strike_index; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if ( !req || req->width < 0 || req->height < 0 || - req->type >= FT_SIZE_REQUEST_TYPE_MAX ) - return FT_Err_Invalid_Argument; - - clazz = face->driver->clazz; - - if ( clazz->request_size ) - return clazz->request_size( face->size, req ); - - /* - * The reason that a driver doesn't have `request_size' defined is - * either that the scaling here suffices or that the supported formats - * are bitmap-only and size matching is not implemented. - * - * In the latter case, a simple size matching is done. - */ - if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) ) - { - FT_Error error; - - - error = FT_Match_Size( face, req, 0, &strike_index ); - if ( error ) - return error; - - FT_TRACE3(( "FT_Request_Size: bitmap strike %lu matched\n", - strike_index )); - - return FT_Select_Size( face, (FT_Int)strike_index ); - } - - FT_Request_Metrics( face, req ); - - return FT_Err_Ok; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_Char_Size( FT_Face face, - FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution ) - { - FT_Size_RequestRec req; - - - if ( !char_width ) - char_width = char_height; - else if ( !char_height ) - char_height = char_width; - - if ( !horz_resolution ) - horz_resolution = vert_resolution; - else if ( !vert_resolution ) - vert_resolution = horz_resolution; - - if ( char_width < 1 * 64 ) - char_width = 1 * 64; - if ( char_height < 1 * 64 ) - char_height = 1 * 64; - - if ( !horz_resolution ) - horz_resolution = vert_resolution = 72; - - req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; - req.width = char_width; - req.height = char_height; - req.horiResolution = horz_resolution; - req.vertResolution = vert_resolution; - - return FT_Request_Size( face, &req ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_Pixel_Sizes( FT_Face face, - FT_UInt pixel_width, - FT_UInt pixel_height ) - { - FT_Size_RequestRec req; - - - if ( pixel_width == 0 ) - pixel_width = pixel_height; - else if ( pixel_height == 0 ) - pixel_height = pixel_width; - - if ( pixel_width < 1 ) - pixel_width = 1; - if ( pixel_height < 1 ) - pixel_height = 1; - - /* use `>=' to avoid potential compiler warning on 16bit platforms */ - if ( pixel_width >= 0xFFFFU ) - pixel_width = 0xFFFFU; - if ( pixel_height >= 0xFFFFU ) - pixel_height = 0xFFFFU; - - req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; - req.width = pixel_width << 6; - req.height = pixel_height << 6; - req.horiResolution = 0; - req.vertResolution = 0; - - return FT_Request_Size( face, &req ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Kerning( FT_Face face, - FT_UInt left_glyph, - FT_UInt right_glyph, - FT_UInt kern_mode, - FT_Vector *akerning ) - { - FT_Error error = FT_Err_Ok; - FT_Driver driver; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if ( !akerning ) - return FT_Err_Invalid_Argument; - - driver = face->driver; - - akerning->x = 0; - akerning->y = 0; - - if ( driver->clazz->get_kerning ) - { - error = driver->clazz->get_kerning( face, - left_glyph, - right_glyph, - akerning ); - if ( !error ) - { - if ( kern_mode != FT_KERNING_UNSCALED ) - { - akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale ); - akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale ); - - if ( kern_mode != FT_KERNING_UNFITTED ) - { - /* we scale down kerning values for small ppem values */ - /* to avoid that rounding makes them too big. */ - /* `25' has been determined heuristically. */ - if ( face->size->metrics.x_ppem < 25 ) - akerning->x = FT_MulDiv( akerning->x, - face->size->metrics.x_ppem, 25 ); - if ( face->size->metrics.y_ppem < 25 ) - akerning->y = FT_MulDiv( akerning->y, - face->size->metrics.y_ppem, 25 ); - - akerning->x = FT_PIX_ROUND( akerning->x ); - akerning->y = FT_PIX_ROUND( akerning->y ); - } - } - } - } - - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Track_Kerning( FT_Face face, - FT_Fixed point_size, - FT_Int degree, - FT_Fixed* akerning ) - { - FT_Service_Kerning service; - FT_Error error = FT_Err_Ok; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if ( !akerning ) - return FT_Err_Invalid_Argument; - - FT_FACE_FIND_SERVICE( face, service, KERNING ); - if ( !service ) - return FT_Err_Unimplemented_Feature; - - error = service->get_track( face, - point_size, - degree, - akerning ); - - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Select_Charmap( FT_Face face, - FT_Encoding encoding ) - { - FT_CharMap* cur; - FT_CharMap* limit; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - if ( encoding == FT_ENCODING_NONE ) - return FT_Err_Invalid_Argument; - - /* FT_ENCODING_UNICODE is special. We try to find the `best' Unicode */ - /* charmap available, i.e., one with UCS-4 characters, if possible. */ - /* */ - /* This is done by find_unicode_charmap() above, to share code. */ - if ( encoding == FT_ENCODING_UNICODE ) - return find_unicode_charmap( face ); - - cur = face->charmaps; - if ( !cur ) - return FT_Err_Invalid_CharMap_Handle; - - limit = cur + face->num_charmaps; - - for ( ; cur < limit; cur++ ) - { - if ( cur[0]->encoding == encoding ) - { - face->charmap = cur[0]; - return 0; - } - } - - return FT_Err_Invalid_Argument; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_Charmap( FT_Face face, - FT_CharMap charmap ) - { - FT_CharMap* cur; - FT_CharMap* limit; - - - if ( !face ) - return FT_Err_Invalid_Face_Handle; - - cur = face->charmaps; - if ( !cur ) - return FT_Err_Invalid_CharMap_Handle; - if ( FT_Get_CMap_Format( charmap ) == 14 ) - return FT_Err_Invalid_Argument; - - limit = cur + face->num_charmaps; - - for ( ; cur < limit; cur++ ) - { - if ( cur[0] == charmap ) - { - face->charmap = cur[0]; - return 0; - } - } - return FT_Err_Invalid_Argument; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Int ) - FT_Get_Charmap_Index( FT_CharMap charmap ) - { - FT_Int i; - - - for ( i = 0; i < charmap->face->num_charmaps; i++ ) - if ( charmap->face->charmaps[i] == charmap ) - break; - - FT_ASSERT( i < charmap->face->num_charmaps ); - - return i; - } - - - static void - ft_cmap_done_internal( FT_CMap cmap ) - { - FT_CMap_Class clazz = cmap->clazz; - FT_Face face = cmap->charmap.face; - FT_Memory memory = FT_FACE_MEMORY(face); - - - if ( clazz->done ) - clazz->done( cmap ); - - FT_FREE( cmap ); - } - - - FT_BASE_DEF( void ) - FT_CMap_Done( FT_CMap cmap ) - { - if ( cmap ) - { - FT_Face face = cmap->charmap.face; - FT_Memory memory = FT_FACE_MEMORY( face ); - FT_Error error; - FT_Int i, j; - - - for ( i = 0; i < face->num_charmaps; i++ ) - { - if ( (FT_CMap)face->charmaps[i] == cmap ) - { - FT_CharMap last_charmap = face->charmaps[face->num_charmaps - 1]; - - - if ( FT_RENEW_ARRAY( face->charmaps, - face->num_charmaps, - face->num_charmaps - 1 ) ) - return; - - /* remove it from our list of charmaps */ - for ( j = i + 1; j < face->num_charmaps; j++ ) - { - if ( j == face->num_charmaps - 1 ) - face->charmaps[j - 1] = last_charmap; - else - face->charmaps[j - 1] = face->charmaps[j]; - } - - face->num_charmaps--; - - if ( (FT_CMap)face->charmap == cmap ) - face->charmap = NULL; - - ft_cmap_done_internal( cmap ); - - break; - } - } - } - } - - - FT_BASE_DEF( FT_Error ) - FT_CMap_New( FT_CMap_Class clazz, - FT_Pointer init_data, - FT_CharMap charmap, - FT_CMap *acmap ) - { - FT_Error error = FT_Err_Ok; - FT_Face face; - FT_Memory memory; - FT_CMap cmap; - - - if ( clazz == NULL || charmap == NULL || charmap->face == NULL ) - return FT_Err_Invalid_Argument; - - face = charmap->face; - memory = FT_FACE_MEMORY( face ); - - if ( !FT_ALLOC( cmap, clazz->size ) ) - { - cmap->charmap = *charmap; - cmap->clazz = clazz; - - if ( clazz->init ) - { - error = clazz->init( cmap, init_data ); - if ( error ) - goto Fail; - } - - /* add it to our list of charmaps */ - if ( FT_RENEW_ARRAY( face->charmaps, - face->num_charmaps, - face->num_charmaps + 1 ) ) - goto Fail; - - face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap; - } - - Exit: - if ( acmap ) - *acmap = cmap; - - return error; - - Fail: - ft_cmap_done_internal( cmap ); - cmap = NULL; - goto Exit; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UInt ) - FT_Get_Char_Index( FT_Face face, - FT_ULong charcode ) - { - FT_UInt result = 0; - - - if ( face && face->charmap ) - { - FT_CMap cmap = FT_CMAP( face->charmap ); - - - result = cmap->clazz->char_index( cmap, charcode ); - } - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_ULong ) - FT_Get_First_Char( FT_Face face, - FT_UInt *agindex ) - { - FT_ULong result = 0; - FT_UInt gindex = 0; - - - if ( face && face->charmap ) - { - gindex = FT_Get_Char_Index( face, 0 ); - if ( gindex == 0 ) - result = FT_Get_Next_Char( face, 0, &gindex ); - } - - if ( agindex ) - *agindex = gindex; - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_ULong ) - FT_Get_Next_Char( FT_Face face, - FT_ULong charcode, - FT_UInt *agindex ) - { - FT_ULong result = 0; - FT_UInt gindex = 0; - - - if ( face && face->charmap ) - { - FT_UInt32 code = (FT_UInt32)charcode; - FT_CMap cmap = FT_CMAP( face->charmap ); - - - gindex = cmap->clazz->char_next( cmap, &code ); - result = ( gindex == 0 ) ? 0 : code; - } - - if ( agindex ) - *agindex = gindex; - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UInt ) - FT_Face_GetCharVariantIndex( FT_Face face, - FT_ULong charcode, - FT_ULong variantSelector ) - { - FT_UInt result = 0; - - - if ( face && face->charmap && - face->charmap->encoding == FT_ENCODING_UNICODE ) - { - FT_CharMap charmap = find_variant_selector_charmap( face ); - FT_CMap ucmap = FT_CMAP( face->charmap ); - - - if ( charmap != NULL ) - { - FT_CMap vcmap = FT_CMAP( charmap ); - - - result = vcmap->clazz->char_var_index( vcmap, ucmap, charcode, - variantSelector ); - } - } - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Int ) - FT_Face_GetCharVariantIsDefault( FT_Face face, - FT_ULong charcode, - FT_ULong variantSelector ) - { - FT_Int result = -1; - - - if ( face ) - { - FT_CharMap charmap = find_variant_selector_charmap( face ); - - - if ( charmap != NULL ) - { - FT_CMap vcmap = FT_CMAP( charmap ); - - - result = vcmap->clazz->char_var_default( vcmap, charcode, - variantSelector ); - } - } - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UInt32* ) - FT_Face_GetVariantSelectors( FT_Face face ) - { - FT_UInt32 *result = NULL; - - - if ( face ) - { - FT_CharMap charmap = find_variant_selector_charmap( face ); - - - if ( charmap != NULL ) - { - FT_CMap vcmap = FT_CMAP( charmap ); - FT_Memory memory = FT_FACE_MEMORY( face ); - - - result = vcmap->clazz->variant_list( vcmap, memory ); - } - } - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UInt32* ) - FT_Face_GetVariantsOfChar( FT_Face face, - FT_ULong charcode ) - { - FT_UInt32 *result = NULL; - - - if ( face ) - { - FT_CharMap charmap = find_variant_selector_charmap( face ); - - - if ( charmap != NULL ) - { - FT_CMap vcmap = FT_CMAP( charmap ); - FT_Memory memory = FT_FACE_MEMORY( face ); - - - result = vcmap->clazz->charvariant_list( vcmap, memory, charcode ); - } - } - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UInt32* ) - FT_Face_GetCharsOfVariant( FT_Face face, - FT_ULong variantSelector ) - { - FT_UInt32 *result = NULL; - - - if ( face ) - { - FT_CharMap charmap = find_variant_selector_charmap( face ); - - - if ( charmap != NULL ) - { - FT_CMap vcmap = FT_CMAP( charmap ); - FT_Memory memory = FT_FACE_MEMORY( face ); - - - result = vcmap->clazz->variantchar_list( vcmap, memory, - variantSelector ); - } - } - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_UInt ) - FT_Get_Name_Index( FT_Face face, - FT_String* glyph_name ) - { - FT_UInt result = 0; - - - if ( face && FT_HAS_GLYPH_NAMES( face ) ) - { - FT_Service_GlyphDict service; - - - FT_FACE_LOOKUP_SERVICE( face, - service, - GLYPH_DICT ); - - if ( service && service->name_index ) - result = service->name_index( face, glyph_name ); - } - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_Glyph_Name( FT_Face face, - FT_UInt glyph_index, - FT_Pointer buffer, - FT_UInt buffer_max ) - { - FT_Error error = FT_Err_Invalid_Argument; - - - /* clean up buffer */ - if ( buffer && buffer_max > 0 ) - ((FT_Byte*)buffer)[0] = 0; - - if ( face && - glyph_index <= (FT_UInt)face->num_glyphs && - FT_HAS_GLYPH_NAMES( face ) ) - { - FT_Service_GlyphDict service; - - - FT_FACE_LOOKUP_SERVICE( face, - service, - GLYPH_DICT ); - - if ( service && service->get_name ) - error = service->get_name( face, glyph_index, buffer, buffer_max ); - } - - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( const char* ) - FT_Get_Postscript_Name( FT_Face face ) - { - const char* result = NULL; - - - if ( !face ) - goto Exit; - - if ( !result ) - { - FT_Service_PsFontName service; - - - FT_FACE_LOOKUP_SERVICE( face, - service, - POSTSCRIPT_FONT_NAME ); - - if ( service && service->get_ps_font_name ) - result = service->get_ps_font_name( face ); - } - - Exit: - return result; - } - - - /* documentation is in tttables.h */ - - FT_EXPORT_DEF( void* ) - FT_Get_Sfnt_Table( FT_Face face, - FT_Sfnt_Tag tag ) - { - void* table = 0; - FT_Service_SFNT_Table service; - - - if ( face && FT_IS_SFNT( face ) ) - { - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service != NULL ) - table = service->get_table( face, tag ); - } - - return table; - } - - - /* documentation is in tttables.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Load_Sfnt_Table( FT_Face face, - FT_ULong tag, - FT_Long offset, - FT_Byte* buffer, - FT_ULong* length ) - { - FT_Service_SFNT_Table service; - - - if ( !face || !FT_IS_SFNT( face ) ) - return FT_Err_Invalid_Face_Handle; - - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) - return FT_Err_Unimplemented_Feature; - - return service->load_table( face, tag, offset, buffer, length ); - } - - - /* documentation is in tttables.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Sfnt_Table_Info( FT_Face face, - FT_UInt table_index, - FT_ULong *tag, - FT_ULong *length ) - { - FT_Service_SFNT_Table service; - - - if ( !face || !FT_IS_SFNT( face ) ) - return FT_Err_Invalid_Face_Handle; - - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) - return FT_Err_Unimplemented_Feature; - - return service->table_info( face, table_index, tag, length ); - } - - - /* documentation is in tttables.h */ - - FT_EXPORT_DEF( FT_ULong ) - FT_Get_CMap_Language_ID( FT_CharMap charmap ) - { - FT_Service_TTCMaps service; - FT_Face face; - TT_CMapInfo cmap_info; - - - if ( !charmap || !charmap->face ) - return 0; - - face = charmap->face; - FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); - if ( service == NULL ) - return 0; - if ( service->get_cmap_info( charmap, &cmap_info )) - return 0; - - return cmap_info.language; - } - - - /* documentation is in tttables.h */ - - FT_EXPORT_DEF( FT_Long ) - FT_Get_CMap_Format( FT_CharMap charmap ) - { - FT_Service_TTCMaps service; - FT_Face face; - TT_CMapInfo cmap_info; - - - if ( !charmap || !charmap->face ) - return -1; - - face = charmap->face; - FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); - if ( service == NULL ) - return -1; - if ( service->get_cmap_info( charmap, &cmap_info )) - return -1; - - return cmap_info.format; - } - - - /* documentation is in ftsizes.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Activate_Size( FT_Size size ) - { - FT_Face face; - - - if ( size == NULL ) - return FT_Err_Bad_Argument; - - face = size->face; - if ( face == NULL || face->driver == NULL ) - return FT_Err_Bad_Argument; - - /* we don't need anything more complex than that; all size objects */ - /* are already listed by the face */ - face->size = size; - - return FT_Err_Ok; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** R E N D E R E R S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - /* lookup a renderer by glyph format in the library's list */ - FT_BASE_DEF( FT_Renderer ) - FT_Lookup_Renderer( FT_Library library, - FT_Glyph_Format format, - FT_ListNode* node ) - { - FT_ListNode cur; - FT_Renderer result = 0; - - - if ( !library ) - goto Exit; - - cur = library->renderers.head; - - if ( node ) - { - if ( *node ) - cur = (*node)->next; - *node = 0; - } - - while ( cur ) - { - FT_Renderer renderer = FT_RENDERER( cur->data ); - - - if ( renderer->glyph_format == format ) - { - if ( node ) - *node = cur; - - result = renderer; - break; - } - cur = cur->next; - } - - Exit: - return result; - } - - - static FT_Renderer - ft_lookup_glyph_renderer( FT_GlyphSlot slot ) - { - FT_Face face = slot->face; - FT_Library library = FT_FACE_LIBRARY( face ); - FT_Renderer result = library->cur_renderer; - - - if ( !result || result->glyph_format != slot->format ) - result = FT_Lookup_Renderer( library, slot->format, 0 ); - - return result; - } - - - static void - ft_set_current_renderer( FT_Library library ) - { - FT_Renderer renderer; - - - renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 0 ); - library->cur_renderer = renderer; - } - - - static FT_Error - ft_add_renderer( FT_Module module ) - { - FT_Library library = module->library; - FT_Memory memory = library->memory; - FT_Error error; - FT_ListNode node; - - - if ( FT_NEW( node ) ) - goto Exit; - - { - FT_Renderer render = FT_RENDERER( module ); - FT_Renderer_Class* clazz = (FT_Renderer_Class*)module->clazz; - - - render->clazz = clazz; - render->glyph_format = clazz->glyph_format; - - /* allocate raster object if needed */ - if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && - clazz->raster_class->raster_new ) - { - error = clazz->raster_class->raster_new( memory, &render->raster ); - if ( error ) - goto Fail; - - render->raster_render = clazz->raster_class->raster_render; - render->render = clazz->render_glyph; - } - - /* add to list */ - node->data = module; - FT_List_Add( &library->renderers, node ); - - ft_set_current_renderer( library ); - } - - Fail: - if ( error ) - FT_FREE( node ); - - Exit: - return error; - } - - - static void - ft_remove_renderer( FT_Module module ) - { - FT_Library library = module->library; - FT_Memory memory = library->memory; - FT_ListNode node; - - - node = FT_List_Find( &library->renderers, module ); - if ( node ) - { - FT_Renderer render = FT_RENDERER( module ); - - - /* release raster object, if any */ - if ( render->raster ) - render->clazz->raster_class->raster_done( render->raster ); - - /* remove from list */ - FT_List_Remove( &library->renderers, node ); - FT_FREE( node ); - - ft_set_current_renderer( library ); - } - } - - - /* documentation is in ftrender.h */ - - FT_EXPORT_DEF( FT_Renderer ) - FT_Get_Renderer( FT_Library library, - FT_Glyph_Format format ) - { - /* test for valid `library' delayed to FT_Lookup_Renderer() */ - - return FT_Lookup_Renderer( library, format, 0 ); - } - - - /* documentation is in ftrender.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Set_Renderer( FT_Library library, - FT_Renderer renderer, - FT_UInt num_params, - FT_Parameter* parameters ) - { - FT_ListNode node; - FT_Error error = FT_Err_Ok; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !renderer ) - return FT_Err_Invalid_Argument; - - node = FT_List_Find( &library->renderers, renderer ); - if ( !node ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - FT_List_Up( &library->renderers, node ); - - if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE ) - library->cur_renderer = renderer; - - if ( num_params > 0 ) - { - FT_Renderer_SetModeFunc set_mode = renderer->clazz->set_mode; - - - for ( ; num_params > 0; num_params-- ) - { - error = set_mode( renderer, parameters->tag, parameters->data ); - if ( error ) - break; - } - } - - Exit: - return error; - } - - - FT_BASE_DEF( FT_Error ) - FT_Render_Glyph_Internal( FT_Library library, - FT_GlyphSlot slot, - FT_Render_Mode render_mode ) - { - FT_Error error = FT_Err_Ok; - FT_Renderer renderer; - - - /* if it is already a bitmap, no need to do anything */ - switch ( slot->format ) - { - case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ - break; - - default: - { - FT_ListNode node = 0; - FT_Bool update = 0; - - - /* small shortcut for the very common case */ - if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - { - renderer = library->cur_renderer; - node = library->renderers.head; - } - else - renderer = FT_Lookup_Renderer( library, slot->format, &node ); - - error = FT_Err_Unimplemented_Feature; - while ( renderer ) - { - error = renderer->render( renderer, slot, render_mode, NULL ); - if ( !error || - FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph ) - break; - - /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ - /* is unsupported by the current renderer for this glyph image */ - /* format. */ - - /* 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 ); - } - } - - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Render_Glyph( FT_GlyphSlot slot, - FT_Render_Mode render_mode ) - { - FT_Library library; - - - if ( !slot ) - return FT_Err_Invalid_Argument; - - library = FT_FACE_LIBRARY( slot->face ); - - return FT_Render_Glyph_Internal( library, slot, render_mode ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** M O D U L E S ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* Destroy_Module */ - /* */ - /* <Description> */ - /* Destroys a given module object. For drivers, this also destroys */ - /* all child faces. */ - /* */ - /* <InOut> */ - /* module :: A handle to the target driver object. */ - /* */ - /* <Note> */ - /* The driver _must_ be LOCKED! */ - /* */ - static void - Destroy_Module( FT_Module module ) - { - FT_Memory memory = module->memory; - FT_Module_Class* clazz = module->clazz; - FT_Library library = module->library; - - - /* finalize client-data - before anything else */ - if ( module->generic.finalizer ) - module->generic.finalizer( module ); - - if ( library && library->auto_hinter == module ) - library->auto_hinter = 0; - - /* if the module is a renderer */ - if ( FT_MODULE_IS_RENDERER( module ) ) - ft_remove_renderer( module ); - - /* if the module is a font driver, add some steps */ - if ( FT_MODULE_IS_DRIVER( module ) ) - Destroy_Driver( FT_DRIVER( module ) ); - - /* finalize the module object */ - if ( clazz->module_done ) - clazz->module_done( module ); - - /* discard it */ - FT_FREE( module ); - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Add_Module( FT_Library library, - const FT_Module_Class* clazz ) - { - FT_Error error; - FT_Memory memory; - FT_Module module; - FT_UInt nn; - - -#define FREETYPE_VER_FIXED ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \ - FREETYPE_MINOR ) - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !clazz ) - return FT_Err_Invalid_Argument; - - /* check freetype version */ - if ( clazz->module_requires > FREETYPE_VER_FIXED ) - return FT_Err_Invalid_Version; - - /* look for a module with the same name in the library's table */ - for ( nn = 0; nn < library->num_modules; nn++ ) - { - module = library->modules[nn]; - if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 ) - { - /* this installed module has the same name, compare their versions */ - if ( clazz->module_version <= module->clazz->module_version ) - return FT_Err_Lower_Module_Version; - - /* remove the module from our list, then exit the loop to replace */ - /* it by our new version.. */ - FT_Remove_Module( library, module ); - break; - } - } - - memory = library->memory; - error = FT_Err_Ok; - - if ( library->num_modules >= FT_MAX_MODULES ) - { - error = FT_Err_Too_Many_Drivers; - goto Exit; - } - - /* allocate module object */ - if ( FT_ALLOC( module, clazz->module_size ) ) - goto Exit; - - /* base initialization */ - module->library = library; - module->memory = memory; - module->clazz = (FT_Module_Class*)clazz; - - /* check whether the module is a renderer - this must be performed */ - /* before the normal module initialization */ - if ( FT_MODULE_IS_RENDERER( module ) ) - { - /* add to the renderers list */ - error = ft_add_renderer( module ); - if ( error ) - goto Fail; - } - - /* is the module a auto-hinter? */ - if ( FT_MODULE_IS_HINTER( module ) ) - library->auto_hinter = module; - - /* 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 ) - { - error = clazz->module_init( module ); - if ( error ) - goto Fail; - } - - /* add module to the library's table */ - library->modules[library->num_modules++] = module; - - Exit: - 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 ); - - - if ( renderer->raster ) - renderer->clazz->raster_class->raster_done( renderer->raster ); - } - - FT_FREE( module ); - goto Exit; - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Module ) - FT_Get_Module( FT_Library library, - const char* module_name ) - { - FT_Module result = 0; - FT_Module* cur; - FT_Module* limit; - - - if ( !library || !module_name ) - return result; - - cur = library->modules; - limit = cur + library->num_modules; - - for ( ; cur < limit; cur++ ) - if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 ) - { - result = cur[0]; - break; - } - - return result; - } - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( const void* ) - FT_Get_Module_Interface( FT_Library library, - const char* mod_name ) - { - FT_Module module; - - - /* test for valid `library' delayed to FT_Get_Module() */ - - module = FT_Get_Module( library, mod_name ); - - return module ? module->clazz->module_interface : 0; - } - - - FT_BASE_DEF( FT_Pointer ) - ft_module_get_service( FT_Module module, - const char* service_id ) - { - FT_Pointer result = NULL; - - if ( module ) - { - FT_ASSERT( module->clazz && module->clazz->get_interface ); - - /* first, look for the service in the module - */ - if ( module->clazz->get_interface ) - result = module->clazz->get_interface( module, service_id ); - - if ( result == NULL ) - { - /* we didn't find it, look in all other modules then - */ - FT_Library library = module->library; - FT_Module* cur = library->modules; - FT_Module* limit = cur + library->num_modules; - - for ( ; cur < limit; cur++ ) - { - if ( cur[0] != module ) - { - FT_ASSERT( cur[0]->clazz ); - - if ( cur[0]->clazz->get_interface ) - { - result = cur[0]->clazz->get_interface( cur[0], service_id ); - if ( result != NULL ) - break; - } - } - } - } - } - - return result; - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Remove_Module( FT_Library library, - FT_Module module ) - { - /* try to find the module from the table, then remove it from there */ - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( module ) - { - FT_Module* cur = library->modules; - FT_Module* limit = cur + library->num_modules; - - - for ( ; cur < limit; cur++ ) - { - if ( cur[0] == module ) - { - /* remove it from the table */ - library->num_modules--; - limit--; - while ( cur < limit ) - { - cur[0] = cur[1]; - cur++; - } - limit[0] = 0; - - /* destroy the module */ - Destroy_Module( module ); - - return FT_Err_Ok; - } - } - } - return FT_Err_Invalid_Driver_Handle; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** L I B R A R Y ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_New_Library( FT_Memory memory, - FT_Library *alibrary ) - { - FT_Library library = 0; - FT_Error error; - - - if ( !memory ) - return FT_Err_Invalid_Argument; - -#ifdef FT_DEBUG_LEVEL_ERROR - /* init debugging support */ - ft_debug_init(); -#endif - - /* first of all, allocate the library object */ - if ( FT_NEW( library ) ) - return error; - - library->memory = memory; - - /* 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 - - /* That's ok now */ - *alibrary = library; - - return FT_Err_Ok; - - Fail: - FT_FREE( library ); - return error; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( void ) - FT_Library_Version( FT_Library library, - FT_Int *amajor, - FT_Int *aminor, - FT_Int *apatch ) - { - FT_Int major = 0; - FT_Int minor = 0; - FT_Int patch = 0; - - - if ( library ) - { - major = library->version_major; - minor = library->version_minor; - patch = library->version_patch; - } - - if ( amajor ) - *amajor = major; - - if ( aminor ) - *aminor = minor; - - if ( apatch ) - *apatch = patch; - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Done_Library( FT_Library library ) - { - FT_Memory memory; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - memory = library->memory; - - /* Discard client-data */ - if ( library->generic.finalizer ) - library->generic.finalizer( library ); - - /* Close all faces in the library. If we don't do - * this, we can have some subtle memory leaks. - * Example: - * - * - the cff font driver uses the pshinter module in cff_size_done - * - if the pshinter module is destroyed before the cff font driver, - * opened FT_Face objects managed by the driver are not properly - * destroyed, resulting in a memory leak - */ - { - FT_UInt n; - - - for ( n = 0; n < library->num_modules; n++ ) - { - FT_Module module = library->modules[n]; - FT_List faces; - - - if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 ) - continue; - - faces = &FT_DRIVER(module)->faces_list; - while ( faces->head ) - FT_Done_Face( FT_FACE( faces->head->data ) ); - } - } - - /* Close all other modules in the library */ -#if 1 - /* XXX Modules are removed in the reversed order so that */ - /* type42 module is removed before truetype module. This */ - /* avoids double free in some occasions. It is a hack. */ - while ( library->num_modules > 0 ) - FT_Remove_Module( library, - library->modules[library->num_modules - 1] ); -#else - { - FT_UInt n; - - - for ( n = 0; n < library->num_modules; n++ ) - { - FT_Module module = library->modules[n]; - - - if ( module ) - { - Destroy_Module( module ); - library->modules[n] = 0; - } - } - } -#endif - - /* Destroy raster objects */ - FT_FREE( library->raster_pool ); - library->raster_pool_size = 0; - - FT_FREE( library ); - return FT_Err_Ok; - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( void ) - FT_Set_Debug_Hook( FT_Library library, - FT_UInt hook_index, - FT_DebugHook_Func debug_hook ) - { - if ( library && debug_hook && - hook_index < - ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) ) - library->debug_hooks[hook_index] = debug_hook; - } - - - /* documentation is in ftmodapi.h */ - - FT_EXPORT_DEF( FT_TrueTypeEngineType ) - FT_Get_TrueType_Engine_Type( FT_Library library ) - { - FT_TrueTypeEngineType result = FT_TRUETYPE_ENGINE_TYPE_NONE; - - - if ( library ) - { - FT_Module module = FT_Get_Module( library, "truetype" ); - - - if ( module ) - { - FT_Service_TrueTypeEngine service; - - - service = (FT_Service_TrueTypeEngine) - ft_module_get_service( module, - FT_SERVICE_ID_TRUETYPE_ENGINE ); - if ( service ) - result = service->engine_type; - } - } - - return result; - } - - -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - - FT_BASE_DEF( FT_Error ) - ft_stub_set_char_sizes( FT_Size size, - FT_F26Dot6 width, - FT_F26Dot6 height, - FT_UInt horz_res, - FT_UInt vert_res ) - { - FT_Size_RequestRec req; - FT_Driver driver = size->face->driver; - - - if ( driver->clazz->request_size ) - { - req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; - req.width = width; - req.height = height; - - if ( horz_res == 0 ) - horz_res = vert_res; - - if ( vert_res == 0 ) - vert_res = horz_res; - - if ( horz_res == 0 ) - horz_res = vert_res = 72; - - req.horiResolution = horz_res; - req.vertResolution = vert_res; - - return driver->clazz->request_size( size, &req ); - } - - return 0; - } - - - FT_BASE_DEF( FT_Error ) - ft_stub_set_pixel_sizes( FT_Size size, - FT_UInt width, - FT_UInt height ) - { - FT_Size_RequestRec req; - FT_Driver driver = size->face->driver; - - - if ( driver->clazz->request_size ) - { - req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; - req.width = width << 6; - req.height = height << 6; - req.horiResolution = 0; - req.vertResolution = 0; - - return driver->clazz->request_size( size, &req ); - } - - return 0; - } - -#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ - - - FT_EXPORT_DEF( FT_Error ) - FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, - FT_UInt sub_index, - FT_Int *p_index, - FT_UInt *p_flags, - FT_Int *p_arg1, - FT_Int *p_arg2, - FT_Matrix *p_transform ) - { - FT_Error error = FT_Err_Invalid_Argument; - - - if ( glyph != NULL && - glyph->format == FT_GLYPH_FORMAT_COMPOSITE && - sub_index < glyph->num_subglyphs ) - { - FT_SubGlyph subg = glyph->subglyphs + sub_index; - - - *p_index = subg->index; - *p_flags = subg->flags; - *p_arg1 = subg->arg1; - *p_arg2 = subg->arg2; - *p_transform = subg->transform; - } - - return error; - } - - -/* END */ diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c deleted file mode 100644 index 2bae857..0000000 --- a/src/base/ftoutln.c +++ /dev/null @@ -1,1090 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoutln.c */ -/* */ -/* FreeType outline management (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - - /*************************************************************************/ - /* */ - /* All functions are declared in freetype.h. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_OUTLINE_H -#include FT_INTERNAL_OBJECTS_H -#include FT_TRIGONOMETRY_H - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_outline - - - static - const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 }; - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Decompose( FT_Outline* outline, - const FT_Outline_Funcs* func_interface, - void* user ) - { -#undef SCALED -#define SCALED( x ) ( ( (x) << shift ) - delta ) - - FT_Vector v_last; - FT_Vector v_control; - FT_Vector v_start; - - FT_Vector* point; - FT_Vector* limit; - char* tags; - - FT_Error error; - - FT_Int n; /* index of contour in outline */ - FT_UInt first; /* index of first point in contour */ - FT_Int tag; /* current point's state */ - - FT_Int shift; - FT_Pos delta; - - - if ( !outline || !func_interface ) - return FT_Err_Invalid_Argument; - - shift = func_interface->shift; - delta = func_interface->delta; - first = 0; - - for ( n = 0; n < outline->n_contours; n++ ) - { - FT_Int last; /* index of last point in contour */ - - - last = outline->contours[n]; - if ( last < 0 ) - goto Invalid_Outline; - limit = outline->points + last; - - v_start = outline->points[first]; - v_last = outline->points[last]; - - v_start.x = SCALED( v_start.x ); v_start.y = SCALED( v_start.y ); - v_last.x = SCALED( v_last.x ); v_last.y = SCALED( v_last.y ); - - v_control = v_start; - - point = outline->points + first; - tags = outline->tags + first; - tag = FT_CURVE_TAG( tags[0] ); - - /* A contour cannot start with a cubic control point! */ - if ( tag == FT_CURVE_TAG_CUBIC ) - goto Invalid_Outline; - - /* check first point to determine origin */ - if ( tag == FT_CURVE_TAG_CONIC ) - { - /* first point is conic control. Yes, this happens. */ - if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) - { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } - else - { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ - v_start.x = ( v_start.x + v_last.x ) / 2; - v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; - } - point--; - tags--; - } - - error = func_interface->move_to( &v_start, user ); - if ( error ) - goto Exit; - - while ( point < limit ) - { - point++; - tags++; - - tag = FT_CURVE_TAG( tags[0] ); - switch ( tag ) - { - case FT_CURVE_TAG_ON: /* emit a single line_to */ - { - FT_Vector vec; - - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - error = func_interface->line_to( &vec, user ); - if ( error ) - goto Exit; - continue; - } - - case FT_CURVE_TAG_CONIC: /* consume conic arcs */ - v_control.x = SCALED( point->x ); - v_control.y = SCALED( point->y ); - - Do_Conic: - if ( point < limit ) - { - FT_Vector vec; - FT_Vector v_middle; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - if ( tag == FT_CURVE_TAG_ON ) - { - error = func_interface->conic_to( &v_control, &vec, user ); - if ( error ) - goto Exit; - continue; - } - - if ( tag != FT_CURVE_TAG_CONIC ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + vec.x ) / 2; - v_middle.y = ( v_control.y + vec.y ) / 2; - - error = func_interface->conic_to( &v_control, &v_middle, user ); - if ( error ) - goto Exit; - - v_control = vec; - goto Do_Conic; - } - - error = func_interface->conic_to( &v_control, &v_start, user ); - goto Close; - - default: /* FT_CURVE_TAG_CUBIC */ - { - FT_Vector vec1, vec2; - - - if ( point + 1 > limit || - FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) - goto Invalid_Outline; - - point += 2; - tags += 2; - - vec1.x = SCALED( point[-2].x ); vec1.y = SCALED( point[-2].y ); - vec2.x = SCALED( point[-1].x ); vec2.y = SCALED( point[-1].y ); - - if ( point <= limit ) - { - FT_Vector vec; - - - vec.x = SCALED( point->x ); - vec.y = SCALED( point->y ); - - error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); - if ( error ) - goto Exit; - continue; - } - - error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); - goto Close; - } - } - } - - /* close the contour with a line segment */ - error = func_interface->line_to( &v_start, user ); - - Close: - if ( error ) - goto Exit; - - first = last + 1; - } - - return 0; - - Exit: - return error; - - Invalid_Outline: - return FT_Err_Invalid_Outline; - } - - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_New_Internal( FT_Memory memory, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline *anoutline ) - { - FT_Error error; - - - if ( !anoutline || !memory ) - return FT_Err_Invalid_Argument; - - *anoutline = null_outline; - - if ( FT_NEW_ARRAY( anoutline->points, numPoints * 2L ) || - FT_NEW_ARRAY( anoutline->tags, numPoints ) || - FT_NEW_ARRAY( anoutline->contours, numContours ) ) - goto Fail; - - anoutline->n_points = (FT_UShort)numPoints; - anoutline->n_contours = (FT_Short)numContours; - anoutline->flags |= FT_OUTLINE_OWNER; - - return FT_Err_Ok; - - Fail: - anoutline->flags |= FT_OUTLINE_OWNER; - FT_Outline_Done_Internal( memory, anoutline ); - - return error; - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_New( FT_Library library, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline *anoutline ) - { - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - return FT_Outline_New_Internal( library->memory, numPoints, - numContours, anoutline ); - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Check( FT_Outline* outline ) - { - if ( outline ) - { - FT_Int n_points = outline->n_points; - FT_Int n_contours = outline->n_contours; - FT_Int end0, end; - FT_Int n; - - - /* empty glyph? */ - if ( n_points == 0 && n_contours == 0 ) - return 0; - - /* check point and contour counts */ - if ( n_points <= 0 || n_contours <= 0 ) - goto Bad; - - end0 = end = -1; - for ( n = 0; n < n_contours; n++ ) - { - end = outline->contours[n]; - - /* note that we don't accept empty contours */ - if ( end <= end0 || end >= n_points ) - goto Bad; - - end0 = end; - } - - if ( end != n_points - 1 ) - goto Bad; - - /* XXX: check the tags array */ - return 0; - } - - Bad: - return FT_Err_Invalid_Argument; - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Copy( const FT_Outline* source, - FT_Outline *target ) - { - FT_Int is_owner; - - - if ( !source || !target || - source->n_points != target->n_points || - source->n_contours != target->n_contours ) - return FT_Err_Invalid_Argument; - - if ( source == target ) - return FT_Err_Ok; - - FT_ARRAY_COPY( target->points, source->points, source->n_points ); - - FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); - - FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); - - /* copy all flags, except the `FT_OUTLINE_OWNER' one */ - is_owner = target->flags & FT_OUTLINE_OWNER; - target->flags = source->flags; - - target->flags &= ~FT_OUTLINE_OWNER; - target->flags |= is_owner; - - return FT_Err_Ok; - } - - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Done_Internal( FT_Memory memory, - FT_Outline* outline ) - { - if ( memory && outline ) - { - if ( outline->flags & FT_OUTLINE_OWNER ) - { - FT_FREE( outline->points ); - FT_FREE( outline->tags ); - FT_FREE( outline->contours ); - } - *outline = null_outline; - - return FT_Err_Ok; - } - else - return FT_Err_Invalid_Argument; - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Done( FT_Library library, - FT_Outline* outline ) - { - /* check for valid `outline' in FT_Outline_Done_Internal() */ - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - return FT_Outline_Done_Internal( library->memory, outline ); - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( void ) - FT_Outline_Get_CBox( const FT_Outline* outline, - FT_BBox *acbox ) - { - FT_Pos xMin, yMin, xMax, yMax; - - - if ( outline && acbox ) - { - if ( outline->n_points == 0 ) - { - xMin = 0; - yMin = 0; - xMax = 0; - yMax = 0; - } - else - { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; - - - xMin = xMax = vec->x; - yMin = yMax = vec->y; - vec++; - - for ( ; vec < limit; vec++ ) - { - FT_Pos x, y; - - - x = vec->x; - if ( x < xMin ) xMin = x; - if ( x > xMax ) xMax = x; - - y = vec->y; - if ( y < yMin ) yMin = y; - if ( y > yMax ) yMax = y; - } - } - acbox->xMin = xMin; - acbox->xMax = xMax; - acbox->yMin = yMin; - acbox->yMax = yMax; - } - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( void ) - FT_Outline_Translate( const FT_Outline* outline, - FT_Pos xOffset, - FT_Pos yOffset ) - { - FT_UShort n; - FT_Vector* vec; - - - if ( !outline ) - return; - - vec = outline->points; - - for ( n = 0; n < outline->n_points; n++ ) - { - vec->x += xOffset; - vec->y += yOffset; - vec++; - } - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( void ) - FT_Outline_Reverse( FT_Outline* outline ) - { - FT_UShort n; - FT_Int first, last; - - - if ( !outline ) - return; - - first = 0; - - for ( n = 0; n < outline->n_contours; n++ ) - { - last = outline->contours[n]; - - /* reverse point table */ - { - FT_Vector* p = outline->points + first; - FT_Vector* q = outline->points + last; - FT_Vector swap; - - - while ( p < q ) - { - swap = *p; - *p = *q; - *q = swap; - p++; - q--; - } - } - - /* reverse tags table */ - { - char* p = outline->tags + first; - char* q = outline->tags + last; - char swap; - - - while ( p < q ) - { - swap = *p; - *p = *q; - *q = swap; - p++; - q--; - } - } - - first = last + 1; - } - - outline->flags ^= FT_OUTLINE_REVERSE_FILL; - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Render( FT_Library library, - FT_Outline* outline, - FT_Raster_Params* params ) - { - FT_Error error; - FT_Bool update = 0; - FT_Renderer renderer; - FT_ListNode node; - - - if ( !library ) - return FT_Err_Invalid_Library_Handle; - - if ( !outline || !params ) - return FT_Err_Invalid_Argument; - - renderer = library->cur_renderer; - node = library->renderers.head; - - params->source = (void*)outline; - - error = FT_Err_Cannot_Render_Glyph; - while ( renderer ) - { - error = renderer->raster_render( renderer->raster, params ); - if ( !error || FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph ) - break; - - /* FT_Err_Cannot_Render_Glyph is returned if the render mode */ - /* is unsupported by the current renderer for this glyph image */ - /* format */ - - /* now, look for another renderer that supports the same */ - /* format */ - renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, - &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 ); - - return error; - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Get_Bitmap( FT_Library library, - FT_Outline* outline, - const FT_Bitmap *abitmap ) - { - FT_Raster_Params params; - - - if ( !abitmap ) - return FT_Err_Invalid_Argument; - - /* other checks are delayed to FT_Outline_Render() */ - - params.target = abitmap; - params.flags = 0; - - if ( abitmap->pixel_mode == FT_PIXEL_MODE_GRAY || - abitmap->pixel_mode == FT_PIXEL_MODE_LCD || - abitmap->pixel_mode == FT_PIXEL_MODE_LCD_V ) - params.flags |= FT_RASTER_FLAG_AA; - - return FT_Outline_Render( library, outline, ¶ms ); - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( void ) - FT_Vector_Transform( FT_Vector* vector, - const FT_Matrix* matrix ) - { - FT_Pos xz, yz; - - - if ( !vector || !matrix ) - return; - - xz = FT_MulFix( vector->x, matrix->xx ) + - FT_MulFix( vector->y, matrix->xy ); - - yz = FT_MulFix( vector->x, matrix->yx ) + - FT_MulFix( vector->y, matrix->yy ); - - vector->x = xz; - vector->y = yz; - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( void ) - FT_Outline_Transform( const FT_Outline* outline, - const FT_Matrix* matrix ) - { - FT_Vector* vec; - FT_Vector* limit; - - - if ( !outline || !matrix ) - return; - - vec = outline->points; - limit = vec + outline->n_points; - - for ( ; vec < limit; vec++ ) - FT_Vector_Transform( vec, matrix ); - } - - -#if 0 - -#define FT_OUTLINE_GET_CONTOUR( outline, c, first, last ) \ - do { \ - (first) = ( c > 0 ) ? (outline)->points + \ - (outline)->contours[c - 1] + 1 \ - : (outline)->points; \ - (last) = (outline)->points + (outline)->contours[c]; \ - } while ( 0 ) - - - /* Is a point in some contour? */ - /* */ - /* We treat every point of the contour as if it */ - /* it were ON. That is, we allow false positives, */ - /* but disallow false negatives. (XXX really?) */ - static FT_Bool - ft_contour_has( FT_Outline* outline, - FT_Short c, - FT_Vector* point ) - { - FT_Vector* first; - FT_Vector* last; - FT_Vector* a; - FT_Vector* b; - FT_UInt n = 0; - - - FT_OUTLINE_GET_CONTOUR( outline, c, first, last ); - - for ( a = first; a <= last; a++ ) - { - FT_Pos x; - FT_Int intersect; - - - b = ( a == last ) ? first : a + 1; - - intersect = ( a->y - point->y ) ^ ( b->y - point->y ); - - /* a and b are on the same side */ - if ( intersect >= 0 ) - { - if ( intersect == 0 && a->y == point->y ) - { - if ( ( a->x <= point->x && b->x >= point->x ) || - ( a->x >= point->x && b->x <= point->x ) ) - return 1; - } - - continue; - } - - x = a->x + ( b->x - a->x ) * (point->y - a->y ) / ( b->y - a->y ); - - if ( x < point->x ) - n++; - else if ( x == point->x ) - return 1; - } - - return ( n % 2 ); - } - - - static FT_Bool - ft_contour_enclosed( FT_Outline* outline, - FT_UShort c ) - { - FT_Vector* first; - FT_Vector* last; - FT_Short i; - - - FT_OUTLINE_GET_CONTOUR( outline, c, first, last ); - - for ( i = 0; i < outline->n_contours; i++ ) - { - if ( i != c && ft_contour_has( outline, i, first ) ) - { - FT_Vector* pt; - - - for ( pt = first + 1; pt <= last; pt++ ) - if ( !ft_contour_has( outline, i, pt ) ) - return 0; - - return 1; - } - } - - return 0; - } - - - /* This version differs from the public one in that each */ - /* part (contour not enclosed in another contour) of the */ - /* outline is checked for orientation. This is */ - /* necessary for some buggy CJK fonts. */ - static FT_Orientation - ft_outline_get_orientation( FT_Outline* outline ) - { - FT_Short i; - FT_Vector* first; - FT_Vector* last; - FT_Orientation orient = FT_ORIENTATION_NONE; - - - first = outline->points; - for ( i = 0; i < outline->n_contours; i++, first = last + 1 ) - { - FT_Vector* point; - FT_Vector* xmin_point; - FT_Pos xmin; - - - last = outline->points + outline->contours[i]; - - /* skip degenerate contours */ - if ( last < first + 2 ) - continue; - - if ( ft_contour_enclosed( outline, i ) ) - continue; - - xmin = first->x; - xmin_point = first; - - for ( point = first + 1; point <= last; point++ ) - { - if ( point->x < xmin ) - { - xmin = point->x; - xmin_point = point; - } - } - - /* check the orientation of the contour */ - { - FT_Vector* prev; - FT_Vector* next; - FT_Orientation o; - - - prev = ( xmin_point == first ) ? last : xmin_point - 1; - next = ( xmin_point == last ) ? first : xmin_point + 1; - - if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) > - FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) ) - o = FT_ORIENTATION_POSTSCRIPT; - else - o = FT_ORIENTATION_TRUETYPE; - - if ( orient == FT_ORIENTATION_NONE ) - orient = o; - else if ( orient != o ) - return FT_ORIENTATION_NONE; - } - } - - return orient; - } - -#endif /* 0 */ - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Outline_Embolden( FT_Outline* outline, - FT_Pos strength ) - { - FT_Vector* points; - FT_Vector v_prev, v_first, v_next, v_cur; - FT_Angle rotate, angle_in, angle_out; - FT_Int c, n, first; - FT_Int orientation; - - - if ( !outline ) - return FT_Err_Invalid_Argument; - - strength /= 2; - if ( strength == 0 ) - return FT_Err_Ok; - - orientation = FT_Outline_Get_Orientation( outline ); - if ( orientation == FT_ORIENTATION_NONE ) - { - if ( outline->n_contours ) - return FT_Err_Invalid_Argument; - else - return FT_Err_Ok; - } - - if ( orientation == FT_ORIENTATION_TRUETYPE ) - rotate = -FT_ANGLE_PI2; - else - rotate = FT_ANGLE_PI2; - - points = outline->points; - - first = 0; - for ( c = 0; c < outline->n_contours; c++ ) - { - int last = outline->contours[c]; - - - v_first = points[first]; - v_prev = points[last]; - v_cur = v_first; - - for ( n = first; n <= last; n++ ) - { - FT_Vector in, out; - FT_Angle angle_diff; - FT_Pos d; - FT_Fixed scale; - - - if ( n < last ) - v_next = points[n + 1]; - else - v_next = v_first; - - /* compute the in and out vectors */ - in.x = v_cur.x - v_prev.x; - in.y = v_cur.y - v_prev.y; - - out.x = v_next.x - v_cur.x; - out.y = v_next.y - v_cur.y; - - angle_in = FT_Atan2( in.x, in.y ); - angle_out = FT_Atan2( out.x, out.y ); - angle_diff = FT_Angle_Diff( angle_in, angle_out ); - scale = FT_Cos( angle_diff / 2 ); - - if ( scale < 0x4000L && scale > -0x4000L ) - in.x = in.y = 0; - else - { - d = FT_DivFix( strength, scale ); - - FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate ); - } - - outline->points[n].x = v_cur.x + strength + in.x; - outline->points[n].y = v_cur.y + strength + in.y; - - v_prev = v_cur; - v_cur = v_next; - } - - first = last + 1; - } - - return FT_Err_Ok; - } - - - /* documentation is in ftoutln.h */ - - FT_EXPORT_DEF( FT_Orientation ) - FT_Outline_Get_Orientation( FT_Outline* outline ) - { - FT_Pos xmin = 32768L; - FT_Pos xmin_ymin = 32768L; - FT_Pos xmin_ymax = -32768L; - FT_Vector* xmin_first = NULL; - FT_Vector* xmin_last = NULL; - - short* contour; - - FT_Vector* first; - FT_Vector* last; - FT_Vector* prev; - FT_Vector* point; - - int i; - FT_Pos ray_y[3]; - FT_Orientation result[3]; - - - if ( !outline || outline->n_points <= 0 ) - return FT_ORIENTATION_TRUETYPE; - - /* We use the nonzero winding rule to find the orientation. */ - /* Since glyph outlines behave much more `regular' than arbitrary */ - /* cubic or quadratic curves, this test deals with the polygon */ - /* only which is spanned up by the control points. */ - - first = outline->points; - for ( contour = outline->contours; - contour < outline->contours + outline->n_contours; - contour++, first = last + 1 ) - { - FT_Pos contour_xmin = 32768L; - FT_Pos contour_xmax = -32768L; - FT_Pos contour_ymin = 32768L; - FT_Pos contour_ymax = -32768L; - - - last = outline->points + *contour; - - /* skip degenerate contours */ - if ( last < first + 2 ) - continue; - - for ( point = first; point <= last; ++point ) - { - if ( point->x < contour_xmin ) - contour_xmin = point->x; - - if ( point->x > contour_xmax ) - contour_xmax = point->x; - - if ( point->y < contour_ymin ) - contour_ymin = point->y; - - if ( point->y > contour_ymax ) - contour_ymax = point->y; - } - - if ( contour_xmin < xmin && - contour_xmin != contour_xmax && - contour_ymin != contour_ymax ) - { - xmin = contour_xmin; - xmin_ymin = contour_ymin; - xmin_ymax = contour_ymax; - xmin_first = first; - xmin_last = last; - } - } - - if ( xmin == 32768 ) - return FT_ORIENTATION_TRUETYPE; - - ray_y[0] = ( xmin_ymin * 3 + xmin_ymax ) >> 2; - ray_y[1] = ( xmin_ymin + xmin_ymax ) >> 1; - ray_y[2] = ( xmin_ymin + xmin_ymax * 3 ) >> 2; - - for ( i = 0; i < 3; i++ ) - { - FT_Pos left_x; - FT_Pos right_x; - FT_Vector* left1; - FT_Vector* left2; - FT_Vector* right1; - FT_Vector* right2; - - - RedoRay: - left_x = 32768L; - right_x = -32768L; - - left1 = left2 = right1 = right2 = NULL; - - prev = xmin_last; - for ( point = xmin_first; point <= xmin_last; prev = point, ++point ) - { - FT_Pos tmp_x; - - - if ( point->y == ray_y[i] || prev->y == ray_y[i] ) - { - ray_y[i]++; - goto RedoRay; - } - - if ( ( point->y < ray_y[i] && prev->y < ray_y[i] ) || - ( point->y > ray_y[i] && prev->y > ray_y[i] ) ) - continue; - - tmp_x = FT_MulDiv( point->x - prev->x, - ray_y[i] - prev->y, - point->y - prev->y ) + prev->x; - - if ( tmp_x < left_x ) - { - left_x = tmp_x; - left1 = prev; - left2 = point; - } - - if ( tmp_x > right_x ) - { - right_x = tmp_x; - right1 = prev; - right2 = point; - } - } - - if ( left1 && right1 ) - { - if ( left1->y < left2->y && right1->y > right2->y ) - result[i] = FT_ORIENTATION_TRUETYPE; - else if ( left1->y > left2->y && right1->y < right2->y ) - result[i] = FT_ORIENTATION_POSTSCRIPT; - else - result[i] = FT_ORIENTATION_NONE; - } - } - - if ( result[0] != FT_ORIENTATION_NONE && - ( result[0] == result[1] || result[0] == result[2] ) ) - return result[0]; - - if ( result[1] != FT_ORIENTATION_NONE && result[1] == result[2] ) - return result[1]; - - return FT_ORIENTATION_TRUETYPE; - } - - -/* END */ diff --git a/src/base/ftpatent.c b/src/base/ftpatent.c deleted file mode 100644 index d63f191..0000000 --- a/src/base/ftpatent.c +++ /dev/null @@ -1,281 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftpatent.c */ -/* */ -/* FreeType API for checking patented TrueType bytecode instructions */ -/* (body). */ -/* */ -/* Copyright 2007 by David Turner. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_TRUETYPE_TAGS_H -#include FT_INTERNAL_OBJECTS_H -#include FT_INTERNAL_STREAM_H -#include FT_SERVICE_SFNT_H -#include FT_SERVICE_TRUETYPE_GLYF_H - - - static FT_Bool - _tt_check_patents_in_range( FT_Stream stream, - FT_ULong size ) - { - FT_Bool result = FALSE; - FT_Error error; - FT_Bytes p, end; - - - if ( FT_FRAME_ENTER( size ) ) - return 0; - - p = stream->cursor; - end = p + size; - - while ( p < end ) - { - switch (p[0]) - { - case 0x06: /* SPvTL // */ - case 0x07: /* SPvTL + */ - case 0x08: /* SFvTL // */ - case 0x09: /* SFvTL + */ - case 0x0A: /* SPvFS */ - case 0x0B: /* SFvFS */ - result = TRUE; - goto Exit; - - case 0x40: - if ( p + 1 >= end ) - goto Exit; - - p += p[1] + 2; - break; - - case 0x41: - if ( p + 1 >= end ) - goto Exit; - - p += p[1] * 2 + 2; - break; - - case 0x71: /* DELTAP2 */ - case 0x72: /* DELTAP3 */ - case 0x73: /* DELTAC0 */ - case 0x74: /* DELTAC1 */ - case 0x75: /* DELTAC2 */ - result = TRUE; - goto Exit; - - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - p += ( p[0] - 0xB0 ) + 2; - break; - - case 0xB8: - case 0xB9: - case 0xBA: - case 0xBB: - case 0xBC: - case 0xBD: - case 0xBE: - case 0xBF: - p += ( p[0] - 0xB8 ) * 2 + 3; - break; - - default: - p += 1; - break; - } - } - - Exit: - FT_FRAME_EXIT(); - return result; - } - - - static FT_Bool - _tt_check_patents_in_table( FT_Face face, - FT_ULong tag ) - { - FT_Stream stream = face->stream; - FT_Error error; - FT_Service_SFNT_Table service; - FT_Bool result = FALSE; - - - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - - if ( service ) - { - FT_ULong offset, size; - - - error = service->table_info( face, tag, &offset, &size ); - if ( error || - FT_STREAM_SEEK( offset ) ) - goto Exit; - - result = _tt_check_patents_in_range( stream, size ); - } - - Exit: - return result; - } - - - static FT_Bool - _tt_face_check_patents( FT_Face face ) - { - FT_Stream stream = face->stream; - FT_UInt gindex; - FT_Error error; - FT_Bool result; - - FT_Service_TTGlyf service; - - - result = _tt_check_patents_in_table( face, TTAG_fpgm ); - if ( result ) - goto Exit; - - result = _tt_check_patents_in_table( face, TTAG_prep ); - if ( result ) - goto Exit; - - FT_FACE_FIND_SERVICE( face, service, TT_GLYF ); - if ( service == NULL ) - goto Exit; - - for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ ) - { - FT_ULong offset, num_ins, size; - FT_Int num_contours; - - - offset = service->get_location( face, gindex, &size ); - if ( size == 0 ) - continue; - - if ( FT_STREAM_SEEK( offset ) || - FT_READ_SHORT( num_contours ) ) - continue; - - if ( num_contours >= 0 ) /* simple glyph */ - { - if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) ) - continue; - } - else /* compound glyph */ - { - FT_Bool has_instr = 0; - - - if ( FT_STREAM_SKIP( 8 ) ) - continue; - - /* now read each component */ - for (;;) - { - FT_UInt flags, toskip; - - - if( FT_READ_USHORT( flags ) ) - break; - - toskip = 2 + 1 + 1; - - if ( ( flags & ( 1 << 0 ) ) != 0 ) /* ARGS_ARE_WORDS */ - toskip += 2; - - if ( ( flags & ( 1 << 3 ) ) != 0 ) /* WE_HAVE_A_SCALE */ - toskip += 2; - else if ( ( flags & ( 1 << 6 ) ) != 0 ) /* WE_HAVE_X_Y_SCALE */ - toskip += 4; - else if ( ( flags & ( 1 << 7 ) ) != 0 ) /* WE_HAVE_A_2x2 */ - toskip += 8; - - if ( ( flags & ( 1 << 8 ) ) != 0 ) /* WE_HAVE_INSTRUCTIONS */ - has_instr = 1; - - if ( FT_STREAM_SKIP( toskip ) ) - goto NextGlyph; - - if ( ( flags & ( 1 << 5 ) ) == 0 ) /* MORE_COMPONENTS */ - break; - } - - if ( !has_instr ) - goto NextGlyph; - } - - if ( FT_READ_USHORT( num_ins ) ) - continue; - - result = _tt_check_patents_in_range( stream, num_ins ); - if ( result ) - goto Exit; - - NextGlyph: - ; - } - - Exit: - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Bool ) - FT_Face_CheckTrueTypePatents( FT_Face face ) - { - FT_Bool result = FALSE; - - - if ( face && FT_IS_SFNT( face ) ) - result = _tt_face_check_patents( face ); - - return result; - } - - - /* documentation is in freetype.h */ - - FT_EXPORT_DEF( FT_Bool ) - FT_Face_SetUnpatentedHinting( FT_Face face, - FT_Bool value ) - { - FT_Bool result = 0; - - -#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ - !defined( TT_CONFIG_OPTION_BYTECODE_INTEPRETER ) - if ( face && FT_IS_SFNT( face ) ) - { - result = !face->internal->ignore_unpatented_hinter; - face->internal->ignore_unpatented_hinter = !value; - } -#else - FT_UNUSED( face ); - FT_UNUSED( value ); -#endif - - return result; - } - -/* END */ diff --git a/src/base/ftrfork.c b/src/base/ftrfork.c deleted file mode 100644 index 5a835ee..0000000 --- a/src/base/ftrfork.c +++ /dev/null @@ -1,811 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftrfork.c */ -/* */ -/* Embedded resource forks accessor (body). */ -/* */ -/* Copyright 2004, 2005, 2006, 2007 by */ -/* Masatake YAMATO and Redhat K.K. */ -/* */ -/* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ -/* derived from ftobjs.c. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - -/***************************************************************************/ -/* Development of the code in this file is support of */ -/* Information-technology Promotion Agency, Japan. */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_RFORK_H - - -#undef FT_COMPONENT -#define FT_COMPONENT trace_raccess - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** Resource fork directory access ****/ - /**** ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - FT_BASE_DEF( FT_Error ) - FT_Raccess_Get_HeaderInfo( FT_Library library, - FT_Stream stream, - FT_Long rfork_offset, - FT_Long *map_offset, - FT_Long *rdata_pos ) - { - FT_Error error; - unsigned char head[16], head2[16]; - FT_Long map_pos, rdata_len; - int allzeros, allmatch, i; - FT_Long type_list; - - FT_UNUSED( library ); - - - error = FT_Stream_Seek( stream, rfork_offset ); - if ( error ) - return error; - - error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); - if ( error ) - return error; - - *rdata_pos = rfork_offset + ( ( head[0] << 24 ) | - ( head[1] << 16 ) | - ( head[2] << 8 ) | - head[3] ); - map_pos = rfork_offset + ( ( head[4] << 24 ) | - ( head[5] << 16 ) | - ( head[6] << 8 ) | - head[7] ); - rdata_len = ( head[ 8] << 24 ) | - ( head[ 9] << 16 ) | - ( head[10] << 8 ) | - head[11]; - - /* map_len = head[12] .. head[15] */ - - if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset ) - return FT_Err_Unknown_File_Format; - - error = FT_Stream_Seek( stream, map_pos ); - if ( error ) - return error; - - head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */ - - error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 ); - if ( error ) - return error; - - allzeros = 1; - allmatch = 1; - for ( i = 0; i < 16; ++i ) - { - if ( head2[i] != 0 ) - allzeros = 0; - if ( head2[i] != head[i] ) - allmatch = 0; - } - if ( !allzeros && !allmatch ) - return FT_Err_Unknown_File_Format; - - /* If we have reached this point then it is probably a mac resource */ - /* file. Now, does it contain any interesting resources? */ - /* Skip handle to next resource map, the file resource number, and */ - /* attributes. */ - (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */ - + 2 /* skip file resource number */ - + 2 ); /* skip attributes */ - - if ( FT_READ_USHORT( type_list ) ) - return error; - if ( type_list == -1 ) - return FT_Err_Unknown_File_Format; - - error = FT_Stream_Seek( stream, map_pos + type_list ); - if ( error ) - return error; - - *map_offset = map_pos + type_list; - return FT_Err_Ok; - } - - - static int - ft_raccess_sort_ref_by_id( FT_RFork_Ref* a, - FT_RFork_Ref* b ) - { - if ( a->res_id < b->res_id ) - return -1; - else if ( a->res_id > b->res_id ) - return 1; - else - return 0; - } - - - FT_BASE_DEF( FT_Error ) - FT_Raccess_Get_DataOffsets( FT_Library library, - FT_Stream stream, - FT_Long map_offset, - FT_Long rdata_pos, - FT_Long tag, - FT_Long **offsets, - FT_Long *count ) - { - FT_Error error; - int i, j, cnt, subcnt; - FT_Long tag_internal, rpos; - FT_Memory memory = library->memory; - FT_Long temp; - FT_Long *offsets_internal; - FT_RFork_Ref *ref; - - - error = FT_Stream_Seek( stream, map_offset ); - if ( error ) - return error; - - if ( FT_READ_USHORT( cnt ) ) - return error; - cnt++; - - for ( i = 0; i < cnt; ++i ) - { - if ( FT_READ_LONG( tag_internal ) || - FT_READ_USHORT( subcnt ) || - FT_READ_USHORT( rpos ) ) - return error; - - FT_TRACE2(( "Resource tags: %c%c%c%c\n", - (char)( 0xff & ( tag_internal >> 24 ) ), - (char)( 0xff & ( tag_internal >> 16 ) ), - (char)( 0xff & ( tag_internal >> 8 ) ), - (char)( 0xff & ( tag_internal >> 0 ) ) )); - - if ( tag_internal == tag ) - { - *count = subcnt + 1; - rpos += map_offset; - - error = FT_Stream_Seek( stream, rpos ); - if ( error ) - return error; - - if ( FT_NEW_ARRAY( ref, *count ) ) - return error; - - for ( j = 0; j < *count; ++j ) - { - if ( FT_READ_USHORT( ref[j].res_id ) ) - goto Exit; - if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ - goto Exit; - if ( FT_READ_LONG( temp ) ) - goto Exit; - if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ - goto Exit; - - ref[j].offset = temp & 0xFFFFFFL; - } - - ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), - ( int(*)(const void*, const void*) ) - ft_raccess_sort_ref_by_id ); - - if ( FT_NEW_ARRAY( offsets_internal, *count ) ) - goto Exit; - - /* XXX: duplicated reference ID, - * gap between reference IDs are acceptable? - * further investigation on Apple implementation is needed. - */ - for ( j = 0; j < *count; ++j ) - offsets_internal[j] = rdata_pos + ref[j].offset; - - *offsets = offsets_internal; - error = FT_Err_Ok; - - Exit: - FT_FREE( ref ); - return error; - } - } - - return FT_Err_Cannot_Open_Resource; - } - - -#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** ****/ - /**** Guessing functions ****/ - /**** ****/ - /**** When you add a new guessing function, ****/ - /**** update FT_RACCESS_N_RULES in ftrfork.h. ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - typedef FT_Error - (*raccess_guess_func)( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - - static FT_Error - raccess_guess_apple_double( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_apple_single( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_darwin_ufs_export( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_darwin_newvfs( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_darwin_hfsplus( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_vfat( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_linux_cap( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_linux_double( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_linux_netatalk( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ); - - - /*************************************************************************/ - /**** ****/ - /**** Helper functions ****/ - /**** ****/ - /*************************************************************************/ - - static FT_Error - raccess_guess_apple_generic( FT_Library library, - FT_Stream stream, - char *base_file_name, - FT_Int32 magic, - FT_Long *result_offset ); - - static FT_Error - raccess_guess_linux_double_from_file_name( FT_Library library, - char * file_name, - FT_Long *result_offset ); - - static char * - raccess_make_file_name( FT_Memory memory, - const char *original_name, - const char *insertion ); - - - FT_BASE_DEF( void ) - FT_Raccess_Guess( FT_Library library, - FT_Stream stream, - char* base_name, - char **new_names, - FT_Long *offsets, - FT_Error *errors ) - { - FT_Long i; - - - raccess_guess_func funcs[FT_RACCESS_N_RULES] = - { - raccess_guess_apple_double, - raccess_guess_apple_single, - raccess_guess_darwin_ufs_export, - raccess_guess_darwin_newvfs, - raccess_guess_darwin_hfsplus, - raccess_guess_vfat, - raccess_guess_linux_cap, - raccess_guess_linux_double, - raccess_guess_linux_netatalk, - }; - - for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) - { - new_names[i] = NULL; - if ( NULL != stream ) - errors[i] = FT_Stream_Seek( stream, 0 ); - else - errors[i] = FT_Err_Ok; - - if ( errors[i] ) - continue ; - - errors[i] = (funcs[i])( library, stream, base_name, - &(new_names[i]), &(offsets[i]) ); - } - - return; - } - - - static FT_Error - raccess_guess_apple_double( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - FT_Int32 magic = ( 0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x07 ); - - - *result_file_name = NULL; - if ( NULL == stream ) - return FT_Err_Cannot_Open_Stream; - - return raccess_guess_apple_generic( library, stream, base_file_name, - magic, result_offset ); - } - - - static FT_Error - raccess_guess_apple_single( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - FT_Int32 magic = (0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x00); - - - *result_file_name = NULL; - if ( NULL == stream ) - return FT_Err_Cannot_Open_Stream; - - return raccess_guess_apple_generic( library, stream, base_file_name, - magic, result_offset ); - } - - - static FT_Error - raccess_guess_darwin_ufs_export( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - char* newpath; - FT_Error error; - FT_Memory memory; - - FT_UNUSED( stream ); - - - memory = library->memory; - newpath = raccess_make_file_name( memory, base_file_name, "._" ); - if ( !newpath ) - return FT_Err_Out_Of_Memory; - - error = raccess_guess_linux_double_from_file_name( library, newpath, - result_offset ); - if ( !error ) - *result_file_name = newpath; - else - FT_FREE( newpath ); - - return error; - } - - - static FT_Error - raccess_guess_darwin_hfsplus( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - /* - Only meaningful on systems with hfs+ drivers (or Macs). - */ - FT_Error error; - char* newpath; - FT_Memory memory; - FT_Long base_file_len = ft_strlen( base_file_name ); - - FT_UNUSED( stream ); - - - memory = library->memory; - - if ( base_file_len + 6 > FT_INT_MAX ) - return FT_Err_Array_Too_Large; - - if ( FT_ALLOC( newpath, base_file_len + 6 ) ) - return error; - - FT_MEM_COPY( newpath, base_file_name, base_file_len ); - FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 ); - - *result_file_name = newpath; - *result_offset = 0; - - return FT_Err_Ok; - } - - - static FT_Error - raccess_guess_darwin_newvfs( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - /* - Only meaningful on systems with Mac OS X (> 10.1). - */ - FT_Error error; - char* newpath; - FT_Memory memory; - FT_Long base_file_len = ft_strlen( base_file_name ); - - FT_UNUSED( stream ); - - - memory = library->memory; - - if ( base_file_len + 18 > FT_INT_MAX ) - return FT_Err_Array_Too_Large; - - if ( FT_ALLOC( newpath, base_file_len + 18 ) ) - return error; - - FT_MEM_COPY( newpath, base_file_name, base_file_len ); - FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 ); - - *result_file_name = newpath; - *result_offset = 0; - - return FT_Err_Ok; - } - - - static FT_Error - raccess_guess_vfat( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - char* newpath; - FT_Memory memory; - - FT_UNUSED( stream ); - - - memory = library->memory; - - newpath = raccess_make_file_name( memory, base_file_name, - "resource.frk/" ); - if ( !newpath ) - return FT_Err_Out_Of_Memory; - - *result_file_name = newpath; - *result_offset = 0; - - return FT_Err_Ok; - } - - - static FT_Error - raccess_guess_linux_cap( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - char* newpath; - FT_Memory memory; - - FT_UNUSED( stream ); - - - memory = library->memory; - - newpath = raccess_make_file_name( memory, base_file_name, ".resource/" ); - if ( !newpath ) - return FT_Err_Out_Of_Memory; - - *result_file_name = newpath; - *result_offset = 0; - - return FT_Err_Ok; - } - - - static FT_Error - raccess_guess_linux_double( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - char* newpath; - FT_Error error; - FT_Memory memory; - - FT_UNUSED( stream ); - - - memory = library->memory; - - newpath = raccess_make_file_name( memory, base_file_name, "%" ); - if ( !newpath ) - return FT_Err_Out_Of_Memory; - - error = raccess_guess_linux_double_from_file_name( library, newpath, - result_offset ); - if ( !error ) - *result_file_name = newpath; - else - FT_FREE( newpath ); - - return error; - } - - - static FT_Error - raccess_guess_linux_netatalk( FT_Library library, - FT_Stream stream, - char *base_file_name, - char **result_file_name, - FT_Long *result_offset ) - { - char* newpath; - FT_Error error; - FT_Memory memory; - - FT_UNUSED( stream ); - - - memory = library->memory; - - newpath = raccess_make_file_name( memory, base_file_name, - ".AppleDouble/" ); - if ( !newpath ) - return FT_Err_Out_Of_Memory; - - error = raccess_guess_linux_double_from_file_name( library, newpath, - result_offset ); - if ( !error ) - *result_file_name = newpath; - else - FT_FREE( newpath ); - - return error; - } - - - static FT_Error - raccess_guess_apple_generic( FT_Library library, - FT_Stream stream, - char *base_file_name, - FT_Int32 magic, - FT_Long *result_offset ) - { - FT_Int32 magic_from_stream; - FT_Error error; - FT_Int32 version_number = 0; - FT_UShort n_of_entries; - - int i; - FT_UInt32 entry_id, entry_offset, entry_length = 0; - - const FT_UInt32 resource_fork_entry_id = 0x2; - - FT_UNUSED( library ); - FT_UNUSED( base_file_name ); - FT_UNUSED( version_number ); - FT_UNUSED( entry_length ); - - - if ( FT_READ_LONG( magic_from_stream ) ) - return error; - if ( magic_from_stream != magic ) - return FT_Err_Unknown_File_Format; - - if ( FT_READ_LONG( version_number ) ) - return error; - - /* filler */ - error = FT_Stream_Skip( stream, 16 ); - if ( error ) - return error; - - if ( FT_READ_USHORT( n_of_entries ) ) - return error; - if ( n_of_entries == 0 ) - return FT_Err_Unknown_File_Format; - - for ( i = 0; i < n_of_entries; i++ ) - { - if ( FT_READ_LONG( entry_id ) ) - return error; - if ( entry_id == resource_fork_entry_id ) - { - if ( FT_READ_LONG( entry_offset ) || - FT_READ_LONG( entry_length ) ) - continue; - *result_offset = entry_offset; - - return FT_Err_Ok; - } - else - FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ - } - - return FT_Err_Unknown_File_Format; - } - - - static FT_Error - raccess_guess_linux_double_from_file_name( FT_Library library, - char *file_name, - FT_Long *result_offset ) - { - FT_Open_Args args2; - FT_Stream stream2; - char * nouse = NULL; - FT_Error error; - - - args2.flags = FT_OPEN_PATHNAME; - args2.pathname = file_name; - error = FT_Stream_New( library, &args2, &stream2 ); - if ( error ) - return error; - - error = raccess_guess_apple_double( library, stream2, file_name, - &nouse, result_offset ); - - FT_Stream_Free( stream2, 0 ); - - return error; - } - - - static char* - raccess_make_file_name( FT_Memory memory, - const char *original_name, - const char *insertion ) - { - char* new_name; - char* tmp; - const char* slash; - unsigned new_length; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( error ); - - - new_length = ft_strlen( original_name ) + ft_strlen( insertion ); - if ( FT_ALLOC( new_name, new_length + 1 ) ) - return NULL; - - tmp = ft_strrchr( original_name, '/' ); - if ( tmp ) - { - ft_strncpy( new_name, original_name, tmp - original_name + 1 ); - new_name[tmp - original_name + 1] = '\0'; - slash = tmp + 1; - } - else - { - slash = original_name; - new_name[0] = '\0'; - } - - ft_strcat( new_name, insertion ); - ft_strcat( new_name, slash ); - - return new_name; - } - - -#else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ - - - /*************************************************************************/ - /* Dummy function; just sets errors */ - /*************************************************************************/ - - FT_BASE_DEF( void ) - FT_Raccess_Guess( FT_Library library, - FT_Stream stream, - char *base_name, - char **new_names, - FT_Long *offsets, - FT_Error *errors ) - { - int i; - - FT_UNUSED( library ); - FT_UNUSED( stream ); - FT_UNUSED( base_name ); - - - for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) - { - new_names[i] = NULL; - offsets[i] = 0; - errors[i] = FT_Err_Unimplemented_Feature; - } - } - - -#endif /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ - - -/* END */ diff --git a/src/base/ftstream.c b/src/base/ftstream.c deleted file mode 100644 index 569e46c..0000000 --- a/src/base/ftstream.c +++ /dev/null @@ -1,845 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftstream.c */ -/* */ -/* I/O stream support (body). */ -/* */ -/* Copyright 2000-2001, 2002, 2004, 2005, 2006, 2008 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_DEBUG_H - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_stream - - - FT_BASE_DEF( void ) - FT_Stream_OpenMemory( FT_Stream stream, - const FT_Byte* base, - FT_ULong size ) - { - stream->base = (FT_Byte*) base; - stream->size = size; - stream->pos = 0; - stream->cursor = 0; - stream->read = 0; - stream->close = 0; - } - - - FT_BASE_DEF( void ) - FT_Stream_Close( FT_Stream stream ) - { - if ( stream && stream->close ) - stream->close( stream ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_Seek( FT_Stream stream, - FT_ULong pos ) - { - FT_Error error = FT_Err_Ok; - - - stream->pos = pos; - - if ( stream->read ) - { - if ( stream->read( stream, pos, 0, 0 ) ) - { - FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n", - pos, stream->size )); - - error = FT_Err_Invalid_Stream_Operation; - } - } - /* note that seeking to the first position after the file is valid */ - else if ( pos > stream->size ) - { - FT_ERROR(( "FT_Stream_Seek: invalid i/o; pos = 0x%lx, size = 0x%lx\n", - pos, stream->size )); - - error = FT_Err_Invalid_Stream_Operation; - } - - return error; - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_Skip( FT_Stream stream, - FT_Long distance ) - { - if ( distance < 0 ) - return FT_Err_Invalid_Stream_Operation; - - return FT_Stream_Seek( stream, (FT_ULong)( stream->pos + distance ) ); - } - - - FT_BASE_DEF( FT_Long ) - FT_Stream_Pos( FT_Stream stream ) - { - return stream->pos; - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_Read( FT_Stream stream, - FT_Byte* buffer, - FT_ULong count ) - { - return FT_Stream_ReadAt( stream, stream->pos, buffer, count ); - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_ReadAt( FT_Stream stream, - FT_ULong pos, - FT_Byte* buffer, - FT_ULong count ) - { - FT_Error error = FT_Err_Ok; - FT_ULong read_bytes; - - - if ( pos >= stream->size ) - { - FT_ERROR(( "FT_Stream_ReadAt: invalid i/o; pos = 0x%lx, size = 0x%lx\n", - pos, stream->size )); - - return FT_Err_Invalid_Stream_Operation; - } - - if ( stream->read ) - read_bytes = stream->read( stream, pos, buffer, count ); - else - { - read_bytes = stream->size - pos; - if ( read_bytes > count ) - read_bytes = count; - - FT_MEM_COPY( buffer, stream->base + pos, read_bytes ); - } - - stream->pos = pos + read_bytes; - - if ( read_bytes < count ) - { - FT_ERROR(( "FT_Stream_ReadAt:" )); - FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n", - count, read_bytes )); - - error = FT_Err_Invalid_Stream_Operation; - } - - return error; - } - - - FT_BASE_DEF( FT_ULong ) - FT_Stream_TryRead( FT_Stream stream, - FT_Byte* buffer, - FT_ULong count ) - { - FT_ULong read_bytes = 0; - - - if ( stream->pos >= stream->size ) - goto Exit; - - if ( stream->read ) - read_bytes = stream->read( stream, stream->pos, buffer, count ); - else - { - read_bytes = stream->size - stream->pos; - if ( read_bytes > count ) - read_bytes = count; - - FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes ); - } - - stream->pos += read_bytes; - - Exit: - return read_bytes; - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_ExtractFrame( FT_Stream stream, - FT_ULong count, - FT_Byte** pbytes ) - { - FT_Error error; - - - error = FT_Stream_EnterFrame( stream, count ); - if ( !error ) - { - *pbytes = (FT_Byte*)stream->cursor; - - /* equivalent to FT_Stream_ExitFrame(), with no memory block release */ - stream->cursor = 0; - stream->limit = 0; - } - - return error; - } - - - FT_BASE_DEF( void ) - FT_Stream_ReleaseFrame( FT_Stream stream, - FT_Byte** pbytes ) - { - if ( stream->read ) - { - FT_Memory memory = stream->memory; - -#ifdef FT_DEBUG_MEMORY - ft_mem_free( memory, *pbytes ); - *pbytes = NULL; -#else - FT_FREE( *pbytes ); -#endif - } - *pbytes = 0; - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_EnterFrame( FT_Stream stream, - FT_ULong count ) - { - FT_Error error = FT_Err_Ok; - FT_ULong read_bytes; - - - /* check for nested frame access */ - FT_ASSERT( stream && stream->cursor == 0 ); - - if ( stream->read ) - { - /* allocate the frame in memory */ - FT_Memory memory = stream->memory; - -#ifdef FT_DEBUG_MEMORY - /* assume _ft_debug_file and _ft_debug_lineno are already set */ - stream->base = (unsigned char*)ft_mem_qalloc( memory, count, &error ); - if ( error ) - goto Exit; -#else - if ( FT_QALLOC( stream->base, count ) ) - goto Exit; -#endif - /* read it */ - read_bytes = stream->read( stream, stream->pos, - stream->base, count ); - if ( read_bytes < count ) - { - FT_ERROR(( "FT_Stream_EnterFrame:" )); - FT_ERROR(( " invalid read; expected %lu bytes, got %lu\n", - count, read_bytes )); - - FT_FREE( stream->base ); - error = FT_Err_Invalid_Stream_Operation; - } - stream->cursor = stream->base; - stream->limit = stream->cursor + count; - stream->pos += read_bytes; - } - else - { - /* check current and new position */ - if ( stream->pos >= stream->size || - stream->pos + count > stream->size ) - { - FT_ERROR(( "FT_Stream_EnterFrame:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, count = %lu, size = 0x%lx\n", - stream->pos, count, stream->size )); - - error = FT_Err_Invalid_Stream_Operation; - goto Exit; - } - - /* set cursor */ - stream->cursor = stream->base + stream->pos; - stream->limit = stream->cursor + count; - stream->pos += count; - } - - Exit: - return error; - } - - - FT_BASE_DEF( void ) - FT_Stream_ExitFrame( FT_Stream stream ) - { - /* IMPORTANT: The assertion stream->cursor != 0 was removed, given */ - /* that it is possible to access a frame of length 0 in */ - /* some weird fonts (usually, when accessing an array of */ - /* 0 records, like in some strange kern tables). */ - /* */ - /* In this case, the loader code handles the 0-length table */ - /* gracefully; however, stream.cursor is really set to 0 by the */ - /* FT_Stream_EnterFrame() call, and this is not an error. */ - /* */ - FT_ASSERT( stream ); - - if ( stream->read ) - { - FT_Memory memory = stream->memory; - -#ifdef FT_DEBUG_MEMORY - ft_mem_free( memory, stream->base ); - stream->base = NULL; -#else - FT_FREE( stream->base ); -#endif - } - stream->cursor = 0; - stream->limit = 0; - } - - - FT_BASE_DEF( FT_Char ) - FT_Stream_GetChar( FT_Stream stream ) - { - FT_Char result; - - - FT_ASSERT( stream && stream->cursor ); - - result = 0; - if ( stream->cursor < stream->limit ) - result = *stream->cursor++; - - return result; - } - - - FT_BASE_DEF( FT_Short ) - FT_Stream_GetShort( FT_Stream stream ) - { - FT_Byte* p; - FT_Short result; - - - FT_ASSERT( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 1 < stream->limit ) - result = FT_NEXT_SHORT( p ); - stream->cursor = p; - - return result; - } - - - FT_BASE_DEF( FT_Short ) - FT_Stream_GetShortLE( FT_Stream stream ) - { - FT_Byte* p; - FT_Short result; - - - FT_ASSERT( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 1 < stream->limit ) - result = FT_NEXT_SHORT_LE( p ); - stream->cursor = p; - - return result; - } - - - FT_BASE_DEF( FT_Long ) - FT_Stream_GetOffset( FT_Stream stream ) - { - FT_Byte* p; - FT_Long result; - - - FT_ASSERT( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 2 < stream->limit ) - result = FT_NEXT_OFF3( p ); - stream->cursor = p; - return result; - } - - - FT_BASE_DEF( FT_Long ) - FT_Stream_GetLong( FT_Stream stream ) - { - FT_Byte* p; - FT_Long result; - - - FT_ASSERT( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 3 < stream->limit ) - result = FT_NEXT_LONG( p ); - stream->cursor = p; - return result; - } - - - FT_BASE_DEF( FT_Long ) - FT_Stream_GetLongLE( FT_Stream stream ) - { - FT_Byte* p; - FT_Long result; - - - FT_ASSERT( stream && stream->cursor ); - - result = 0; - p = stream->cursor; - if ( p + 3 < stream->limit ) - result = FT_NEXT_LONG_LE( p ); - stream->cursor = p; - return result; - } - - - FT_BASE_DEF( FT_Char ) - FT_Stream_ReadChar( FT_Stream stream, - FT_Error* error ) - { - FT_Byte result = 0; - - - FT_ASSERT( stream ); - - *error = FT_Err_Ok; - - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, &result, 1L ) != 1L ) - goto Fail; - } - else - { - if ( stream->pos < stream->size ) - result = stream->base[stream->pos]; - else - goto Fail; - } - stream->pos++; - - return result; - - Fail: - *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadChar: invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - FT_BASE_DEF( FT_Short ) - FT_Stream_ReadShort( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[2]; - FT_Byte* p = 0; - FT_Short result = 0; - - - FT_ASSERT( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 1 < stream->size ) - { - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = FT_NEXT_SHORT( p ); - } - else - goto Fail; - - stream->pos += 2; - - return result; - - Fail: - *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadShort:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - FT_BASE_DEF( FT_Short ) - FT_Stream_ReadShortLE( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[2]; - FT_Byte* p = 0; - FT_Short result = 0; - - - FT_ASSERT( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 1 < stream->size ) - { - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = FT_NEXT_SHORT_LE( p ); - } - else - goto Fail; - - stream->pos += 2; - - return result; - - Fail: - *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadShortLE:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - FT_BASE_DEF( FT_Long ) - FT_Stream_ReadOffset( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[3]; - FT_Byte* p = 0; - FT_Long result = 0; - - - FT_ASSERT( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 2 < stream->size ) - { - if ( stream->read ) - { - if (stream->read( stream, stream->pos, reads, 3L ) != 3L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = FT_NEXT_OFF3( p ); - } - else - goto Fail; - - stream->pos += 3; - - return result; - - Fail: - *error = FT_Err_Invalid_Stream_Operation; - FT_ERROR(( "FT_Stream_ReadOffset:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - - return 0; - } - - - FT_BASE_DEF( FT_Long ) - FT_Stream_ReadLong( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[4]; - FT_Byte* p = 0; - FT_Long result = 0; - - - FT_ASSERT( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 3 < stream->size ) - { - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = FT_NEXT_LONG( p ); - } - else - goto Fail; - - stream->pos += 4; - - return result; - - Fail: - FT_ERROR(( "FT_Stream_ReadLong: invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - *error = FT_Err_Invalid_Stream_Operation; - - return 0; - } - - - FT_BASE_DEF( FT_Long ) - FT_Stream_ReadLongLE( FT_Stream stream, - FT_Error* error ) - { - FT_Byte reads[4]; - FT_Byte* p = 0; - FT_Long result = 0; - - - FT_ASSERT( stream ); - - *error = FT_Err_Ok; - - if ( stream->pos + 3 < stream->size ) - { - if ( stream->read ) - { - if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) - goto Fail; - - p = reads; - } - else - { - p = stream->base + stream->pos; - } - - if ( p ) - result = FT_NEXT_LONG_LE( p ); - } - else - goto Fail; - - stream->pos += 4; - - return result; - - Fail: - FT_ERROR(( "FT_Stream_ReadLongLE:" )); - FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", - stream->pos, stream->size )); - *error = FT_Err_Invalid_Stream_Operation; - - return 0; - } - - - FT_BASE_DEF( FT_Error ) - FT_Stream_ReadFields( FT_Stream stream, - const FT_Frame_Field* fields, - void* structure ) - { - FT_Error error; - FT_Bool frame_accessed = 0; - FT_Byte* cursor = stream->cursor; - - - if ( !fields || !stream ) - return FT_Err_Invalid_Argument; - - error = FT_Err_Ok; - do - { - FT_ULong value; - FT_Int sign_shift; - FT_Byte* p; - - - switch ( fields->value ) - { - case ft_frame_start: /* access a new frame */ - error = FT_Stream_EnterFrame( stream, fields->offset ); - if ( error ) - goto Exit; - - frame_accessed = 1; - cursor = stream->cursor; - fields++; - continue; /* loop! */ - - case ft_frame_bytes: /* read a byte sequence */ - case ft_frame_skip: /* skip some bytes */ - { - FT_UInt len = fields->size; - - - if ( cursor + len > stream->limit ) - { - error = FT_Err_Invalid_Stream_Operation; - goto Exit; - } - - if ( fields->value == ft_frame_bytes ) - { - p = (FT_Byte*)structure + fields->offset; - FT_MEM_COPY( p, cursor, len ); - } - cursor += len; - fields++; - continue; - } - - case ft_frame_byte: - case ft_frame_schar: /* read a single byte */ - value = FT_NEXT_BYTE(cursor); - sign_shift = 24; - break; - - case ft_frame_short_be: - case ft_frame_ushort_be: /* read a 2-byte big-endian short */ - value = FT_NEXT_USHORT(cursor); - sign_shift = 16; - break; - - case ft_frame_short_le: - case ft_frame_ushort_le: /* read a 2-byte little-endian short */ - value = FT_NEXT_USHORT_LE(cursor); - sign_shift = 16; - break; - - case ft_frame_long_be: - case ft_frame_ulong_be: /* read a 4-byte big-endian long */ - value = FT_NEXT_ULONG(cursor); - sign_shift = 0; - break; - - case ft_frame_long_le: - case ft_frame_ulong_le: /* read a 4-byte little-endian long */ - value = FT_NEXT_ULONG_LE(cursor); - sign_shift = 0; - break; - - case ft_frame_off3_be: - case ft_frame_uoff3_be: /* read a 3-byte big-endian long */ - value = FT_NEXT_UOFF3(cursor); - sign_shift = 8; - break; - - case ft_frame_off3_le: - case ft_frame_uoff3_le: /* read a 3-byte little-endian long */ - value = FT_NEXT_UOFF3_LE(cursor); - sign_shift = 8; - break; - - default: - /* otherwise, exit the loop */ - stream->cursor = cursor; - goto Exit; - } - - /* now, compute the signed value is necessary */ - if ( fields->value & FT_FRAME_OP_SIGNED ) - value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift ); - - /* finally, store the value in the object */ - - p = (FT_Byte*)structure + fields->offset; - switch ( fields->size ) - { - case (8 / FT_CHAR_BIT): - *(FT_Byte*)p = (FT_Byte)value; - break; - - case (16 / FT_CHAR_BIT): - *(FT_UShort*)p = (FT_UShort)value; - break; - - case (32 / FT_CHAR_BIT): - *(FT_UInt32*)p = (FT_UInt32)value; - break; - - default: /* for 64-bit systems */ - *(FT_ULong*)p = (FT_ULong)value; - } - - /* go to next field */ - fields++; - } - while ( 1 ); - - Exit: - /* close the frame if it was opened by this read */ - if ( frame_accessed ) - FT_Stream_ExitFrame( stream ); - - return error; - } - - -/* END */ diff --git a/src/base/ftstroke.c b/src/base/ftstroke.c deleted file mode 100644 index 5dfee8b..0000000 --- a/src/base/ftstroke.c +++ /dev/null @@ -1,2010 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftstroke.c */ -/* */ -/* FreeType path stroker (body). */ -/* */ -/* Copyright 2002, 2003, 2004, 2005, 2006, 2008 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_STROKER_H -#include FT_TRIGONOMETRY_H -#include FT_OUTLINE_H -#include FT_INTERNAL_MEMORY_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_OBJECTS_H - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_StrokerBorder ) - FT_Outline_GetInsideBorder( FT_Outline* outline ) - { - FT_Orientation o = FT_Outline_Get_Orientation( outline ); - - - return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_RIGHT - : FT_STROKER_BORDER_LEFT ; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_StrokerBorder ) - FT_Outline_GetOutsideBorder( FT_Outline* outline ) - { - FT_Orientation o = FT_Outline_Get_Orientation( outline ); - - - return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_LEFT - : FT_STROKER_BORDER_RIGHT ; - } - - - /***************************************************************************/ - /***************************************************************************/ - /***** *****/ - /***** BEZIER COMPUTATIONS *****/ - /***** *****/ - /***************************************************************************/ - /***************************************************************************/ - -#define FT_SMALL_CONIC_THRESHOLD ( FT_ANGLE_PI / 6 ) -#define FT_SMALL_CUBIC_THRESHOLD ( FT_ANGLE_PI / 6 ) -#define FT_EPSILON 2 - -#define FT_IS_SMALL( x ) ( (x) > -FT_EPSILON && (x) < FT_EPSILON ) - - - static FT_Pos - ft_pos_abs( FT_Pos x ) - { - return x >= 0 ? x : -x ; - } - - - static void - ft_conic_split( FT_Vector* base ) - { - FT_Pos a, b; - - - base[4].x = base[2].x; - b = base[1].x; - a = base[3].x = ( base[2].x + b ) / 2; - b = base[1].x = ( base[0].x + b ) / 2; - base[2].x = ( a + b ) / 2; - - base[4].y = base[2].y; - b = base[1].y; - a = base[3].y = ( base[2].y + b ) / 2; - b = base[1].y = ( base[0].y + b ) / 2; - base[2].y = ( a + b ) / 2; - } - - - static FT_Bool - ft_conic_is_small_enough( FT_Vector* base, - FT_Angle *angle_in, - FT_Angle *angle_out ) - { - FT_Vector d1, d2; - FT_Angle theta; - FT_Int close1, close2; - - - d1.x = base[1].x - base[2].x; - d1.y = base[1].y - base[2].y; - d2.x = base[0].x - base[1].x; - d2.y = base[0].y - base[1].y; - - close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y ); - close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y ); - - if ( close1 ) - { - if ( close2 ) - *angle_in = *angle_out = 0; - else - *angle_in = *angle_out = FT_Atan2( d2.x, d2.y ); - } - else if ( close2 ) - { - *angle_in = *angle_out = FT_Atan2( d1.x, d1.y ); - } - else - { - *angle_in = FT_Atan2( d1.x, d1.y ); - *angle_out = FT_Atan2( d2.x, d2.y ); - } - - theta = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_out ) ); - - return FT_BOOL( theta < FT_SMALL_CONIC_THRESHOLD ); - } - - - static void - ft_cubic_split( FT_Vector* base ) - { - FT_Pos a, b, c, d; - - - base[6].x = base[3].x; - c = base[1].x; - d = base[2].x; - base[1].x = a = ( base[0].x + c ) / 2; - base[5].x = b = ( base[3].x + d ) / 2; - c = ( c + d ) / 2; - base[2].x = a = ( a + c ) / 2; - base[4].x = b = ( b + c ) / 2; - base[3].x = ( a + b ) / 2; - - base[6].y = base[3].y; - c = base[1].y; - d = base[2].y; - base[1].y = a = ( base[0].y + c ) / 2; - base[5].y = b = ( base[3].y + d ) / 2; - c = ( c + d ) / 2; - base[2].y = a = ( a + c ) / 2; - base[4].y = b = ( b + c ) / 2; - base[3].y = ( a + b ) / 2; - } - - - static FT_Bool - ft_cubic_is_small_enough( FT_Vector* base, - FT_Angle *angle_in, - FT_Angle *angle_mid, - FT_Angle *angle_out ) - { - FT_Vector d1, d2, d3; - FT_Angle theta1, theta2; - FT_Int close1, close2, close3; - - - d1.x = base[2].x - base[3].x; - d1.y = base[2].y - base[3].y; - d2.x = base[1].x - base[2].x; - d2.y = base[1].y - base[2].y; - d3.x = base[0].x - base[1].x; - d3.y = base[0].y - base[1].y; - - close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y ); - close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y ); - close3 = FT_IS_SMALL( d3.x ) && FT_IS_SMALL( d3.y ); - - if ( close1 || close3 ) - { - if ( close2 ) - { - /* basically a point */ - *angle_in = *angle_out = *angle_mid = 0; - } - else if ( close1 ) - { - *angle_in = *angle_mid = FT_Atan2( d2.x, d2.y ); - *angle_out = FT_Atan2( d3.x, d3.y ); - } - else /* close2 */ - { - *angle_in = FT_Atan2( d1.x, d1.y ); - *angle_mid = *angle_out = FT_Atan2( d2.x, d2.y ); - } - } - else if ( close2 ) - { - *angle_in = *angle_mid = FT_Atan2( d1.x, d1.y ); - *angle_out = FT_Atan2( d3.x, d3.y ); - } - else - { - *angle_in = FT_Atan2( d1.x, d1.y ); - *angle_mid = FT_Atan2( d2.x, d2.y ); - *angle_out = FT_Atan2( d3.x, d3.y ); - } - - theta1 = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_mid ) ); - theta2 = ft_pos_abs( FT_Angle_Diff( *angle_mid, *angle_out ) ); - - return FT_BOOL( theta1 < FT_SMALL_CUBIC_THRESHOLD && - theta2 < FT_SMALL_CUBIC_THRESHOLD ); - } - - - /***************************************************************************/ - /***************************************************************************/ - /***** *****/ - /***** STROKE BORDERS *****/ - /***** *****/ - /***************************************************************************/ - /***************************************************************************/ - - typedef enum FT_StrokeTags_ - { - FT_STROKE_TAG_ON = 1, /* on-curve point */ - FT_STROKE_TAG_CUBIC = 2, /* cubic off-point */ - FT_STROKE_TAG_BEGIN = 4, /* sub-path start */ - FT_STROKE_TAG_END = 8 /* sub-path end */ - - } FT_StrokeTags; - -#define FT_STROKE_TAG_BEGIN_END (FT_STROKE_TAG_BEGIN|FT_STROKE_TAG_END) - - typedef struct FT_StrokeBorderRec_ - { - FT_UInt num_points; - FT_UInt max_points; - FT_Vector* points; - FT_Byte* tags; - FT_Bool movable; - FT_Int start; /* index of current sub-path start point */ - FT_Memory memory; - FT_Bool valid; - - } FT_StrokeBorderRec, *FT_StrokeBorder; - - - static FT_Error - ft_stroke_border_grow( FT_StrokeBorder border, - FT_UInt new_points ) - { - FT_UInt old_max = border->max_points; - FT_UInt new_max = border->num_points + new_points; - FT_Error error = 0; - - - if ( new_max > old_max ) - { - FT_UInt cur_max = old_max; - FT_Memory memory = border->memory; - - - while ( cur_max < new_max ) - cur_max += ( cur_max >> 1 ) + 16; - - if ( FT_RENEW_ARRAY( border->points, old_max, cur_max ) || - FT_RENEW_ARRAY( border->tags, old_max, cur_max ) ) - goto Exit; - - border->max_points = cur_max; - } - Exit: - return error; - } - - - static void - ft_stroke_border_close( FT_StrokeBorder border, - FT_Bool reverse ) - { - FT_UInt start = border->start; - FT_UInt count = border->num_points; - - - FT_ASSERT( border->start >= 0 ); - - /* don't record empty paths! */ - if ( count <= start + 1U ) - border->num_points = start; - else - { - /* copy the last point to the start of this sub-path, since */ - /* it contains the `adjusted' starting coordinates */ - border->num_points = --count; - border->points[start] = border->points[count]; - - if ( reverse ) - { - /* reverse the points */ - { - FT_Vector* vec1 = border->points + start + 1; - FT_Vector* vec2 = border->points + count - 1; - - - for ( ; vec1 < vec2; vec1++, vec2-- ) - { - FT_Vector tmp; - - - tmp = *vec1; - *vec1 = *vec2; - *vec2 = tmp; - } - } - - /* then the tags */ - { - FT_Byte* tag1 = border->tags + start + 1; - FT_Byte* tag2 = border->tags + count - 1; - - - for ( ; tag1 < tag2; tag1++, tag2-- ) - { - FT_Byte tmp; - - - tmp = *tag1; - *tag1 = *tag2; - *tag2 = tmp; - } - } - } - - border->tags[start ] |= FT_STROKE_TAG_BEGIN; - border->tags[count - 1] |= FT_STROKE_TAG_END; - } - - border->start = -1; - border->movable = 0; - } - - - static FT_Error - ft_stroke_border_lineto( FT_StrokeBorder border, - FT_Vector* to, - FT_Bool movable ) - { - FT_Error error = 0; - - - FT_ASSERT( border->start >= 0 ); - - if ( border->movable ) - { - /* move last point */ - border->points[border->num_points - 1] = *to; - } - else - { - /* add one point */ - error = ft_stroke_border_grow( border, 1 ); - if ( !error ) - { - FT_Vector* vec = border->points + border->num_points; - FT_Byte* tag = border->tags + border->num_points; - - - vec[0] = *to; - tag[0] = FT_STROKE_TAG_ON; - - border->num_points += 1; - } - } - border->movable = movable; - return error; - } - - - static FT_Error - ft_stroke_border_conicto( FT_StrokeBorder border, - FT_Vector* control, - FT_Vector* to ) - { - FT_Error error; - - - FT_ASSERT( border->start >= 0 ); - - error = ft_stroke_border_grow( border, 2 ); - if ( !error ) - { - FT_Vector* vec = border->points + border->num_points; - FT_Byte* tag = border->tags + border->num_points; - - vec[0] = *control; - vec[1] = *to; - - tag[0] = 0; - tag[1] = FT_STROKE_TAG_ON; - - border->num_points += 2; - } - border->movable = 0; - return error; - } - - - static FT_Error - ft_stroke_border_cubicto( FT_StrokeBorder border, - FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to ) - { - FT_Error error; - - - FT_ASSERT( border->start >= 0 ); - - error = ft_stroke_border_grow( border, 3 ); - if ( !error ) - { - FT_Vector* vec = border->points + border->num_points; - FT_Byte* tag = border->tags + border->num_points; - - - vec[0] = *control1; - vec[1] = *control2; - vec[2] = *to; - - tag[0] = FT_STROKE_TAG_CUBIC; - tag[1] = FT_STROKE_TAG_CUBIC; - tag[2] = FT_STROKE_TAG_ON; - - border->num_points += 3; - } - border->movable = 0; - return error; - } - - -#define FT_ARC_CUBIC_ANGLE ( FT_ANGLE_PI / 2 ) - - - static FT_Error - ft_stroke_border_arcto( FT_StrokeBorder border, - FT_Vector* center, - FT_Fixed radius, - FT_Angle angle_start, - FT_Angle angle_diff ) - { - FT_Angle total, angle, step, rotate, next, theta; - FT_Vector a, b, a2, b2; - FT_Fixed length; - FT_Error error = 0; - - - /* compute start point */ - FT_Vector_From_Polar( &a, radius, angle_start ); - a.x += center->x; - a.y += center->y; - - total = angle_diff; - angle = angle_start; - rotate = ( angle_diff >= 0 ) ? FT_ANGLE_PI2 : -FT_ANGLE_PI2; - - while ( total != 0 ) - { - step = total; - if ( step > FT_ARC_CUBIC_ANGLE ) - step = FT_ARC_CUBIC_ANGLE; - - else if ( step < -FT_ARC_CUBIC_ANGLE ) - step = -FT_ARC_CUBIC_ANGLE; - - next = angle + step; - theta = step; - if ( theta < 0 ) - theta = -theta; - - theta >>= 1; - - /* compute end point */ - FT_Vector_From_Polar( &b, radius, next ); - b.x += center->x; - b.y += center->y; - - /* compute first and second control points */ - length = FT_MulDiv( radius, FT_Sin( theta ) * 4, - ( 0x10000L + FT_Cos( theta ) ) * 3 ); - - FT_Vector_From_Polar( &a2, length, angle + rotate ); - a2.x += a.x; - a2.y += a.y; - - FT_Vector_From_Polar( &b2, length, next - rotate ); - b2.x += b.x; - b2.y += b.y; - - /* add cubic arc */ - error = ft_stroke_border_cubicto( border, &a2, &b2, &b ); - if ( error ) - break; - - /* process the rest of the arc ?? */ - a = b; - total -= step; - angle = next; - } - - return error; - } - - - static FT_Error - ft_stroke_border_moveto( FT_StrokeBorder border, - FT_Vector* to ) - { - /* close current open path if any ? */ - if ( border->start >= 0 ) - ft_stroke_border_close( border, 0 ); - - border->start = border->num_points; - border->movable = 0; - - return ft_stroke_border_lineto( border, to, 0 ); - } - - - static void - ft_stroke_border_init( FT_StrokeBorder border, - FT_Memory memory ) - { - border->memory = memory; - border->points = NULL; - border->tags = NULL; - - border->num_points = 0; - border->max_points = 0; - border->start = -1; - border->valid = 0; - } - - - static void - ft_stroke_border_reset( FT_StrokeBorder border ) - { - border->num_points = 0; - border->start = -1; - border->valid = 0; - } - - - static void - ft_stroke_border_done( FT_StrokeBorder border ) - { - FT_Memory memory = border->memory; - - - FT_FREE( border->points ); - FT_FREE( border->tags ); - - border->num_points = 0; - border->max_points = 0; - border->start = -1; - border->valid = 0; - } - - - static FT_Error - ft_stroke_border_get_counts( FT_StrokeBorder border, - FT_UInt *anum_points, - FT_UInt *anum_contours ) - { - FT_Error error = 0; - FT_UInt num_points = 0; - FT_UInt num_contours = 0; - - FT_UInt count = border->num_points; - FT_Vector* point = border->points; - FT_Byte* tags = border->tags; - FT_Int in_contour = 0; - - - for ( ; count > 0; count--, num_points++, point++, tags++ ) - { - if ( tags[0] & FT_STROKE_TAG_BEGIN ) - { - if ( in_contour != 0 ) - goto Fail; - - in_contour = 1; - } - else if ( in_contour == 0 ) - goto Fail; - - if ( tags[0] & FT_STROKE_TAG_END ) - { - if ( in_contour == 0 ) - goto Fail; - - in_contour = 0; - num_contours++; - } - } - - if ( in_contour != 0 ) - goto Fail; - - border->valid = 1; - - Exit: - *anum_points = num_points; - *anum_contours = num_contours; - return error; - - Fail: - num_points = 0; - num_contours = 0; - goto Exit; - } - - - static void - ft_stroke_border_export( FT_StrokeBorder border, - FT_Outline* outline ) - { - /* copy point locations */ - FT_ARRAY_COPY( outline->points + outline->n_points, - border->points, - border->num_points ); - - /* copy tags */ - { - FT_UInt count = border->num_points; - FT_Byte* read = border->tags; - FT_Byte* write = (FT_Byte*)outline->tags + outline->n_points; - - - for ( ; count > 0; count--, read++, write++ ) - { - if ( *read & FT_STROKE_TAG_ON ) - *write = FT_CURVE_TAG_ON; - else if ( *read & FT_STROKE_TAG_CUBIC ) - *write = FT_CURVE_TAG_CUBIC; - else - *write = FT_CURVE_TAG_CONIC; - } - } - - /* copy contours */ - { - FT_UInt count = border->num_points; - FT_Byte* tags = border->tags; - FT_Short* write = outline->contours + outline->n_contours; - FT_Short idx = (FT_Short)outline->n_points; - - - for ( ; count > 0; count--, tags++, idx++ ) - { - if ( *tags & FT_STROKE_TAG_END ) - { - *write++ = idx; - outline->n_contours++; - } - } - } - - outline->n_points = (short)( outline->n_points + border->num_points ); - - FT_ASSERT( FT_Outline_Check( outline ) == 0 ); - } - - - /***************************************************************************/ - /***************************************************************************/ - /***** *****/ - /***** STROKER *****/ - /***** *****/ - /***************************************************************************/ - /***************************************************************************/ - -#define FT_SIDE_TO_ROTATE( s ) ( FT_ANGLE_PI2 - (s) * FT_ANGLE_PI ) - - typedef struct FT_StrokerRec_ - { - FT_Angle angle_in; - FT_Angle angle_out; - FT_Vector center; - FT_Bool first_point; - FT_Bool subpath_open; - FT_Angle subpath_angle; - FT_Vector subpath_start; - - FT_Stroker_LineCap line_cap; - FT_Stroker_LineJoin line_join; - FT_Fixed miter_limit; - FT_Fixed radius; - - FT_Bool valid; - FT_StrokeBorderRec borders[2]; - FT_Memory memory; - - } FT_StrokerRec; - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_New( FT_Library library, - FT_Stroker *astroker ) - { - FT_Error error; - FT_Memory memory; - FT_Stroker stroker; - - - if ( !library ) - return FT_Err_Invalid_Argument; - - memory = library->memory; - - if ( !FT_NEW( stroker ) ) - { - stroker->memory = memory; - - ft_stroke_border_init( &stroker->borders[0], memory ); - ft_stroke_border_init( &stroker->borders[1], memory ); - } - *astroker = stroker; - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( void ) - FT_Stroker_Set( FT_Stroker stroker, - FT_Fixed radius, - FT_Stroker_LineCap line_cap, - FT_Stroker_LineJoin line_join, - FT_Fixed miter_limit ) - { - stroker->radius = radius; - stroker->line_cap = line_cap; - stroker->line_join = line_join; - stroker->miter_limit = miter_limit; - - FT_Stroker_Rewind( stroker ); - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( void ) - FT_Stroker_Rewind( FT_Stroker stroker ) - { - if ( stroker ) - { - ft_stroke_border_reset( &stroker->borders[0] ); - ft_stroke_border_reset( &stroker->borders[1] ); - } - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( void ) - FT_Stroker_Done( FT_Stroker stroker ) - { - if ( stroker ) - { - FT_Memory memory = stroker->memory; - - - ft_stroke_border_done( &stroker->borders[0] ); - ft_stroke_border_done( &stroker->borders[1] ); - - stroker->memory = NULL; - FT_FREE( stroker ); - } - } - - - /* creates a circular arc at a corner or cap */ - static FT_Error - ft_stroker_arcto( FT_Stroker stroker, - FT_Int side ) - { - FT_Angle total, rotate; - FT_Fixed radius = stroker->radius; - FT_Error error = 0; - FT_StrokeBorder border = stroker->borders + side; - - - rotate = FT_SIDE_TO_ROTATE( side ); - - total = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); - if ( total == FT_ANGLE_PI ) - total = -rotate * 2; - - error = ft_stroke_border_arcto( border, - &stroker->center, - radius, - stroker->angle_in + rotate, - total ); - border->movable = 0; - return error; - } - - - /* adds a cap at the end of an opened path */ - static FT_Error - ft_stroker_cap( FT_Stroker stroker, - FT_Angle angle, - FT_Int side ) - { - FT_Error error = 0; - - - if ( stroker->line_cap == FT_STROKER_LINECAP_ROUND ) - { - /* add a round cap */ - stroker->angle_in = angle; - stroker->angle_out = angle + FT_ANGLE_PI; - error = ft_stroker_arcto( stroker, side ); - } - else if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE ) - { - /* add a square cap */ - FT_Vector delta, delta2; - FT_Angle rotate = FT_SIDE_TO_ROTATE( side ); - FT_Fixed radius = stroker->radius; - FT_StrokeBorder border = stroker->borders + side; - - - FT_Vector_From_Polar( &delta2, radius, angle + rotate ); - FT_Vector_From_Polar( &delta, radius, angle ); - - delta.x += stroker->center.x + delta2.x; - delta.y += stroker->center.y + delta2.y; - - error = ft_stroke_border_lineto( border, &delta, 0 ); - if ( error ) - goto Exit; - - FT_Vector_From_Polar( &delta2, radius, angle - rotate ); - FT_Vector_From_Polar( &delta, radius, angle ); - - delta.x += delta2.x + stroker->center.x; - delta.y += delta2.y + stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, 0 ); - } - - Exit: - return error; - } - - - /* process an inside corner, i.e. compute intersection */ - static FT_Error - ft_stroker_inside( FT_Stroker stroker, - FT_Int side) - { - FT_StrokeBorder border = stroker->borders + side; - FT_Angle phi, theta, rotate; - FT_Fixed length, thcos, sigma; - FT_Vector delta; - FT_Error error = 0; - - - rotate = FT_SIDE_TO_ROTATE( side ); - - /* compute median angle */ - theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); - if ( theta == FT_ANGLE_PI ) - theta = rotate; - else - theta = theta / 2; - - phi = stroker->angle_in + theta; - - thcos = FT_Cos( theta ); - sigma = FT_MulFix( stroker->miter_limit, thcos ); - - /* TODO: find better criterion to switch off the optimization */ - if ( sigma < 0x10000L ) - { - FT_Vector_From_Polar( &delta, stroker->radius, - stroker->angle_out + rotate ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - border->movable = 0; - } - else - { - length = FT_DivFix( stroker->radius, thcos ); - - FT_Vector_From_Polar( &delta, length, phi + rotate ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - } - - error = ft_stroke_border_lineto( border, &delta, 0 ); - - return error; - } - - - /* process an outside corner, i.e. compute bevel/miter/round */ - static FT_Error - ft_stroker_outside( FT_Stroker stroker, - FT_Int side ) - { - FT_StrokeBorder border = stroker->borders + side; - FT_Error error; - FT_Angle rotate; - - - if ( stroker->line_join == FT_STROKER_LINEJOIN_ROUND ) - { - error = ft_stroker_arcto( stroker, side ); - } - else - { - /* this is a mitered or beveled corner */ - FT_Fixed sigma, radius = stroker->radius; - FT_Angle theta, phi; - FT_Fixed thcos; - FT_Bool miter; - - - rotate = FT_SIDE_TO_ROTATE( side ); - miter = FT_BOOL( stroker->line_join == FT_STROKER_LINEJOIN_MITER ); - - theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); - if ( theta == FT_ANGLE_PI ) - { - theta = rotate; - phi = stroker->angle_in; - } - else - { - theta = theta / 2; - phi = stroker->angle_in + theta + rotate; - } - - thcos = FT_Cos( theta ); - sigma = FT_MulFix( stroker->miter_limit, thcos ); - - if ( sigma >= 0x10000L ) - miter = 0; - - if ( miter ) /* this is a miter (broken angle) */ - { - FT_Vector middle, delta; - FT_Fixed length; - - - /* compute middle point */ - FT_Vector_From_Polar( &middle, - FT_MulFix( radius, stroker->miter_limit ), - phi ); - middle.x += stroker->center.x; - middle.y += stroker->center.y; - - /* compute first angle point */ - length = FT_MulFix( radius, - FT_DivFix( 0x10000L - sigma, - ft_pos_abs( FT_Sin( theta ) ) ) ); - - FT_Vector_From_Polar( &delta, length, phi + rotate ); - delta.x += middle.x; - delta.y += middle.y; - - error = ft_stroke_border_lineto( border, &delta, 0 ); - if ( error ) - goto Exit; - - /* compute second angle point */ - FT_Vector_From_Polar( &delta, length, phi - rotate ); - delta.x += middle.x; - delta.y += middle.y; - - error = ft_stroke_border_lineto( border, &delta, 0 ); - if ( error ) - goto Exit; - - /* finally, add a movable end point */ - FT_Vector_From_Polar( &delta, radius, stroker->angle_out + rotate ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, 1 ); - } - - else /* this is a bevel (intersection) */ - { - FT_Fixed length; - FT_Vector delta; - - - length = FT_DivFix( stroker->radius, thcos ); - - FT_Vector_From_Polar( &delta, length, phi ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, 0 ); - if (error) goto Exit; - - /* now add end point */ - FT_Vector_From_Polar( &delta, stroker->radius, - stroker->angle_out + rotate ); - delta.x += stroker->center.x; - delta.y += stroker->center.y; - - error = ft_stroke_border_lineto( border, &delta, 1 ); - } - } - - Exit: - return error; - } - - - static FT_Error - ft_stroker_process_corner( FT_Stroker stroker ) - { - FT_Error error = 0; - FT_Angle turn; - FT_Int inside_side; - - - turn = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ); - - /* no specific corner processing is required if the turn is 0 */ - if ( turn == 0 ) - goto Exit; - - /* when we turn to the right, the inside side is 0 */ - inside_side = 0; - - /* otherwise, the inside side is 1 */ - if ( turn < 0 ) - inside_side = 1; - - /* process the inside side */ - error = ft_stroker_inside( stroker, inside_side ); - if ( error ) - goto Exit; - - /* process the outside side */ - error = ft_stroker_outside( stroker, 1 - inside_side ); - - Exit: - return error; - } - - - /* add two points to the left and right borders corresponding to the */ - /* start of the subpath.. */ - static FT_Error - ft_stroker_subpath_start( FT_Stroker stroker, - FT_Angle start_angle ) - { - FT_Vector delta; - FT_Vector point; - FT_Error error; - FT_StrokeBorder border; - - - FT_Vector_From_Polar( &delta, stroker->radius, - start_angle + FT_ANGLE_PI2 ); - - point.x = stroker->center.x + delta.x; - point.y = stroker->center.y + delta.y; - - border = stroker->borders; - error = ft_stroke_border_moveto( border, &point ); - if ( error ) - goto Exit; - - point.x = stroker->center.x - delta.x; - point.y = stroker->center.y - delta.y; - - border++; - error = ft_stroke_border_moveto( border, &point ); - - /* save angle for last cap */ - stroker->subpath_angle = start_angle; - stroker->first_point = 0; - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_LineTo( FT_Stroker stroker, - FT_Vector* to ) - { - FT_Error error = 0; - FT_StrokeBorder border; - FT_Vector delta; - FT_Angle angle; - FT_Int side; - - delta.x = to->x - stroker->center.x; - delta.y = to->y - stroker->center.y; - - angle = FT_Atan2( delta.x, delta.y ); - FT_Vector_From_Polar( &delta, stroker->radius, angle + FT_ANGLE_PI2 ); - - /* process corner if necessary */ - if ( stroker->first_point ) - { - /* This is the first segment of a subpath. We need to */ - /* add a point to each border at their respective starting */ - /* point locations. */ - error = ft_stroker_subpath_start( stroker, angle ); - if ( error ) - goto Exit; - } - else - { - /* process the current corner */ - stroker->angle_out = angle; - error = ft_stroker_process_corner( stroker ); - if ( error ) - goto Exit; - } - - /* now add a line segment to both the "inside" and "outside" paths */ - - for ( border = stroker->borders, side = 1; side >= 0; side--, border++ ) - { - FT_Vector point; - - - point.x = to->x + delta.x; - point.y = to->y + delta.y; - - error = ft_stroke_border_lineto( border, &point, 1 ); - if ( error ) - goto Exit; - - delta.x = -delta.x; - delta.y = -delta.y; - } - - stroker->angle_in = angle; - stroker->center = *to; - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_ConicTo( FT_Stroker stroker, - FT_Vector* control, - FT_Vector* to ) - { - FT_Error error = 0; - FT_Vector bez_stack[34]; - FT_Vector* arc; - FT_Vector* limit = bez_stack + 30; - FT_Angle start_angle; - FT_Bool first_arc = 1; - - - arc = bez_stack; - arc[0] = *to; - arc[1] = *control; - arc[2] = stroker->center; - - while ( arc >= bez_stack ) - { - FT_Angle angle_in, angle_out; - - - angle_in = angle_out = 0; /* remove compiler warnings */ - - if ( arc < limit && - !ft_conic_is_small_enough( arc, &angle_in, &angle_out ) ) - { - ft_conic_split( arc ); - arc += 2; - continue; - } - - if ( first_arc ) - { - first_arc = 0; - - start_angle = angle_in; - - /* process corner if necessary */ - if ( stroker->first_point ) - error = ft_stroker_subpath_start( stroker, start_angle ); - else - { - stroker->angle_out = start_angle; - error = ft_stroker_process_corner( stroker ); - } - } - - /* the arc's angle is small enough; we can add it directly to each */ - /* border */ - { - FT_Vector ctrl, end; - FT_Angle theta, phi, rotate; - FT_Fixed length; - FT_Int side; - - - theta = FT_Angle_Diff( angle_in, angle_out ) / 2; - phi = angle_in + theta; - length = FT_DivFix( stroker->radius, FT_Cos( theta ) ); - - for ( side = 0; side <= 1; side++ ) - { - rotate = FT_SIDE_TO_ROTATE( side ); - - /* compute control point */ - FT_Vector_From_Polar( &ctrl, length, phi + rotate ); - ctrl.x += arc[1].x; - ctrl.y += arc[1].y; - - /* compute end point */ - FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate ); - end.x += arc[0].x; - end.y += arc[0].y; - - error = ft_stroke_border_conicto( stroker->borders + side, - &ctrl, &end ); - if ( error ) - goto Exit; - } - } - - arc -= 2; - - if ( arc < bez_stack ) - stroker->angle_in = angle_out; - } - - stroker->center = *to; - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_CubicTo( FT_Stroker stroker, - FT_Vector* control1, - FT_Vector* control2, - FT_Vector* to ) - { - FT_Error error = 0; - FT_Vector bez_stack[37]; - FT_Vector* arc; - FT_Vector* limit = bez_stack + 32; - FT_Angle start_angle; - FT_Bool first_arc = 1; - - - arc = bez_stack; - arc[0] = *to; - arc[1] = *control2; - arc[2] = *control1; - arc[3] = stroker->center; - - while ( arc >= bez_stack ) - { - FT_Angle angle_in, angle_mid, angle_out; - - - /* remove compiler warnings */ - angle_in = angle_out = angle_mid = 0; - - if ( arc < limit && - !ft_cubic_is_small_enough( arc, &angle_in, - &angle_mid, &angle_out ) ) - { - ft_cubic_split( arc ); - arc += 3; - continue; - } - - if ( first_arc ) - { - first_arc = 0; - - /* process corner if necessary */ - start_angle = angle_in; - - if ( stroker->first_point ) - error = ft_stroker_subpath_start( stroker, start_angle ); - else - { - stroker->angle_out = start_angle; - error = ft_stroker_process_corner( stroker ); - } - if ( error ) - goto Exit; - } - - /* the arc's angle is small enough; we can add it directly to each */ - /* border */ - { - FT_Vector ctrl1, ctrl2, end; - FT_Angle theta1, phi1, theta2, phi2, rotate; - FT_Fixed length1, length2; - FT_Int side; - - - theta1 = ft_pos_abs( angle_mid - angle_in ) / 2; - theta2 = ft_pos_abs( angle_out - angle_mid ) / 2; - phi1 = (angle_mid + angle_in ) / 2; - phi2 = (angle_mid + angle_out ) / 2; - length1 = FT_DivFix( stroker->radius, FT_Cos( theta1 ) ); - length2 = FT_DivFix( stroker->radius, FT_Cos(theta2) ); - - for ( side = 0; side <= 1; side++ ) - { - rotate = FT_SIDE_TO_ROTATE( side ); - - /* compute control points */ - FT_Vector_From_Polar( &ctrl1, length1, phi1 + rotate ); - ctrl1.x += arc[2].x; - ctrl1.y += arc[2].y; - - FT_Vector_From_Polar( &ctrl2, length2, phi2 + rotate ); - ctrl2.x += arc[1].x; - ctrl2.y += arc[1].y; - - /* compute end point */ - FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate ); - end.x += arc[0].x; - end.y += arc[0].y; - - error = ft_stroke_border_cubicto( stroker->borders + side, - &ctrl1, &ctrl2, &end ); - if ( error ) - goto Exit; - } - } - - arc -= 3; - if ( arc < bez_stack ) - stroker->angle_in = angle_out; - } - - stroker->center = *to; - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_BeginSubPath( FT_Stroker stroker, - FT_Vector* to, - FT_Bool open ) - { - /* We cannot process the first point, because there is not enough */ - /* information regarding its corner/cap. The latter will be processed */ - /* in the "end_subpath" routine. */ - /* */ - stroker->first_point = 1; - stroker->center = *to; - stroker->subpath_open = open; - - /* record the subpath start point index for each border */ - stroker->subpath_start = *to; - return 0; - } - - - static FT_Error - ft_stroker_add_reverse_left( FT_Stroker stroker, - FT_Bool open ) - { - FT_StrokeBorder right = stroker->borders + 0; - FT_StrokeBorder left = stroker->borders + 1; - FT_Int new_points; - FT_Error error = 0; - - - FT_ASSERT( left->start >= 0 ); - - new_points = left->num_points - left->start; - if ( new_points > 0 ) - { - error = ft_stroke_border_grow( right, (FT_UInt)new_points ); - if ( error ) - goto Exit; - - { - FT_Vector* dst_point = right->points + right->num_points; - FT_Byte* dst_tag = right->tags + right->num_points; - FT_Vector* src_point = left->points + left->num_points - 1; - FT_Byte* src_tag = left->tags + left->num_points - 1; - - while ( src_point >= left->points + left->start ) - { - *dst_point = *src_point; - *dst_tag = *src_tag; - - if ( open ) - dst_tag[0] &= ~FT_STROKE_TAG_BEGIN_END; - else - { - FT_Byte ttag = (FT_Byte)( dst_tag[0] & FT_STROKE_TAG_BEGIN_END ); - - - /* switch begin/end tags if necessary */ - if ( ttag == FT_STROKE_TAG_BEGIN || - ttag == FT_STROKE_TAG_END ) - dst_tag[0] ^= FT_STROKE_TAG_BEGIN_END; - - } - - src_point--; - src_tag--; - dst_point++; - dst_tag++; - } - } - - left->num_points = left->start; - right->num_points += new_points; - - right->movable = 0; - left->movable = 0; - } - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - /* there's a lot of magic in this function! */ - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_EndSubPath( FT_Stroker stroker ) - { - FT_Error error = 0; - - if ( stroker->subpath_open ) - { - FT_StrokeBorder right = stroker->borders; - - /* All right, this is an opened path, we need to add a cap between */ - /* right & left, add the reverse of left, then add a final cap */ - /* between left & right. */ - error = ft_stroker_cap( stroker, stroker->angle_in, 0 ); - if ( error ) - goto Exit; - - /* add reversed points from "left" to "right" */ - error = ft_stroker_add_reverse_left( stroker, 1 ); - if ( error ) - goto Exit; - - /* now add the final cap */ - stroker->center = stroker->subpath_start; - error = ft_stroker_cap( stroker, - stroker->subpath_angle + FT_ANGLE_PI, 0 ); - if ( error ) - goto Exit; - - /* Now end the right subpath accordingly. The left one is */ - /* rewind and doesn't need further processing. */ - ft_stroke_border_close( right, 0 ); - } - else - { - FT_Angle turn; - FT_Int inside_side; - - /* close the path if needed */ - if ( stroker->center.x != stroker->subpath_start.x || - stroker->center.y != stroker->subpath_start.y ) - { - error = FT_Stroker_LineTo( stroker, &stroker->subpath_start ); - if ( error ) - goto Exit; - } - - /* process the corner */ - stroker->angle_out = stroker->subpath_angle; - turn = FT_Angle_Diff( stroker->angle_in, - stroker->angle_out ); - - /* no specific corner processing is required if the turn is 0 */ - if ( turn != 0 ) - { - /* when we turn to the right, the inside side is 0 */ - inside_side = 0; - - /* otherwise, the inside side is 1 */ - if ( turn < 0 ) - inside_side = 1; - - error = ft_stroker_inside( stroker, inside_side ); - if ( error ) - goto Exit; - - /* process the outside side */ - error = ft_stroker_outside( stroker, 1 - inside_side ); - if ( error ) - goto Exit; - } - - /* then end our two subpaths */ - ft_stroke_border_close( stroker->borders + 0, 1 ); - ft_stroke_border_close( stroker->borders + 1, 0 ); - } - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_GetBorderCounts( FT_Stroker stroker, - FT_StrokerBorder border, - FT_UInt *anum_points, - FT_UInt *anum_contours ) - { - FT_UInt num_points = 0, num_contours = 0; - FT_Error error; - - - if ( !stroker || border > 1 ) - { - error = FT_Err_Invalid_Argument; - goto Exit; - } - - error = ft_stroke_border_get_counts( stroker->borders + border, - &num_points, &num_contours ); - Exit: - if ( anum_points ) - *anum_points = num_points; - - if ( anum_contours ) - *anum_contours = num_contours; - - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_GetCounts( FT_Stroker stroker, - FT_UInt *anum_points, - FT_UInt *anum_contours ) - { - FT_UInt count1, count2, num_points = 0; - FT_UInt count3, count4, num_contours = 0; - FT_Error error; - - - error = ft_stroke_border_get_counts( stroker->borders + 0, - &count1, &count2 ); - if ( error ) - goto Exit; - - error = ft_stroke_border_get_counts( stroker->borders + 1, - &count3, &count4 ); - if ( error ) - goto Exit; - - num_points = count1 + count3; - num_contours = count2 + count4; - - Exit: - *anum_points = num_points; - *anum_contours = num_contours; - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( void ) - FT_Stroker_ExportBorder( FT_Stroker stroker, - FT_StrokerBorder border, - FT_Outline* outline ) - { - if ( border == FT_STROKER_BORDER_LEFT || - border == FT_STROKER_BORDER_RIGHT ) - { - FT_StrokeBorder sborder = & stroker->borders[border]; - - - if ( sborder->valid ) - ft_stroke_border_export( sborder, outline ); - } - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( void ) - FT_Stroker_Export( FT_Stroker stroker, - FT_Outline* outline ) - { - FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_LEFT, outline ); - FT_Stroker_ExportBorder( stroker, FT_STROKER_BORDER_RIGHT, outline ); - } - - - /* documentation is in ftstroke.h */ - - /* - * The following is very similar to FT_Outline_Decompose, except - * that we do support opened paths, and do not scale the outline. - */ - FT_EXPORT_DEF( FT_Error ) - FT_Stroker_ParseOutline( FT_Stroker stroker, - FT_Outline* outline, - FT_Bool opened ) - { - FT_Vector v_last; - FT_Vector v_control; - FT_Vector v_start; - - FT_Vector* point; - FT_Vector* limit; - char* tags; - - FT_Error error; - - FT_Int n; /* index of contour in outline */ - FT_UInt first; /* index of first point in contour */ - FT_Int tag; /* current point's state */ - - - if ( !outline || !stroker ) - return FT_Err_Invalid_Argument; - - FT_Stroker_Rewind( stroker ); - - first = 0; - - for ( n = 0; n < outline->n_contours; n++ ) - { - FT_UInt last; /* index of last point in contour */ - - - last = outline->contours[n]; - limit = outline->points + last; - - /* skip empty points; we don't stroke these */ - if ( last <= first ) - { - first = last + 1; - continue; - } - - v_start = outline->points[first]; - v_last = outline->points[last]; - - v_control = v_start; - - point = outline->points + first; - tags = outline->tags + first; - tag = FT_CURVE_TAG( tags[0] ); - - /* A contour cannot start with a cubic control point! */ - if ( tag == FT_CURVE_TAG_CUBIC ) - goto Invalid_Outline; - - /* check first point to determine origin */ - if ( tag == FT_CURVE_TAG_CONIC ) - { - /* First point is conic control. Yes, this happens. */ - if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) - { - /* start at last point if it is on the curve */ - v_start = v_last; - limit--; - } - else - { - /* if both first and last points are conic, */ - /* start at their middle and record its position */ - /* for closure */ - v_start.x = ( v_start.x + v_last.x ) / 2; - v_start.y = ( v_start.y + v_last.y ) / 2; - - v_last = v_start; - } - point--; - tags--; - } - - error = FT_Stroker_BeginSubPath( stroker, &v_start, opened ); - if ( error ) - goto Exit; - - while ( point < limit ) - { - point++; - tags++; - - tag = FT_CURVE_TAG( tags[0] ); - switch ( tag ) - { - case FT_CURVE_TAG_ON: /* emit a single line_to */ - { - FT_Vector vec; - - - vec.x = point->x; - vec.y = point->y; - - error = FT_Stroker_LineTo( stroker, &vec ); - if ( error ) - goto Exit; - continue; - } - - case FT_CURVE_TAG_CONIC: /* consume conic arcs */ - v_control.x = point->x; - v_control.y = point->y; - - Do_Conic: - if ( point < limit ) - { - FT_Vector vec; - FT_Vector v_middle; - - - point++; - tags++; - tag = FT_CURVE_TAG( tags[0] ); - - vec = point[0]; - - if ( tag == FT_CURVE_TAG_ON ) - { - error = FT_Stroker_ConicTo( stroker, &v_control, &vec ); - if ( error ) - goto Exit; - continue; - } - - if ( tag != FT_CURVE_TAG_CONIC ) - goto Invalid_Outline; - - v_middle.x = ( v_control.x + vec.x ) / 2; - v_middle.y = ( v_control.y + vec.y ) / 2; - - error = FT_Stroker_ConicTo( stroker, &v_control, &v_middle ); - if ( error ) - goto Exit; - - v_control = vec; - goto Do_Conic; - } - - error = FT_Stroker_ConicTo( stroker, &v_control, &v_start ); - goto Close; - - default: /* FT_CURVE_TAG_CUBIC */ - { - FT_Vector vec1, vec2; - - - if ( point + 1 > limit || - FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) - goto Invalid_Outline; - - point += 2; - tags += 2; - - vec1 = point[-2]; - vec2 = point[-1]; - - if ( point <= limit ) - { - FT_Vector vec; - - - vec = point[0]; - - error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &vec ); - if ( error ) - goto Exit; - continue; - } - - error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &v_start ); - goto Close; - } - } - } - - Close: - if ( error ) - goto Exit; - - error = FT_Stroker_EndSubPath( stroker ); - if ( error ) - goto Exit; - - first = last + 1; - } - - return 0; - - Exit: - return error; - - Invalid_Outline: - return FT_Err_Invalid_Outline; - } - - - extern const FT_Glyph_Class ft_outline_glyph_class; - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Glyph_Stroke( FT_Glyph *pglyph, - FT_Stroker stroker, - FT_Bool destroy ) - { - FT_Error error = FT_Err_Invalid_Argument; - FT_Glyph glyph = NULL; - - - if ( pglyph == NULL ) - goto Exit; - - glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class ) - goto Exit; - - { - FT_Glyph copy; - - - error = FT_Glyph_Copy( glyph, © ); - if ( error ) - goto Exit; - - glyph = copy; - } - - { - FT_OutlineGlyph oglyph = (FT_OutlineGlyph) glyph; - FT_Outline* outline = &oglyph->outline; - FT_UInt num_points, num_contours; - - - error = FT_Stroker_ParseOutline( stroker, outline, 0 ); - if ( error ) - goto Fail; - - (void)FT_Stroker_GetCounts( stroker, &num_points, &num_contours ); - - FT_Outline_Done( glyph->library, outline ); - - error = FT_Outline_New( glyph->library, - num_points, num_contours, outline ); - if ( error ) - goto Fail; - - outline->n_points = 0; - outline->n_contours = 0; - - FT_Stroker_Export( stroker, outline ); - } - - if ( destroy ) - FT_Done_Glyph( *pglyph ); - - *pglyph = glyph; - goto Exit; - - Fail: - FT_Done_Glyph( glyph ); - glyph = NULL; - - if ( !destroy ) - *pglyph = NULL; - - Exit: - return error; - } - - - /* documentation is in ftstroke.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Glyph_StrokeBorder( FT_Glyph *pglyph, - FT_Stroker stroker, - FT_Bool inside, - FT_Bool destroy ) - { - FT_Error error = FT_Err_Invalid_Argument; - FT_Glyph glyph = NULL; - - - if ( pglyph == NULL ) - goto Exit; - - glyph = *pglyph; - if ( glyph == NULL || glyph->clazz != &ft_outline_glyph_class ) - goto Exit; - - { - FT_Glyph copy; - - - error = FT_Glyph_Copy( glyph, © ); - if ( error ) - goto Exit; - - glyph = copy; - } - - { - FT_OutlineGlyph oglyph = (FT_OutlineGlyph) glyph; - FT_StrokerBorder border; - FT_Outline* outline = &oglyph->outline; - FT_UInt num_points, num_contours; - - - border = FT_Outline_GetOutsideBorder( outline ); - if ( inside ) - { - if ( border == FT_STROKER_BORDER_LEFT ) - border = FT_STROKER_BORDER_RIGHT; - else - border = FT_STROKER_BORDER_LEFT; - } - - error = FT_Stroker_ParseOutline( stroker, outline, 0 ); - if ( error ) - goto Fail; - - (void)FT_Stroker_GetBorderCounts( stroker, border, - &num_points, &num_contours ); - - FT_Outline_Done( glyph->library, outline ); - - error = FT_Outline_New( glyph->library, - num_points, - num_contours, - outline ); - if ( error ) - goto Fail; - - outline->n_points = 0; - outline->n_contours = 0; - - FT_Stroker_ExportBorder( stroker, border, outline ); - } - - if ( destroy ) - FT_Done_Glyph( *pglyph ); - - *pglyph = glyph; - goto Exit; - - Fail: - FT_Done_Glyph( glyph ); - glyph = NULL; - - if ( !destroy ) - *pglyph = NULL; - - Exit: - return error; - } - - -/* END */ diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c deleted file mode 100644 index ff88ce9..0000000 --- a/src/base/ftsynth.c +++ /dev/null @@ -1,159 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsynth.c */ -/* */ -/* FreeType synthesizing code for emboldening and slanting (body). */ -/* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_SYNTHESIS_H -#include FT_INTERNAL_OBJECTS_H -#include FT_OUTLINE_H -#include FT_BITMAP_H - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** EXPERIMENTAL OBLIQUING SUPPORT ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - /* documentation is in ftsynth.h */ - - FT_EXPORT_DEF( void ) - FT_GlyphSlot_Oblique( FT_GlyphSlot slot ) - { - FT_Matrix transform; - FT_Outline* outline = &slot->outline; - - - /* only oblique outline glyphs */ - if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) - return; - - /* we don't touch the advance width */ - - /* For italic, simply apply a shear transform, with an angle */ - /* of about 12 degrees. */ - - transform.xx = 0x10000L; - transform.yx = 0x00000L; - - transform.xy = 0x06000L; - transform.yy = 0x10000L; - - FT_Outline_Transform( outline, &transform ); - } - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** EXPERIMENTAL EMBOLDENING/OUTLINING SUPPORT ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_EXPORT_DEF( FT_Error ) - FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ) - { - if ( slot && slot->format == FT_GLYPH_FORMAT_BITMAP && - !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) - { - FT_Bitmap bitmap; - FT_Error error; - - - FT_Bitmap_New( &bitmap ); - error = FT_Bitmap_Copy( slot->library, &slot->bitmap, &bitmap ); - if ( error ) - return error; - - slot->bitmap = bitmap; - slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - } - - return FT_Err_Ok; - } - - - /* documentation is in ftsynth.h */ - - FT_EXPORT_DEF( void ) - FT_GlyphSlot_Embolden( FT_GlyphSlot slot ) - { - FT_Library library = slot->library; - FT_Face face = FT_SLOT_FACE( slot ); - FT_Error error; - FT_Pos xstr, ystr; - - - if ( slot->format != FT_GLYPH_FORMAT_OUTLINE && - slot->format != FT_GLYPH_FORMAT_BITMAP ) - return; - - /* some reasonable strength */ - xstr = FT_MulFix( face->units_per_EM, - face->size->metrics.y_scale ) / 24; - ystr = xstr; - - if ( slot->format == FT_GLYPH_FORMAT_OUTLINE ) - { - error = FT_Outline_Embolden( &slot->outline, xstr ); - /* ignore error */ - - /* this is more than enough for most glyphs; if you need accurate */ - /* values, you have to call FT_Outline_Get_CBox */ - xstr = xstr * 2; - ystr = xstr; - } - else if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) - { - xstr = FT_PIX_FLOOR( xstr ); - if ( xstr == 0 ) - xstr = 1 << 6; - ystr = FT_PIX_FLOOR( ystr ); - - error = FT_GlyphSlot_Own_Bitmap( slot ); - if ( error ) - return; - - error = FT_Bitmap_Embolden( library, &slot->bitmap, xstr, ystr ); - if ( error ) - return; - } - - if ( slot->advance.x ) - slot->advance.x += xstr; - - if ( slot->advance.y ) - slot->advance.y += ystr; - - slot->metrics.width += xstr; - slot->metrics.height += ystr; - slot->metrics.horiBearingY += ystr; - slot->metrics.horiAdvance += xstr; - slot->metrics.vertBearingX -= xstr / 2; - slot->metrics.vertBearingY += ystr; - slot->metrics.vertAdvance += ystr; - - if ( slot->format == FT_GLYPH_FORMAT_BITMAP ) - slot->bitmap_top += ystr >> 6; - } - - -/* END */ diff --git a/src/base/ftsystem.c b/src/base/ftsystem.c deleted file mode 100644 index f61a3ed..0000000 --- a/src/base/ftsystem.c +++ /dev/null @@ -1,301 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftsystem.c */ -/* */ -/* ANSI-specific FreeType low-level system interface (body). */ -/* */ -/* Copyright 1996-2001, 2002, 2006 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - /*************************************************************************/ - /* */ - /* This file contains the default interface used by FreeType to access */ - /* low-level, i.e. memory management, i/o access as well as thread */ - /* synchronisation. It can be replaced by user-specific routines if */ - /* necessary. */ - /* */ - /*************************************************************************/ - - -#include <ft2build.h> -#include FT_CONFIG_CONFIG_H -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_SYSTEM_H -#include FT_ERRORS_H -#include FT_TYPES_H - - - /*************************************************************************/ - /* */ - /* MEMORY MANAGEMENT INTERFACE */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* It is not necessary to do any error checking for the */ - /* allocation-related functions. This will be done by the higher level */ - /* routines like ft_mem_alloc() or ft_mem_realloc(). */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_alloc */ - /* */ - /* <Description> */ - /* The memory allocation function. */ - /* */ - /* <Input> */ - /* memory :: A pointer to the memory object. */ - /* */ - /* size :: The requested size in bytes. */ - /* */ - /* <Return> */ - /* The address of newly allocated block. */ - /* */ - FT_CALLBACK_DEF( void* ) - ft_alloc( FT_Memory memory, - long size ) - { - FT_UNUSED( memory ); - - return ft_smalloc( size ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_realloc */ - /* */ - /* <Description> */ - /* The memory reallocation function. */ - /* */ - /* <Input> */ - /* memory :: A pointer to the memory object. */ - /* */ - /* cur_size :: The current size of the allocated memory block. */ - /* */ - /* new_size :: The newly requested size in bytes. */ - /* */ - /* block :: The current address of the block in memory. */ - /* */ - /* <Return> */ - /* The address of the reallocated memory block. */ - /* */ - FT_CALLBACK_DEF( void* ) - ft_realloc( FT_Memory memory, - long cur_size, - long new_size, - void* block ) - { - FT_UNUSED( memory ); - FT_UNUSED( cur_size ); - - return ft_srealloc( block, new_size ); - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_free */ - /* */ - /* <Description> */ - /* The memory release function. */ - /* */ - /* <Input> */ - /* memory :: A pointer to the memory object. */ - /* */ - /* block :: The address of block in memory to be freed. */ - /* */ - FT_CALLBACK_DEF( void ) - ft_free( FT_Memory memory, - void* block ) - { - FT_UNUSED( memory ); - - ft_sfree( block ); - } - - - /*************************************************************************/ - /* */ - /* RESOURCE MANAGEMENT INTERFACE */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_io - - /* We use the macro STREAM_FILE for convenience to extract the */ - /* system-specific stream handle from a given FreeType stream object */ -#define STREAM_FILE( stream ) ( (FT_FILE*)stream->descriptor.pointer ) - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_ansi_stream_close */ - /* */ - /* <Description> */ - /* The function to close a stream. */ - /* */ - /* <Input> */ - /* stream :: A pointer to the stream object. */ - /* */ - FT_CALLBACK_DEF( void ) - ft_ansi_stream_close( FT_Stream stream ) - { - ft_fclose( STREAM_FILE( stream ) ); - - stream->descriptor.pointer = NULL; - stream->size = 0; - stream->base = 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* ft_ansi_stream_io */ - /* */ - /* <Description> */ - /* The function to open a stream. */ - /* */ - /* <Input> */ - /* stream :: A pointer to the stream object. */ - /* */ - /* offset :: The position in the data stream to start reading. */ - /* */ - /* buffer :: The address of buffer to store the read data. */ - /* */ - /* count :: The number of bytes to read from the stream. */ - /* */ - /* <Return> */ - /* The number of bytes actually read. */ - /* */ - FT_CALLBACK_DEF( unsigned long ) - ft_ansi_stream_io( FT_Stream stream, - unsigned long offset, - unsigned char* buffer, - unsigned long count ) - { - FT_FILE* file; - - - file = STREAM_FILE( stream ); - - ft_fseek( file, offset, SEEK_SET ); - - return (unsigned long)ft_fread( buffer, 1, count, file ); - } - - - /* documentation is in ftstream.h */ - - FT_BASE_DEF( FT_Error ) - FT_Stream_Open( FT_Stream stream, - const char* filepathname ) - { - FT_FILE* file; - - - if ( !stream ) - return FT_Err_Invalid_Stream_Handle; - - file = ft_fopen( filepathname, "rb" ); - if ( !file ) - { - FT_ERROR(( "FT_Stream_Open:" )); - FT_ERROR(( " could not open `%s'\n", filepathname )); - - return FT_Err_Cannot_Open_Resource; - } - - ft_fseek( file, 0, SEEK_END ); - stream->size = ft_ftell( file ); - ft_fseek( file, 0, SEEK_SET ); - - stream->descriptor.pointer = file; - stream->pathname.pointer = (char*)filepathname; - stream->pos = 0; - - stream->read = ft_ansi_stream_io; - stream->close = ft_ansi_stream_close; - - FT_TRACE1(( "FT_Stream_Open:" )); - FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", - filepathname, stream->size )); - - return FT_Err_Ok; - } - - -#ifdef FT_DEBUG_MEMORY - - extern FT_Int - ft_mem_debug_init( FT_Memory memory ); - - extern void - ft_mem_debug_done( FT_Memory memory ); - -#endif - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( FT_Memory ) - FT_New_Memory( void ) - { - FT_Memory memory; - - - memory = (FT_Memory)ft_smalloc( sizeof ( *memory ) ); - if ( memory ) - { - memory->user = 0; - memory->alloc = ft_alloc; - memory->realloc = ft_realloc; - memory->free = ft_free; -#ifdef FT_DEBUG_MEMORY - ft_mem_debug_init( memory ); -#endif - } - - return memory; - } - - - /* documentation is in ftobjs.h */ - - FT_BASE_DEF( void ) - FT_Done_Memory( FT_Memory memory ) - { -#ifdef FT_DEBUG_MEMORY - ft_mem_debug_done( memory ); -#endif - memory->free( memory, memory ); - } - - -/* END */ diff --git a/src/base/fttrigon.c b/src/base/fttrigon.c deleted file mode 100644 index 9f51394..0000000 --- a/src/base/fttrigon.c +++ /dev/null @@ -1,546 +0,0 @@ -/***************************************************************************/ -/* */ -/* fttrigon.c */ -/* */ -/* FreeType trigonometric functions (body). */ -/* */ -/* Copyright 2001, 2002, 2003, 2004, 2005 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include FT_TRIGONOMETRY_H - - - /* the following is 0.2715717684432231 * 2^30 */ -#define FT_TRIG_COSCALE 0x11616E8EUL - - /* this table was generated for FT_PI = 180L << 16, i.e. degrees */ -#define FT_TRIG_MAX_ITERS 23 - - static const FT_Fixed - ft_trig_arctan_table[24] = - { - 4157273L, 2949120L, 1740967L, 919879L, 466945L, 234379L, 117304L, - 58666L, 29335L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L, - 57L, 29L, 14L, 7L, 4L, 2L, 1L - }; - - /* the Cordic shrink factor, multiplied by 2^32 */ -#define FT_TRIG_SCALE 1166391785UL /* 0x4585BA38UL */ - - -#ifdef FT_CONFIG_HAS_INT64 - - /* multiply a given value by the CORDIC shrink factor */ - static FT_Fixed - ft_trig_downscale( FT_Fixed val ) - { - FT_Fixed s; - FT_Int64 v; - - - s = val; - val = ( val >= 0 ) ? val : -val; - - v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL; - val = (FT_Fixed)( v >> 32 ); - - return ( s >= 0 ) ? val : -val; - } - -#else /* !FT_CONFIG_HAS_INT64 */ - - /* multiply a given value by the CORDIC shrink factor */ - static FT_Fixed - ft_trig_downscale( FT_Fixed val ) - { - FT_Fixed s; - FT_UInt32 v1, v2, k1, k2, hi, lo1, lo2, lo3; - - - s = val; - val = ( val >= 0 ) ? val : -val; - - v1 = (FT_UInt32)val >> 16; - v2 = (FT_UInt32)val & 0xFFFFL; - - k1 = FT_TRIG_SCALE >> 16; /* constant */ - k2 = FT_TRIG_SCALE & 0xFFFFL; /* constant */ - - hi = k1 * v1; - lo1 = k1 * v2 + k2 * v1; /* can't overflow */ - - lo2 = ( k2 * v2 ) >> 16; - lo3 = ( lo1 >= lo2 ) ? lo1 : lo2; - lo1 += lo2; - - hi += lo1 >> 16; - if ( lo1 < lo3 ) - hi += 0x10000UL; - - val = (FT_Fixed)hi; - - return ( s >= 0 ) ? val : -val; - } - -#endif /* !FT_CONFIG_HAS_INT64 */ - - - static FT_Int - ft_trig_prenorm( FT_Vector* vec ) - { - FT_Fixed x, y, z; - FT_Int shift; - - - x = vec->x; - y = vec->y; - - z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y ); - shift = 0; - -#if 1 - /* determine msb bit index in `shift' */ - if ( z >= ( 1L << 16 ) ) - { - z >>= 16; - shift += 16; - } - if ( z >= ( 1L << 8 ) ) - { - z >>= 8; - shift += 8; - } - if ( z >= ( 1L << 4 ) ) - { - z >>= 4; - shift += 4; - } - if ( z >= ( 1L << 2 ) ) - { - z >>= 2; - shift += 2; - } - if ( z >= ( 1L << 1 ) ) - { - z >>= 1; - shift += 1; - } - - if ( shift <= 27 ) - { - shift = 27 - shift; - vec->x = x << shift; - vec->y = y << shift; - } - else - { - shift -= 27; - vec->x = x >> shift; - vec->y = y >> shift; - shift = -shift; - } - -#else /* 0 */ - - if ( z < ( 1L << 27 ) ) - { - do - { - shift++; - z <<= 1; - } while ( z < ( 1L << 27 ) ); - vec->x = x << shift; - vec->y = y << shift; - } - else if ( z > ( 1L << 28 ) ) - { - do - { - shift++; - z >>= 1; - } while ( z > ( 1L << 28 ) ); - - vec->x = x >> shift; - vec->y = y >> shift; - shift = -shift; - } - -#endif /* 0 */ - - return shift; - } - - - static void - ft_trig_pseudo_rotate( FT_Vector* vec, - FT_Angle theta ) - { - FT_Int i; - FT_Fixed x, y, xtemp; - const FT_Fixed *arctanptr; - - - x = vec->x; - y = vec->y; - - /* Get angle between -90 and 90 degrees */ - while ( theta <= -FT_ANGLE_PI2 ) - { - x = -x; - y = -y; - theta += FT_ANGLE_PI; - } - - while ( theta > FT_ANGLE_PI2 ) - { - x = -x; - y = -y; - theta -= FT_ANGLE_PI; - } - - /* Initial pseudorotation, with left shift */ - arctanptr = ft_trig_arctan_table; - - if ( theta < 0 ) - { - xtemp = x + ( y << 1 ); - y = y - ( x << 1 ); - x = xtemp; - theta += *arctanptr++; - } - else - { - xtemp = x - ( y << 1 ); - y = y + ( x << 1 ); - x = xtemp; - theta -= *arctanptr++; - } - - /* Subsequent pseudorotations, with right shifts */ - i = 0; - do - { - if ( theta < 0 ) - { - xtemp = x + ( y >> i ); - y = y - ( x >> i ); - x = xtemp; - theta += *arctanptr++; - } - else - { - xtemp = x - ( y >> i ); - y = y + ( x >> i ); - x = xtemp; - theta -= *arctanptr++; - } - } while ( ++i < FT_TRIG_MAX_ITERS ); - - vec->x = x; - vec->y = y; - } - - - static void - ft_trig_pseudo_polarize( FT_Vector* vec ) - { - FT_Fixed theta; - FT_Fixed yi, i; - FT_Fixed x, y; - const FT_Fixed *arctanptr; - - - x = vec->x; - y = vec->y; - - /* Get the vector into the right half plane */ - theta = 0; - if ( x < 0 ) - { - x = -x; - y = -y; - theta = 2 * FT_ANGLE_PI2; - } - - if ( y > 0 ) - theta = - theta; - - arctanptr = ft_trig_arctan_table; - - if ( y < 0 ) - { - /* Rotate positive */ - yi = y + ( x << 1 ); - x = x - ( y << 1 ); - y = yi; - theta -= *arctanptr++; /* Subtract angle */ - } - else - { - /* Rotate negative */ - yi = y - ( x << 1 ); - x = x + ( y << 1 ); - y = yi; - theta += *arctanptr++; /* Add angle */ - } - - i = 0; - do - { - if ( y < 0 ) - { - /* Rotate positive */ - yi = y + ( x >> i ); - x = x - ( y >> i ); - y = yi; - theta -= *arctanptr++; - } - else - { - /* Rotate negative */ - yi = y - ( x >> i ); - x = x + ( y >> i ); - y = yi; - theta += *arctanptr++; - } - } while ( ++i < FT_TRIG_MAX_ITERS ); - - /* round theta */ - if ( theta >= 0 ) - theta = FT_PAD_ROUND( theta, 32 ); - else - theta = -FT_PAD_ROUND( -theta, 32 ); - - vec->x = x; - vec->y = theta; - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_Cos( FT_Angle angle ) - { - FT_Vector v; - - - v.x = FT_TRIG_COSCALE >> 2; - v.y = 0; - ft_trig_pseudo_rotate( &v, angle ); - - return v.x / ( 1 << 12 ); - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_Sin( FT_Angle angle ) - { - return FT_Cos( FT_ANGLE_PI2 - angle ); - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_Tan( FT_Angle angle ) - { - FT_Vector v; - - - v.x = FT_TRIG_COSCALE >> 2; - v.y = 0; - ft_trig_pseudo_rotate( &v, angle ); - - return FT_DivFix( v.y, v.x ); - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( FT_Angle ) - FT_Atan2( FT_Fixed dx, - FT_Fixed dy ) - { - FT_Vector v; - - - if ( dx == 0 && dy == 0 ) - return 0; - - v.x = dx; - v.y = dy; - ft_trig_prenorm( &v ); - ft_trig_pseudo_polarize( &v ); - - return v.y; - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( void ) - FT_Vector_Unit( FT_Vector* vec, - FT_Angle angle ) - { - vec->x = FT_TRIG_COSCALE >> 2; - vec->y = 0; - ft_trig_pseudo_rotate( vec, angle ); - vec->x >>= 12; - vec->y >>= 12; - } - - - /* these macros return 0 for positive numbers, - and -1 for negative ones */ -#define FT_SIGN_LONG( x ) ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) ) -#define FT_SIGN_INT( x ) ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) ) -#define FT_SIGN_INT32( x ) ( (x) >> 31 ) -#define FT_SIGN_INT16( x ) ( (x) >> 15 ) - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( void ) - FT_Vector_Rotate( FT_Vector* vec, - FT_Angle angle ) - { - FT_Int shift; - FT_Vector v; - - - v.x = vec->x; - v.y = vec->y; - - if ( angle && ( v.x != 0 || v.y != 0 ) ) - { - shift = ft_trig_prenorm( &v ); - ft_trig_pseudo_rotate( &v, angle ); - v.x = ft_trig_downscale( v.x ); - v.y = ft_trig_downscale( v.y ); - - if ( shift > 0 ) - { - FT_Int32 half = 1L << ( shift - 1 ); - - - vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; - vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; - } - else - { - shift = -shift; - vec->x = v.x << shift; - vec->y = v.y << shift; - } - } - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( FT_Fixed ) - FT_Vector_Length( FT_Vector* vec ) - { - FT_Int shift; - FT_Vector v; - - - v = *vec; - - /* handle trivial cases */ - if ( v.x == 0 ) - { - return ( v.y >= 0 ) ? v.y : -v.y; - } - else if ( v.y == 0 ) - { - return ( v.x >= 0 ) ? v.x : -v.x; - } - - /* general case */ - shift = ft_trig_prenorm( &v ); - ft_trig_pseudo_polarize( &v ); - - v.x = ft_trig_downscale( v.x ); - - if ( shift > 0 ) - return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift; - - return v.x << -shift; - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( void ) - FT_Vector_Polarize( FT_Vector* vec, - FT_Fixed *length, - FT_Angle *angle ) - { - FT_Int shift; - FT_Vector v; - - - v = *vec; - - if ( v.x == 0 && v.y == 0 ) - return; - - shift = ft_trig_prenorm( &v ); - ft_trig_pseudo_polarize( &v ); - - v.x = ft_trig_downscale( v.x ); - - *length = ( shift >= 0 ) ? ( v.x >> shift ) : ( v.x << -shift ); - *angle = v.y; - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( void ) - FT_Vector_From_Polar( FT_Vector* vec, - FT_Fixed length, - FT_Angle angle ) - { - vec->x = length; - vec->y = 0; - - FT_Vector_Rotate( vec, angle ); - } - - - /* documentation is in fttrigon.h */ - - FT_EXPORT_DEF( FT_Angle ) - FT_Angle_Diff( FT_Angle angle1, - FT_Angle angle2 ) - { - FT_Angle delta = angle2 - angle1; - - - delta %= FT_ANGLE_2PI; - if ( delta < 0 ) - delta += FT_ANGLE_2PI; - - if ( delta > FT_ANGLE_PI ) - delta -= FT_ANGLE_2PI; - - return delta; - } - - -/* END */ diff --git a/src/base/ftutil.c b/src/base/ftutil.c deleted file mode 100644 index 5f77be5..0000000 --- a/src/base/ftutil.c +++ /dev/null @@ -1,501 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftutil.c */ -/* */ -/* FreeType utility file for memory and list management (body). */ -/* */ -/* Copyright 2002, 2004, 2005, 2006, 2007 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_MEMORY_H -#include FT_INTERNAL_OBJECTS_H -#include FT_LIST_H - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_memory - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** *****/ - /***** M E M O R Y M A N A G E M E N T *****/ - /***** *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - FT_BASE_DEF( FT_Pointer ) - ft_mem_alloc( FT_Memory memory, - FT_Long size, - FT_Error *p_error ) - { - FT_Error error; - FT_Pointer block = ft_mem_qalloc( memory, size, &error ); - - if ( !error && size > 0 ) - FT_MEM_ZERO( block, size ); - - *p_error = error; - return block; - } - - - FT_BASE_DEF( FT_Pointer ) - ft_mem_qalloc( FT_Memory memory, - FT_Long size, - FT_Error *p_error ) - { - FT_Error error = FT_Err_Ok; - FT_Pointer block = NULL; - - - if ( size > 0 ) - { - block = memory->alloc( memory, size ); - if ( block == NULL ) - error = FT_Err_Out_Of_Memory; - } - else if ( size < 0 ) - { - /* may help catch/prevent security issues */ - error = FT_Err_Invalid_Argument; - } - - *p_error = error; - return block; - } - - - FT_BASE_DEF( FT_Pointer ) - ft_mem_realloc( FT_Memory memory, - FT_Long item_size, - FT_Long cur_count, - FT_Long new_count, - void* block, - FT_Error *p_error ) - { - FT_Error error = FT_Err_Ok; - - block = ft_mem_qrealloc( memory, item_size, - cur_count, new_count, block, &error ); - if ( !error && new_count > cur_count ) - FT_MEM_ZERO( (char*)block + cur_count * item_size, - ( new_count - cur_count ) * item_size ); - - *p_error = error; - return block; - } - - - FT_BASE_DEF( FT_Pointer ) - ft_mem_qrealloc( FT_Memory memory, - FT_Long item_size, - FT_Long cur_count, - FT_Long new_count, - void* block, - FT_Error *p_error ) - { - FT_Error error = FT_Err_Ok; - - - /* Note that we now accept `item_size == 0' as a valid parameter, in - * order to cover very weird cases where an ALLOC_MULT macro would be - * called. - */ - if ( cur_count < 0 || new_count < 0 || item_size < 0 ) - { - /* may help catch/prevent nasty security issues */ - error = FT_Err_Invalid_Argument; - } - else if ( new_count == 0 || item_size == 0 ) - { - ft_mem_free( memory, block ); - block = NULL; - } - else if ( new_count > FT_INT_MAX/item_size ) - { - error = FT_Err_Array_Too_Large; - } - else if ( cur_count == 0 ) - { - FT_ASSERT( block == NULL ); - - block = ft_mem_alloc( memory, new_count*item_size, &error ); - } - else - { - FT_Pointer block2; - FT_Long cur_size = cur_count*item_size; - FT_Long new_size = new_count*item_size; - - - block2 = memory->realloc( memory, cur_size, new_size, block ); - if ( block2 == NULL ) - error = FT_Err_Out_Of_Memory; - else - block = block2; - } - - *p_error = error; - return block; - } - - - FT_BASE_DEF( void ) - ft_mem_free( FT_Memory memory, - const void *P ) - { - if ( P ) - memory->free( memory, (void*)P ); - } - - - FT_BASE_DEF( FT_Pointer ) - ft_mem_dup( FT_Memory memory, - const void* address, - FT_ULong size, - FT_Error *p_error ) - { - FT_Error error; - FT_Pointer p = ft_mem_qalloc( memory, size, &error ); - - - if ( !error && address ) - ft_memcpy( p, address, size ); - - *p_error = error; - return p; - } - - - FT_BASE_DEF( FT_Pointer ) - ft_mem_strdup( FT_Memory memory, - const char* str, - FT_Error *p_error ) - { - FT_ULong len = str ? (FT_ULong)ft_strlen( str ) + 1 - : 0; - - - return ft_mem_dup( memory, str, len, p_error ); - } - - - FT_BASE_DEF( FT_Int ) - ft_mem_strcpyn( char* dst, - const char* src, - FT_ULong size ) - { - while ( size > 1 && *src != 0 ) - { - *dst++ = *src++; - size--; - } - - *dst = 0; /* always zero-terminate */ - - return *src != 0; - } - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /***** *****/ - /***** *****/ - /***** D O U B L Y L I N K E D L I S T S *****/ - /***** *****/ - /***** *****/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - -#undef FT_COMPONENT -#define FT_COMPONENT trace_list - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( FT_ListNode ) - FT_List_Find( FT_List list, - void* data ) - { - FT_ListNode cur; - - - cur = list->head; - while ( cur ) - { - if ( cur->data == data ) - return cur; - - cur = cur->next; - } - - return (FT_ListNode)0; - } - - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( void ) - FT_List_Add( FT_List list, - FT_ListNode node ) - { - FT_ListNode before = list->tail; - - - node->next = 0; - node->prev = before; - - if ( before ) - before->next = node; - else - list->head = node; - - list->tail = node; - } - - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( void ) - FT_List_Insert( FT_List list, - FT_ListNode node ) - { - FT_ListNode after = list->head; - - - node->next = after; - node->prev = 0; - - if ( !after ) - list->tail = node; - else - after->prev = node; - - list->head = node; - } - - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( void ) - FT_List_Remove( FT_List list, - FT_ListNode node ) - { - FT_ListNode before, after; - - - before = node->prev; - after = node->next; - - if ( before ) - before->next = after; - else - list->head = after; - - if ( after ) - after->prev = before; - else - list->tail = before; - } - - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( void ) - FT_List_Up( FT_List list, - FT_ListNode node ) - { - FT_ListNode before, after; - - - before = node->prev; - after = node->next; - - /* check whether we are already on top of the list */ - if ( !before ) - return; - - before->next = after; - - if ( after ) - after->prev = before; - else - list->tail = before; - - node->prev = 0; - node->next = list->head; - list->head->prev = node; - list->head = node; - } - - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_List_Iterate( FT_List list, - FT_List_Iterator iterator, - void* user ) - { - FT_ListNode cur = list->head; - FT_Error error = FT_Err_Ok; - - - while ( cur ) - { - FT_ListNode next = cur->next; - - - error = iterator( cur, user ); - if ( error ) - break; - - cur = next; - } - - return error; - } - - - /* documentation is in ftlist.h */ - - FT_EXPORT_DEF( void ) - FT_List_Finalize( FT_List list, - FT_List_Destructor destroy, - FT_Memory memory, - void* user ) - { - FT_ListNode cur; - - - cur = list->head; - while ( cur ) - { - FT_ListNode next = cur->next; - void* data = cur->data; - - - if ( destroy ) - destroy( memory, data, user ); - - FT_FREE( cur ); - cur = next; - } - - list->head = 0; - list->tail = 0; - } - - - FT_BASE_DEF( FT_UInt32 ) - ft_highpow2( FT_UInt32 value ) - { - FT_UInt32 value2; - - - /* - * We simply clear the lowest bit in each iteration. When - * we reach 0, we know that the previous value was our result. - */ - for ( ;; ) - { - value2 = value & (value - 1); /* clear lowest bit */ - if ( value2 == 0 ) - break; - - value = value2; - } - return value; - } - - -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS - - FT_BASE_DEF( FT_Error ) - FT_Alloc( FT_Memory memory, - FT_Long size, - void* *P ) - { - FT_Error error; - - - (void)FT_ALLOC( *P, size ); - return error; - } - - - FT_BASE_DEF( FT_Error ) - FT_QAlloc( FT_Memory memory, - FT_Long size, - void* *p ) - { - FT_Error error; - - - (void)FT_QALLOC( *p, size ); - return error; - } - - - FT_BASE_DEF( FT_Error ) - FT_Realloc( FT_Memory memory, - FT_Long current, - FT_Long size, - void* *P ) - { - FT_Error error; - - - (void)FT_REALLOC( *P, current, size ); - return error; - } - - - FT_BASE_DEF( FT_Error ) - FT_QRealloc( FT_Memory memory, - FT_Long current, - FT_Long size, - void* *p ) - { - FT_Error error; - - - (void)FT_QREALLOC( *p, current, size ); - return error; - } - - - FT_BASE_DEF( void ) - FT_Free( FT_Memory memory, - void* *P ) - { - if ( *P ) - FT_MEM_FREE( *P ); - } - -#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ - -/* END */ diff --git a/src/base/ftwinfnt.c b/src/base/ftwinfnt.c deleted file mode 100644 index bc2e90e..0000000 --- a/src/base/ftwinfnt.c +++ /dev/null @@ -1,51 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftwinfnt.c */ -/* */ -/* FreeType API for accessing Windows FNT specific info (body). */ -/* */ -/* Copyright 2003, 2004 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_WINFONTS_H -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_WINFNT_H - - - /* documentation is in ftwinfnt.h */ - - FT_EXPORT_DEF( FT_Error ) - FT_Get_WinFNT_Header( FT_Face face, - FT_WinFNT_HeaderRec *header ) - { - FT_Service_WinFnt service; - FT_Error error; - - - error = FT_Err_Invalid_Argument; - - if ( face != NULL ) - { - FT_FACE_LOOKUP_SERVICE( face, service, WINFNT ); - - if ( service != NULL ) - { - error = service->get_header( face, header ); - } - } - - return error; - } - - -/* END */ diff --git a/src/base/ftxf86.c b/src/base/ftxf86.c deleted file mode 100644 index a4bf767..0000000 --- a/src/base/ftxf86.c +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftxf86.c */ -/* */ -/* FreeType utility file for X11 support (body). */ -/* */ -/* Copyright 2002, 2003, 2004 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include <ft2build.h> -#include FT_XFREE86_H -#include FT_INTERNAL_OBJECTS_H -#include FT_SERVICE_XFREE86_NAME_H - - - /* documentation is in ftxf86.h */ - - FT_EXPORT_DEF( const char* ) - FT_Get_X11_Font_Format( FT_Face face ) - { - const char* result = NULL; - - - if ( face ) - FT_FACE_FIND_SERVICE( face, result, XF86_NAME ); - - return result; - } - - -/* END */ |