文档章节

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

涂孟超
 涂孟超
发布于 2014/09/26 15:37
字数 562
阅读 70
收藏 0
点赞 0
评论 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
博文 2004
码字总数 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
01/12
0
0
关于Direct3D11里汉字显示的一些思考

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

长平狐
2012/11/12
690
0
WPF 使用 Direct2D1 画图 绘制基本图形

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

lindexi_gd
04/19
0
0
如何在 PDF Transformer+中进行FB2和EPUB转换设置

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

ABBYY
2016/01/22
65
0
深度解读 - Windows 7核心图形架构细致分析(转贴)

原帖地址:http://technet.microsoft.com/zh-cn/library/ee921514.aspx 如现在大家所想的那样, Windows7 其实是 Windows Vista 的改进版。 Windows 7 在 Windows Vista 的基础上进行了大量的...

迈克老狼1
2012/12/23
0
0
杂谈SharpDx中的WIC组件——我们需要WIC的图片编码功能么?

在前文 SharpDX之Direct2D教程II——加载位图文件和保存位图文件 中,发现在VB2010中不能很好的运用SharpDx中的WIC组件进行图片的编码工作。可能是我的设置问题,也可能是SharpDx对VB2010支持...

万仓一黍
2013/10/08
0
0
ABBYY导出PDF时注意哪些信息

使用ABBYY FineReader Pro for Mac OCR文字识别软件识别文档时,可以将已识别的文本保存到文件中,还可以通过电子邮件发送已识别的文本,只要输出格式受FineReader支持。那么如果想要将识别结...

ABBYY
2016/11/09
6
0
硬件加速:浏览器大战的新前沿

硬件加速:浏览器大战的新前沿 作者:Frederic Lardinois / 2009年11月24日 9:04AM 微软在本月初召开的专业开发者大会(Professional Developers Conference)上宣布了其最新的IE9计划,微软在...

老枪
2009/11/26
189
0
9个非常有用的CSS网页设计技巧

CSS也叫层叠样式表,它现在是web开发不可或缺的一部分。开发者可以对任何页面中的任意元素使用CSS,使之前认为不可能的效果成为可能。如果你有正确的源代码,你可以轻易改变本空间、下划链接...

曾沙
2012/10/09
7.3K
25

没有更多内容

加载失败,请刷新页面

加载更多

下一页

自定义OkHttp的UA

背景 上次的问题很明显 由于我们的ua清一色OkHttp导致快速定位到内部应用。 既然如此我们是否考虑可以在UA上做点手脚。 自定义我们的UA呢??? 分析 首先UA在 均为okhttp/3.2.0 大概率是由于...

Mr_Qi
21分钟前
0
0
【scikit-learn】01:使用案例对sklearn库进行简单介绍

sklearn学习笔记:Quick Start 源地址:http://scikit-learn.org/stable/tutorial/basic/tutorial.html # -*-coding:utf-8-*-''' Author:kevinelstri Datetime:2017.2.16'''......

wangxuwei
25分钟前
0
0
Linux Kernel 4.16 系列停止维护,用户应升级至 4.17

知名 Linux 内核维护人员兼开发人员 Greg Kroah-Hartman 近日在发布 4.16.18 版本的同时,宣布这是 4.16 系列的最后一个维护版本,强烈建议用户立即升级至 4.17 系列。 Linux 4.16 于 2018 年...

问题终结者
27分钟前
0
0
Apache配置时.htaccess失效不起作用的原因分析

.htaccess 失效的原因 1. 重写规则有问题,检查自己的重写规则 2.Apache配置问题,配置中没有配置启用 rewrite a2enmod rewrite 3.网站配置文件没有启用配置需要配置 000-default.conf <Dire...

TU-DESGIN
47分钟前
1
0
两个求最大公约数C/C++算法实现

#include<stdio.h> #include<time.h> #include <iostream>using namespace std;//求最大公约数 LCD(Largest Common Division)//短除法 //m=8251, n=6105; int LCD_ShortDiv(int m, ......

失落的艺术
53分钟前
1
0
QueryPerformanceCounter

windows的Sleep函数,睡眠线程指定毫秒数,可以用来做毫秒延时。 对于微秒延时,没有一个现成的函数,但是可以通过 QueryPerformanceFrequency QueryPerformanceCounter 来间接实现。原理就是...

开飞色
今天
1
0
log4j2使用AsyncRoot不显示行号问题处理

<AsyncRoot level="info" includeLocation="true"> <AppenderRef ref="File"/></AsyncRoot><!--1.异步logger,还需要在pom.xml中添加disruptor的依赖。2.includeLocation结合异......

小翔
今天
3
0
安卓手机上 K 歌,声音延迟怎么解决?

这篇文章可以为你提供一个解决录音和播放同步问题的思路,而且解决了声音从手机传输到耳机上有延时的问题。 初识音频 在开始之前,我先简单介绍一下音频相关的基础知识,方便下文理解。 我们...

编辑部的故事
今天
2
0
使用token实现在有效期内APP自动登录功能

使用token实现在有效期内APP自动登录功能 http://sevennight.cc/2016/07/19/auto_login_impl.html

风云海滩
今天
2
0
Spring Boot集成RabbitMQ发送接收JSON

默认情况下RabbitMQ发送的消息是转换为字节码,这里介绍一下如何发送JSON数据。 ObjectMapper 最简单发送JSON数据的方式是把对象使用ObjectMapper等JSON工具类把对象转换为JSON格式,然后发送...

小致dad
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部