function SetDrawingEffect( const drawingEffect: IUnknown; //颜色接口; 该接口需自己定义和实现, 只要能存取颜色即可 textRange: TDwriteTextRange //要设置的范围 ): HResult; stdcall;
测试代码:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Direct2D, D2D1; const SID_IColorDrawingEffect = '{22FBE54E-5058-47C4-9A7C-6482827713A6}'; //这是使用 Ctri+Shift+G 随意产生的 IID_IColorDrawingEffect: TGUID = SID_IColorDrawingEffect; type TForm1 = class(TForm) procedure FormPaint(Sender: TObject); procedure FormResize(Sender: TObject); end; {自定义的颜色接口} IColorDrawingEffect = interface [SID_IColorDrawingEffect] function GetColor: TD2D1ColorF; end; {实现 IColorDrawingEffect 的类} TColorDrawingEffect = class(TInterfacedObject, IColorDrawingEffect) private FColor: TD2D1ColorF; public constructor Create(const AColor: TD2D1ColorF); function GetColor: TD2D1ColorF; end; {实现 IWriteTextRenderer 接口} TMyWriteTextRenderer = class(TInterfacedObject, IDWriteTextRenderer) private FRenderTarge: ID2D1RenderTarget; public constructor Create(ARenderTarge: ID2D1RenderTarget); function IsPixelSnappingDisabled(clientDrawingContext: Pointer; var isDisabled: LongBool): HRESULT; stdcall; function GetCurrentTransform(clientDrawingContext: Pointer; var transform: DWRITE_MATRIX): HRESULT; stdcall; function GetPixelsPerDip(clientDrawingContext: Pointer; var pixelsPerDip: Single): HRESULT; stdcall; function DrawGlyphRun(clientDrawingContext: Pointer; baselineOriginX: Single; baselineOriginY: Single; measuringMode: DWRITE_MEASURING_MODE; var glyphRun: DWRITE_GLYPH_RUN; var glyphRunDescription: DWRITE_GLYPH_RUN_DESCRIPTION; const clientDrawingEffect: IInterface): HRESULT; stdcall; function DrawUnderline(clientDrawingContext: Pointer; baselineOriginX: Single; baselineOriginY: Single; var underline: DWRITE_UNDERLINE; const clientDrawingEffect: IInterface): HRESULT; stdcall; function DrawStrikethrough(clientDrawingContext: Pointer; baselineOriginX: Single; baselineOriginY: Single; var strikethrough: DWRITE_STRIKETHROUGH; const clientDrawingEffect: IInterface): HRESULT; stdcall; function DrawInlineObject(clientDrawingContext: Pointer; originX: Single; originY: Single; var inlineObject: IDWriteInlineObject; isSideways: LongBool; isRightToLeft: LongBool; const clientDrawingEffect: IInterface): HRESULT; stdcall; end; var Form1: TForm1; implementation {$R *.dfm} {构建 DWRITE_TEXT_RANGE 结构的函数} function DWriteTextRange(pos,len: Cardinal): TDwriteTextRange; begin Result.startPosition := pos; Result.length := len; end; {构建 DWRITE_FONT_FEATURE 结构的函数} function DWriteFontFeature(nameTag: Integer; parameter: Cardinal): TDwriteFontFeature; begin Result.nameTag := nameTag; Result.parameter := parameter; end; procedure TForm1.FormPaint(Sender: TObject); var cvs: TDirect2DCanvas; str: string; iTextFormat: IDWriteTextFormat; iTextLayout: IDWriteTextLayout; iTypography: IDWriteTypography; iTextRenderer: IDWriteTextRenderer; iColor1,iColor2,iColor3: IColorDrawingEffect; begin str := 'Client Drawing Effect Example!'; DWriteFactory.CreateTextFormat( 'Gabriola', nil, DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 72.0, 'en-us', iTextFormat ); iTextFormat.SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER); iTextFormat.SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER); DWriteFactory.CreateTextLayout( PWideChar(str), Length(str), iTextFormat, ClientWidth, ClientHeight, iTextLayout ); DWriteFactory.CreateTypography(iTypography); iTypography.AddFontFeature(DWriteFontFeature(DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_7, 1)); iTextLayout.SetTypography(iTypography, DWriteTextRange(0, Length(str))); {分段设置颜色; 算上没有设置的范围, 下面的设置将会有四种颜色} iColor1 := TColorDrawingEffect.Create(D2D1ColorF(clRed)); iColor2 := TColorDrawingEffect.Create(D2D1ColorF(clBlue)); iColor3 := TColorDrawingEffect.Create(D2D1ColorF(clGreen)); iTextLayout.SetDrawingEffect(iColor1, DWriteTextRange(0, 14)); iTextLayout.SetDrawingEffect(iColor2, DWriteTextRange(14, 7)); iTextLayout.SetDrawingEffect(iColor3, DWriteTextRange(21, 8)); cvs := TDirect2DCanvas.Create(Canvas, ClientRect); iTextRenderer := TMyWriteTextRenderer.Create(cvs.RenderTarget); cvs.RenderTarget.BeginDraw; cvs.RenderTarget.Clear(D2D1ColorF(clWhite)); iTextLayout.Draw(nil, iTextRenderer, 0, 0); //! cvs.RenderTarget.EndDraw(); cvs.Free; end; procedure TForm1.FormResize(Sender: TObject); begin Repaint; end; { TColorDrawingEffect } constructor TColorDrawingEffect.Create(const AColor: TD2D1ColorF); begin inherited Create; FColor := AColor; end; function TColorDrawingEffect.GetColor: TD2D1ColorF; begin Result := FColor; end; { TMyWriteTextRenderer } constructor TMyWriteTextRenderer.Create(ARenderTarge: ID2D1RenderTarget); begin FRenderTarge := ARenderTarge; end; function TMyWriteTextRenderer.DrawGlyphRun(clientDrawingContext: Pointer; baselineOriginX, baselineOriginY: Single; measuringMode: DWRITE_MEASURING_MODE; var glyphRun: DWRITE_GLYPH_RUN; var glyphRunDescription: DWRITE_GLYPH_RUN_DESCRIPTION; const clientDrawingEffect: IInterface): HRESULT; var iPathGeometry: ID2D1PathGeometry; iGeometrySink: ID2D1GeometrySink; iTransformedGeometry: ID2D1TransformedGeometry; iBrush: ID2D1SolidColorBrush; iColorEffect: IColorDrawingEffect; //供注释掉的代码使用 rColor: TD2D1ColorF; 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, baselineOriginY), iTransformedGeometry ); {获取颜色} rColor := D2D1ColorF(clBlack); if Assigned(clientDrawingEffect) then rColor := IColorDrawingEffect(clientDrawingEffect).GetColor; {下面是官方获取颜色的写法} // if clientDrawingEffect <> nil then // begin // clientDrawingEffect.QueryInterface(IID_IColorDrawingEffect, iColorEffect); // rColor := iColorEffect.GetColor; // end else // rColor := D2D1ColorF(clBlack); FRenderTarge.CreateSolidColorBrush(rColor, nil, iBrush); FRenderTarge.DrawGeometry(iTransformedGeometry, iBrush); FRenderTarge.FillGeometry(iTransformedGeometry, iBrush); Result := S_OK; end; function TMyWriteTextRenderer.DrawInlineObject(clientDrawingContext: Pointer; originX, originY: Single; var inlineObject: IDWriteInlineObject; isSideways, isRightToLeft: LongBool; const clientDrawingEffect: IInterface): HRESULT; begin Result := E_NOTIMPL; end; function TMyWriteTextRenderer.DrawStrikethrough(clientDrawingContext: Pointer; baselineOriginX, baselineOriginY: Single; var strikethrough: DWRITE_STRIKETHROUGH; const clientDrawingEffect: IInterface): HRESULT; var rRectF: TD2DRectF; iRectangleGeometry: ID2D1RectangleGeometry; iTransformedGeometry: ID2D1TransformedGeometry; iBrush: ID2D1SolidColorBrush; rColor: TD2D1ColorF; begin rRectF := D2D1RectF( 0, strikethrough.offset, strikethrough.width, strikethrough.offset + strikethrough.thickness ); D2DFactory.CreateRectangleGeometry(rRectF, iRectangleGeometry); D2DFactory.CreateTransformedGeometry( iRectangleGeometry, TD2DMatrix3x2F.Translation(baselineOriginX, baselineOriginY), iTransformedGeometry ); rColor := D2D1ColorF(clBlack); //没有设置的部分默认使用黑色 if Assigned(clientDrawingEffect) then rColor := IColorDrawingEffect(clientDrawingEffect).GetColor; FRenderTarge.CreateSolidColorBrush(rColor, nil, iBrush); FRenderTarge.DrawGeometry(iTransformedGeometry, iBrush); FRenderTarge.FillGeometry(iTransformedGeometry, iBrush); Result := S_OK; end; function TMyWriteTextRenderer.DrawUnderline(clientDrawingContext: Pointer; baselineOriginX, baselineOriginY: Single; var underline: DWRITE_UNDERLINE; const clientDrawingEffect: IInterface): HRESULT; var rRectF: TD2DRectF; iRectangleGeometry: ID2D1RectangleGeometry; iTransformedGeometry: ID2D1TransformedGeometry; iBrush: ID2D1SolidColorBrush; rColor: TD2D1ColorF; begin rRectF := D2D1RectF( 0, underline.offset, underline.width, underline.offset + underline.thickness ); D2DFactory.CreateRectangleGeometry(rRectF, iRectangleGeometry); D2DFactory.CreateTransformedGeometry( iRectangleGeometry, TD2DMatrix3x2F.Translation(baselineOriginX, baselineOriginY), iTransformedGeometry ); rColor := D2D1ColorF(clBlack); if Assigned(clientDrawingEffect) then rColor := IColorDrawingEffect(clientDrawingEffect).GetColor; FRenderTarge.CreateSolidColorBrush(rColor, nil, iBrush); FRenderTarge.DrawGeometry(iTransformedGeometry, iBrush); FRenderTarge.FillGeometry(iTransformedGeometry, iBrush); 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; end.
效果图: