文档章节

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

涂孟超
 涂孟超
发布于 2014/09/26 15:37
字数 562
阅读 71
收藏 0

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

上面是刚碰到错误时的求助信息;现在终于找到错误了:是 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.


效果图:



本文转载自:http://www.cnblogs.com/del/archive/2011/04/14/2016589.html

共有 人打赏支持
涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
私信 提问
Direct2D教程(十)绘制文本

概述 在Direct2D中,文本的绘制是通过DirectWrite来实现的,DirectWrite实际上已经是一个独立的DirectX组件了。关于DirectWrite,我摘录了MSDN的一段文字。 DirectWrite介绍 当今的应用程序应...

吞吞吐吐的
2017/10/17
0
0
Windows桌面应用程序(1-2-4-7th) DPI和设备无关的像素

要使用Windows图形进行有效编程,您必须了解两个相关的概念: 每英寸点数(DPI) 设备无关像素(DIP)。 我们从DPI开始。这将需要短暂的绕行排版。在印刷术中,类型的大小以称为点的单位来测量。一点...

qq_37422196
2018/01/12
0
0
关于Direct3D11里汉字显示的一些思考

本系列文章由zhmxy555(毛星云)编写,转载请注明出处。 http://blog.csdn.net/zhmxy555/article/details/8147234 作者:毛星云 邮箱: happylifemxy@163.com 这篇文章里,浅墨希望与大家一起...

长平狐
2012/11/12
794
0
如何在 PDF Transformer+中进行FB2和EPUB转换设置

作为可创建、编辑及将PDF文件转换为其他可编辑格式的通用工具,ABBYY PDF Transformer+为受支持的输出格式提供多种转换设置,选定的转换设置影响生成文档的外观,本文具体为大家讲解ABBYY P...

ABBYY
2016/01/22
65
0
WPF 使用 Direct2D1 画图 绘制基本图形

本文来告诉大家如何在 Direct2D1 绘制基本图形,包括线段、矩形、椭圆 本文是一个系列 WPF 使用 Direct2D1 画图入门 WPF 使用 Direct2D1 画图 绘制基本图形 本文的组织参考Direct2D,对大神表...

lindexi_gd
2018/04/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周一乱弹 —— 白掌柜说了卖货不卖身

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @爱漫爱 :这是一场修行分享羽肿的单曲《Moony》 手机党少年们想听歌,请使劲儿戳(这里) @clouddyy :开不开心? 开心呀, 我又不爱睡懒觉…...

小小编辑
今天
8
0
大数据教程(11.7)hadoop2.9.1平台上仓库工具hive1.2.2搭建

上一篇文章介绍了hive2.3.4的搭建,然而这个版本已经不能稳定的支持mapreduce程序。本篇博主将分享hive1.2.2工具搭建全过程。先说明:本节就直接在上一节的hadoop环境中搭建了! 一、下载apa...

em_aaron
今天
3
0
开始看《JSP&Servlet学习笔记》

1:WEB应用简介。其中1.2.1对Web容器的工作流程写得不错 2:编写Servlet。搞清楚了Java的Web目录结构,以及Web.xml的一些配置作用。特别是讲了@WebServlet标签 3:请求与响应。更细致的讲了从...

max佩恩
今天
4
0
mysql分区功能详细介绍,以及实例

一,什么是数据库分区 前段时间写过一篇关于mysql分表的的文章,下面来说一下什么是数据库分区,以mysql为例。mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可...

吴伟祥
今天
3
0
SQL语句查询

1.1 排序 通过order by语句,可以将查询出的结果进行排序。放置在select语句的最后。 格式: SELECT * FROM 表名 ORDER BY 排序字段ASC|DESC; ASC 升序 (默认) DESC 降序 1.查询所有商品信息,...

stars永恒
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部