RAD Studio 13.1 May Patch
RAD Studio 13.1 Florence : May パッチをリリース (en)
とりあえず Embarcadero RAD Studio/Delphi/C++Builder 関係のあれやこれや。 Prism.jsによるコードのハイライトのテスト中。
<Configuration>
<VGpu>Enable</VGpu>
<Networking>Enable</Networking>
<AudioInput>Disable</AudioInput>
<VideoInput>Disable</VideoInput>
<ProtectedClient>Enable</ProtectedClient>
<PrinterRedirection>Disable</PrinterRedirection>
<ClipboardRedirection>Enable</ClipboardRedirection>
<MemoryInMB>4096</MemoryInMB>
<MappedFolders>
<MappedFolder>
<HostFolder>%USERPROFILE%\Documents\WindowsSandbox</HostFolder>
<SandboxFolder>C:\Users\WDAGUtilityAccount\Documents\WindowsSandbox</SandboxFolder>
<ReadOnly>true</ReadOnly>
</MappedFolder>
</MappedFolders>
<LogonCommand>
<Command>reg import C:\Users\WDAGUtilityAccount\Documents\WindowsSandbox\SystemFontLink.reg</Command>
</LogonCommand>
</Configuration>
作成した.wsbファイルをダブルクリックすることで、unit LoadResFontsForSkia;
{$IFNDEF SKIA}
{$MESSAGE ERROR 'Enable Skia4Delphi.'}
{$ENDIF}
interface
uses
Winapi.Windows,
System.SysUtils, System.Classes,
Vcl.Skia;
implementation
type
TFontType = (ftNotFont, ftGDIFont, ftWebFont);
function CheckFontData(Stream: TStream): TFontType;
var
Signature: DWORD;
begin
Result := TFontType.ftNotFont;
Stream.Position := 0;
try
if Stream.Read(Signature,SizeOf(Signature)) <> SizeOf(Signature) then
begin
Exit;
end;
case Signature of
$00000100, // TrueType
$4F45454F, // 'OTTO' OpenType
$66637474: // 'ttcf' TrueType Collection
begin
Result := TFontType.ftGDIFont;
end;
$46464F77, // 'wOFF' Web Open Font
$32464F77: // 'wOF2' Web Open Font 2
begin
Result := TFontType.ftWebFont;
end;
end;
finally
Stream.Position := 0;
end;
end;
function EnumResNameProc(hModule: HMODULE; lpszType: PChar; lpszName: PChar; lParam: LONG_PTR): BOOL; stdcall;
var
RS: TResourceStream;
NumFonts: DWORD;
FontType: TFontType;
begin
{ Load resource }
if Is_IntResource(lpszName) = False then
begin
{ By name }
RS := TResourceStream.Create(HInstance,String(lpszName),RT_RCDATA);
end
else
begin
{ By index }
RS := TResourceStream.CreateFromID(HInstance,NativeUInt(lpszName),RT_RCDATA);
end;
try
FontType := CheckFontData(RS);
if FontType in [TFontType.ftGDIFont] then
begin
{ Regsiter font to GDI }
if AddFontMemResourceEx(RS.Memory,RS.Size,nil,@NumFonts) = 0 then
begin
RaiseLastOSError;
end;
end;
if FontType in [TFontType.ftGDIFont, TFontType.ftWebFont] then
begin
{ Register font to Skia4Delphi }
TSkDefaultProviders.RegisterTypeface(RS);
end;
finally
RS.Free;
end;
Result := True;
end;
procedure LoadResourceFonts;
begin
if EnumResourceNames(HInstance,RT_RCDATA,@EnumResNameProc,0) = False then
begin
RaiseLastOSError;
end;
end;
initialization
LoadResourceFonts;
end.
ユニットのinitialization部で呼び出しているLoadResourceFonts関数では、Win32APIのEnumResourceNames関数でプログラムに含まれるRT_RCDATAのリソースを列挙します。コールバック関数EnumResNameProcではコンストラクタTResourceStream.Createを呼び出してフォントをストリームに読み出し、フォントデータかどうかの判定関数CheckFontDataを呼び出します。CheckFontData関数ではストリームから先頭4バイトを読み出し、TrueType(.ttf)、TrueType Collection(.ttc)、OpenType(.otf)、OpenType Collection(.otc)、WOFF(.woff)、WOFF2(.woff2)のそれぞれのシグネチャに一致するかどうかでフォントデータかどうかの判定を行います。GDIでは使用できないWOFF/WOFF2形式のフォントもSkia4Delphiでは使用できるので、WOFF/WOFF2形式のときはAddFontMemResourceEx関数に加えてTSkDefaultProviders.RegisterTypefaceも呼び出すようにしています。[BRCC32 エラー] "brcc32" はコード 1 を伴って終了しました。
とリソースコンパイラでエラーになることがあります。resinator.exe -v $(PROJECTNAME)Resource.rc $(PROJECTNAME).dres
と設定します(もしパスが通っていない場所にresinator.exeを配置した場合は"resinator.exe"を絶対パスで指定してください)。program Project1;
{$R *.dres}
uses
Vcl.Forms,
...
こんな感じです。これでコンパイルするとビルド前イベントで"(プロジェクト名)を信頼しますか?"という警告ダイアログが表示されるので、"このプロジェクトを常に信頼する"にチェックを入れて"はい"をクリックします。unit LoadResFontsForGDI;
interface
uses
Winapi.Windows,
System.SysUtils, System.Classes;
implementation
function EnumResNameProc(hModule: HMODULE; lpszType: PChar; lpszName: PChar; lParam: LONG_PTR): BOOL; stdcall;
var
RS: TResourceStream;
NumFonts: DWORD;
begin
{ Load font }
if Is_IntResource(lpszName) = False then
begin
{ By name }
RS := TResourceStream.Create(HInstance,String(lpszName),RT_FONT);
end
else
begin
{ By index }
RS := TResourceStream.CreateFromID(HInstance,NativeUInt(lpszName),RT_FONT);
end;
try
{ Regsiter font to GDI }
if AddFontMemResourceEx(RS.Memory,RS.Size,nil,@NumFonts) = 0 then
begin
RaiseLastOSError;
end;
finally
RS.Free;
end;
Result := True;
end;
procedure LoadResourceFonts;
begin
if EnumResourceNames(HInstance,RT_FONT,@EnumResNameProc,0) = False then
begin
RaiseLastOSError;
end;
end;
initialization
LoadResourceFonts;
end.
ユニットのinitialization部で呼び出しているLoadResourceFonts関数では、Win32APIのEnumResourceNames関数でプログラムに含まれるRT_FONTのリソースを列挙します。コールバック関数EnumResNameProcではパラメータlpszNameに格納されているリソース名が名前かインデックスかをIs_IntResource関数で判定し、名前であればコンストラクタTResourceStream.Createの文字列を取るオーバロードを、インデックスであればインデックスを取るオーバロードを呼び出してフォントをリソースストリームに読み出し、Memoryプロパティの示すアドレスとSizeプロパティの示すサイズ(バイト数)をWin32APIのAddFontMemResourceEx関数に渡して登録します。