Using the IDWriteTextLayout. Draw () method to Draw text is mainly to implement the IDWriteTextRenderer interface.
The IDWriteTextRenderer interface can only be implemented manually and is flexible.
Unit Unit1; interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Direct2D, D2D1; type TForm1 = class (TForm) procedure FormPaint (Sender: TObject); procedure FormResize (Sender: TObject); end; iterator = class (TInterfacedObject, IDWriteTextRenderer) private FRenderTarge: iterator; FOutLineBrush, FFillBrush: ID2D1Brush; public constructor Reate (ARenderTarge: ID2D1RenderTarget; AOutLineBrush, AFillBrush: ID2D1Brush); function Merge (vertex: Pointer; var isDisabled: LongBool): HRESULT; stdcall; function GetCurrentTransform (vertex: Pointer; var transform: DWRITE_MATRIX): HRESULT; stdcall; function GetPixelsPerDip (clientDrawingContext: Pointer; var pixelsPerDip: Single): HRESULT; stdcall; fun Ction DrawGlyphRun (clientDrawingContext: Pointer; baselineorigsequence: Single; sequence: Single; measuringMode: sequence; var glyphRun: sequence; var glyphRunDescription: sequence; const sequence: IInterface): HRESULT; stdcall; function DrawUnderline (clientDrawingContext: Pointer; baselineOriginX: Single; baselineOriginY: Single; var underline: DWRITE_UNDERLINE; const outputs: IInterface): HRESULT; stdcall; function DrawStrikethrough (clientDrawingContext: Pointer; baselineorigrough rough: Single; principal: Single; var strikethrough: lower; const outputs: IInterface ): HRESULT; stdcall; function DrawInlineObject (clientDrawingContext: Pointer; origter: Single; originY: Single; var inlineObject: IDWrit EInlineObject; isSideways: LongBool; isRightToLeft: LongBool; const clientDrawingEffect: IInterface): HRESULT; stdcall; end; var Form1: TForm1; implementation {$ R *. dfm} {function for constructing the DWRITE_TEXT_RANGE structure} function DWriteTextRange (pos, len: Cardinal): TDwriteTextRange; begin Result. startPosition: = pos; Result. length: = len; end; {function for constructing the DWRITE_FONT_FEATURE structure} function DWriteFontFeature (nameTag: Integer; parameter: Cardinal): TDwriteFontFeature; begin Result. nameTag: = nameTag; Result. parameter: = parameter; end; {function for creating bitmap painter} function GetBitmapBrush (Canvas: TDirect2DCanvas; filePath: string): ID2D1BitmapBrush; var rBBP: TD2D1BitmapBrushProperties; bit: TBitmap; begin: = TBitmap. create; bit. loadFromFile (filePath); rBBP. extendModeX: = D2D1_EXTEND_MODE_WRAP; rBBP. extendModeY: = D2D1_EXTEND_MODE_WRAP; rBBP. interp OlationMode: = D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR; Canvas. renderTarget. createBitmapBrush (Canvas. createBitmap (bit), @ rBBP, nil, Result); bit. free; end; procedure extract (Sender: TObject); var cvs: TDirect2DCanvas; str: string; iTextFormat: IDWriteTextFormat; iso1_colorbrush: interval; iBitmapBrush: interval; iTextLayout: interval; iTypography: IDWrit ETypography; iTextRenderer: IDWriteTextRenderer; begin str: = 'Hello World using DirectWrite! '; DWriteFactory. createTextFormat ('nginola ', nil, DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 72.0, 'en-use', iTextFormat); iTextFormat. setTextAlignment (DWRITE_TEXT_ALIGNMENT_CENTER); iTextFormat. setParagraphAlignment (DWRITE_PARAGRAPH_ALIGNMENT_CENTER); DWriteFactory. createTextLayout (PWideChar (str), Length (str), iTextFormat, ClientWidth, ClientHeight, iTextLayout); iTextLayout. setFontSize (100.0, DWriteTextRange (18, 6); iTextLayout. setUnderline (True, DWriteTextRange (18, 11); iTextLayout. setFontWeight (DWRITE_FONT_WEIGHT_BOLD, DWriteTextRange (18, 11); DWriteFactory. createTypography (iTypography); iTypography. addFontFeature (DWriteFontFeature (DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_6, 1); iTextLayout. setTypography (iTypography, DWriteTextRange (0, Length (str); cvs: = TDirect2DCanvas. create (Canvas, ClientRect); cvs. renderTarget. createSolidColorBrush (d2d1colgrading (clBlack), nil, iso1_colorbrush); iBitmapBrush: = GetBitmapBrush (cvs, 'c: \ Temp \ Test.bmp '); iTextRenderer: = TMyWriteTextRenderer. create (cvs. renderTarget, iso1_colorbrush, iBitmapBrush); cvs. renderTarget. beginDraw; cvs. renderTarget. clear (d2d1colgrading (clWhite); iTextLayout. draw (nil, iTextRenderer, 0, 0); cvs. renderTarget. endDraw (); cvs. free; end; procedure TForm1.FormResize (Sender: TObject); begin Repaint; end; {TMyWriteTextRenderer} constructor TMyWriteTextRenderer. create (ARenderTarge: Fill; AOutLineBrush, AFillBrush: ID2D1Brush); begin FRenderTarge: = ARenderTarge; FOutLineBrush: = AOutLineBrush; FFillBrush: = AFillBrush; end; function resume. drawGlyphRun (clientDrawingContext: Pointer; baselineOriginX, gradient: Single; measuringMode: Random; var glyphRun: Random; var glyphRunDescription: Random; const regression: IInterface): HRESULT; var iPathGeometry: Random; iGeometrySink: ID2D1GeometrySink; iTransformedGeometry: ID2D1TransformedGeometry; begin D2DFactory. createPathGeometry (iPathGeometry); iPathGeometry. open (iGeometrySink); glyphRun. fontFace. getGlyphRunOutline (glyphRun. fontEmSize, glyphRun. glyphIndices, glyphRun. glyphAdvances, glyphRun. glyphOffsets, glyphRun. glyphCount, glyphRun. isSideways, longBool (glyphRun. bidiLevel div 2), iGeometrySink); iGeometrySink. close; D2DFactory. createTransformedGeometry (iPathGeometry, TD2DMatrix3x2F. translation (baselineOriginX ry, baselineOriginY), iTransformedGeometry); FRenderTarge. drawGeometry (iTransformedGeometry, FOutLineBrush); FRenderTarge. fillGeometry (iTransformedGeometry, FFillBrush); Result: = S_ OK; end; function TMyWriteTextRenderer. drawInlineObject (vertex: Pointer; origter, originY: Single; var inlineObject: IDWriteInlineObject; isSideways, isRightToLeft: LongBool; const vertex: IInterface): HRESULT; begin Result: = E_NOTIMPL; // end is not implemented; function TMyWriteTextRenderer. histogram (clientDrawingContext: Pointer; baselineOriginX, direction: Single; var strikethrough: direction; const direction: IInterface): HRESULT; var rRectF: TD2DRectF; iRectangleGeometry: direction; direction: direction; begin rRectF: = D2D1RectF (0, strikethrough. offset, strikethrough. width, strikethrough. offset + strikethrough. thickness); D2DFactory. createRectangleGeometry (rRectF, iRectangleGeometry); D2DFactory. createTransformedGeometry (iRectangleGeometry, TD2DMatrix3x2F. translation (baselineOriginX ry, baselineOriginY), iTransformedGeometry); FRenderTarge. drawGeometry (iTransformedGeometry, FOutLineBrush); FRenderTarge. fillGeometry (iTransformedGeometry, FFillBrush); Result: = S_ OK; end; function TMyWriteTextRenderer. drawUnderline (clientDrawingContext: Pointer; baselineOriginX, direction: Single; var underline: DWRITE_UNDERLINE; const direction: IInterface): HRESULT; var rRectF: TD2DRectF; direction: direction; begin rRectF: = D2D1RectF (0, underline. offset, underline. width, underline. offset + underline. thickness); D2DFactory. createRectangleGeometry (rRectF, iRectangleGeometry); D2DFactory. createTransformedGeometry (iRectangleGeometry, TD2DMatrix3x2F. translation (baselineOriginX ry, baselineOriginY), iTransformedGeometry); FRenderTarge. drawGeometry (iTransformedGeometry, FOutLineBrush); FRenderTarge. fillGeometry (iTransformedGeometry, FFillBrush); Result: = S_ OK; end; function TMyWriteTextRenderer. getCurrentTransform (clientDrawingContext: Pointer; var transform: DWRITE_MATRIX): HRESULT; begin FRenderTarge. getTransform (TD2D1Matrix3x2F (transform); Result: = S_ OK; end; function TMyWriteTextRenderer. getPixelsPerDip (clientDrawingContext: Pointer; var pixelsPerDip: Single): HRESULT; var x, y: Single; begin FRenderTarge. getDpi (x, y); pixelsPerDip: = x/96; Result: = S_ OK; end; function TMyWriteTextRenderer. isPixelSnappingDisabled (clientDrawingContext: Pointer; var isDisabled: LongBool): HRESULT; begin isDisabled: = False; Result: = S_ OK; end.
:
To simplify the process, you can only outline the text:
Unit Unit1; interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Direct2D, D2D1; type TForm1 = class (TForm) procedure FormPaint (Sender: TObject); procedure FormResize (Sender: TObject); end; iterator = class (TInterfacedObject, IDWriteTextRenderer) private FRenderTarge: iterator; FOutLineBrush: ID2D1Brush; public constructor Create (ARend ErTarge: train; AOutLineBrush: ID2D1Brush); function compute (clientDrawingContext: Pointer; var isDisabled: LongBool): HRESULT; stdcall; function GetCurrentTransform (vertex: Pointer; var transform: DWRITE_MATRIX ): HRESULT; stdcall; function GetPixelsPerDip (clientDrawingContext: Pointer; var pixelsPerDip: Single): HRESULT; stdcall; function DrawGlyphRun (cli EntDrawingContext: Pointer; baselineOriginX INX: Single; baselineOriginY: Single; measuringMode: Random; var glyphRun: Random; var glyphRunDescription: Random; const clientDrawingEffect: IInterface): HRESULT; stdcall; function DrawUnderline (clientDrawingContext: Pointer; baselineOriginX: Single; baselineOriginY: Single; var underline: DWRITE_UNDERLINE; co Nst outputs: IInterface): HRESULT; stdcall; function DrawStrikethrough (clientDrawingContext: Pointer; baselineorigpartition: Single; gradient: Single; var strikethrough: gradient; const outputs: IInterface): HRESULT; stdcall; function DrawInlineObject (clientDrawingContext: Pointer; origter: Single; originY: Single; var inlineObject: IDWriteInlineObject; isSidew Ays: LongBool; isRightToLeft: LongBool; const clientDrawingEffect: IInterface): HRESULT; stdcall; end; var Form1: TForm1; implementation {$ R *. dfm} {function for constructing the DWRITE_TEXT_RANGE structure} function DWriteTextRange (pos, len: Cardinal): TDwriteTextRange; begin Result. startPosition: = pos; Result. length: = len; end; {function for building the DWRITE_FONT_FEATURE structure} function DWriteFontFeature (nameTag: Integer; parameter: Cardinal): TDwriteFo NtFeature; begin Result. nameTag: = nameTag; Result. parameter: = parameter; end; procedure alert (Sender: TObject); var cvs: TDirect2DCanvas; str: string; iTextFormat: IDWriteTextFormat; iso1_colorbrush: alert; iTextLayout: IDWriteTextLayout; iTypography: Alert; iTextRenderer: IDWriteTextRenderer; begin str: = 'Hello World using DirectWrite! '; DWriteFactory. createTextFormat ('Gabriel A', nil, DWRITE_FONT_WEIGHT_ULTRA_BLACK, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 72.0, 'en-use', iTextFormat); iTextFormat. setTextAlignment (DWRITE_TEXT_ALIGNMENT_CENTER); iTextFormat. setParagraphAlignment (DWRITE_PARAGRAPH_ALIGNMENT_CENTER); DWriteFactory. createTextLayout (PWideChar (str), Length (str), iTextFormat, ClientWidth, ClientHeight, iTextLayout); iTextLayout. setFontSize (100.0, DWriteTextRange (18, 6); iTextLayout. setUnderline (True, DWriteTextRange (18, 11); iTextLayout. setFontWeight (DWRITE_FONT_WEIGHT_BOLD, DWriteTextRange (18, 11); DWriteFactory. createTypography (iTypography); iTypography. addFontFeature (DWriteFontFeature (DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_6, 1); iTextLayout. setTypography (iTypography, DWriteTextRange (0, Length (str); cvs: = TDirect2DCanvas. create (Canvas, ClientRect); cvs. renderTarget. createSolidColorBrush (d2d1colgrading (clRed), nil, iso1_colorbrush); iTextRenderer: = TMyWriteTextRenderer. create (cvs. renderTarget, iso1_colorbrush); cvs. renderTarget. beginDraw; cvs. renderTarget. clear (d2d1colgrading (clWhite); iTextLayout. draw (nil, iTextRenderer, 0, 0); cvs. renderTarget. endDraw (); cvs. free; end; procedure TForm1.FormResize (Sender: TObject); begin Repaint; end; {TMyWriteTextRenderer} constructor TMyWriteTextRenderer. create (ARenderTarge: ID2D1RenderTarget; AOutLineBrush: ID2D1Brush); begin FRenderTarge: = ARenderTarge; FOutLineBrush: = AOutLineBrush; end; function TMyWriteTextRenderer. drawGlyphRun (clientDrawingContext: Pointer; baselineOriginX, gradient: Single; measuringMode: Random; var glyphRun: Random; var glyphRunDescription: Random; const regression: IInterface): HRESULT; var iPathGeometry: Random; iGeometrySink: ID2D1GeometrySink; iTransformedGeometry: ID2D1TransformedGeometry; begin D2DFactory. createPathGeometry (iPathGeometry); iPathGeometry. open (iGeometrySink); glyphRun. fontFace. getGlyphRunOutline (glyphRun. fontEmSize, glyphRun. glyphIndices, glyphRun. glyphAdvances, glyphRun. glyphOffsets, glyphRun. glyphCount, glyphRun. isSideways, longBool (glyphRun. bidiLevel div 2), iGeometrySink); iGeometrySink. close; D2DFactory. createTransformedGeometry (iPathGeometry, TD2DMatrix3x2F. translation (baselineOriginX ry, baselineOriginY), iTransformedGeometry); FRenderTarge. drawGeometry (iTransformedGeometry, FOutLineBrush); Result: = S_ OK; end; function TMyWriteTextRenderer. drawInlineObject (vertex: Pointer; origter INX, originY: Single; var inlineObject: IDWriteInlineObject; isSideways, isRightToLeft: LongBool; const vertex: IInterface): HRESULT; begin Result: = E_NOTIMPL; end; function TMyWriteTextRenderer. drawStrikethrough (clientDrawingContext: Pointer; baselineOriginX INX, baselineOriginY: Single; var strikethrough: Upper; const lower: IInterface): HRESULT; begin Result: = E_NOTIMPL; end; function lower. drawUnderline (clientDrawingContext: Pointer; baselineOriginX, direction: Single; var underline: DWRITE_UNDERLINE; const direction: IInterface): HRESULT; var rRectF: TD2DRectF; direction: direction; begin rRectF: = D2D1RectF (0, underline. offset, underline. width, underline. offset + underline. thickness); D2DFactory. createRectangleGeometry (rRectF, iRectangleGeometry); D2DFactory. createTransformedGeometry (iRectangleGeometry, TD2DMatrix3x2F. translation (baselineOriginX ry, baselineOriginY), iTransformedGeometry); FRenderTarge. drawGeometry (iTransformedGeometry, FOutLineBrush); Result: = S_ OK; end; function TMyWriteTextRenderer. getCurrentTransform (clientDrawingContext: Pointer; var transform: DWRITE_MATRIX): HRESULT; begin FRenderTarge. getTransform (TD2D1Matrix3x2F (transform); Result: = S_ OK; end; function TMyWriteTextRenderer. getPixelsPerDip (clientDrawingContext: Pointer; var pixelsPerDip: Single): HRESULT; var x, y: Single; begin FRenderTarge. getDpi (x, y); pixelsPerDip: = x/96; Result: = S_ OK; end; function TMyWriteTextRenderer. isPixelSnappingDisabled (clientDrawingContext: Pointer; var isDisabled: LongBool): HRESULT; begin isDisabled: = False; Result: = S_ OK; end.
: