Ignore:
Timestamp:
Apr 9, 2015, 9:58:36 PM (9 years ago)
Author:
chronos
Message:
  • Fixed: Use csOpaque control style also to Image, PaintBox and OpenGLControl.
  • Modified: Change size of test frame with SpinEdits as delayed using timer.
  • Updated: BRGABitmap package to version 8.1.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • GraphicTest/Packages/bgrabitmap/bgravectorize.pas

    r452 r472  
    55interface
    66
     7{
     8  Font rendering units : BGRAText, BGRATextFX, BGRAVectorize, BGRAFreeType
     9
     10  This unit provides vectorizers :
     11  - VectorizeMonochrome function vectorizes a back'n'white image
     12  - TBGRAVectorizedFont allows to vectorize and to load vectorized font and draw them
     13
     14  TBGRAVectorizedFontRenderer class works like other font renderers, i.e., it can
     15  be assigned to the FontRenderer property. You can use it in two different modes :
     16  - if you supply a directory, it will look for *.glyphs files in it to load fonts
     17  - if you don't supply a directory, fonts will be vectorized from LCL
     18
     19  Note that unless you want to supply your own glyphs files, you don't need
     20  to use explicitely this renderer, because TBGRATextEffectFontRenderer will
     21  make use of it if necessary, according to effects parameters used.
     22}
     23
    724uses
    8   Classes, SysUtils, Graphics, BGRABitmapTypes, BGRATypewriter, BGRATransform, BGRACanvas2D;
    9 
     25  Types, Classes, SysUtils, Graphics, BGRABitmapTypes, BGRATypewriter, BGRATransform, BGRACanvas2D, BGRAText;
     26
     27//vectorize a monochrome bitmap
    1028function VectorizeMonochrome(ASource: TBGRACustomBitmap; zoom: single; PixelCenteredCoordinates: boolean): ArrayOfTPointF;
    1129
    1230type
     31  TBGRAVectorizedFont = class;
     32
     33  //this is the class to assign to FontRenderer property of TBGRABitmap
     34  { TBGRAVectorizedFontRenderer }
     35
     36  TBGRAVectorizedFontRenderer = class(TBGRACustomFontRenderer)
     37  protected
     38    FVectorizedFontArray: array of record
     39        FontName: string;
     40        FontStyle: TFontStyles;
     41        VectorizedFont: TBGRAVectorizedFont;
     42      end;
     43    FVectorizedFont: TBGRAVectorizedFont;
     44    FCanvas2D: TBGRACanvas2D;
     45    FDirectoryUTF8: string;
     46    function OutlineActuallyVisible: boolean;
     47    procedure UpdateFont;
     48    function GetCanvas2D(ASurface: TBGRACustomBitmap): TBGRACanvas2D;
     49    procedure InternalTextRect(ADest: TBGRACustomBitmap; ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; c: TBGRAPixel; texture: IBGRAScanner);
     50    procedure Init;
     51  public
     52    MaxFontResolution: integer;
     53
     54    OutlineVisible: boolean;
     55    OutlineWidth: single;
     56    OutlineColor: TBGRAPixel;
     57    OutlineTexture: IBGRAScanner;
     58    OuterOutlineOnly: boolean;
     59
     60    ShadowVisible: boolean;
     61    ShadowColor: TBGRAPixel;
     62    ShadowRadius: integer;
     63    ShadowOffset: TPoint;
     64
     65    constructor Create;
     66    constructor Create(ADirectoryUTF8: string);
     67    function GetFontPixelMetric: TFontPixelMetric; override;
     68    procedure TextOutAngle(ADest: TBGRACustomBitmap; x, y: single; orientation: integer; s: string; c: TBGRAPixel; align: TAlignment); override;
     69    procedure TextOutAngle(ADest: TBGRACustomBitmap; x, y: single; orientation: integer; s: string; texture: IBGRAScanner; align: TAlignment); override;
     70    procedure TextOut(ADest: TBGRACustomBitmap; x, y: single; s: string; texture: IBGRAScanner; align: TAlignment); override;
     71    procedure TextOut(ADest: TBGRACustomBitmap; x, y: single; s: string; c: TBGRAPixel; align: TAlignment); override;
     72    procedure TextRect(ADest: TBGRACustomBitmap; ARect: TRect; x, y: integer; s: string; style: TTextStyle; c: TBGRAPixel); override;
     73    procedure TextRect(ADest: TBGRACustomBitmap; ARect: TRect; x, y: integer; s: string; style: TTextStyle; texture: IBGRAScanner); override;
     74    procedure CopyTextPathTo(ADest: IBGRAPath; x, y: single; s: string; align: TAlignment); override;
     75    function TextSize(s: string): TSize; override;
     76    destructor Destroy; override;
     77  end;
     78
    1379  TGlyphSizes = array of record
    1480            Glyph: String;
     
    1682  end;
    1783
    18   TWordBreakHandler = procedure(var ABefore, AAfter: string) of object;
     84  TBGRAVectorizedFontHeader = record
     85    Name: string;
     86    Style: TFontStyles;
     87    EmHeightRatio: single;
     88    Resolution: integer;
     89    PixelMetric: TFontPixelMetric;
     90  end;
     91  TBGRAGlyphsInfo = record
     92    Name: string;
     93    Style: TFontStyles;
     94    NbGlyphs: integer;
     95  end;
    1996
    2097  { TBGRAVectorizedFont }
     
    33110    FItalicSlope: single;
    34111    FWordBreakHandler: TWordBreakHandler;
     112    FDirectory: string;
     113    FDirectoryContent: array of record
     114      Filename: string;
     115      FontName: string;
     116      FontStyle: TFontStyles;
     117    end;
     118    FFontEmHeightRatioComputed: boolean;
     119    FFontEmHeightRatio: single;
     120    FFontPixelMetric: TFontPixelMetric;
     121    FFontPixelMetricComputed: boolean;
     122    FFontFound: boolean;
     123    function GetEmHeight: single;
     124    function GetFontPixelMetric: TFontPixelMetric;
     125    function GetLCLHeight: single;
     126    function GetVectorizeLCL: boolean;
     127    procedure SetEmHeight(AValue: single);
    35128    procedure SetItalicSlope(AValue: single);
     129    procedure SetLCLHeight(AValue: single);
    36130    procedure SetOrientation(AValue: single);
    37131    procedure SetQuadraticCurves(AValue: boolean);
     
    41135    procedure SetName(AValue: string);
    42136    procedure SetStyle(AValue: TFontStyles);
     137    function GetFontEmHeightRatio: single;
     138    procedure SetVectorizeLCL(AValue: boolean);
    43139  protected
    44140    procedure UpdateFont;
     
    46142    function GetGlyph(AIdentifier: string): TBGRAGlyph; override;
    47143    procedure DefaultWordBreakHandler(var ABefore, AAfter: string);
     144    procedure Init(AVectorize: boolean);
     145    function CustomHeaderSize: integer; override;
     146    procedure WriteCustomHeader(AStream: TStream); override;
     147    procedure ReadAdditionalHeader(AStream: TStream); override;
     148    function ReadVectorizedFontHeader(AStream: TStream): TBGRAVectorizedFontHeader;
     149    function HeaderName: string; override;
     150    procedure SetDirectory(const AValue: string);
    48151  public
     152    UnderlineDecoration,StrikeOutDecoration: boolean;
    49153    constructor Create;
     154    constructor Create(AVectorizeLCL: boolean);
    50155    destructor Destroy; override;
    51156    function GetGlyphSize(AIdentifier:string): TPointF;
    52157    function GetTextGlyphSizes(AText:string): TGlyphSizes;
    53158    function GetTextSize(AText:string): TPointF;
    54     procedure SplitText(var AText: string; AMaxWidth: single; out ARemains: string);
    55     procedure DrawTextWordBreak(ADest: TBGRACanvas2D; AText: string; X, Y, MaxWidth: Single; AAlign: TBGRATypeWriterAlignment=twaTopLeft);
    56     procedure DrawTextRect(ADest: TBGRACanvas2D; AText: string; X1,Y1,X2,Y2: Single; AAlign: TBGRATypeWriterAlignment=twaTopLeft);
    57     procedure DrawTextRect(ADest: TBGRACanvas2D; AText: string; ATopLeft,ABottomRight: TPointF; AAlign: TBGRATypeWriterAlignment=twaTopLeft);
    58     function GetTextWordBreakGlyphBoxes(AText: string; X,Y, MaxWidth: Single; AAlign: TBGRATypeWriterAlignment = twaTopLeft): TGlyphBoxes;
    59     function GetTextRectGlyphBoxes(AText: string; X1,Y1,X2,Y2: Single; AAlign: TBGRATypeWriterAlignment=twaTopLeft): TGlyphBoxes;
    60     function GetTextRectGlyphBoxes(AText: string; ATopLeft,ABottomRight: TPointF; AAlign: TBGRATypeWriterAlignment=twaTopLeft): TGlyphBoxes;
     159    procedure SplitText(var ATextUTF8: string; AMaxWidth: single; out ARemainsUTF8: string);
     160    procedure DrawText(ADest: TBGRACanvas2D; ATextUTF8: string; X, Y: Single; AAlign: TBGRATypeWriterAlignment=twaTopLeft); override;
     161    procedure CopyTextPathTo(ADest: IBGRAPath; ATextUTF8: string; X, Y: Single;
     162      AAlign: TBGRATypeWriterAlignment=twaTopLeft); override;
     163    procedure DrawTextWordBreak(ADest: TBGRACanvas2D; ATextUTF8: string; X, Y, MaxWidth: Single; AAlign: TBGRATypeWriterAlignment=twaTopLeft);
     164    procedure DrawTextRect(ADest: TBGRACanvas2D; ATextUTF8: string; X1,Y1,X2,Y2: Single; AAlign: TBGRATypeWriterAlignment=twaTopLeft);
     165    procedure DrawTextRect(ADest: TBGRACanvas2D; ATextUTF8: string; ATopLeft,ABottomRight: TPointF; AAlign: TBGRATypeWriterAlignment=twaTopLeft);
     166    function GetTextWordBreakGlyphBoxes(ATextUTF8: string; X,Y, MaxWidth: Single; AAlign: TBGRATypeWriterAlignment = twaTopLeft): TGlyphBoxes;
     167    function GetTextRectGlyphBoxes(ATextUTF8: string; X1,Y1,X2,Y2: Single; AAlign: TBGRATypeWriterAlignment=twaTopLeft): TGlyphBoxes;
     168    function GetTextRectGlyphBoxes(ATextUTF8: string; ATopLeft,ABottomRight: TPointF; AAlign: TBGRATypeWriterAlignment=twaTopLeft): TGlyphBoxes;
     169    procedure UpdateDirectory;
     170    function LoadGlyphsInfo(AFilenameUTF8: string): TBGRAGlyphsInfo;
    61171
    62172    property Resolution: integer read FResolution write SetResolution;
    63173    property Style: TFontStyles read FStyle write SetStyle;
    64174    property Name: string read FName write SetName;
     175    property LCLHeight: single read GetLCLHeight write SetLCLHeight;
     176    property EmHeight: single read GetEmHeight write SetEmHeight;
    65177    property FullHeight: single read FFullHeight write SetFullHeight;
    66178    property FontMatrix: TAffineMatrix read FFontMatrix write SetFontMatrix;
     
    69181    property ItalicSlope: single read FItalicSlope write SetItalicSlope;
    70182    property OnWordBreak: TWordBreakHandler read FWordBreakHandler write FWordBreakHandler;
     183    property Directory: string read FDirectory write SetDirectory;
     184    property FontEmHeightRatio: single read GetFontEmHeightRatio;
     185    property FontPixelMetric: TFontPixelMetric read GetFontPixelMetric;
     186    property FontFound: boolean read FFontFound;
     187    property VectorizeLCL: boolean read GetVectorizeLCL write SetVectorizeLCL;
    71188  end;
    72189
    73190implementation
    74191
    75 uses BGRAText, LCLProc, Types;
    76 
     192uses LCLProc, FileUtil, lazutf8classes;
     193
     194{$i winstream.inc}
    77195function VectorizeMonochrome(ASource: TBGRACustomBitmap; zoom: single; PixelCenteredCoordinates: boolean): ArrayOfTPointF;
    78196const unitShift = 6;
     
    516634          (ord(cur[1])+ord(cur[3])+ord(cur[7])+ord(cur[9]) = 3)) then
    517635      begin
    518         if (not cur[6] and not cur[9] and not cur[8] and ((ASource.getPixel(integer(x-1),integer(y-2)).green <= 128) or (ASource.getPixel(integer(x+2),integer(y+1)).green <= 128)) ) or
    519           (not cur[8] and not cur[7] and not cur[4] and ((ASource.getPixel(integer(x-2),integer(y+1)).green <= 128) or (ASource.getPixel(integer(x+1),integer(y-2)).green <= 128)) ) or
    520           (not cur[4] and not cur[1] and not cur[2] and ((ASource.getPixel(integer(x+1),integer(y+2)).green <= 128) or (ASource.getPixel(integer(x-2),integer(y-1)).green <= 128)) ) or
    521           (not cur[2] and not cur[3] and not cur[6] and ((ASource.getPixel(integer(x-1),integer(y+2)).green <= 128) or (ASource.getPixel(integer(x+2),integer(y-1)).green <= 128)) ) then
     636        if (not cur[6] and not cur[9] and not cur[8] and ((ASource.getPixel(x-1,y-2).green <= 128) or (ASource.getPixel(x+2,y+1).green <= 128)) ) or
     637          (not cur[8] and not cur[7] and not cur[4] and ((ASource.getPixel(x-2,y+1).green <= 128) or (ASource.getPixel(x+1,y-2).green <= 128)) ) or
     638          (not cur[4] and not cur[1] and not cur[2] and ((ASource.getPixel(x+1,y+2).green <= 128) or (ASource.getPixel(x-2,y-1).green <= 128)) ) or
     639          (not cur[2] and not cur[3] and not cur[6] and ((ASource.getPixel(x-1,y+2).green <= 128) or (ASource.getPixel(x+2,y-1).green <= 128)) ) then
    522640            ortho[y,x] := true;
    523641      end;
     
    839957end;
    840958
     959{ TBGRAVectorizedFontRenderer }
     960
     961function TBGRAVectorizedFontRenderer.OutlineActuallyVisible: boolean;
     962begin
     963  result := OutlineVisible and (abs(OutlineWidth) > 0) and (OutlineColor.Alpha <> 0) or (OutlineTexture <> nil);
     964end;
     965
     966procedure TBGRAVectorizedFontRenderer.UpdateFont;
     967var i,neededResolution: integer;
     968begin
     969  FVectorizedFont := nil;
     970  FontName := Trim(FontName);
     971  for i := 0 to high(FVectorizedFontArray) do
     972    if (CompareText(FVectorizedFontArray[i].FontName,FontName)=0) and
     973      (FVectorizedFontArray[i].FontStyle = FontStyle) then
     974    begin
     975      FVectorizedFont := FVectorizedFontArray[i].VectorizedFont;
     976      break;
     977    end;
     978
     979  if FVectorizedFont = nil then
     980  begin
     981    FVectorizedFont:= TBGRAVectorizedFont.Create(False);
     982    FVectorizedFont.Name := FontName;
     983    FVectorizedFont.Style := FontStyle;
     984    FVectorizedFont.Directory := FDirectoryUTF8;
     985    if not FVectorizedFont.FontFound and LCLFontAvailable then
     986      FVectorizedFont.VectorizeLCL := True;
     987    Setlength(FVectorizedFontArray,length(FVectorizedFontArray)+1);
     988    FVectorizedFontArray[high(FVectorizedFontArray)].FontName := FontName;
     989    FVectorizedFontArray[high(FVectorizedFontArray)].FontStyle := FontStyle;
     990    FVectorizedFontArray[high(FVectorizedFontArray)].VectorizedFont := FVectorizedFont;
     991  end;
     992  if FontEmHeight > 0 then
     993    FVectorizedFont.EmHeight := FontEmHeight
     994  else
     995    FVectorizedFont.FullHeight:= -FontEmHeight;
     996  if OutlineActuallyVisible then
     997  begin
     998    if OuterOutlineOnly then
     999      FVectorizedFont.OutlineMode := twoFillOverStroke
     1000    else
     1001      FVectorizedFont.OutlineMode := twoStrokeOverFill;
     1002    FVectorizedFont.QuadraticCurves := False;
     1003  end
     1004  else
     1005  begin
     1006    FVectorizedFont.OutlineMode := twoFill;
     1007    FVectorizedFont.QuadraticCurves := FVectorizedFont.FullHeight > FVectorizedFont.Resolution*0.8;
     1008  end;
     1009  if FVectorizedFont.VectorizeLCL then
     1010  begin
     1011    neededResolution := trunc((FVectorizedFont.FullHeight+80)/50)*50;
     1012    if neededResolution > MaxFontResolution then neededResolution := MaxFontResolution;
     1013    if FVectorizedFont.Resolution < neededResolution then FVectorizedFont.Resolution:= neededResolution;
     1014  end;
     1015end;
     1016
     1017function TBGRAVectorizedFontRenderer.GetCanvas2D(ASurface: TBGRACustomBitmap
     1018  ): TBGRACanvas2D;
     1019begin
     1020  if (FCanvas2D = nil) or (FCanvas2D.surface <> ASurface) then
     1021  begin
     1022    FCanvas2D.Free;
     1023    FCanvas2D := TBGRACanvas2D.Create(ASurface);
     1024  end;
     1025  result := FCanvas2D;
     1026  FCanvas2D.antialiasing:= FontQuality in[fqFineAntialiasing,fqFineClearTypeBGR,fqFineClearTypeRGB];
     1027  if OutlineTexture <> nil then
     1028    FCanvas2D.strokeStyle(OutlineTexture)
     1029  else
     1030    FCanvas2D.strokeStyle(OutlineColor);
     1031  FCanvas2D.lineWidth := abs(OutlineWidth);
     1032  if not ShadowVisible then
     1033    FCanvas2D.shadowColor(BGRAPixelTransparent)
     1034  else
     1035  begin
     1036    FCanvas2D.shadowColor(ShadowColor);
     1037    FCanvas2D.shadowBlur:= ShadowRadius;
     1038    FCanvas2D.shadowOffset := PointF(ShadowOffset.X,ShadowOffset.Y);
     1039  end;
     1040end;
     1041
     1042procedure TBGRAVectorizedFontRenderer.InternalTextRect(
     1043  ADest: TBGRACustomBitmap; ARect: TRect; x, y: integer; sUTF8: string;
     1044  style: TTextStyle; c: TBGRAPixel; texture: IBGRAScanner);
     1045var
     1046  twAlign : TBGRATypeWriterAlignment;
     1047  c2D: TBGRACanvas2D;
     1048  intersectedClip,previousClip: TRect;
     1049begin
     1050  previousClip := ADest.ClipRect;
     1051  if style.Clipping then
     1052  begin
     1053    intersectedClip := rect(0,0,0,0);
     1054    if not IntersectRect(intersectedClip, previousClip, ARect) then exit;
     1055    ADest.ClipRect := intersectedClip;
     1056  end;
     1057  UpdateFont;
     1058  FVectorizedFont.Orientation := 0;
     1059  case style.Alignment of
     1060    taCenter: case style.Layout of
     1061              tlCenter: twAlign := twaMiddle;
     1062              tlBottom: twAlign := twaBottom;
     1063              else twAlign:= twaTop;
     1064              end;
     1065    taRightJustify:
     1066              case style.Layout of
     1067              tlCenter: twAlign := twaRight;
     1068              tlBottom: twAlign := twaBottomRight;
     1069              else twAlign := twaTopRight;
     1070              end;
     1071    else
     1072              case style.Layout of
     1073              tlCenter: twAlign := twaLeft;
     1074              tlBottom: twAlign := twaBottomLeft;
     1075              else twAlign:= twaTopLeft;
     1076              end;
     1077  end;
     1078  c2D := GetCanvas2D(ADest);
     1079  if texture = nil then
     1080    c2D.fillStyle(c)
     1081  else
     1082    c2D.fillStyle(texture);
     1083  if style.Wordbreak then
     1084    FVectorizedFont.DrawTextRect(c2D, sUTF8, x-0.5,y-0.5,ARect.Right-0.5,ARect.Bottom-0.5, twAlign)
     1085  else
     1086  begin
     1087    case style.Layout of
     1088    tlCenter: y := (ARect.Top+ARect.Bottom) div 2;
     1089    tlBottom: y := ARect.Bottom;
     1090    end;
     1091    case style.Alignment of
     1092    taCenter: FVectorizedFont.DrawText(c2D, sUTF8, (ARect.Left+ARect.Right-1)/2,y-0.5, twAlign);
     1093    taRightJustify: FVectorizedFont.DrawText(c2D, sUTF8, ARect.Right-0.5,y-0.5, twAlign);
     1094    else
     1095      FVectorizedFont.DrawText(c2D, sUTF8, x-0.5,y-0.5, twAlign);
     1096    end;
     1097  end;
     1098  if style.Clipping then
     1099    ADest.ClipRect := previousClip;
     1100end;
     1101
     1102procedure TBGRAVectorizedFontRenderer.Init;
     1103begin
     1104  FVectorizedFontArray := nil;
     1105  FDirectoryUTF8 := '';
     1106
     1107  OutlineVisible:= True;
     1108  OutlineColor := BGRAPixelTransparent;
     1109  OuterOutlineOnly := false;
     1110
     1111  ShadowColor := BGRABlack;
     1112  ShadowVisible := false;
     1113  ShadowOffset := Point(5,5);
     1114  ShadowRadius := 5;
     1115
     1116  MaxFontResolution := 300;
     1117end;
     1118
     1119constructor TBGRAVectorizedFontRenderer.Create;
     1120begin
     1121  Init;
     1122end;
     1123
     1124constructor TBGRAVectorizedFontRenderer.Create(ADirectoryUTF8: string);
     1125begin
     1126  Init;
     1127  FDirectoryUTF8 := ADirectoryUTF8;
     1128end;
     1129
     1130function TBGRAVectorizedFontRenderer.GetFontPixelMetric: TFontPixelMetric;
     1131var factor: single;
     1132begin
     1133  UpdateFont;
     1134  result := FVectorizedFont.FontPixelMetric;
     1135  if FVectorizedFont.Resolution > 0 then
     1136  begin
     1137    factor := FVectorizedFont.FullHeight/FVectorizedFont.Resolution;
     1138    result.Baseline := round(result.Baseline*factor);
     1139    result.CapLine := round(result.CapLine*factor);
     1140    result.Lineheight := round(result.Lineheight*factor);
     1141    result.DescentLine := round(result.DescentLine*factor);
     1142    result.xLine := round(result.xLine*factor);
     1143  end;
     1144end;
     1145
     1146procedure TBGRAVectorizedFontRenderer.TextOutAngle(ADest: TBGRACustomBitmap; x,
     1147  y: single; orientation: integer; s: string; c: TBGRAPixel; align: TAlignment);
     1148var
     1149  twAlign : TBGRATypeWriterAlignment;
     1150  c2D: TBGRACanvas2D;
     1151  ofs: TPointF;
     1152begin
     1153  UpdateFont;
     1154  FVectorizedFont.Orientation := orientation;
     1155  case align of
     1156    taCenter: twAlign:= twaMiddle;
     1157    taRightJustify: twAlign := twaRight;
     1158    else twAlign:= twaLeft;
     1159  end;
     1160  c2D := GetCanvas2D(ADest);
     1161  c2D.fillStyle(c);
     1162  ofs := PointF(x,y);
     1163  ofs += AffineMatrixRotationDeg(-orientation*0.1)*PointF(0,FVectorizedFont.FullHeight*0.5);
     1164  FVectorizedFont.DrawText(c2D, s, ofs.x,ofs.y, twAlign);
     1165end;
     1166
     1167procedure TBGRAVectorizedFontRenderer.TextOutAngle(ADest: TBGRACustomBitmap; x,
     1168  y: single; orientation: integer; s: string; texture: IBGRAScanner;
     1169  align: TAlignment);
     1170var
     1171  twAlign : TBGRATypeWriterAlignment;
     1172  c2D: TBGRACanvas2D;
     1173begin
     1174  UpdateFont;
     1175  FVectorizedFont.Orientation := orientation;
     1176  case align of
     1177    taCenter: twAlign:= twaTop;
     1178    taRightJustify: twAlign := twaTopRight;
     1179    else twAlign:= twaTopLeft;
     1180  end;
     1181  c2D := GetCanvas2D(ADest);
     1182  c2D.fillStyle(texture);
     1183  FVectorizedFont.DrawText(c2D, s, x,y, twAlign);
     1184end;
     1185
     1186procedure TBGRAVectorizedFontRenderer.TextOut(ADest: TBGRACustomBitmap; x,
     1187  y: single; s: string; texture: IBGRAScanner; align: TAlignment);
     1188begin
     1189  TextOutAngle(ADest,x,y,FontOrientation,s,texture,align);
     1190end;
     1191
     1192procedure TBGRAVectorizedFontRenderer.TextOut(ADest: TBGRACustomBitmap; x,
     1193  y: single; s: string; c: TBGRAPixel; align: TAlignment);
     1194begin
     1195  TextOutAngle(ADest,x,y,FontOrientation,s,c,align);
     1196end;
     1197
     1198procedure TBGRAVectorizedFontRenderer.TextRect(ADest: TBGRACustomBitmap;
     1199  ARect: TRect; x, y: integer; s: string; style: TTextStyle; c: TBGRAPixel);
     1200begin
     1201  InternalTextRect(ADest,ARect,x,y,s,style,c,nil);
     1202end;
     1203
     1204procedure TBGRAVectorizedFontRenderer.TextRect(ADest: TBGRACustomBitmap;
     1205  ARect: TRect; x, y: integer; s: string; style: TTextStyle;
     1206  texture: IBGRAScanner);
     1207begin
     1208  InternalTextRect(ADest,ARect,x,y,s,style,BGRAPixelTransparent,texture);
     1209end;
     1210
     1211procedure TBGRAVectorizedFontRenderer.CopyTextPathTo(ADest: IBGRAPath; x, y: single; s: string; align: TAlignment);
     1212var
     1213  twAlign : TBGRATypeWriterAlignment;
     1214  ofs: TPointF;
     1215begin
     1216  UpdateFont;
     1217  FVectorizedFont.Orientation := 0;
     1218  case align of
     1219    taCenter: twAlign:= twaMiddle;
     1220    taRightJustify: twAlign := twaRight;
     1221    else twAlign:= twaLeft;
     1222  end;
     1223  ofs := PointF(x,y);
     1224  ofs += PointF(0,FVectorizedFont.FullHeight*0.5);
     1225  FVectorizedFont.CopyTextPathTo(ADest, s, ofs.x,ofs.y, twAlign);
     1226end;
     1227
     1228function TBGRAVectorizedFontRenderer.TextSize(s: string): TSize;
     1229var sizeF: TPointF;
     1230begin
     1231  UpdateFont;
     1232  sizeF := FVectorizedFont.GetTextSize(s);
     1233  result.cx := round(sizeF.x);
     1234  result.cy := round(sizeF.y);
     1235end;
     1236
     1237destructor TBGRAVectorizedFontRenderer.Destroy;
     1238var i: integer;
     1239begin
     1240  FCanvas2D.Free;
     1241  for i := 0 to high(FVectorizedFontArray) do
     1242    FVectorizedFontArray[i].VectorizedFont.Free;
     1243  FVectorizedFontArray := nil;
     1244  inherited Destroy;
     1245end;
     1246
    8411247{ TBGRAVectorizedFont }
    8421248
     
    8621268end;
    8631269
     1270procedure TBGRAVectorizedFont.SetLCLHeight(AValue: single);
     1271begin
     1272  if (AValue > 0) xor (FontEmHeightSign < 0) then
     1273    EmHeight := abs(AValue)
     1274  else
     1275    FullHeight := abs(AValue);
     1276end;
     1277
     1278function TBGRAVectorizedFont.GetEmHeight: single;
     1279begin
     1280  result := FullHeight * FontEmHeightRatio;
     1281end;
     1282
     1283function TBGRAVectorizedFont.GetFontPixelMetric: TFontPixelMetric;
     1284begin
     1285  if not FFontPixelMetricComputed and (FFont <> nil) then
     1286  begin
     1287    FFontPixelMetric := BGRAText.GetFontPixelMetric(FFont);
     1288    FFontPixelMetricComputed := true;
     1289  end;
     1290  result := FFontPixelMetric;
     1291end;
     1292
     1293function TBGRAVectorizedFont.GetLCLHeight: single;
     1294begin
     1295  result := FullHeight * FontFullHeightSign;
     1296end;
     1297
     1298function TBGRAVectorizedFont.GetVectorizeLCL: boolean;
     1299begin
     1300  result := FFont <> nil;
     1301end;
     1302
     1303procedure TBGRAVectorizedFont.SetEmHeight(AValue: single);
     1304begin
     1305  if FontEmHeightRatio > 0 then
     1306    FullHeight := AValue / FontEmHeightRatio;
     1307end;
     1308
    8641309procedure TBGRAVectorizedFont.SetQuadraticCurves(AValue: boolean);
    8651310begin
     
    8951340end;
    8961341
     1342function TBGRAVectorizedFont.GetFontEmHeightRatio: single;
     1343var
     1344  lEmHeight, lFullHeight: single;
     1345  OldHeight: integer;
     1346begin
     1347  if not FFontEmHeightRatioComputed then
     1348  begin
     1349    if FFont <> nil then
     1350    begin
     1351      OldHeight := FFont.Height;
     1352      FFont.Height := FontEmHeightSign * 100;
     1353      lEmHeight := BGRATextSize(FFont, fqSystem, 'Hg', 1).cy;
     1354      FFont.Height := FontFullHeightSign * 100;
     1355      lFullHeight := BGRATextSize(FFont, fqSystem, 'Hg', 1).cy;
     1356      if lEmHeight = 0 then
     1357        FFontEmHeightRatio := 1
     1358      else
     1359        FFontEmHeightRatio := lFullHeight/lEmHeight;
     1360      FFontEmHeightRatioComputed := true;
     1361      FFont.Height := OldHeight;
     1362    end else
     1363    begin
     1364      result := 1;
     1365      exit;
     1366    end;
     1367  end;
     1368  result := FFontEmHeightRatio;
     1369end;
     1370
     1371procedure TBGRAVectorizedFont.SetVectorizeLCL(AValue: boolean);
     1372begin
     1373  if AValue then
     1374  begin
     1375    if FFont = nil then
     1376      FFont := TFont.Create;
     1377  end else
     1378  begin
     1379    if FFont <> nil then
     1380      FreeAndNil(FFont);
     1381  end;
     1382  UpdateFont;
     1383end;
     1384
    8971385procedure TBGRAVectorizedFont.UpdateFont;
    898 begin
    899   ClearGlyphs;
    900   FFont.Name := FName;
    901   FFont.Style := FStyle;
    902   FFont.Height := FontFullHeightSign * FResolution;
     1386var i: integer;
     1387  bestIndex, bestDistance: integer;
     1388  distance: integer;
     1389begin
     1390  if FFont <> nil then
     1391  begin
     1392    ClearGlyphs;
     1393    FFont.Name := FName;
     1394    FFont.Style := FStyle;
     1395    FFont.Height := FontFullHeightSign * FResolution;
     1396    FFontEmHeightRatio := 1;
     1397    FFontEmHeightRatioComputed := false;
     1398    fillchar(FFontPixelMetric,sizeof(FFontPixelMetric),0);
     1399    FFontPixelMetricComputed := false;
     1400    FFontFound := True;
     1401  end else
     1402  begin
     1403    bestIndex := -1;
     1404    bestDistance := 1000;
     1405    for i := 0 to high(FDirectoryContent) do
     1406    begin
     1407      if CompareText(FDirectoryContent[i].FontName,FName) = 0 then
     1408      begin
     1409        distance := 0;
     1410        if (fsBold in FDirectoryContent[i].FontStyle) xor (fsBold in FStyle) then distance += 10;
     1411        if (fsItalic in FDirectoryContent[i].FontStyle) xor (fsItalic in FStyle) then distance += 5;
     1412        if (fsStrikeOut in FDirectoryContent[i].FontStyle) xor (fsStrikeOut in FStyle) then distance += 1;
     1413        if (fsUnderline in FDirectoryContent[i].FontStyle) xor (fsUnderline in FStyle) then distance += 1;
     1414        if (bestIndex = -1) or (distance < bestDistance) then
     1415        begin
     1416          bestIndex := i;
     1417          bestDistance := distance;
     1418          if FDirectoryContent[i].FontStyle = FStyle then break;
     1419        end;
     1420      end;
     1421    end;
     1422    if bestIndex <> -1 then
     1423    begin
     1424      if not (fsItalic in FDirectoryContent[bestIndex].FontStyle) and (fsItalic in FStyle) then
     1425        ItalicSlope := 0.25
     1426      else if (fsItalic in FDirectoryContent[bestIndex].FontStyle) and not (fsItalic in FStyle) then
     1427        ItalicSlope := -0.25
     1428      else
     1429        ItalicSlope := 0;
     1430
     1431      UnderlineDecoration := not (fsUnderline in FDirectoryContent[bestIndex].FontStyle) and (fsUnderline in FStyle);
     1432      StrikeOutDecoration := not (fsStrikeOut in FDirectoryContent[bestIndex].FontStyle) and (fsStrikeOut in FStyle);
     1433
     1434      ClearGlyphs;
     1435      LoadGlyphsFromFile(FDirectoryContent[bestIndex].Filename);
     1436      FFontFound := True;
     1437    end else
     1438      FFontFound := false;
     1439  end;
    9031440end;
    9041441
     
    9111448begin
    9121449  inherited Create;
    913   FName := 'Arial';
    914   FStyle := [];
    915   FFontMatrix := AffineMatrixIdentity;
    916   FOrientation := 0;
    917   FResolution := 100;
    918   FFont := TFont.Create;
    919   FBuffer := BGRABitmapFactory.Create;
    920   FFullHeight := 20;
    921   FItalicSlope := 0;
    922   UpdateFont;
    923   UpdateMatrix;
    924   FWordBreakHandler:= nil;
     1450  Init(True);
     1451end;
     1452
     1453constructor TBGRAVectorizedFont.Create(AVectorizeLCL: boolean);
     1454begin
     1455  inherited Create;
     1456  Init(AVectorizeLCL);
    9251457end;
    9261458
     
    10121544end;
    10131545
    1014 procedure TBGRAVectorizedFont.SplitText(var AText: string; AMaxWidth: single;
    1015   out ARemains: string);
     1546procedure TBGRAVectorizedFont.SplitText(var ATextUTF8: string; AMaxWidth: single;
     1547  out ARemainsUTF8: string);
    10161548var
    10171549  pstr: pchar;
    1018   left,charlen: integer;
     1550  p,left,charlen: integer;
     1551  totalWidth: single;
     1552  firstChar: boolean;
    10191553  nextchar: string;
    10201554  g: TBGRAGlyph;
    1021   totalWidth: single;
    1022   firstChar: boolean;
    10231555begin
    10241556  totalWidth := 0;
    1025   if AText = '' then
    1026   begin
    1027     ARemains := '';
     1557  if ATextUTF8 = '' then
     1558  begin
     1559    ARemainsUTF8 := '';
    10281560    exit;
    10291561  end else
    10301562  begin
    1031     pstr := @AText[1];
    1032     left := length(AText);
     1563    p := 1;
     1564    pstr := @ATextUTF8[1];
     1565    left := length(ATextUTF8);
    10331566    firstChar := true;
    10341567    while left > 0 do
    10351568    begin
     1569      if RemoveLineEnding(ATextUTF8,p) then
     1570      begin
     1571        ARemainsUTF8 := copy(ATextUTF8,p,length(ATextUTF8)-p+1);
     1572        ATextUTF8 := copy(ATextUTF8,1,p-1);
     1573        exit;
     1574      end;
     1575
    10361576      charlen := UTF8CharacterLength(pstr);
    10371577      setlength(nextchar, charlen);
     
    10431583      begin
    10441584        totalWidth += g.Width*FullHeight;
    1045         if (totalWidth > AMaxWidth) and not firstChar then
     1585        if not firstChar and (totalWidth > AMaxWidth) then
    10461586        begin
    1047           ARemains:= copy(AText,length(AText)-left+1,left);
    1048           AText := copy(AText, 1, length(AText)-left);
     1587          ARemainsUTF8:= copy(ATextUTF8,p,length(ATextUTF8)-p+1);
     1588          ATextUTF8 := copy(ATextUTF8,1,p-1);
    10491589          if Assigned(FWordBreakHandler) then
    1050             FWordBreakHandler(AText,ARemains) else
    1051               DefaultWordBreakHandler(AText,ARemains);
     1590            FWordBreakHandler(ATextUTF8,ARemainsUTF8) else
     1591              DefaultWordBreakHandler(ATextUTF8,ARemainsUTF8);
    10521592          exit;
    10531593        end;
     
    10551595
    10561596      dec(left,charlen);
     1597      inc(p,charlen);
    10571598      firstChar := false;
    10581599    end;
    10591600  end;
    1060   ARemains := ''; //no split
     1601  ARemainsUTF8 := ''; //no split
     1602end;
     1603
     1604procedure TBGRAVectorizedFont.DrawText(ADest: TBGRACanvas2D; ATextUTF8: string; X,
     1605  Y: Single; AAlign: TBGRATypeWriterAlignment);
     1606var underlinePoly: ArrayOfTPointF;
     1607  m: TAffineMatrix;
     1608  i: integer;
     1609  deltaY: single;
     1610begin
     1611  inherited DrawText(ADest, ATextUTF8, X, Y, AAlign);
     1612  if AAlign in [twaBottom,twaBottomLeft,twaBottomRight] then deltaY := -1 else
     1613  if AAlign in [twaLeft,twaMiddle,twaRight] then deltaY := -0.5 else
     1614    deltaY := 0;
     1615  if UnderlineDecoration and (Resolution > 0) then
     1616  begin
     1617    underlinePoly := BGRATextUnderline(PointF(0,deltaY), GetTextSize(ATextUTF8).x/FullHeight, FontPixelMetric.Baseline/Resolution,
     1618      (FontPixelMetric.Baseline-FontPixelMetric.CapLine)/Resolution);
     1619    if underlinePoly <> nil then
     1620    begin
     1621      m := GetTextMatrix(ATextUTF8, X,Y,AAlign);
     1622      for i := 0 to high(underlinePoly) do
     1623        underlinePoly[i] := m*underlinePoly[i];
     1624      if OutlineMode <> twoPath then ADest.beginPath;
     1625      ADest.polylineTo(underlinePoly);
     1626      DrawLastPath(ADest);
     1627    end;
     1628  end;
     1629  if StrikeOutDecoration and (Resolution > 0) then
     1630  begin
     1631    underlinePoly := BGRATextStrikeOut(PointF(0,deltaY), GetTextSize(ATextUTF8).x/FullHeight, FontPixelMetric.Baseline/Resolution,
     1632      (FontPixelMetric.Baseline-FontPixelMetric.CapLine)/Resolution, (FontPixelMetric.Baseline-FontPixelMetric.xLine)/Resolution);
     1633    if underlinePoly <> nil then
     1634    begin
     1635      m := GetTextMatrix(ATextUTF8, X,Y,AAlign);
     1636      for i := 0 to high(underlinePoly) do
     1637        underlinePoly[i] := m*underlinePoly[i];
     1638      if OutlineMode <> twoPath then ADest.beginPath;
     1639      ADest.polylineTo(underlinePoly);
     1640      DrawLastPath(ADest);
     1641    end;
     1642  end;
     1643end;
     1644
     1645procedure TBGRAVectorizedFont.CopyTextPathTo(ADest: IBGRAPath;
     1646  ATextUTF8: string; X, Y: Single; AAlign: TBGRATypeWriterAlignment);
     1647var underlinePoly: ArrayOfTPointF;
     1648  m: TAffineMatrix;
     1649  i: integer;
     1650  deltaY: single;
     1651begin
     1652  inherited CopyTextPathTo(ADest,ATextUTF8, X, Y, AAlign);
     1653  if AAlign in [twaBottom,twaBottomLeft,twaBottomRight] then deltaY := -1 else
     1654  if AAlign in [twaLeft,twaMiddle,twaRight] then deltaY := -0.5 else
     1655    deltaY := 0;
     1656  if UnderlineDecoration and (Resolution > 0) then
     1657  begin
     1658    underlinePoly := BGRATextUnderline(PointF(0,deltaY), GetTextSize(ATextUTF8).x/FullHeight, FontPixelMetric.Baseline/Resolution,
     1659      (FontPixelMetric.Baseline-FontPixelMetric.CapLine)/Resolution);
     1660    if underlinePoly <> nil then
     1661    begin
     1662      m := GetTextMatrix(ATextUTF8, X,Y,AAlign);
     1663      ADest.moveTo(m*underlinePoly[0]);
     1664      for i := 1 to high(underlinePoly) do
     1665        ADest.lineTo(m*underlinePoly[i]);
     1666      ADest.closePath;
     1667    end;
     1668  end;
     1669  if StrikeOutDecoration and (Resolution > 0) then
     1670  begin
     1671    underlinePoly := BGRATextStrikeOut(PointF(0,deltaY), GetTextSize(ATextUTF8).x/FullHeight, FontPixelMetric.Baseline/Resolution,
     1672      (FontPixelMetric.Baseline-FontPixelMetric.CapLine)/Resolution, (FontPixelMetric.Baseline-FontPixelMetric.xLine)/Resolution);
     1673    if underlinePoly <> nil then
     1674    begin
     1675      m := GetTextMatrix(ATextUTF8, X,Y,AAlign);
     1676      ADest.moveTo(m*underlinePoly[0]);
     1677      for i := 1 to high(underlinePoly) do
     1678        ADest.lineTo(m*underlinePoly[i]);
     1679      ADest.closePath;
     1680    end;
     1681  end;
    10611682end;
    10621683
    10631684procedure TBGRAVectorizedFont.DrawTextWordBreak(ADest: TBGRACanvas2D;
    1064   AText: string; X, Y, MaxWidth: Single; AAlign: TBGRATypeWriterAlignment);
     1685  ATextUTF8: string; X, Y, MaxWidth: Single; AAlign: TBGRATypeWriterAlignment);
    10651686var ARemains: string;
    10661687  step: TPointF;
     
    10711692  lineAlignment: TBGRATypeWriterAlignment;
    10721693begin
    1073   if (AText = '') or (MaxWidth <= 0) then exit;
     1694  if (ATextUTF8 = '') or (MaxWidth <= 0) then exit;
    10741695
    10751696  oldItalicSlope:= ItalicSlope;
     
    11041725    Y += step.Y*lineShift;
    11051726    repeat
    1106       SplitText(AText, MaxWidth, ARemains);
    1107       DrawText(ADest,AText,X,Y,lineAlignment);
    1108       AText := ARemains;
     1727      SplitText(ATextUTF8, MaxWidth, ARemains);
     1728      DrawText(ADest,ATextUTF8,X,Y,lineAlignment);
     1729      ATextUTF8 := ARemains;
    11091730      X+= step.X;
    11101731      Y+= step.Y;
     
    11141735    lines := TStringList.Create;
    11151736    repeat
    1116       SplitText(AText, MaxWidth, ARemains);
    1117       lines.Add(AText);
    1118       AText := ARemains;
     1737      SplitText(ATextUTF8, MaxWidth, ARemains);
     1738      lines.Add(ATextUTF8);
     1739      ATextUTF8 := ARemains;
    11191740    until ARemains = '';
    11201741    if AAlign in[twaLeft,twaMiddle,twaRight] then lineShift := lines.Count/2-0.5
     
    11401761end;
    11411762
    1142 procedure TBGRAVectorizedFont.DrawTextRect(ADest: TBGRACanvas2D; AText: string;
     1763procedure TBGRAVectorizedFont.DrawTextRect(ADest: TBGRACanvas2D; ATextUTF8: string;
    11431764  X1, Y1, X2, Y2: Single; AAlign: TBGRATypeWriterAlignment);
    11441765var X,Y: single;
     
    11541775  oldOrientation:= Orientation;
    11551776  Orientation:= 0;
    1156   DrawTextWordBreak(ADest,AText,X,Y,X2-X1,AAlign);
     1777  DrawTextWordBreak(ADest,ATextUTF8,X,Y,X2-X1,AAlign);
    11571778  Orientation:= oldOrientation;
    11581779end;
    11591780
    1160 procedure TBGRAVectorizedFont.DrawTextRect(ADest: TBGRACanvas2D; AText: string;
     1781procedure TBGRAVectorizedFont.DrawTextRect(ADest: TBGRACanvas2D; ATextUTF8: string;
    11611782  ATopLeft, ABottomRight: TPointF; AAlign: TBGRATypeWriterAlignment);
    11621783begin
    1163   DrawTextRect(ADest,AText,ATopLeft.X,ATopLeft.Y,ABottomRight.X,ABottomRight.Y,AAlign);
    1164 end;
    1165 
    1166 function TBGRAVectorizedFont.GetTextWordBreakGlyphBoxes(AText: string; X, Y,
     1784  DrawTextRect(ADest,ATextUTF8,ATopLeft.X,ATopLeft.Y,ABottomRight.X,ABottomRight.Y,AAlign);
     1785end;
     1786
     1787function TBGRAVectorizedFont.GetTextWordBreakGlyphBoxes(ATextUTF8: string; X, Y,
    11671788  MaxWidth: Single; AAlign: TBGRATypeWriterAlignment): TGlyphBoxes;
    11681789var ARemains: string;
     
    11771798begin
    11781799  result := nil;
    1179   if AText = '' then exit;
     1800  if ATextUTF8 = '' then exit;
    11801801
    11811802  oldItalicSlope:= ItalicSlope;
     
    12021823  lines := TStringList.Create;
    12031824  repeat
    1204     SplitText(AText, MaxWidth, ARemains);
    1205     lines.Add(AText);
    1206     AText := ARemains;
     1825    SplitText(ATextUTF8, MaxWidth, ARemains);
     1826    lines.Add(ATextUTF8);
     1827    ATextUTF8 := ARemains;
    12071828  until ARemains = '';
    12081829
     
    12391860end;
    12401861
    1241 function TBGRAVectorizedFont.GetTextRectGlyphBoxes(AText: string; X1, Y1, X2,
     1862function TBGRAVectorizedFont.GetTextRectGlyphBoxes(ATextUTF8: string; X1, Y1, X2,
    12421863  Y2: Single; AAlign: TBGRATypeWriterAlignment): TGlyphBoxes;
    12431864var X,Y,oldOrientation: single;
     
    12561877  oldOrientation:= Orientation;
    12571878  Orientation:= 0;
    1258   result := GetTextWordBreakGlyphBoxes(AText,X,Y,X2-X1,AAlign);
     1879  result := GetTextWordBreakGlyphBoxes(ATextUTF8,X,Y,X2-X1,AAlign);
    12591880  Orientation:= oldOrientation;
    12601881end;
    12611882
    1262 function TBGRAVectorizedFont.GetTextRectGlyphBoxes(AText: string; ATopLeft,
     1883function TBGRAVectorizedFont.GetTextRectGlyphBoxes(ATextUTF8: string; ATopLeft,
    12631884  ABottomRight: TPointF; AAlign: TBGRATypeWriterAlignment): TGlyphBoxes;
    12641885begin
    1265   result := GetTextRectGlyphBoxes(AText,ATopLeft.X,ATopLeft.Y,ABottomRight.X,ABottomRight.Y,AAlign);
     1886  result := GetTextRectGlyphBoxes(ATextUTF8,ATopLeft.X,ATopLeft.Y,ABottomRight.X,ABottomRight.Y,AAlign);
     1887end;
     1888
     1889procedure TBGRAVectorizedFont.UpdateDirectory;
     1890var
     1891  NbFiles: integer;
     1892  SearchRec: TSearchRec;
     1893  Info: TBGRAGlyphsInfo;
     1894  Fullname: string;
     1895begin
     1896  NbFiles := 0;
     1897  FDirectoryContent := nil;
     1898  if FDirectory = '' then exit;
     1899  if (length(FDirectory) > 0) and not (FDirectory[length(FDirectory)] in AllowDirectorySeparators) then
     1900    FDirectory += DirectorySeparator;
     1901  if FindFirstUTF8(FDirectory +'*.glyphs', faAnyFile, SearchRec) = 0 then
     1902  repeat
     1903    if (faDirectory or faVolumeId or faSysFile) and SearchRec.Attr = 0 then
     1904    begin
     1905      Fullname := FDirectory+SearchRec.Name;
     1906      Info := LoadGlyphsInfo(Fullname);
     1907      if (info.Name <> '') and (info.NbGlyphs > 0) then
     1908      begin
     1909        if NbFiles = length(FDirectoryContent) then
     1910          setlength(FDirectoryContent,2*NbFiles+1);
     1911        FDirectoryContent[NbFiles].Filename:= Fullname;
     1912        FDirectoryContent[NbFiles].FontName:= info.Name;
     1913        FDirectoryContent[NbFiles].FontStyle:= info.Style;
     1914        inc(NbFiles);
     1915      end;
     1916    end;
     1917  until FindNext(SearchRec) <> 0;
     1918  SetLength(FDirectoryContent,NbFiles);
     1919end;
     1920
     1921function TBGRAVectorizedFont.LoadGlyphsInfo(AFilenameUTF8: string): TBGRAGlyphsInfo;
     1922var Stream: TFileStreamUTF8;
     1923  twHeader: TBGRACustomTypeWriterHeader;
     1924  vfHeader: TBGRAVectorizedFontHeader;
     1925begin
     1926  result.Name := '';
     1927  result.NbGlyphs := 0;
     1928  result.Style := [];
     1929  Stream := nil;
     1930  try
     1931    Stream := TFileStreamUTF8.Create(AFilenameUTF8,fmOpenRead);
     1932    Stream.Position := 4;
     1933    twHeader := ReadCustomTypeWriterHeader(Stream);
     1934    result.NbGlyphs := twHeader.NbGlyphs;
     1935    if twHeader.HeaderName = HeaderName then
     1936    begin
     1937      vfHeader := ReadVectorizedFontHeader(Stream);
     1938      result.Name := vfHeader.Name;
     1939      result.Style:= vfHeader.Style;
     1940    end;
     1941  except
     1942    on ex:exception do
     1943    begin
     1944
     1945    end;
     1946  end;
     1947  Stream.Free;
    12661948end;
    12671949
     
    12711953begin
    12721954  Result:=inherited GetGlyph(AIdentifier);
    1273   if (result = nil) and (FResolution > 0) then
     1955  if (result = nil) and (FResolution > 0) and (FFont <> nil) then
    12741956  begin
    12751957    g := TBGRAPolygonalGlyph.Create(AIdentifier);
     
    12941976
    12951977procedure TBGRAVectorizedFont.DefaultWordBreakHandler(var ABefore,AAfter: string);
    1296 var p: integer;
    1297 begin
    1298   if (AAfter <> '') and (ABefore <> '') and (AAfter[1]<> ' ') and (ABefore[length(ABefore)] <> ' ') then
    1299   begin
    1300     p := length(ABefore);
    1301     while (p > 1) and (ABefore[p-1] <> ' ') do dec(p);
    1302     if p > 1 then //can put the word after
    1303     begin
    1304       AAfter := copy(ABefore,p,length(ABefore)-p+1)+AAfter;
    1305       ABefore := copy(ABefore,1,p-1);
    1306     end else
    1307     begin //cannot put the word after, so before
    1308 
    1309     end;
    1310   end;
    1311   while (ABefore <> '') and (ABefore[length(ABefore)] =' ') do delete(ABefore,length(ABefore),1);
    1312   while (AAfter <> '') and (AAfter[1] =' ') do delete(AAfter,1,1);
     1978begin
     1979  BGRADefaultWordBreakHandler(ABefore,AAfter);
     1980end;
     1981
     1982procedure TBGRAVectorizedFont.Init(AVectorize: boolean);
     1983begin
     1984  FName := 'Arial';
     1985  FStyle := [];
     1986  FFontMatrix := AffineMatrixIdentity;
     1987  FOrientation := 0;
     1988  FResolution := 100;
     1989  FFontEmHeightRatio := 1;
     1990  FFontEmHeightRatioComputed := false;
     1991  if AVectorize then
     1992    FFont := TFont.Create
     1993  else
     1994    FFont := nil;
     1995  FBuffer := BGRABitmapFactory.Create;
     1996  FFullHeight := 20;
     1997  FItalicSlope := 0;
     1998  UpdateFont;
     1999  UpdateMatrix;
     2000  FWordBreakHandler:= nil;
     2001end;
     2002
     2003function TBGRAVectorizedFont.CustomHeaderSize: integer;
     2004begin
     2005  Result:= (inherited CustomHeaderSize) + 4+length(FName)+4 + sizeof(single) + 4 + 5*4;
     2006end;
     2007
     2008procedure TBGRAVectorizedFont.WriteCustomHeader(AStream: TStream);
     2009var metric: TFontPixelMetric;
     2010begin
     2011  inherited WriteCustomHeader(AStream);
     2012  WinWriteLongint(AStream, length(FName));
     2013  AStream.Write(FName[1],length(FName));
     2014  WinWriteLongint(AStream, integer(FStyle));
     2015  WinWriteSingle(AStream, FontEmHeightRatio);
     2016  WinWriteLongint(AStream, Resolution);
     2017  metric := FontPixelMetric;
     2018  WinWriteLongint(AStream, metric.Baseline);
     2019  WinWriteLongint(AStream, metric.xLine);
     2020  WinWriteLongint(AStream, metric.CapLine);
     2021  WinWriteLongint(AStream, metric.DescentLine);
     2022  WinWriteLongint(AStream, metric.Lineheight);
     2023end;
     2024
     2025procedure TBGRAVectorizedFont.ReadAdditionalHeader(AStream: TStream);
     2026var Header: TBGRAVectorizedFontHeader;
     2027begin
     2028  inherited ReadAdditionalHeader(AStream);
     2029  Header := ReadVectorizedFontHeader(AStream);
     2030  FName := Header.Name;
     2031  FStyle := Header.Style;
     2032  if header.EmHeightRatio <> 0 then
     2033  begin
     2034    FFontEmHeightRatio := Header.EmHeightRatio;
     2035    FFontEmHeightRatioComputed := true;
     2036  end else
     2037  begin
     2038    FFontEmHeightRatio := 1;
     2039    FFontEmHeightRatioComputed := false;
     2040  end;
     2041  FFontPixelMetric := Header.PixelMetric;
     2042  FFontPixelMetricComputed := True;
     2043  if FFont = nil then
     2044    FResolution := Header.Resolution;
     2045end;
     2046
     2047function TBGRAVectorizedFont.ReadVectorizedFontHeader(AStream: TStream): TBGRAVectorizedFontHeader;
     2048var lNameLength: integer;
     2049begin
     2050  lNameLength := WinReadLongint(AStream);
     2051  setlength(result.Name, lNameLength);
     2052  AStream.Read(result.Name[1],length(result.Name));
     2053  result.Style := TFontStyles(WinReadLongint(AStream));
     2054  result.EmHeightRatio:= WinReadSingle(AStream);
     2055  result.Resolution := WinReadLongint(AStream);
     2056  result.PixelMetric.Baseline := WinReadLongint(AStream);
     2057  result.PixelMetric.xLine := WinReadLongint(AStream);
     2058  result.PixelMetric.CapLine := WinReadLongint(AStream);
     2059  result.PixelMetric.DescentLine := WinReadLongint(AStream);
     2060  result.PixelMetric.Lineheight := WinReadLongint(AStream);
     2061  result.PixelMetric.Defined := result.PixelMetric.Lineheight > 0;
     2062end;
     2063
     2064function TBGRAVectorizedFont.HeaderName: string;
     2065begin
     2066  Result:= 'TBGRAVectorizedFont';
     2067end;
     2068
     2069procedure TBGRAVectorizedFont.SetDirectory(const AValue: string);
     2070begin
     2071  if Trim(AValue) = Trim(FDirectory) then exit;
     2072  FDirectory := Trim(AValue);
     2073  UpdateDirectory;
     2074  UpdateFont;
    13132075end;
    13142076
Note: See TracChangeset for help on using the changeset viewer.