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;