Direct2D (42) : 在文本布局中嵌入图片 IDWriteTextLayout.SetInlineObject()


这段代码怎么也过不去了,反反复复找不到原因;有谁知道,万望提醒我一下。

上面是刚碰到错误时的求助信息;现在终于找到错误了:是 D2D1.pas 的代码有问题,修改方法如下:


{ 1、把 D2D1.pas 中 4142 行中的 var 修改为 const 或者去掉 }

function SetInlineObject(var inlineObject: IDWriteInlineObject;

  textRange: TDwriteTextRange): HResult; stdcall;



{ 2、重新编译 Direct2D.pas、D2D1.pas,最好在 Debug 和 Release 两种模式下分别编译 }



{ 3、把编译后的相关 dcu 分别覆盖到 \Program Files\Embarcadero\RAD Studio\8.0\lib\win32\ 的相应目录下 }






unit Unit1;



interface



uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, Direct2D, D2D1, Wincodec, ActiveX;



type

  TForm1 = class(TForm)

    procedure FormPaint(Sender: TObject);

    procedure FormResize(Sender: TObject);

  end;



  {实现 IDWriteInlineObject 的类}

  TDWriteInlineObject = class(TInterfacedObject, IDWriteInlineObject)

  private

    FRenderTarge: ID2D1RenderTarget;

    FBitmap: ID2D1Bitmap;

  public

    constructor Create(ARenderTarge: ID2D1RenderTarget; ABitmap: ID2D1Bitmap);

    function Draw(clientDrawingContext: Pointer; var renderer: IDWriteTextRenderer; originX: Single;

      originY: Single; isSideways: LongBool; isRightToLeft: LongBool;

      const clientDrawingEffect: IInterface): HRESULT; stdcall;

    function GetMetrics(var metrics: DWRITE_INLINE_OBJECT_METRICS): HRESULT; stdcall;

    function GetOverhangMetrics(var overhangs: DWRITE_OVERHANG_METRICS): HRESULT; stdcall;

    function GetBreakConditions(var breakConditionBefore: DWRITE_BREAK_CONDITION;

      var breakConditionAfter: DWRITE_BREAK_CONDITION): HRESULT; stdcall;

  end;



var

  Form1: TForm1;



implementation



{$R *.dfm}



{从指定文件建立 ID2D1Bitmap 的函数}

function GetD2D1Bitmap(RenderTarget: ID2D1RenderTarget; imgPath: string): ID2D1Bitmap;

var

  iWicFactory: IWICImagingFactory;

  iWICDecoder: IWICBitmapDecoder;

  iWICFrameDecode: IWICBitmapFrameDecode;

  iFormatConverter: IWICFormatConverter;

begin

  CoCreateInstance(CLSID_WICImagingFactory, nil, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, iWicFactory);

  iWicFactory.CreateDecoderFromFilename(PWideChar(imgPath), GUID_NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, iWICDecoder);

  iWicDecoder.GetFrame(0, iWICFrameDecode);

  iWicFactory.CreateFormatConverter(iFormatConverter);

  iFormatConverter.Initialize(iWICFrameDecode, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nil, 0, WICBitmapPaletteTypeMedianCut);

  RenderTarget.CreateBitmapFromWicBitmap(iFormatConverter, nil, Result);

end;



{构建 DWRITE_TEXT_RANGE 结构的函数}

function DWriteTextRange(pos,len: Cardinal): TDwriteTextRange;

begin

  Result.startPosition := pos;

  Result.length := len;

end;



procedure TForm1.FormPaint(Sender: TObject);

var

  cvs: TDirect2DCanvas;

  str: string;

  iTextFormat: IDWriteTextFormat;

  iTextLayout: IDWriteTextLayout;

  iInlineObject: IDWriteInlineObject;

  iBitmap: ID2D1Bitmap;

  iBrush: ID2D1SolidColorBrush;

begin

  str := 'Inline Object * 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

  );



  cvs := TDirect2DCanvas.Create(Canvas, ClientRect);

  cvs.RenderTarget.BeginDraw;

  cvs.RenderTarget.Clear(D2D1ColorF(clWhite));



  iBitmap := GetD2D1Bitmap(cvs.RenderTarget, 'C:\Temp\Test.jpg');

  iInlineObject := TDWriteInlineObject.Create(cvs.RenderTarget, iBitmap);

//  DWriteFactory.CreateEllipsisTrimmingSign(iTextLayout, iInlineObject); //使用这行代码可以生成表示 "..." 符号的 IDWriteInlineObject

  iTextLayout.SetInlineObject(iInlineObject, DWriteTextRange(14, 1)); {!!!}



  cvs.RenderTarget.CreateSolidColorBrush(D2D1ColorF(clBlack), nil, iBrush);

  cvs.RenderTarget.DrawTextLayout(D2D1PointF(0,0), iTextLayout, iBrush);

  cvs.RenderTarget.EndDraw();

  cvs.Free;

end;



procedure TForm1.FormResize(Sender: TObject);

begin

  Repaint;

end;



{ TDWriteInlineObject }



constructor TDWriteInlineObject.Create(ARenderTarge: ID2D1RenderTarget; ABitmap: ID2D1Bitmap);

begin

  inherited Create;

  FRenderTarge := ARenderTarge;

  FBitmap := ABitmap;

end;



function TDWriteInlineObject.Draw(clientDrawingContext: Pointer; var renderer: IDWriteTextRenderer; originX,

  originY: Single; isSideways, isRightToLeft: LongBool; const clientDrawingEffect: IInterface): HRESULT;

var

  rSizeF: TD2DSizeF;

  rRectF: TD2DRectF;

begin

  FBitmap.GetSize(rSizeF);

  rRectF := D2D1RectF(originX, originY, originX+rSizeF.width, originY+rSizeF.height);

  FRenderTarge.DrawBitmap(FBitmap, @rRectF);

  Result := S_OK;

end;



function TDWriteInlineObject.GetBreakConditions(var breakConditionBefore,

  breakConditionAfter: DWRITE_BREAK_CONDITION): HRESULT;

begin

  breakConditionBefore := DWRITE_BREAK_CONDITION_NEUTRAL;

  breakConditionAfter := DWRITE_BREAK_CONDITION_NEUTRAL;

  Result := S_OK;

end;



function TDWriteInlineObject.GetMetrics(var metrics: DWRITE_INLINE_OBJECT_METRICS): HRESULT;

var

  rSizeF: TD2DSizeF;

begin

  FBitmap.GetSize(rSizeF);

  metrics.width := rSizeF.width;

  metrics.height := rSizeF.height;

  metrics.baseline := rSizeF.height;

  Result := S_OK;

end;



function TDWriteInlineObject.GetOverhangMetrics(var overhangs: DWRITE_OVERHANG_METRICS): HRESULT;

begin

  overhangs.left := 0;

  overhangs.top := 0;

  overhangs.right := 0;

  overhangs.bottom := 0;

  Result := S_OK;

end;



end.



效果图:

Direct2D (42) : 在文本布局中嵌入图片 IDWriteTextLayout.SetInlineObject()

你可能感兴趣的:(object)