diff --git a/examples/simple/TextSuiteTest.lpi b/examples/simple/TextSuiteTest.lpi
index da32eb9..786f8bf 100644
--- a/examples/simple/TextSuiteTest.lpi
+++ b/examples/simple/TextSuiteTest.lpi
@@ -49,7 +49,6 @@
-
@@ -68,7 +67,6 @@
-
@@ -78,12 +76,10 @@
-
-
diff --git a/examples/simple/TextSuiteTest.lps b/examples/simple/TextSuiteTest.lps
index 09122fd..97fd7aa 100644
--- a/examples/simple/TextSuiteTest.lps
+++ b/examples/simple/TextSuiteTest.lps
@@ -10,7 +10,7 @@
-
+
@@ -19,37 +19,35 @@
-
-
-
-
+
+
+
-
-
+
-
-
-
+
+
+
-
+
@@ -58,17 +56,16 @@
-
+
-
-
+
@@ -76,37 +73,36 @@
-
-
-
+
+
+
-
-
+
-
-
+
+
-
-
-
+
+
+
@@ -117,7 +113,7 @@
-
+
@@ -126,9 +122,9 @@
-
-
-
+
+
+
@@ -260,7 +256,7 @@
-
+
@@ -268,7 +264,7 @@
-
+
@@ -276,7 +272,7 @@
-
+
@@ -326,7 +322,7 @@
-
+
@@ -334,7 +330,7 @@
-
+
@@ -377,7 +373,7 @@
-
+
@@ -442,7 +438,7 @@
-
+
@@ -511,125 +507,131 @@
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/simple/uMainForm.pas b/examples/simple/uMainForm.pas
index 77c66ea..ac7a4e7 100644
--- a/examples/simple/uMainForm.pas
+++ b/examples/simple/uMainForm.pas
@@ -50,8 +50,8 @@ uses
dglOpenGL;
const
- //TEST_STRING = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.';
- TEST_STRING = 'Lorem';
+ TEST_STRING = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.';
+ //TEST_STRING = 'Lorem';
procedure TMainForm.FormCreate(Sender: TObject);
var
@@ -85,9 +85,9 @@ begin
ftsGenerator.AddPostProcessStep(pp);
}
try
- ftsFont1 := ftsGenerator.GetFontByFile('Calibri', ftsRenderer, 25, [tsStyleBold], tsAANormal);
- ftsFont2 := ftsGenerator.GetFontByName('Calibri', ftsRenderer, 20, [], tsAANormal);
- ftsFont3 := ftsFreeType.GetFontByFile('calibrib.ttf', ftsRenderer, 25, tsAANone);
+ ftsFont1 := ftsGenerator.GetFontByName('Calibri', ftsRenderer, 25, [tsStyleUnderline], tsAANormal);
+ ftsFont2 := ftsGenerator.GetFontByName('Calibri', ftsRenderer, 20, [], tsAANormal);
+ ftsFont3 := ftsFreeType.GetFontByFile('calibri.ttf', ftsRenderer, 25, [tsStyleUnderline], tsAANormal);
except
on e: EtsException do
MessageDlg('Error', e.Message, mtError, [mbOK], 0);
@@ -154,11 +154,11 @@ begin
{$ELSE}
block := ftsRenderer.BeginBlock(0, 0, ClientWidth, ClientHeight, [tsBlockFlagWordWrap]);
try
- block.HorzAlign := tsHorzAlignJustify;
+ //block.HorzAlign := tsHorzAlignJustify;
block.ChangeFont(ftsFont1);
- block.ChangeColor(tsColor4f(1.0, 1.0, 1.0, 1.0));
- block.TextOutW(TEST_STRING + sLineBreak);
+ block.ChangeColor(tsColor4f(1.0, 0.0, 0.0, 1.0));
+ block.TextOutA(TEST_STRING + sLineBreak);
block.ChangeFont(ftsFont3);
block.ChangeColor(tsColor4f(1.0, 1.0, 1.0, 1.0));
diff --git a/utsFontCreatorFreeType.pas b/utsFontCreatorFreeType.pas
index a7297eb..0222580 100644
--- a/utsFontCreatorFreeType.pas
+++ b/utsFontCreatorFreeType.pas
@@ -41,8 +41,8 @@ type
procedure GetCharImage(const aFont: TtsFont; const aCharCode: WideChar;
const aCharImage: TtsImage); override;
public
- function GetFontByFile(const aFilename: String; const aRenderer: TtsRenderer;
- const aSize: Integer; const aAntiAliasing: TtsAntiAliasing): TtsFont; overload;
+ function GetFontByFile(const aFilename: String; const aRenderer: TtsRenderer; const aSize: Integer;
+ const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TtsFont; overload;
constructor Create(const aContext: TtsContext);
destructor Destroy; override;
@@ -299,11 +299,13 @@ end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TtsFontGeneratorFreeType.GetFontByFile(const aFilename: String; const aRenderer: TtsRenderer;
- const aSize: Integer; const aAntiAliasing: TtsAntiAliasing): TtsFont;
+ const aSize: Integer; const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TtsFont;
var
face: FT_Face;
err: FT_Error;
prop: TtsFontProperties;
+ os2: PTT_OS2;
+ hz: PTT_HoriHeader;
begin
err := FT_New_Face(fHandle, PAnsiChar(aFilename), 0, @face);
if (err <> 0) then
@@ -322,21 +324,30 @@ begin
prop.Size := aSize;
prop.AntiAliasing := aAntiAliasing;
prop.DefaultChar := '?';
- prop.Style := [];
- if ((face^.style_flags and FT_STYLE_FLAG_BOLD) <> 0) then
- Include(prop.Style, tsStyleBold);
- if ((face^.style_flags and FT_STYLE_FLAG_ITALIC) <> 0) then
- Include(prop.Style, tsStyleItalic);
+ prop.Style := aStyle + [tsStyleBold, tsStyleItalic];
+ if ((face^.style_flags and FT_STYLE_FLAG_BOLD) = 0) then
+ Exclude(prop.Style, tsStyleBold);
+ if ((face^.style_flags and FT_STYLE_FLAG_ITALIC) = 0) then
+ Exclude(prop.Style, tsStyleItalic);
prop.Ascent := face^.size^.metrics.ascender div FT_SIZE_FACTOR;
prop.Descent := -face^.size^.metrics.descender div FT_SIZE_FACTOR;
prop.ExternalLeading := 0;
prop.BaseLineOffset := 0;
- prop.UnderlinePos := face^.underline_position div FT_SIZE_FACTOR;
- prop.UnderlineSize := face^.underline_thickness div FT_SIZE_FACTOR;
- prop.StrikeoutPos := 0;
- prop.StrikeoutSize := 0;
+ prop.UnderlinePos := face^.underline_position div FT_SIZE_FACTOR;
+ prop.UnderlineSize := face^.underline_thickness div FT_SIZE_FACTOR;
+
+ os2 := PTT_OS2(FT_Get_Sfnt_Table(face, FT_SFNT_OS2));
+ if Assigned(os2) and (os2^.version <> $FFFF) then begin
+ prop.StrikeoutPos := os2^.yStrikeoutPosition div FT_SIZE_FACTOR;
+ prop.StrikeoutSize := os2^.yStrikeoutSize div FT_SIZE_FACTOR;
+ end;
+
+ hz := PTT_HoriHeader(FT_Get_Sfnt_Table(face, FT_SFNT_HHEA));
+ if Assigned(hz) then begin
+ prop.ExternalLeading := hz^.Line_Gap div FT_SIZE_FACTOR;
+ end;
result := TtsFontFreeType.Create(TtsFreeTypeFaceHandle.Create(face), aRenderer, self, prop);
end;
diff --git a/utsFreeType.pas b/utsFreeType.pas
index d24fb15..2054d0a 100644
--- a/utsFreeType.pas
+++ b/utsFreeType.pas
@@ -11,7 +11,9 @@ type
// Simple Types
FT_Error = Integer;
FT_Library = Pointer;
- FT_Short = ShortInt;
+ FT_Short = SmallInt;
+ FT_Byte = Byte;
+ FT_Char = AnsiChar;
FT_UShort = Word;
FT_Int = Integer;
FT_Int32 = Integer;
@@ -33,11 +35,14 @@ type
FT_Size = ^FT_SizeRec;
FT_CharMap = ^FT_CharMapRec;
- PFT_Library = ^FT_Library;
- PFT_Face = ^FT_Face;
- PFT_String = ^FT_String;
- PFT_SfntName = ^FT_SfntName;
- PFT_Bitmap = ^FT_Bitmap;
+ PFT_Library = ^FT_Library;
+ PFT_Face = ^FT_Face;
+ PFT_String = ^FT_String;
+ PFT_SfntName = ^FT_SfntName;
+ PFT_Bitmap = ^FT_Bitmap;
+ PTT_OS2 = ^TT_OS2;
+ PTT_Postscript = ^TT_Postscript;
+ PTT_HoriHeader = ^TT_HoriHeader;
// unneeded
FT_Driver = Pointer;
@@ -233,6 +238,94 @@ type
string_len: FT_UInt;
end;
+ TT_OS2 = record
+ version: FT_UShort;
+ xAvgCharWidth: FT_Short;
+ usWeightClass: FT_UShort;
+ usWidthClass: FT_UShort;
+ fsType: FT_Short;
+
+ ySubscriptXSize: FT_Short;
+ ySubscriptYSize: FT_Short;
+ ySubscriptXOffset: FT_Short;
+ ySubscriptYOffset: FT_Short;
+ ySuperscriptXSize: FT_Short;
+ ySuperscriptYSize: FT_Short;
+ ySuperscriptXOffset: FT_Short;
+ ySuperscriptYOffset: FT_Short;
+ yStrikeoutSize: FT_Short;
+ yStrikeoutPosition: FT_Short;
+ sFamilyClass: FT_Short;
+
+ panose: array[0..9] of FT_Byte;
+
+ ulUnicodeRange1: FT_ULong;
+ ulUnicodeRange3: FT_ULong;
+ ulUnicodeRange2: FT_ULong;
+ ulUnicodeRange4: FT_ULong;
+
+ achVendID: array[0..3] of FT_Char;
+
+ fsSelection: FT_UShort;
+ usFirstCharIndex: FT_UShort;
+ usLastCharIndex: FT_UShort;
+ sTypoAscender: FT_Short;
+ sTypoDescender: FT_Short;
+ sTypoLineGap: FT_Short;
+ usWinAscent: FT_UShort;
+ usWinDescent: FT_UShort;
+
+ ulCodePageRange1: FT_ULong;
+ ulCodePageRange2: FT_ULong;
+
+ { only version 2 and higher: }
+ sxHeight: FT_Short;
+ sCapHeight: FT_Short;
+ usDefaultChar: FT_UShort;
+ usBreakChar: FT_UShort;
+ usMaxContext: FT_UShort;
+
+ { only version 5 and higher: }
+ usLowerOpticalPointSize: FT_UShort;
+ usUpperOpticalPointSize: FT_UShort;
+ end;
+
+ TT_Postscript = record
+ FormatType: FT_Fixed;
+ italicAngle: FT_Fixed;
+ underlinePosition: FT_Short;
+ underlineThickness: FT_Short;
+ isFixedPitch: FT_ULong;
+ minMemType42: FT_ULong;
+ maxMemType42: FT_ULong;
+ minMemType1: FT_ULong;
+ maxMemType1: FT_ULong;
+ end;
+
+ TT_HoriHeader = record
+ Version: FT_Fixed;
+ Ascender: FT_Short;
+ Descender: FT_Short;
+ Line_Gap: FT_Short;
+
+ advance_Width_Max: FT_UShort;
+
+ min_Left_Side_Bearin: FT_Short;
+ min_Right_Side_Bearing: FT_Short;
+ xMax_Extent: FT_Short;
+ caret_Slope_Rise: FT_Short;
+ caret_Slope_Run: FT_Short;
+ caret_Offset: FT_Short;
+
+ Reserved: array[0..3] of FT_Short;
+
+ metric_Data_Format: FT_Short;
+ number_Of_HMetrics: FT_UShort;
+
+ long_metrics: Pointer;
+ short_metrics: Pointer;
+ end;
+
TFT_Init_FreeType = function(aLibrary: PFT_Library): FT_Error;
TFT_Done_FreeType = function(aLibrary: FT_Library): FT_Error;
TFT_New_Face = function(aLibrary: FT_Library; const aFilename: PAnsiChar; aFaceIndex: FT_Long; aFace: PFT_Face): FT_Error;
@@ -241,8 +334,9 @@ type
TFT_Get_Sfnt_Name_Count = function(aFace: FT_Face): FT_UInt;
TFT_Get_Sfnt_Name = function(aFace: FT_Face; aIndex: FT_UInt; aName: PFT_SfntName): FT_Error;
- TFT_Set_Char_Size = function(aFace: FT_Face; aCharWidth: FT_F26Dot6; aCharHeight: FT_F26Dot6; aHorzDPI: FT_UInt; aVertDPI: FT_UInt): FT_Error;
- TFT_Load_Char = function(aFace: FT_Face; aCharCode: FT_ULong; aLoadFlags: FT_Int32): FT_Error;
+ TFT_Set_Char_Size = function(aFace: FT_Face; aCharWidth: FT_F26Dot6; aCharHeight: FT_F26Dot6; aHorzDPI: FT_UInt; aVertDPI: FT_UInt): FT_Error;
+ TFT_Load_Char = function(aFace: FT_Face; aCharCode: FT_ULong; aLoadFlags: FT_Int32): FT_Error;
+ TFT_Get_Sfnt_Table = function(aFace: FT_Face; aTag: Integer): Pointer;
var
FT_Init_FreeType: TFT_Init_FreeType;
@@ -253,8 +347,9 @@ var
FT_Get_Sfnt_Name_Count: TFT_Get_Sfnt_Name_Count;
FT_Get_Sfnt_Name: TFT_Get_Sfnt_Name;
- FT_Set_Char_Size: TFT_Set_Char_Size;
- FT_Load_Char: TFT_Load_Char;
+ FT_Set_Char_Size: TFT_Set_Char_Size;
+ FT_Load_Char: TFT_Load_Char;
+ FT_Get_Sfnt_Table: TFT_Get_Sfnt_Table;
const
TT_NAME_ID_COPYRIGHT = 0;
@@ -486,6 +581,14 @@ const
FT_LOAD_TARGET_LCD = FT_RENDER_MODE_LCD shl 16;
FT_LOAD_TARGET_LCD_V = FT_RENDER_MODE_LCD_V shl 16;
+ FT_SFNT_HEAD = 0;
+ FT_SFNT_MAXP = 1;
+ FT_SFNT_OS2 = 2;
+ FT_SFNT_HHEA = 3;
+ FT_SFNT_VHEA = 4;
+ FT_SFNT_POST = 5;
+ FT_SFNT_PCLT = 6;
+
function InitFreeType: FT_Library;
procedure QuitFreeType;
@@ -553,8 +656,9 @@ begin
FT_Get_Sfnt_Name_Count := TFT_Get_Sfnt_Name_Count(GetProcAddr('FT_Get_Sfnt_Name_Count'));
FT_Get_Sfnt_Name := TFT_Get_Sfnt_Name( GetProcAddr('FT_Get_Sfnt_Name'));
- FT_Set_Char_Size := TFT_Set_Char_Size(GetProcAddr('FT_Set_Char_Size'));
- FT_Load_Char := TFT_Load_Char( GetProcAddr('FT_Load_Char'));
+ FT_Set_Char_Size := TFT_Set_Char_Size( GetProcAddr('FT_Set_Char_Size'));
+ FT_Load_Char := TFT_Load_Char( GetProcAddr('FT_Load_Char'));
+ FT_Get_Sfnt_Table := TFT_Get_Sfnt_Table(GetProcAddr('FT_Get_Sfnt_Table'));
err := FT_Init_FreeType(@ftLibrary);
if (err <> 0) then
diff --git a/utsTextSuite.pas b/utsTextSuite.pas
index 4a8179f..8620377 100644
--- a/utsTextSuite.pas
+++ b/utsTextSuite.pas
@@ -1446,8 +1446,8 @@ begin
// move glyph rect
aChar.GlyphRect := tsRect(
aChar.GlyphRect.Left + NewPos.x,
- aChar.GlyphRect.Right + NewPos.x,
aChar.GlyphRect.Top + NewPos.y,
+ aChar.GlyphRect.Right + NewPos.x,
aChar.GlyphRect.Bottom + NewPos.y);
end;