3

我想从文本创建 Direct2D 路径几何。据我了解,我需要创建一个 IDWriteFontFace,我必须从中调用 GetGlyphRunOutline。

不幸的是,我无法弄清楚如何创建该字体。到目前为止,我什至偶然发现了一个字体文件引用,我认为我必须使用它来创建字体。

procedure CreateFontFace;
var
  hr: HRESULT;
  FontDir: string;
  FontPath: string;
  ft: _FILETIME;
  FontFile: IDWriteFontFile;
  FontFace: IDWriteFontFace;
begin

  FontDir := GetSpecialFolder(CSIDL_FONTS);
  FontPath := IncludeTrailingPathDelimiter(FontDir) + 'Arial.ttf';

  // Here, FontPath contains 'C:\Windows\Fonts\Arial.ttf' 
  // (which exists on my machine)

  ft.dwLowDateTime := 0;
  ft.dwHighDateTime := 0;

  hr := DWriteFactory.CreateFontFileReference( 
   FontPath, // DOES NOT COMPILE
   ft,
   FontFile);

  if Succeeded(hr) then begin
    hr := DWriteFactory.CreateFontFace(
      DWRITE_FONT_FACE_TYPE_TRUETYPE,
      1,
      @FontFile,
      0,
      DWRITE_FONT_SIMULATIONS_NONE,
      FontFace);
  end;

end;

Winapi.D2D1中CreateFontFileReference的原型如下:

    function CreateFontFileReference(var filePath: WCHAR;
      var lastWriteTime: FILETIME;
      out fontFile: IDWriteFontFile): HResult; stdcall;

我知道放置字符串而不是 WCHAR 会打扰编译器,但是应该如何编写呢?如果有另一种更简单的方法,我也很感兴趣......

更新: 正如 Remy Lebeau 所说,Winapi.D2D1 单元中还有其他类似的错误声明。我遇到的第二个也是在 CreateFontFileReference 中:参数 lastWriteTime 应该是一个指针,所以为了让我的代码工作,我必须改变我对 ft 变量的使用,如下所示:

var
  ...
  ft: ^_FILETIME;
  ...
begin
  ...
  ft := nil;

  hr := DWriteFactory.CreateFontFileReference( 
    PChar(FontPath)^,
    ft^, // Yes, I am dereferencing nil, and it's working!
    FontFile);
  ...
end;
4

1 回答 1

3

如果您使用的是 Delphi 2009 或更高版本,StringUnicode 在哪里,您需要在将其传递String给时进行类型转换:PCharCreateFontFileReference()

hr := DWriteFactory.CreateFontFileReference( 
  PChar(FontPath),
  ft,
  FontFile);

如果您使用的是 Delphi 2007 或更早版本,StringAnsi 在哪里,您需要将您的转换StringWideString第一个,然后将其类型转换为PWideChar

hr := DWriteFactory.CreateFontFileReference( 
  PWideChar(WideString(FontPath)),
  ft,
  FontFile);

更新:原来在声明的第一个参数中有一个错误CreateFontFileReference()。Embarcadero 将其声明为var filePath: WCHAR,但它应该被声明为const filePath: PWCHAR。因此,您必须通过取消引用PChar/PWideChar指针来解决该错误,例如:

hr := DWriteFactory.CreateFontFileReference( 
  PChar(FontPath)^,
  ...);

hr := DWriteFactory.CreateFontFileReference( 
  PWideChar(WideString(FontPath))^,
  ...);
于 2013-06-27T21:10:24.560 回答