fontreader.pas
上传用户:raido2005
上传日期:2022-06-22
资源大小:5044k
文件大小:6k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. //*******************************************************//
  2. //                                                       //
  3. //                      DelphiFlash.com                  //
  4. //         Copyright (c) 2004-2005 FeatherySoft, Inc.    //
  5. //                    info@delphiflash.com               //
  6. //                                                       //
  7. //*******************************************************//
  8. //  Description:  Font reading functions
  9. //  Last update:  21 sep 2006
  10. unit FontReader;
  11. interface
  12. Uses Windows, Classes, SWFObjects, FlashObjects;
  13. const EMS = 1024;
  14. Procedure ReadFontMetric(Font: TFlashFont);
  15. Procedure FillCharInfo(DC: HDC; FChar: TFlashChar);
  16. Procedure GetCharOutlines(DC: HDC; code: word; Shape: TFlashEdges);
  17. Function MakeLogFont(Font: TFlashFont): TLogFont;
  18. implementation
  19. Uses SysUtils, SWFConst;
  20. var fLogFont: TLogFont;
  21. function gdEnumFontsProc(var LogFont: TLogFont; var TextMetric: TTextMetric; FontType: Integer; Data: Pointer): Integer; {export;} stdcall;
  22. begin
  23.  fLogFont := LogFont;
  24.  result := 0;
  25. end;
  26. Function MakeLogFont(Font: TFlashFont): TLogFont;
  27.  var ach: array [0..128] of char;
  28.      DC: HDC;
  29. begin
  30.  StrPCopy(ach, Font.Name);
  31.  DC:=GetDC(0);
  32.  FillChar(fLogFont, SizeOf(fLogFont), 0);
  33.  fLogFont.lfCharSet := Font.FontCharset;
  34.  EnumFonts(DC, ach, @gdEnumFontsProc, nil);
  35.  ReleaseDC(0, DC);
  36.  if fLogFont.lfFaceName = '' then StrPCopy(fLogFont.lfFaceName, Font.Name);
  37.  
  38.  Result := fLogFont;
  39.  with fLogFont do
  40.    begin
  41.      lfHeight := - EMS;
  42.      lfWidth := 0;
  43.      lfEscapement := 0;
  44.      lfOrientation := 0;
  45.  //    lfCharset := Font.FontCharset;
  46.      if Font.Bold then lfWeight := FW_Bold else lfWeight := FW_Normal;
  47.      lfItalic := Byte(Font.Italic);
  48.      lfUnderline := 0;
  49.      lfStrikeOut := 0;
  50.      if Font.AntiAlias then lfQuality := ANTIALIASED_QUALITY
  51.       else lfQuality := NONANTIALIASED_QUALITY;
  52. //     lfOutPrecision := OUT_DEFAULT_PRECIS;
  53. //     lfClipPrecision := CLIP_DEFAULT_PRECIS;
  54. //     lfPitchAndFamily := DEFAULT_PITCH;
  55.    end;
  56.  Result := fLogFont;
  57. end;
  58. {..$DEFINE ExMetrics}
  59. Procedure ReadFontMetric(Font: TFlashFont);
  60.  var FDC, HF, OldF: THandle;
  61. {$IFDEF ExMetrics}
  62.      L: longint;
  63.      OM: POutlineTextmetric;
  64. {$ELSE}
  65.      TM: TTextmetric;
  66. {$ENDIF}
  67. begin
  68.  FDC := CreateCompatibleDC(0);
  69.  if Font.FontInfo.lfFaceName = ''
  70.    then
  71.      HF := CreateFontIndirect(MakeLogFont(Font))
  72.    else
  73.      HF := CreateFontIndirect(Font.FontInfo);
  74.  OldF := SelectObject(FDC, HF);
  75. {$IFDEF ExMetrics}
  76.  l := GetOutlineTextMetrics(FDC, 0, nil);
  77.  GetMem(OM, L);
  78.  GetOutlineTextMetrics(FDC, L, OM);
  79.  Font.Ascent := OM.otmTextMetrics.tmAscent;
  80.  Font.Descent := OM.otmTextMetrics.tmDescent;
  81.  Font.Leading := OM.otmTextMetrics.tmInternalLeading;
  82.  //OM.otmsStrikeoutSize;
  83.  FreeMem(OM, L);
  84. {$ELSE}
  85.  GetTextMetrics(FDC, TM);
  86.  Font.Ascent := TM.tmAscent;
  87.  Font.Descent := TM.tmDescent;
  88.  Font.Leading := TM.tmInternalLeading;
  89. {$ENDIF}
  90.  DeleteObject(SelectObject(FDC, OldF));
  91.  DeleteDC(FDC);
  92. end;
  93. Procedure FillCharInfo(DC: HDC; FChar: TFlashChar);
  94.  var ABC: TABC;
  95. begin
  96.  FChar.ShapeInit := true;
  97.  GetCharOutlines(DC, FChar.WideCode, FChar.Edges);
  98.  GetCharABCWidthsW(DC, FChar.WideCode, FChar.WideCode, ABC);
  99.  With FChar do
  100.   begin
  101.    GlyphAdvance := ABC.abcA + integer(ABC.abcB) + ABC.abcC;
  102. {..$DEFINE Kerning}
  103. {$IFDEF Kerning}
  104.    // Kerning table is not used now in Flash Player
  105.    // I don't no wot this for
  106.    Kerning.FontKerningAdjustment := ABC.abcB;
  107.    Kerning.FontKerningCode1 := ABC.abcA;
  108.    Kerning.FontKerningCode2 := ABC.abcC;
  109. {$ENDIF}
  110.   end;
  111. end;
  112. Function GetFixed(v: TFixed): Longint;
  113. begin
  114.   if V.fract > 0 then Result := Round(V.value + V.fract / specFixed)
  115.     else Result := V.value;
  116. end;
  117. Procedure GetCharOutlines(DC: HDC; code: word; Shape: TFlashEdges);
  118.  var
  119.      M2: TMAT2;
  120.      GM: TGlyphMetrics;
  121.      Mem: TMemoryStream;
  122.      Header: TTPolygonHeader;
  123.      L: Longint;
  124.      pcSize: integer;
  125.      LType, PCount: word;
  126.      pB, pC, p1: TPointFX;
  127. begin
  128. // |1,0|
  129. // |0,1|
  130.  M2.eM11.value := 1; M2.eM11.fract := 1;
  131.  M2.eM12.value := 0; M2.eM12.fract := 1;
  132.  M2.eM21.value := 0; M2.eM21.fract := 1;
  133.  M2.eM22.value := 1; M2.eM22.fract := 1;
  134.  FillChar(GM, SizeOf(GM), 0);
  135.  L := GetGlyphOutlineW(DC, Code, GGO_NATIVE, GM, 0, nil, M2);
  136. // if not Shape.NoStyles then
  137. //   begin
  138.  //   Shape.SetShapeBound(0, - GM.gmBlackBoxY, GM.gmBlackBoxX, 0);
  139. //   end;
  140.  if L > 0 then
  141.    begin
  142.      Mem := TMemoryStream.Create;
  143.      Mem.SetSize(L);
  144.      GetGlyphOutlineW(DC, Code, GGO_NATIVE, GM, L, Mem.Memory, M2);
  145.      While Mem.Position < Mem.Size do
  146.        begin
  147.          Mem.Read(Header, sizeOf(Header));
  148.          Shape.MoveTo(GetFixed(Header.pfxStart.x){.value}, GetFixed(Header.pfxStart.y){.value});
  149.          pcSize := Header.cb - SizeOf(Header);
  150.          While pcSize > 0 do
  151.           begin
  152.             Mem.Read(LType, 2);
  153.             Mem.Read(pCount, 2);
  154.             Dec(pcSize, 4);
  155.             Case LType of
  156.              TT_PRIM_LINE:
  157.               While pCount > 0 do
  158.                begin
  159.                  Mem.Read(pB, SizeOf(pB));
  160.                  Shape.LineTo(GetFixed(pB.X), GetFixed(pB.Y));
  161.                  Dec(pCount);
  162.                  Dec(pcSize, SizeOf(pB));
  163.                end;
  164.              TT_PRIM_QSPLINE:
  165.                begin
  166.                  Mem.Read(pB, SizeOf(pB));
  167.                  Dec(pCount);
  168.                  Dec(pcSize, SizeOf(pB));
  169.                  While pCount > 0 do
  170.                   begin
  171.                      Mem.Read(p1, SizeOf(p1));
  172.                      Dec(pCount);
  173.                      Dec(pcSize, SizeOf(p1));
  174.                      pC := p1;
  175.                      if pCount > 0 then
  176.                        begin
  177.                          pC.X.value := Round((pC.x.value + pB.x.value + (pC.x.fract + pB.x.fract)/ specFixed) / 2);
  178.                          pC.Y.value := Round((pC.y.value + pB.y.value + (pC.y.fract + pB.y.fract)/ specFixed) / 2);
  179.                          pc.x.fract := 0;
  180.                          pc.y.fract := 0;
  181.                        end;
  182.                      Shape.CurveTo(GetFixed(pB.x), GetFixed(pB.y), pC.x.value, pC.y.value);
  183.                      pB := p1;
  184.                    end;
  185.                end;
  186.             end;
  187.           end;
  188.          Shape.CloseShape;
  189.        end;
  190.      Shape.MakeMirror(false, true);
  191.      Mem.Free;
  192.    end;
  193. end;
  194. end.