• 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.
    


    效果图:



  • 相关阅读:
    核心容器的两个接口(ApplicationContext和BeanFactory)引发出的问题
    ApplicationContext的三个常用实现类:
    IDEA如何找到接口的实现类
    编写BeanFactory
    9.4 Binder系统_驱动情景分析_服务使用过程
    9.3 Binder系统_驱动情景分析_服务获取过程
    9.2 Binder系统_驱动情景分析_服务注册过程
    9.1 Binder系统_C程序示例_框架分析和编写程序
    8.6 Android灯光系统_源码分析_背光灯
    8.5 Android灯光系统_源码分析_通知灯
  • 原文地址:https://www.cnblogs.com/del/p/2016589.html
Copyright © 2020-2023  润新知