(******************************************************************* * * FreeType.Pas * * High-level interface specification. * * Copyright 1996 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. * * Notes : * * This is the only file that should be included by client * application sources for the final release. All other types * and functions defined in the "tt*.h" files are library * internals, and should not be included ( except of course * during development, as now ) * ******************************************************************) unit FreeType; interface type {$IFDEF OS2} TT_Int = Longint; {$ELSE} TT_Int = Integer; {$ENDIF} TT_Long = longint; TT_ULong = longint; (* there are no unsigned longs in Pascal :-( *) (* it will probably be a good idea to use cardinals *) (* with Delphi and Virtual a bit later.. *) TT_Short = integer; TT_UShort = word; TT_Fixed = LongInt; (* Signed Fixed 16.16 Float *) TT_FWord = Integer; (* Distance in FUnits *) TT_UFWord = Word; (* Unsigned Distance *) TT_F2Dot14 = Integer; (* signed fixed float 2.14 used for *) (* unary vectors, with layout : *) (* *) (* s : 1 -- sign bit *) (* m : 1 -- mantissa bit *) (* f : 14 -- unsigned fractional *) (* *) (* 's:m' is the 2-bit signed int *) (* value to which the *positive* *) (* fractional part should be *) (* added. *) (* *) TT_F26Dot6 = LongInt; (* 26.6 fixed float, used for pixel coordinates *) TT_Pos = Longint; (* funits or 26.6, depending on context *) (******************************************************) (* a simple unit vector type *) (* *) TT_UnitVector = record x : TT_F2Dot14; y : TT_F2Dot14; end; (******************************************************) (* a simple vector type *) (* *) TT_Vector = record x : TT_Pos; y : TT_Pos; end; (******************************************************) (* a simple 2x2 matrix type *) (* *) TT_Matrix = record xx, xy : TT_Fixed; yx, yy : TT_Fixed; end; (******************************************************) (* a glyph's bounding box *) (* *) TT_BBox = record xMin, yMin : TT_Pos; xMax, yMax : TT_Pos; end; (******************************************************) (* the engine's error condition type - 0 always *) (* means success. *) (* *) TT_Error = TT_Int; TT_Points_Table = array[0..99] of TT_Vector; TT_Points = ^TT_Points_Table; TT_Coordinates = array[0..99] of TT_Pos; TT_PCoordinates = ^TT_Coordinates; TT_TouchTable = array[0..9] of byte; TT_PTouchTable = ^TT_TouchTable; TT_ConStarts = array[0..9] of word; TT_PConStarts = ^TT_ConStarts; (******************************************************) (* glyph outline description *) (* *) TT_Outline = record n_points : integer; n_contours : integer; points : TT_Points; (* array of point coordinates *) flags : TT_PTouchTable; (* array of point flags *) conEnds : TT_PConStarts; (* array of contours ends *) owner : Boolean; (* this flag is set when the outline *) (* owns the arrays it uses. *) high_precision : Boolean; second_pass : Boolean; dropout_mode : Byte; end; (******************************************************) (* glyph metrics structure *) (* *) TT_Glyph_Metrics = record bbox : TT_BBox; bearingX : TT_Pos; bearingY : TT_Pos; advance : TT_Pos; end; (******************************************************) (* big glyph metrics structure *) (* *) TT_Big_Glyph_Metrics = record bbox : TT_BBox; horiBearingX : TT_Pos; horiBearingY : TT_Pos; horiAdvance : TT_Pos; vertBearingX : TT_Pos; vertBearingY : TT_Pos; vertAdvance : TT_Pos; end; (******************************************************) (* instance metrics. used to return information to *) (* clients regarding an instance's important state *) (* *) TT_Instance_Metrics = record pointsize : integer; x_ppem : integer; y_ppem : integer; x_scale : TT_Fixed; y_scale : TT_Fixed; x_resolution : integer; y_resolution : integer; end; const TT_Flow_Down = -1; TT_Flow_Up = +1; type (******************************************************) (* a record used to describe a bitmap or pixmap to *) (* the rasterizer. *) (* *) TT_Raster_Map = record Rows : TT_Int; (* rows number of the bitmap *) Cols : TT_Int; (* columns (bytes) per row *) Width : TT_Int; (* pixels per row *) Flow : TT_Int; (* bit/pixmap's flow *) Buffer : pointer; (* bit/pixmap data *) Size : longint; (* bit/pixmap data size (bytes) *) end; (******************************************************) (* The TrueType font header table structure *) (* *) TT_Header = record table_version : TT_Fixed; font_revision : TT_Fixed; checksum_adjust : TT_Long; magic_number : TT_Long; flags : TT_UShort; units_per_EM : TT_UShort; created : array[0..1] of TT_Long; modified : array[0..1] of TT_Long; xMin, yMin : TT_FWord; xMax, yMax : TT_FWord; mac_style : TT_UShort; lowest_rec_PPEM : TT_UShort; font_direction : TT_Short; index_to_loc_format : TT_Short; glyph_data_format : TT_Short; end; (******************************************************) (* The TrueType horizontal header table structure *) (* *) TT_Horizontal_Header = record version : TT_Fixed; ascender : TT_FWord; descender : TT_FWord; line_gap : TT_FWord; advance_Width_Max : TT_UShort; min_left_side_bearing : TT_Short; min_right_side_bearing : TT_Short; xMax_extent : TT_Short; caret_slope_rise : TT_Short; caret_slope_run : TT_Short; reserved : array[0..4] of TT_SHort; metric_data_format : TT_Short; number_of_HMetrics : TT_UShort; (* the following are not part of the header in the file *) short_metrics : Pointer; long_metrics : Pointer; end; (******************************************************) (* The TrueType vertical header table structure *) (* *) TT_Vertical_Header = record version : TT_Fixed; ascender : TT_FWord; descender : TT_FWord; line_gap : TT_FWord; advance_Height_Max : TT_UShort; min_top_side_bearing : TT_Short; min_bottom_side_bearing : TT_Short; yMax_extent : TT_Short; caret_slope_rise : TT_Short; caret_slope_run : TT_Short; reserved : array[0..4] of TT_SHort; metric_data_format : TT_Short; number_of_VMetrics : TT_UShort; (* the following are not part of the header in the file *) short_metrics : Pointer; long_metrics : Pointer; end; (******************************************************) (* The TrueType OS/2 table structure *) (* *) TT_OS2 = record version : TT_UShort; (* $0001 *) xAvgCharWidth : TT_Short; usWeightClass : TT_UShort; usWidthClass : TT_UShort; fsType : TT_Short; ySubscriptXSize : TT_Short; ySubscriptYSize : TT_Short; ySubScriptXOffset : TT_Short; ySubscriptYOffset : TT_Short; ySuperscriptXSize : TT_Short; ySuperscriptYSize : TT_Short; ySuperscriptXOffset : TT_Short; ySuperscriptYOffset : TT_Short; yStrikeoutSize : TT_Short; yStrikeoutPosition : TT_Short; sFamilyClass : TT_Short; panose : array[0..9] of Byte; ulUnicodeRange1 : TT_ULong; (* bits 0-31 *) ulUnicodeRange2 : TT_ULong; (* bits 32-63 *) ulUnicodeRange3 : TT_ULong; (* bits 64-95 *) ulUnicodeRange4 : TT_ULong; (* bits 96-127 *) achVendID : array[0..3] of Byte; fsSelection : TT_UShort; usFirstCharIndex : TT_UShort; usLastCharIndex : TT_UShort; sTypoAscender : TT_Short; sTypoDescender : TT_Short; sTypoLineGap : TT_Short; usWinAscent : TT_UShort; usWinDescent : TT_UShort; (* only version 1 tables *) ulCodePageRange1 : TT_ULong; ulCodePageRange2 : TT_ULong; end; (******************************************************) (* The TrueType Postscript table structure *) (* *) TT_Postscript = record FormatType : TT_Fixed; italicAngle : TT_Fixed; underlinePosition : TT_Short; underlineThickness : TT_Short; isFixedPitch : TT_ULong; minMemType42 : TT_ULong; maxMemType42 : TT_ULong; minMemType1 : TT_ULong; maxMemType1 : TT_ULong; end; (******************************************************) (* face properties. use to report important face *) (* data to clients *) (* *) TT_Face_Properties = record num_glyphs : integer; max_points : integer; max_contours : integer; max_faces : integer; header : ^TT_Header; horizontal : ^TT_Horizontal_Header; vertical : ^TT_Vertical_Header; os2 : ^TT_OS2; postscript : ^TT_Postscript; end; (******************************************************) (* Objects handle types *) (* *) TT_Stream = record z : Pointer; end; TT_Face = record z : Pointer; end; TT_Instance = record z : Pointer; end; TT_Glyph = record z : Pointer; end; TT_CharMap = record z : Pointer; end; TT_Gray_Palette = array[0..4] of byte; (******************************************************************) (* *) (* ERROR CODES *) (* *) (******************************************************************) const (* ------------------- Success is always 0 ---------------------- *) TT_Err_Ok = 0; (* -------------------------------------------------------------- *) TT_Err_Invalid_Face_Handle = $0001; TT_Err_Invalid_Instance_Handle = $0002; TT_Err_Invalid_Glyph_Handle = $0003; TT_Err_Invalid_CharMap_Handle = $0004; TT_Err_Invalid_Result_Address = $0005; TT_Err_Invalid_Glyph_Index = $0006; TT_Err_Invalid_Argument = $0007; TT_Err_Could_Not_Open_File = $0008; TT_Err_File_Is_Not_Collection = $0009; TT_Err_Table_Missing = $000A; TT_Err_Invalid_Horiz_Metrics = $000B; TT_Err_Invalid_Vert_Metrics = $000B; TT_Err_Invalid_CharMap_Format = $000C; TT_Err_Invalid_File_Format = $0010; TT_Err_File_Error = $0011; TT_Err_Invalid_Engine = $0020; TT_Err_Too_Many_Extensions = $0021; TT_Err_Extensions_Unsupported = $0022; TT_Err_Invalid_Extension_Id = $0023; TT_Err_No_Vertical_Data = $0030; TT_Err_Max_Profile_Missing = $0080; TT_Err_Header_Table_Missing = $0081; TT_Err_Horiz_Header_Missing = $0082; TT_Err_Locations_Missing = $0083; TT_Err_Name_Table_Missing = $0084; TT_Err_CMap_Table_Missing = $0085; TT_Err_Hmtx_Table_Missing = $0086; TT_Err_OS2_Table_Missing = $0087; TT_Err_Post_Table_Missing = $0088; (* -------------------------------------------------------------- *) TT_Err_Out_Of_Memory = $0100; (* -------------------------------------------------------------- *) TT_Err_Invalid_File_Offset = $0200; TT_Err_Invalid_File_Read = $0201; TT_Err_Invalid_Frame_Access = $0202; (* -------------------------------------------------------------- *) TT_Err_Too_Many_Points = $0300; TT_Err_Too_Many_Contours = $0301; TT_Err_Invalid_Composite = $0302; TT_Err_Too_Many_Ins = $0303; (* -------------------------------------------------------------- *) TT_Err_Invalid_Opcode = $0400; TT_Err_Too_Few_Arguments = $0401; TT_Err_Stack_Overflow = $0402; TT_Err_Code_Overflow = $0403; TT_Err_Bad_Argument = $0404; TT_Err_Divide_By_Zero = $0405; TT_Err_Storage_Overflow = $0406; TT_Err_Cvt_Overflow = $0407; TT_Err_Invalid_Reference = $0408; TT_Err_Invalid_Distance = $0409; TT_Err_Interpolate_Twilight = $040A; TT_Err_Debug_Opcode = $040B; TT_Err_ENDF_In_Exec_Stream = $040C; TT_Err_Out_Of_CodeRanges = $040D; TT_Err_Nested_DEFs = $040E; TT_Err_Invalid_CodeRange = $040F; TT_Err_Invalid_Displacement = $0410; TT_Err_Execution_Too_Long = $0411; TT_Err_Too_Many_FuncDefs = $0412; TT_Err_Too_Many_InsDefs = $0413; TT_Err_Nested_Frame_Access = $0500; TT_Err_Invalid_Cache_List = $0501; TT_Err_Could_Not_Find_Context = $0502; TT_Err_UNlisted_Object = $0503; TT_Err_Raster_Pool_Overflow = $0600; TT_Err_Raster_Negative_Height = $0601; TT_Err_Invalid_Value = $0602; TT_Err_Raster_Not_Initialised = $0603; (* -------------------------------------------------------------- *) (***********************************************************************) (* *) (* Base Library Functions *) (* *) (***********************************************************************) (*****************************************************************) (* Initialise the engine *) (* *) function TT_Init_FreeType : TT_Error; (*****************************************************************) (* Finalise the engine - discards all objects *) (* *) procedure TT_Done_FreeType; (*****************************************************************) (* Set the gray-level palette used for font-smoothing *) (* *) (* it is an array of 5 bytes following this convention : *) (* *) (* palette[0] := background (white) *) (* palette[1] := light *) (* palette[2] := medium *) (* palette[3] := dark *) (* palette[4] := foreground (black) *) (* *) function TT_Set_Raster_Palette( palette : TT_Gray_Palette ) : TT_Error; (***********************************************************************) (* *) (* Face Management functions *) (* *) (***********************************************************************) (*****************************************************************) (* Open a new font file and returns a handle for it in '_face' *) (* *) (* The file can be a TrueType collection, in which case the *) (* first embedded font will be loaded. *) (* *) function TT_Open_Face( fontname : string; var _face : TT_Face ) : TT_Error; (*****************************************************************) (* Open a font file embedded in a collection. *) (* *) function TT_Open_Collection( fontname : string; faceIndex : integer; var _face : TT_Face ) : TT_Error; (*****************************************************************) (* Return face properties in 'prop' *) (* *) function TT_Get_Face_Properties( _face : TT_Face; var prop : TT_Face_Properties ) : TT_Error; (*****************************************************************) (* Set face's generic pointer *) (* *) function TT_Set_Face_Pointer( _face : TT_Face; data : Pointer ) : TT_Error; (*****************************************************************) (* Get face's generic pointer *) (* *) function TT_Get_Face_Pointer( _face : TT_Face ) : Pointer; (*****************************************************************) (* close a given face object. This releases all child objects *) (* like instances and glyphs *) (* *) function TT_Close_Face( _face : TT_Face ) : TT_Error; (***********************************************************************) (* *) (* Instance management functions *) (* *) (***********************************************************************) (*****************************************************************) (* open a new face instance and return a handle in '_ins' *) (* *) function TT_New_Instance( _face : TT_Face; var _ins : TT_Instance ) : TT_Error; (*****************************************************************) (* set an instance's device resolutions, expressed in dpi *) (* *) function TT_Set_Instance_Resolutions( _ins : TT_Instance; x_resolution : Integer; y_resolution : Integer ) : TT_Error; (*****************************************************************) (* set an instance's point size (assumes width==height) *) (* *) function TT_Set_Instance_PointSize( _ins : TT_Instance; pointsize : Integer ) : TT_Error; (*****************************************************************) (* set an instance's point size (assumes width==height) *) (* *) function TT_Set_Instance_CharSize( _ins : TT_Instance; charsize : Integer ) : TT_Error; (*****************************************************************) (* set an instance's point size (assumes width==height) *) (* *) function TT_Set_Instance_CharSizes( _ins : TT_Instance; charsizex : Integer; charsizey : Integer ) : TT_Error; (*****************************************************************) (* set an instance's height and width, expressed in pixels *) (* *) function TT_Set_Instance_PixelSizes( _ins : TT_Instance; pixelX : Integer; pixelY : Integer; pointsize : Integer ) : TT_Error; (*****************************************************************) (* set an instance's height and width, expressed in pixels *) (* *) (*****************************************************************) (* the core truetype engine doesn't provide _direct_ support *) (* for rotation or stretching. This means that the transforms *) (* must be applied on the glyph outline by a higher-level *) (* library or the client application. However, we use two flags *) (* to notice the TrueType hinter that the glyphs will be *) (* transformed later. *) (* *) (* rotated : set if the glyphs are to be rotated *) (* distorted : set if the glyphs are to be distorted *) (* *) (* an application is any transform that doesn't keep distances *) (* constants. skewing and stretching are examples of distorsion *) (* *) function TT_Set_Instance_Transforms( _ins : TT_Instance; rotated : Boolean; distorted : Boolean ) : TT_Error; (*****************************************************************) (* Return instance metrics in 'm' *) (* *) function TT_Get_Instance_Metrics( _ins : TT_Instance; var m : TT_Instance_Metrics ) : TT_Error; (*****************************************************************) (* Set instance generic pointer *) (* *) function TT_Set_Instance_Pointer( _ins : TT_Instance; data : Pointer ) : TT_Error; (*****************************************************************) (* Get instance generic pointer *) (* *) function TT_Get_Instance_Pointer( _ins : TT_Instance ) : Pointer; (*****************************************************************) (* Close an instance *) (* *) function TT_Done_Instance( _ins : TT_Instance ) : TT_Error; (***********************************************************************) (* *) (* Glyph management functions *) (* *) (***********************************************************************) (*****************************************************************) (* Create a new glyph container, return a handle in '_glyph' *) (* *) function TT_New_Glyph( _face : TT_Face; var _glyph : TT_Glyph ) : TT_Error; (*****************************************************************) (* Releases a glyph container *) (* *) function TT_Done_Glyph( _glyph : TT_Glyph ) : TT_Error; (*****************************************************************) (* Load a glyph inside a container *) (* *) function TT_Load_Glyph( _instance : TT_Instance; _glyph : TT_Glyph; glyph_index : Word; load_flags : Integer ) : TT_Error; const TT_Load_Scale_Glyph = 1; (* ask the loader to scale the glyph *) (* to the current pointsize/transform *) TT_Load_Hint_Glyph = 2; (* when scaling is on, ask the loader *) (* to hint the glyph too.. *) TT_Load_Debug = 16; TT_Load_Default = TT_Load_Scale_Glyph or TT_Load_Hint_Glyph; (*****************************************************************) (* Get a glyph's outline *) (* *) function TT_Get_Glyph_Outline( _glyph : TT_Glyph; var outline : TT_Outline ) : TT_Error; (*****************************************************************) (* Get a glyph's metrics *) (* *) function TT_Get_Glyph_Metrics( _glyph : TT_Glyph; var gmetrics : TT_Glyph_Metrics ) : TT_Error; (*****************************************************************) (* Get a glyph's big metrics *) (* *) function TT_Get_Glyph_Big_Metrics( _glyph : TT_Glyph; var gmetrics : TT_Big_Glyph_Metrics ) : TT_Error; (*****************************************************************) (* Render a glyph's bitmap *) (* *) function TT_Get_Glyph_Bitmap( _glyph : TT_Glyph; var map : TT_Raster_Map; x_offset : TT_F26Dot6; y_offset : TT_F26Dot6 ) : TT_Error; (*****************************************************************) (* Render a glyph's pixmap (i.e. smoothed glyph ) *) (* *) function TT_Get_Glyph_Pixmap( _glyph : TT_Glyph; var map : TT_Raster_Map; x_offset : TT_F26Dot6; y_offset : TT_F26Dot6 ) : TT_Error; (***********************************************************************) (* *) (* Outline functions *) (* *) (***********************************************************************) (*****************************************************************) (* Apply translation to an outline *) (* *) function TT_Translate_Outline( var out : TT_Outline; x, y : TT_F26Dot6 ) : TT_Error; (*****************************************************************) (* Apply a 2x2 transform to an outline *) (* *) function TT_Transform_Outline( var out : TT_Outline; var mat : TT_Matrix ) : TT_Error; (*****************************************************************) (* Apply a 2x2 transform to a vector *) (* *) function TT_Transform_Vector( var x, y : TT_F26Dot6; var mat : TT_Matrix ) : TT_Error; (*****************************************************************) (* Render an outline into a bitmap *) (* *) function TT_Get_Outline_Bitmap( var out : TT_Outline; var map : TT_raster_Map ) : TT_Error; (*****************************************************************) (* Render an outline into a pixmap *) (* *) function TT_Get_Outline_Pixmap( var out : TT_Outline; var map : TT_raster_Map ) : TT_Error; (*****************************************************************) (* Get an outline's bounding box *) (* *) function TT_Get_Outline_BBox( var out : TT_Outline; var bbox : TT_Bbox ) : TT_Error; (*****************************************************************) (* Create a new glyph outline *) (* *) function TT_New_Outline( n_points : integer; n_contours : integer; var out : TT_Outline ) : TT_Error; (*****************************************************************) (* Copy a glyph outline into another one *) (* *) function TT_Copy_Outline( var source : TT_Outline; var target : TT_Outline ) : TT_Error; (*****************************************************************) (* Clone a given outline. This will create the outline, then *) (* copy the source in it *) (* *) function TT_Clone_Outline( var source : TT_Outline; var target : TT_Outline ) : TT_Error; (*****************************************************************) (* Discards a glyph outline *) (* *) function TT_Done_Outline( var out : TT_Outline ) : TT_Error; (***********************************************************************) (* *) (* Character Mapping support *) (* *) (***********************************************************************) (*****************************************************************) (* Get a face's number of character maps *) (* *) function TT_Get_CharMap_Count( face : TT_Face ) : integer; (*****************************************************************) (* Get a given char. map's ID in a face *) (* *) function TT_Get_CharMap_ID( face : TT_Face; charmapIndex : integer; var platform : integer; var encoding : integer ) : TT_Error; (*****************************************************************) (* Get a handle to a given char. map *) (* *) function TT_Get_CharMap( face : TT_Face; charmapIndex : integer; var charMap : TT_CharMap ) : TT_Error; (*****************************************************************) (* Translate from char. code to glyph index *) (* *) function TT_Char_Index( charmap : TT_CharMap; charCode : Longint ) : Word; (***********************************************************************) (* *) (* Names Table support *) (* *) (***********************************************************************) (*****************************************************************) (* Return number of name table entries *) (* *) function TT_Get_Name_Count( face : TT_Face ) : integer; (*****************************************************************) (* Return the ID of a given name table entry *) (* *) function TT_Get_Name_ID( face : TT_Face; nameIndex : integer; var platform : integer; var encoding : integer; var language : integer; var nameid : integer ) : TT_Error; (*****************************************************************) (* Return a given name table string *) (* *) function TT_Get_Name_String( face : TT_Face; nameIndex : integer; var str : Pointer; var len : integer ) : TT_Error; (***********************************************************************) (* *) (* Font Storage Access *) (* *) (***********************************************************************) (*****************************************************************) (* Access font data and copies it into user block *) (* *) function TT_Get_Font_Data( face : TT_Face; tableTag : Longint; offset : Longint; var buffer; var length : longint ) : TT_Error; implementation uses TTTypes, TTError, TTCalc, TTMemory, TTTables, TTCache, TTFile, TTCMap, TTObjs, TTLoad, TTGLoad, TTRaster, TTInterp; var raster_palette : TT_Gray_Palette; (*****************************************************************) (* *) (* *) function TT_Init_FreeType : TT_Error; begin if TTMemory_Init or TTCache_Init or TTFile_Init or TTObjs_Init or TTRaster_Init then begin TT_Init_FreeType := error; exit; end; TT_Init_FreeType := TT_Err_Ok; end; (*****************************************************************) (* *) (* *) procedure TT_Done_FreeType; begin TTRaster_Done; TTObjs_Done; TTFile_Done; TTCache_Done; TTMemory_Done; end; (*****************************************************************) (* *) (* *) function TT_Set_Raster_Palette( palette : TT_Gray_Palette ) : TT_Error; begin raster_palette := palette; TT_Set_Raster_Palette := TT_Err_Ok; end; (*****************************************************************) (* *) (* *) function TT_Open_Face( fontname : string; var _face : TT_Face ) : TT_Error; var input : TFont_Input; begin input.fontIndex := 0; if TT_Open_Stream( fontname, input.stream ) then begin TT_Open_Face := error; exit; end; Cache_New( face_cache, Pointer(_face), @input ); TT_Open_Face := error; end; (*****************************************************************) (* *) (* *) function TT_Open_Collection( fontname : string; faceIndex : integer; var _face : TT_Face ) : TT_Error; var input : TFont_Input; begin input.fontIndex := faceIndex; if TT_Open_Stream( fontname, input.stream ) then begin TT_Open_Collection := error; exit; end; Cache_New( face_cache, Pointer(_face), @input ); TT_Open_Collection := error; end; (*****************************************************************) (* *) (* *) function TT_Get_Face_Properties( _face : TT_Face; var prop : TT_Face_Properties ) : TT_Error; var face : PFace; begin face := _face.z; if face <> nil then begin with prop do begin num_Glyphs := face^.numGlyphs; max_Points := face^.maxPoints; max_Contours := face^.maxContours; max_Faces := face^.ttcHeader.dirCount; header := @face^.fontHeader; horizontal := @face^.horizontalHeader; if face^.verticalInfo then vertical := @face^.verticalHeader else vertical := nil; os2 := @face^.os2; postscript := @face^.postscript; end; TT_Get_Face_Properties := TT_Err_Ok; end else TT_Get_Face_Properties := TT_Err_Invalid_Face_Handle; end; (*****************************************************************) (* Set face's generic pointer *) (* *) function TT_Set_Face_Pointer( _face : TT_Face; data : Pointer ) : TT_Error; var face :PFace; begin face := PFace(_face.z); if face <> nil then begin face^.generic := data; TT_Set_Face_Pointer := TT_Err_Ok; end else TT_Set_Face_Pointer := TT_Err_Invalid_Face_Handle; end; (*****************************************************************) (* Get face's generic pointer *) (* *) function TT_Get_Face_Pointer( _face : TT_Face ) : Pointer; var face : PFace; begin face := PFace(_face.z); if face <> nil then TT_Get_Face_Pointer := face^.generic else TT_get_Face_Pointer := nil; end; (*****************************************************************) (* *) (* *) function TT_Close_Face( _face : TT_Face ) : TT_Error; var face : PFace; begin face := _face.z; if face <> nil then begin error := TT_Err_Ok; (* Note : the stream is closed by the face destructor !! *) Cache_Done( face_cache, _face.z ); TT_Close_Face := error; end else TT_Close_Face := TT_Err_Invalid_Face_Handle; end; (*****************************************************************) (* *) (* *) function TT_New_Instance( _face : TT_Face; var _ins : TT_Instance ) : TT_Error; var face : PFace; ins : PInstance; begin face := _face.z; if face <> nil then begin error := TT_Err_Ok; if not Cache_New( face^.instances, _ins.z, face ) then Instance_Init( _ins.z ); TT_New_Instance := error; end else TT_New_Instance := TT_Err_Invalid_Face_Handle; end; (*****************************************************************) (* *) (* *) function TT_Set_Instance_Resolutions( _ins : TT_Instance; x_resolution : Integer; y_resolution : Integer ) : TT_Error; var ins : PInstance; begin ins := _ins.z; if ins <> nil then begin ins^.metrics.x_resolution := x_resolution; ins^.metrics.y_resolution := y_resolution; ins^.valid := False; TT_Set_Instance_Resolutions := TT_Err_Ok; end else TT_Set_Instance_Resolutions := TT_Err_Invalid_Instance_Handle; end; (*****************************************************************) (* *) (* *) function TT_Set_Instance_CharSize( _ins : TT_Instance; charsize : Integer ) : TT_Error; var ins : PInstance; begin TT_Set_Instance_CharSize := TT_Set_Instance_CharSizes( _ins, charsize, charsize ); end; (*****************************************************************) (* *) (* *) function TT_Set_Instance_CharSizes( _ins : TT_Instance; charsizex : Integer; charsizey : Integer ) : TT_Error; var ins : PInstance; begin if (charsizex < 1*64) or (charsizey < 1*64) then begin TT_Set_Instance_CharSizes := TT_Err_Bad_Argument; exit; end; ins := _ins.z; if ins <> nil then begin with ins^.metrics do begin x_scale1 := ( Long(charsizex) * x_resolution ) div 72; x_scale2 := ins^.owner^.fontHeader.units_per_EM; y_scale1 := ( Long(charsizey) * y_resolution ) div 72; y_scale2 := x_scale2; if ins^.owner^.fontHeader.flags and 8 <> 0 then begin x_scale1 := (x_scale1 + 32) and -64; y_scale1 := (y_scale1 + 32) and -64; end; x_ppem := x_scale1 div 64; y_ppem := y_scale1 div 64; end; if charsizex > charsizey then ins^.metrics.pointsize := charsizex else ins^.metrics.pointsize := charsizey; ins^.valid := False; TT_Set_Instance_CharSizes := TT_Err_Ok; end else TT_Set_Instance_CharSizes := TT_Err_Invalid_Instance_Handle; end; (*****************************************************************) (* *) (* *) function TT_Set_Instance_PointSize( _ins : TT_Instance; pointsize : integer ) : TT_Error; begin TT_Set_Instance_PointSize := TT_Set_Instance_CharSize( _ins, pointsize*64 ); end; (*****************************************************************) (* *) (* *) function TT_Set_Instance_PixelSizes( _ins : TT_Instance; pixelX : Integer; pixelY : Integer; pointsize : Integer ) : TT_Error; var ins : PInstance; begin ins := _ins.z; if ins <> nil then begin ins^.metrics.x_ppem := pixelX; ins^.metrics.y_ppem := pixelY; ins^.metrics.pointSize := pointsize; ins^.metrics.x_scale1 := ins^.metrics.x_ppem * 64; ins^.metrics.x_scale2 := ins^.owner^.fontHeader.units_per_EM; ins^.metrics.y_scale1 := ins^.metrics.y_ppem * 64; ins^.metrics.y_scale2 := ins^.metrics.x_scale2; ins^.valid := false; TT_Set_Instance_PixelSizes := TT_Err_Ok; end else TT_Set_Instance_PixelSizes := TT_Err_Invalid_Instance_Handle; end; (*****************************************************************) (* *) (* *) function TT_Set_Instance_Transforms( _ins : TT_Instance; rotated : Boolean; distorted : Boolean ) : TT_Error; var ins : PInstance; begin ins := _ins.z; if ins <> nil then begin ins^.metrics.rotated := rotated; ins^.metrics.stretched := distorted; TT_Set_Instance_Transforms := TT_Err_Ok; end else TT_Set_Instance_Transforms := TT_Err_Invalid_Instance_Handle; end; (*****************************************************************) (* *) (* *) function TT_Get_Instance_Metrics( _ins : TT_Instance; var m : TT_Instance_Metrics ) : TT_Error; var ins : PInstance; begin ins := _ins.z; if ins <> nil then begin if not ins^.valid then if Instance_Reset( ins, False ) then begin TT_Get_Instance_Metrics := error; exit; end; with m do begin pointSize := ins^.metrics.pointSize; x_scale := MulDiv_Round( $10000, ins^.metrics.x_scale1, ins^.metrics.x_scale2 ); y_scale := MulDiv_Round( $10000, ins^.metrics.y_scale1, ins^.metrics.y_scale2 ); x_resolution := ins^.metrics.x_resolution; y_resolution := ins^.metrics.y_resolution; x_ppem := ins^.metrics.x_ppem; y_ppem := ins^.metrics.y_ppem; TT_Get_Instance_Metrics := TT_Err_Ok; end; end else TT_Get_Instance_Metrics := TT_Err_Invalid_Instance_Handle; end; (*****************************************************************) (* Set instance generic pointer *) (* *) function TT_Set_Instance_Pointer( _ins : TT_Instance; data : Pointer ) : TT_Error; var ins : PInstance; begin ins := PInstance(_ins.z); if ins <> nil then begin ins^.generic := data; TT_Set_Instance_Pointer := TT_Err_Ok; end else TT_Set_Instance_Pointer := TT_Err_Invalid_Instance_Handle; end; (*****************************************************************) (* Get instance generic pointer *) (* *) function TT_Get_Instance_Pointer( _ins : TT_Instance ) : Pointer; var ins : PInstance; begin ins := PInstance(_ins.z); if ins <> nil then TT_Get_Instance_Pointer := ins^.generic else TT_Get_Instance_Pointer := nil; end; (*****************************************************************) (* *) (* *) function TT_Done_Instance( _ins : TT_Instance ) : TT_Error; var ins : PInstance; begin ins := PInstance(_ins.z); if ins <> nil then begin error := TT_Err_Ok; Cache_Done( ins^.owner^.instances, ins ); TT_Done_Instance := error; end else TT_Done_Instance := TT_Err_Invalid_Instance_Handle; end; (*****************************************************************) (* *) (* *) function TT_New_Glyph( _face : TT_Face; var _glyph : TT_Glyph ) : TT_Error; var face : PFace; begin face := PFace(_face.z); if face <> nil then begin error := TT_Err_Ok; Cache_New( face^.glyphs, _glyph.z, _face.z ); TT_New_Glyph := error; end else TT_New_Glyph := TT_Err_Invalid_Face_Handle; end; (*****************************************************************) (* *) (* *) function TT_Done_Glyph( _glyph : TT_Glyph ) : TT_Error; var glyph : PGlyph; begin glyph := PGlyph(_glyph.z); if glyph <> nil then begin error := TT_Err_Ok; Cache_Done( glyph^.face^.glyphs, glyph ); TT_Done_Glyph := error; end else TT_Done_Glyph := TT_Err_Invalid_Glyph_Handle; end; (*****************************************************************) (* *) (* *) function TT_Load_Glyph( _instance : TT_Instance; _glyph : TT_Glyph; glyph_index : Word; load_flags : Integer ) : TT_Error; var ins : PInstance; glyph : PGlyph; begin ins := PInstance(_instance.z); if ins = nil then begin TT_Load_Glyph := TT_Err_Invalid_Instance_Handle; exit; end; glyph := PGlyph(_glyph.z); if glyph = nil then begin TT_Load_Glyph := TT_Err_Invalid_Glyph_Handle; exit; end; if ins^.owner <> glyph^.face then begin TT_Load_Glyph := TT_Err_Invalid_Face_Handle; exit; end; if not ins^.valid then if Instance_Reset( ins, False ) then begin TT_Load_Glyph := error; exit; end; error := TT_Err_Ok; Load_TrueType_Glyph( ins, glyph, glyph_index, load_flags ); TT_Load_Glyph := error; end; (*****************************************************************) (* *) (* *) function TT_Get_Glyph_Outline( _glyph : TT_Glyph; var outline : TT_Outline ) : TT_Error; var glyph : PGlyph; begin glyph := PGlyph(_glyph.z); if glyph <> nil then begin outline := glyph^.outline; outline.owner := false; TT_Get_Glyph_Outline := TT_Err_Ok; end else TT_Get_Glyph_Outline := TT_Err_Invalid_Glyph_Handle; end; (*****************************************************************) (* *) (* *) function TT_Get_Glyph_Metrics( _glyph : TT_Glyph; var gmetrics : TT_Glyph_Metrics ) : TT_Error; var glyph : PGlyph; begin glyph := PGlyph(_glyph.z); if glyph <> nil then begin gmetrics.bbox := glyph^.metrics.bbox; gmetrics.bearingX := glyph^.metrics.horiBearingX; gmetrics.bearingY := glyph^.metrics.horiBearingY; gmetrics.advance := glyph^.metrics.horiAdvance; TT_Get_Glyph_Metrics := TT_Err_Ok; end else TT_Get_Glyph_Metrics := TT_Err_Invalid_Glyph_Handle; end; (*****************************************************************) (* Get a glyph's big metrics *) (* *) function TT_Get_Glyph_Big_Metrics( _glyph : TT_Glyph; var gmetrics : TT_Big_Glyph_Metrics ) : TT_Error; var glyph : PGlyph; begin glyph := PGlyph(_glyph.z); if glyph <> nil then begin gmetrics := glyph^.metrics; TT_Get_Glyph_Big_Metrics := TT_Err_Ok; end else TT_Get_Glyph_Big_Metrics := TT_Err_Invalid_Glyph_Handle; end; (*****************************************************************) (* *) (* *) function TT_Get_Glyph_Bitmap( _glyph : TT_Glyph; var map : TT_raster_Map; x_offset : TT_F26Dot6; y_offset : TT_F26Dot6 ) : TT_Error; var glyph : PGlyph; outline : TT_Outline; n : Int; begin glyph := _glyph.z; if glyph <> nil then begin outline := glyph^.outline; (* XXX: for now, we only use dropout mode #2 *) outline.dropout_mode := 2; TT_Translate_Outline( outline, x_offset, y_offset ); TT_Get_Glyph_Bitmap := TT_Get_Outline_Bitmap( outline, map ); TT_Translate_Outline( outline, -x_offset, -y_offset ); end else TT_Get_Glyph_Bitmap := TT_Err_Invalid_Glyph_Handle; end; (*****************************************************************) (* *) (* *) function TT_Get_Glyph_Pixmap( _glyph : TT_Glyph; var map : TT_raster_Map; x_offset : TT_F26Dot6; y_offset : TT_F26Dot6 ) : TT_Error; var glyph : PGlyph; outline : TT_Outline; n : Int; begin glyph := _glyph.z; if glyph <> nil then begin outline := glyph^.outline; (* XXX: for now, we only use dropout mode #2 *) outline.dropout_mode := 2; TT_translate_Outline( outline, x_offset, y_offset ); TT_Get_Glyph_Pixmap := TT_Get_Outline_Pixmap( outline, map ); TT_translate_Outline( outline, -x_offset, -y_offset ); end else TT_Get_Glyph_Pixmap := TT_Err_Invalid_Glyph_Handle; end; (*****************************************************************) (* Create a new glyph outline *) (* *) function TT_New_Outline( n_points : integer; n_contours : integer; var out : TT_Outline ) : TT_Error; label Fail; begin out.n_points := n_points; out.n_contours := n_contours; out.points := nil; out.flags := nil; out.conEnds := nil; out.owner := true; if Alloc( Pointer(out.points), 2*n_points*sizeof(TT_Pos) ) or Alloc( Pointer(out.flags), n_points*sizeof(Byte) ) or Alloc( Pointer(out.conEnds), n_contours*sizeof(Short) ) then goto Fail; TT_New_Outline := TT_Err_Ok; exit; Fail: TT_Done_Outline( out ); TT_New_Outline := error; end; (*****************************************************************) (* Copy a glyph outline into another one *) (* *) function TT_Copy_Outline( var source : TT_Outline; var target : TT_Outline ) : TT_Error; begin if (source.n_points = target.n_points) and (source.n_contours = target.n_contours) then begin move( source.points^, target.points^, 2*source.n_points*4 ); move( source.flags^, target.flags^, source.n_points ); move( source.conEnds^,target.conEnds^, source.n_contours*2 ); end else TT_Copy_Outline := TT_Err_Invalid_Argument; end; (*****************************************************************) (* Clone a given outline. This will create the outline, then *) (* copy the source in it *) (* *) function TT_Clone_Outline( var source : TT_Outline; var target : TT_Outline ) : TT_Error; begin error := TT_New_Outline( source.n_points, source.n_contours, target ); if error = TT_Err_Ok then TT_Copy_Outline( source, target ); TT_Clone_Outline := error; end; (*****************************************************************) (* Discards a glyph outline *) (* *) function TT_Done_Outline( var out : TT_Outline ) : TT_Error; begin if out.owner then begin Free( Pointer(out.conEnds) ); Free( Pointer(out.flags) ); Free( Pointer(out.points) ); out.n_points := 0; out.n_contours := 0; TT_Done_Outline := TT_Err_Ok; end else TT_Done_Outline := TT_Err_Invalid_Argument; end; (*****************************************************************) (* Render an outline into a bitmap *) (* *) function TT_Get_Outline_Bitmap( var out : TT_Outline; var map : TT_raster_Map ) : TT_Error; begin if Render_Glyph( out, map ) then TT_Get_Outline_Bitmap := error else TT_Get_Outline_Bitmap := TT_Err_Ok; end; (*****************************************************************) (* Render an outline into a pixmap *) (* *) function TT_Get_Outline_Pixmap( var out : TT_Outline; var map : TT_raster_Map ) : TT_Error; begin if Render_Gray_Glyph( out, map ) then TT_Get_Outline_Pixmap := error else TT_Get_Outline_Pixmap := TT_Err_Ok; end; (*****************************************************************) (* Compute an outline's bounding box *) (* *) function TT_Get_Outline_BBox( var out : TT_Outline; var bbox : TT_Bbox ) : TT_Error; var x, y, xMin, yMin, xMax, yMax : TT_Pos; n : Int; begin with bbox do begin xMin := $7FFFFFFF; xMax := $80000000; yMin := $7FFFFFFF; yMax := $80000000; for n := 0 to out.n_points-1 do begin x := out.points^[n].x; if x < xMin then xMin := x; if x > xMax then xMax := x; y := out.points^[n].y; if y < yMin then yMin := y; if y > yMax then yMax := y; end; end; TT_Get_Outline_BBox := TT_Err_Ok; end; (*****************************************************************) (* *) (* *) function TT_Translate_Outline( var out : TT_Outline; x, y : TT_F26Dot6 ) : TT_Error; var n : integer; begin if x <> 0 then for n := 0 to out.n_points-1 do inc( out.points^[n].x, x ); if y <> 0 then for n := 0 to out.n_points-1 do inc( out.points^[n].y, y ); TT_Translate_Outline := TT_Err_Ok; end; (*****************************************************************) (* *) (* *) function TT_Transform_Outline( var out : TT_Outline; var mat : TT_Matrix ) : TT_Error; var n : integer; x, y, nx, ny : TT_F26Dot6; begin for n := 0 to out.n_points-1 do begin x := out.points^[n].x; y := out.points^[n].y; nx := MulDiv_Round( mat.xx, x, $10000 ) + MulDiv_Round( mat.xy, y, $10000 ); ny := MulDiv_ROund( mat.yx, x, $10000 ) + MulDiv_Round( mat.yy, y, $10000 ); out.points^[n].x := nx; out.points^[n].y := ny; end; TT_Transform_Outline := TT_Err_Ok; end; (*****************************************************************) (* *) (* *) function TT_Transform_Vector( var x, y : TT_F26Dot6; var mat : TT_Matrix ) : TT_Error; var nx, ny : TT_F26Dot6; begin nx := MulDiv_Round( mat.xx, x, $10000 ) + MulDiv_Round( mat.xy, y, $10000 ); ny := MulDiv_Round( mat.yx, x, $10000 ) + MulDiv_Round( mat.yy, y, $10000 ); x := nx; y := ny; TT_Transform_Vector := TT_Err_Ok; end; (***********************************************************************) (* *) (* Character Mapping support *) (* *) (***********************************************************************) (*****************************************************************) (* *) (* *) function TT_Get_CharMap_Count( face : TT_Face ) : integer; var faze : PFace; begin faze := PFace(face.z); if faze = nil then TT_Get_CharMap_Count := -1 else TT_Get_CharMap_Count := faze^.numCMaps; end; (*****************************************************************) (* *) (* *) function TT_Get_CharMap_ID( face : TT_Face; charmapIndex : integer; var platform : integer; var encoding : integer ) : TT_Error; var faze : PFace; cmap : PCMapTable; begin faze := PFace(face.z); if faze = nil then begin TT_Get_CharMap_ID := TT_Err_Invalid_Face_Handle; exit; end; if (charmapIndex < 0) or (charmapIndex >= faze^.numCMaps) then begin TT_Get_CharMap_ID := TT_Err_Invalid_Argument; exit; end; cmap := @faze^.cMaps^[charmapIndex]; platform := cmap^.platformID; encoding := cmap^.platformEncodingID; TT_Get_CharMap_ID := TT_Err_Ok; end; (*****************************************************************) (* *) (* *) function TT_Get_CharMap( face : TT_Face; charmapIndex : integer; var charMap : TT_CharMap ) : TT_Error; var faze : PFace; begin faze := PFace(face.z); if faze = nil then begin TT_Get_CharMap := TT_Err_Invalid_Face_Handle; exit; end; if (charmapIndex < 0) or (charmapIndex >= faze^.numCMaps) then begin TT_Get_CharMap := TT_Err_Invalid_Argument; exit; end; charmap.z := @faze^.cMaps^[charmapIndex]; TT_Get_CharMap := TT_Err_Ok; end; (*****************************************************************) (* *) (* *) function TT_Char_Index( charmap : TT_CharMap; charCode : Longint ) : Word; begin TT_Char_Index := CharMap_Index( PCMapTable(charmap.z)^, charCode ); end; (***********************************************************************) (* *) (* Names Table support *) (* *) (***********************************************************************) (*****************************************************************) (* *) (* *) function TT_Get_Name_Count( face : TT_Face ) : integer; var faze : PFace; begin TT_Get_Name_Count := 0; faze := PFace( face.z ); if faze = nil then exit; TT_Get_Name_Count := faze^.nameTable.numNameRecords; end; (*****************************************************************) (* *) (* *) function TT_Get_Name_ID( face : TT_Face; nameIndex : integer; var platform : integer; var encoding : integer; var language : integer; var nameid : integer ) : TT_Error; var faze : PFace; table : PName_Table; rec : PName_Record; label Fail; begin faze := PFace( face.z ); if faze = nil then begin TT_Get_Name_Id := TT_Err_Invalid_Face_Handle; goto Fail; end; table := @faze^.nameTable; if (nameIndex < 0) or (nameIndex > table^.numNameRecords) then begin TT_Get_Name_Id := TT_Err_Bad_Argument; goto Fail; end; rec := @table^.names^[nameIndex]; platform := rec^.platformID; encoding := rec^.encodingID; language := rec^.languageID; nameid := rec^.nameID; TT_Get_Name_ID := TT_Err_Ok; exit; Fail: platform := -1; encoding := -1; language := -1; nameid := -1; end; (*****************************************************************) (* *) (* *) function TT_Get_Name_String( face : TT_Face; nameIndex : integer; var str : Pointer; var len : integer ) : TT_Error; var faze : PFace; table : PName_Table; rec : PName_Record; label Fail; begin faze := PFace( face.z ); if faze = nil then begin TT_Get_Name_String := TT_Err_Invalid_Face_Handle; goto Fail; end; table := @faze^.nameTable; if (nameIndex < 0) or (nameIndex > table^.numNameRecords) then begin TT_Get_Name_String := TT_Err_Bad_Argument; goto Fail; end; rec := @table^.names^[nameIndex]; str := @table^.storage^[rec^.offset]; len := rec^.length; TT_Get_Name_String := TT_Err_Ok; exit; Fail: str := nil; len := 0; end; (*****************************************************************) (* Access font data and copies it into user block *) (* *) function TT_Get_Font_Data( face : TT_Face; tableTag : Longint; offset : Longint; var buffer; var length : longint ) : TT_Error; var faze : PFace; begin faze := PFace(face.z); if faze = nil then begin TT_Get_Font_Data := TT_Err_Invalid_Face_Handle; length := 0; end else begin TT_Get_Font_Data := TT_Err_Ok; if Load_TrueType_Any( faze, tableTag, offset, buffer, length ) then TT_Get_Font_Data := error; end; end; end.