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.
效果图:
浙公网安备 33010602011771号