unit FreeType;
interface
type
TT_Int = Longint;
TT_Int = Integer;
TT_Long = longint;
TT_ULong = longint;
TT_Short = integer;
TT_UShort = word;
TT_Fixed = LongInt;
TT_FWord = Integer;
TT_UFWord = Word;
TT_F2Dot14 = Integer;
TT_F26Dot6 = LongInt;
TT_Pos = Longint;
TT_UnitVector = record
x : TT_F2Dot14;
y : TT_F2Dot14;
end;
TT_Vector = record
x : TT_Pos;
y : TT_Pos;
end;
TT_Matrix = record
xx, xy : TT_Fixed;
yx, yy : TT_Fixed;
end;
TT_BBox = record
xMin, yMin : TT_Pos;
xMax, yMax : TT_Pos;
end;
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;
TT_Outline = record
n_points : integer;
n_contours : integer;
points : TT_Points;
flags : TT_PTouchTable;
conEnds : TT_PConStarts;
owner : Boolean;
high_precision : Boolean;
second_pass : Boolean;
dropout_mode : Byte;
end;
TT_Glyph_Metrics = record
bbox : TT_BBox;
bearingX : TT_Pos;
bearingY : TT_Pos;
advance : TT_Pos;
end;
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;
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
TT_Raster_Map = record
Rows : TT_Int;
Cols : TT_Int;
Width : TT_Int;
Flow : TT_Int;
Buffer : pointer;
Size : longint;
end;
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;
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;
short_metrics : Pointer;
long_metrics : Pointer;
end;
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;
short_metrics : Pointer;
long_metrics : Pointer;
end;
TT_OS2 = record
version : TT_UShort;
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;
ulUnicodeRange2 : TT_ULong;
ulUnicodeRange3 : TT_ULong;
ulUnicodeRange4 : TT_ULong;
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;
ulCodePageRange1 : TT_ULong;
ulCodePageRange2 : TT_ULong;
end;
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;
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;
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;
const
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;
function TT_Init_FreeType : TT_Error;
procedure TT_Done_FreeType;
function TT_Set_Raster_Palette( palette : TT_Gray_Palette ) : TT_Error;
function TT_Open_Face( fontname : string;
var _face : TT_Face ) : TT_Error;
function TT_Open_Collection( fontname : string;
faceIndex : integer;
var _face : TT_Face ) : TT_Error;
function TT_Get_Face_Properties( _face : TT_Face;
var prop : TT_Face_Properties ) : TT_Error;
function TT_Set_Face_Pointer( _face : TT_Face;
data : Pointer ) : TT_Error;
function TT_Get_Face_Pointer( _face : TT_Face ) : Pointer;
function TT_Close_Face( _face : TT_Face ) : TT_Error;
function TT_New_Instance( _face : TT_Face;
var _ins : TT_Instance ) : TT_Error;
function TT_Set_Instance_Resolutions( _ins : TT_Instance;
x_resolution : Integer;
y_resolution : Integer ) : TT_Error;
function TT_Set_Instance_PointSize( _ins : TT_Instance;
pointsize : Integer ) : TT_Error;
function TT_Set_Instance_CharSize( _ins : TT_Instance;
charsize : Integer ) : TT_Error;
function TT_Set_Instance_CharSizes( _ins : TT_Instance;
charsizex : Integer;
charsizey : Integer ) : TT_Error;
function TT_Set_Instance_PixelSizes( _ins : TT_Instance;
pixelX : Integer;
pixelY : Integer;
pointsize : Integer ) : TT_Error;
function TT_Set_Instance_Transforms( _ins : TT_Instance;
rotated : Boolean;
distorted : Boolean ) : TT_Error;
function TT_Get_Instance_Metrics( _ins : TT_Instance;
var m : TT_Instance_Metrics ) : TT_Error;
function TT_Set_Instance_Pointer( _ins : TT_Instance;
data : Pointer ) : TT_Error;
function TT_Get_Instance_Pointer( _ins : TT_Instance ) : Pointer;
function TT_Done_Instance( _ins : TT_Instance ) : TT_Error;
function TT_New_Glyph( _face : TT_Face;
var _glyph : TT_Glyph ) : TT_Error;
function TT_Done_Glyph( _glyph : TT_Glyph ) : TT_Error;
function TT_Load_Glyph( _instance : TT_Instance;
_glyph : TT_Glyph;
glyph_index : Word;
load_flags : Integer ) : TT_Error;
const
TT_Load_Scale_Glyph = 1;
TT_Load_Hint_Glyph = 2;
TT_Load_Debug = 16;
TT_Load_Default = TT_Load_Scale_Glyph or
TT_Load_Hint_Glyph;
function TT_Get_Glyph_Outline( _glyph : TT_Glyph;
var outline : TT_Outline ) : TT_Error;
function TT_Get_Glyph_Metrics( _glyph : TT_Glyph;
var gmetrics : TT_Glyph_Metrics ) : TT_Error;
function TT_Get_Glyph_Big_Metrics( _glyph : TT_Glyph;
var gmetrics : TT_Big_Glyph_Metrics
) : TT_Error;
function TT_Get_Glyph_Bitmap( _glyph : TT_Glyph;
var map : TT_Raster_Map;
x_offset : TT_F26Dot6;
y_offset : TT_F26Dot6 ) : TT_Error;
function TT_Get_Glyph_Pixmap( _glyph : TT_Glyph;
var map : TT_Raster_Map;
x_offset : TT_F26Dot6;
y_offset : TT_F26Dot6 ) : TT_Error;
function TT_Translate_Outline( var out : TT_Outline;
x, y : TT_F26Dot6 ) : TT_Error;
function TT_Transform_Outline( var out : TT_Outline;
var mat : TT_Matrix ) : TT_Error;
function TT_Transform_Vector( var x, y : TT_F26Dot6;
var mat : TT_Matrix ) : TT_Error;
function TT_Get_Outline_Bitmap( var out : TT_Outline;
var map : TT_raster_Map ) : TT_Error;
function TT_Get_Outline_Pixmap( var out : TT_Outline;
var map : TT_raster_Map ) : TT_Error;
function TT_Get_Outline_BBox( var out : TT_Outline;
var bbox : TT_Bbox ) : TT_Error;
function TT_New_Outline( n_points : integer;
n_contours : integer;
var out : TT_Outline ) : TT_Error;
function TT_Copy_Outline( var source : TT_Outline;
var target : TT_Outline ) : TT_Error;
function TT_Clone_Outline( var source : TT_Outline;
var target : TT_Outline ) : TT_Error;
function TT_Done_Outline( var out : TT_Outline ) : TT_Error;
function TT_Get_CharMap_Count( face : TT_Face ) : integer;
function TT_Get_CharMap_ID( face : TT_Face;
charmapIndex : integer;
var platform : integer;
var encoding : integer ) : TT_Error;
function TT_Get_CharMap( face : TT_Face;
charmapIndex : integer;
var charMap : TT_CharMap ) : TT_Error;
function TT_Char_Index( charmap : TT_CharMap;
charCode : Longint ) : Word;
function TT_Get_Name_Count( face : TT_Face ) : integer;
function TT_Get_Name_ID( face : TT_Face;
nameIndex : integer;
var platform : integer;
var encoding : integer;
var language : integer;
var nameid : integer ) : TT_Error;
function TT_Get_Name_String( face : TT_Face;
nameIndex : integer;
var str : Pointer;
var len : integer ) : TT_Error;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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.