Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Direct2D / DirectWrite CreateGdiCompatibleTextLayout Implementation (https://www.delphipraxis.net/185925-direct2d-directwrite-creategdicompatibletextlayout-implementation.html)

Sunec 18. Jul 2015 23:01

Delphi-Version: 5

Direct2D / DirectWrite CreateGdiCompatibleTextLayout Implementation
 
Nabend!

Möchte gerne meine Text in DirectWrite durch ein TextLayout zeichnen.

MS hat dafür eine entsprechende Funktion:
https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx

Nachteil dabei ist, dass sie nicht auf aliased Texte reagiert.

Dafür gibt's:
https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx

Code:
virtual HRESULT CreateGdiCompatibleTextLayout(
  [in]          const WCHAR            * string,
                       UINT32             stringLength,
                       IDWriteTextFormat * textFormat,
                       FLOAT             layoutWidth,
                       FLOAT             layoutHeight,
                       FLOAT             pixelsPerDip,
  [in, optional] const DWRITE_MATRIX    * transform,
                       BOOL              useGdiNatural,
  [out]               IDWriteTextLayout ** textLayout
) = 0;

In Delphi erwartet das ganze folgende Parameter:
Delphi-Quellcode:
    function CreateGdiCompatibleTextLayout(var _string: WCHAR; stringLength: Cardinal;
      var textFormat: IDWriteTextFormat; layoutWidth: Single; layoutHeight: Single;
      pixelsPerDip: Single; var transform: TDwriteMatrix; useGdiNatural: BOOL;
      out textLayout: IDWriteTextLayout): HResult; stdcall;
Warum muss ich nun den string sowie die transform-Matrix als Referenz übertragen?

Bei CreateTextLayout habe ich keine Probleme.

Sehe ich was Offensichtliches nicht oder ist das falsch implementiert worden?



EDIT:

Sieht so aus als wäre ich nicht der erste dem dies aufgefallen ist:

http://qc.embarcadero.com/wc/qcmain.aspx?d=112581

Dieser ist jedoch geschlossen worden mit der Begründung: "As Designed"

Was soll das?

SonnyBoyPro 19. Jul 2015 08:06

AW: Direct2D / DirectWrite CreateGdiCompatibleTextLayout Implementation
 
Hallo Sunec,

ich würde sagen der Header ist falsch übersetzt worden. Ich hab das bei meiner DX12 Lib so gemacht:

Delphi-Quellcode:
function CreateGdiCompatibleTextLayout(_string: PWideChar; stringLength: UINT32; textFormat: IDWriteTextFormat;
            layoutWidth: single; layoutHeight: single; pixelsPerDip: single; transform: PDWRITE_MATRIX; useGdiNatural: longbool;
            out textLayout: IDWriteTextLayout): HResult; stdcall;
Begründung: TextFormat ist ein Interface. In C++ ist ein Variable auf ein Interface ein Pointer. Delphi behandelt aber Interfaces aber per se als "Pointer".
Würde TextFormat eine Var sein müsste im C++ Header **textformat stehen. Detto bei string (wobei man jetzt bei mir noch diskutieren kann, ob vor dem _string nicht ein const schreiben kann).

Jetzt zur [in, optional] const DWRITE_MATRIX * transform,

in bedeutet das es eine Eingangsvariable ist. und zwar ein Pointer auf einen DWRITE_MATRIX Struktur. damit müsste man mit transform: PDWRITE_MATRIX übersetzen, weils ja ein Pointer ist.
Anmerkung: da aber die Aufrufkonvention stdcall ist werden hier const Deklarationen automatisch als call by referenz ausgeführt, könnte man auch übersetzen mit
const transform: TDWrite_Matrix. Ist bei meinen Headern auch nicht 100%, ist aber halt nur ne Sache des Aufrufes (@varDWriteMatrix oder varDWriteMatrix).

Textlayout ist okay, weil Interface (*) und Rückgabewert (*), also **.

Probier's mal so, sollte eigentlich so gehen.

bg

Norbert

Sunec 19. Jul 2015 08:11

AW: Direct2D / DirectWrite CreateGdiCompatibleTextLayout Implementation
 
Hallo Nobert,

danke für die schnelle Antwort und super Erklärung!

Ich habe nun die
Delphi-Quellcode:
Winapi.D2D1.pas
in mein Projektverzeichnis verschoben und die Änderungen durchgeführt.

Funktioniert nun einwandfrei!

Sunec 11. Aug 2015 08:29

AW: Direct2D / DirectWrite CreateGdiCompatibleTextLayout Implementation
 
Noch eine kurze Rückfrage bezüglich der Einbindung der Winapi.D2D1.pas

Ich möchte die Datei nicht mehr im Projektverzeichnis haben und auch nicht in einen Ordner ablegen, den ich bei den Suchpfaden eintrage.


Ich habe versucht die Originaldatei im Installationspfad (C:\Programme\Emba\Sources\...) durch die abgeänderte Winapi.D2D1.pas zu ersetzen.

Nun müsste ich die Dateien im Installationspfad ja neu compilen, da die .dcu-Files neu erzeugt werden müssen und auch einige Packages die Winapi.D2D1.pas beinhalten.


Gibt es sonst noch Alternativen die Funktion der D2D1.dll korrekt anzusprechen?

TiGü 13. Aug 2015 13:34

AW: Direct2D / DirectWrite CreateGdiCompatibleTextLayout Implementation
 
Zitat:

Zitat von Sunec (Beitrag 1311751)
Nun müsste ich die Dateien im Installationspfad ja neu compilen, da die .dcu-Files neu erzeugt werden müssen und auch einige Packages die Winapi.D2D1.pas beinhalten.

Guck mal hier in diesen Thread ab Post Nr. 9:
http://www.delphipraxis.net/90085-sy...mpilieren.html


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:23 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz