DirectWrite是 DirectX 家族中专门用来做文本处理的部分,主要配合Direct2D进行渲染工作。

一、字符串去尾介绍
在文字渲染中,不免会遇到字符串去尾的需求。字符串去尾指的是:当字符串在指定的RECT中无法全部显示时,如何对文本进行截取,以适应目标区域大小;DirectWrite中的介绍是设置溢出布局宽度的文本的剪裁。我们把这种截取操作称为“字符串去尾”。

 
首先,给大家介绍一个DirectWrite中的类,IDWriteTextFormat类用于格式化文本的字体和段落属性,并且它还描述区域设置信息。
 
(1)IDWriteTextFormat::SetTrimming 方法

  设置溢出布局宽度的文本的剪裁选项。

  语法

  virtual HRESULT SetTrimming(
  [in] const DWRITE_TRIMMING * trimmingOptions,
  IDWriteInlineObject * trimmingSign
  ) = 0;

  参数

  trimmingOptions [in]

  文本剪裁选项。

  trimmingSign

  应用程序定义的忽略符号。此参数可为 NULL。注意:我们想要用到省略号代替裁剪部分就需要用到这个参数。

  返回值

  如果该方法成功,则返回 S_OK。 否则,将返回错误代码。HRESULT.

(2)DWRITE_TRIMMING 结构 (SetTrimming函数的第一个参数)

  指定用于溢出布局框的文本的剪裁选项。

  语法

  struct DWRITE_TRIMMING { 
    DWRITE_TRIMMING_GRANULARITY granularity; 
    UINT32                      delimiter; 
    UINT32                      delimiterCount; 
  };

  成员

  granularity

  一个值,指定用于对溢出布局框的文本进行剪裁的文本粒度。

  enum DWRITE_TRIMMING_GRANULARITY { 
    DWRITE_TRIMMING_GRANULARITY_NONE,      //不进行任何剪裁。文本流超出布局宽度。
    DWRITE_TRIMMING_GRANULARITY_CHARACTER,   //在字符群集边界处进行剪裁
    DWRITE_TRIMMING_GRANULARITY_WORD      //在字边界处进行剪裁
  };

  delimiter

  一个字符代码,用作指示要保留的文本部分开头的分隔符。对路径省略号最有用,其中分隔符为斜杠。

  delimiterCount

  一个值,指示要后退的分隔符数量。

(3)DWriteFactory::CreateEllipsisTrimmingSign()方法

  此方法可以生成表示省略号的 IDWriteInlineObject(此方法得到的IDWriteInlineObject可以作为SetTrimming方法的第二个参数)。

二、实现字符串去尾效果

字符串裁剪效果完全可以通过配置IDWriteTextFormat对象来实现。下面来展示5种不同情况的字符串去尾效果的IDWriteTextFormat对象的创建及配置过程:
 
a)不使用去尾
     // 字体格式1:不使用去尾
if (SUCCEEDED(hr))
{
DWRITE_TRIMMING trim1;
IDWriteInlineObject* trim2 = NULL;
hr = m_pDWriteFactory->CreateTextFormat( L"Arial Black", NULL, DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 20.0, L"en-us",&m_pTF1); if (SUCCEEDED(hr))
{ // 换行模式(DWRITE_WORD_WRAPPING)设置为不换行
hr = m_pTF1->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
} if (SUCCEEDED(hr))
{
trim1.granularity = DWRITE_TRIMMING_GRANULARITY_NONE;
trim1.delimiter = ;
trim1.delimiterCount = ;
hr = m_pTF1->SetTrimming(&trim1,trim2);
}
}
b)以字符为单位去尾
     // 字体格式2:以字符为单位去尾
if (SUCCEEDED(hr))
{
DWRITE_TRIMMING trim1;
IDWriteInlineObject* trim2 = NULL;
hr = m_pDWriteFactory->CreateTextFormat( L"Arial Black", NULL, DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 20.0, L"en-us",&m_pTF2); if (SUCCEEDED(hr))
{ // 换行模式(DWRITE_WORD_WRAPPING)设置为不换行
hr = m_pTF2->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
} if (SUCCEEDED(hr))
{
trim1.granularity = DWRITE_TRIMMING_GRANULARITY_CHARACTER;
trim1.delimiter = ;
trim1.delimiterCount = ;
hr = m_pTF2->SetTrimming(&trim1,trim2);
}
}
c)以单词为单位去尾
     // 字体格式3:以单词为单位去尾
if (SUCCEEDED(hr))
{
DWRITE_TRIMMING trim1;
IDWriteInlineObject* trim2 = NULL;
hr = m_pDWriteFactory->CreateTextFormat( L"Arial Black", NULL, DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 20.0, L"en-us",&m_pTF3); if (SUCCEEDED(hr))
{ // 换行模式(DWRITE_WORD_WRAPPING)设置为不换行
hr = m_pTF3->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
} if (SUCCEEDED(hr))
{
trim1.granularity = DWRITE_TRIMMING_GRANULARITY_WORD;
trim1.delimiter = ;
trim1.delimiterCount = ;
hr = m_pTF3->SetTrimming(&trim1,trim2);
}
}
d)以字符为单位去尾,用省略号代替略去部分
     // 字体格式4:以字符为单位去尾,用省略号代替略去部分
if (SUCCEEDED(hr))
{
DWRITE_TRIMMING trim1;
IDWriteInlineObject* trim2 = NULL;
hr = m_pDWriteFactory->CreateTextFormat( L"Arial Black", NULL, DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 20.0, L"en-us",&m_pTF4); if (SUCCEEDED(hr))
{ // 换行模式(DWRITE_WORD_WRAPPING)设置为不换行
hr = m_pTF4->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
} if (SUCCEEDED(hr))
{              //
m_pDWriteFactory->CreateEllipsisTrimmingSign(m_pTF4,&trim2);
} if (SUCCEEDED(hr))
{
trim1.granularity = DWRITE_TRIMMING_GRANULARITY_CHARACTER;
trim1.delimiter = ;
trim1.delimiterCount = ;
hr = m_pTF4->SetTrimming(&trim1,trim2);
}
}
e)以单词为单位去尾,用省略号代替略去部分
     // 字体格式4:以字符为单位去尾,用省略号代替略去部分
if (SUCCEEDED(hr))
{
DWRITE_TRIMMING trim1;
IDWriteInlineObject* trim2 = NULL;
hr = m_pDWriteFactory->CreateTextFormat( L"Arial Black", NULL, DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 20.0, L"en-us",&m_pTF4); if (SUCCEEDED(hr))
{ // 换行模式(DWRITE_WORD_WRAPPING)设置为不换行
hr = m_pTF4->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
} if (SUCCEEDED(hr))
{
m_pDWriteFactory->CreateEllipsisTrimmingSign(m_pTF4,&trim2);
} if (SUCCEEDED(hr))
{
trim1.granularity = DWRITE_TRIMMING_GRANULARITY_CHARACTER;
trim1.delimiter = ;
trim1.delimiterCount = ;
hr = m_pTF4->SetTrimming(&trim1,trim2);
}
}
 
根据我们的实验发现,如果要实现“字符串去尾”的显示效果,必须先将换行模式(DWRITE_WORD_WRAPPING)设置为不换行;注意让显示的字符串长度超出目标矩形宽度,这样才能看出字符串去尾的效果。
 
在此Demo中,为了更好的展示出字符串去尾的视觉效果,我们将字符串绘制的目标矩形范围使用绿色画刷绘制出来,如下:

想看源码的朋友可以点击此处下载,Demo源码是Direct2DTests目录下的DWriteStringTrimming文件。

DirectWrite文字排版——字符串去尾的更多相关文章

  1. OpenJudge计算概论-文字排版

    /*====================================================================== 文字排版 总时间限制: 1000ms 内存限制: 65 ...

  2. 【html】文字排版

    Web开发过程中文字排版,默认的情况下,行末的长单词会撑开容器. 我们想要的是(像word一样.能够自动换行.既不撑大容器.也不强制拆开行末单词.并且不会隐藏行末单词的多余字母) ①不能撑开容器 ②完 ...

  3. iOS开发-UITextView文字排版

    UITextView文本排版 1.配置NSMutableParagraphStyle NSMutableParagraphStyle *MParaStyle = [[NSMutableParagrap ...

  4. 题目1049:字符串去特定字符——九度OJ

    题目1049:字符串去特定字符 http://ac.jobdu.com/problem.php?pid=1049 时间限制:1 秒 内存限制:32 兆 题目描述: 输入字符串s和字符c,要求去掉s中所 ...

  5. (转)iOS7界面设计规范(10) - UI基础 - 文字排版与配色

    明天就是周四了.貌似前几天还在恨周一呢.话说今天几乎开了一整天的会,正经事情没做多少:这种感觉比一整天从早到晚12个小时的忙碌于一件事情还要让人感到疲惫的对叭?那今天的iOS7设计规范更新又是一篇很简 ...

  6. NSIS文字及字符串函数与头文件介绍

    原文 NSIS文字及字符串函数与头文件介绍 文字函数,顾名思义就是处理字符串的函数.使用这些字符串函数前,必须先包含头文件WordFunc.nsh.该头文件目前包含如下一些函数:WordFind.Wo ...

  7. nefu 903 字符串去星

    字符串去星 Problem : 903 Time Limit : 1000ms Memory Limit : 65536K description 有一个字符串(长度小于100),要统计其中有多少个* ...

  8. div介绍 盒子模型边框属性 CSS初始化 文字排版 边框调整 溢出

    今天学习的div,了解了div是干什么用的掌握了什么是盒子模型,以及div的外边距内边距以及边框,运用div和CSS给文字排版,利用边框的来做图像,div溢出的处理 CSS初始化: 精确排版的时候用这 ...

  9. JS保留小数 去尾法 进一法 四舍五入法

    //toFixed 四舍五入遇到坑. 1.235.toFixed(2) = 1.23 1.2350001.toFixed(2) = 1.24 //去尾法 Number.prototype.toFloo ...

随机推荐

  1. iOS 7.1 UITableView添加footerView 后 最后一行分割线无法显示

    今天用故事版 遇到个奇怪的问题: 我要用 tbView(tableView)展示写信息.最后一行我要显示些文案什么的.考虑用 footerView ,开心coding ..,show下 哪里有些不对吧 ...

  2. highcharts插件使用总结和开发中遇到的问题及解决办法

    这里使用的highchart是2014-01-09从官网下载的版本,版本号是3.0.8, 当过了几天后,发现版本号变成了3.0.9,不由得的感叹highchart的版本更新之快. 在jsp中使用hig ...

  3. Navi.Soft30.框架.Mobile.开发手册

    1概述 1.1应用场景 互联网的发展,使用基于Web的软件异军突起,目前占据着相当大的市场份额,而手机,平板电脑等移动端设备的频繁使用,使移动端的软件快速发展,逐步有超越Web软件的趋势 移动软件中, ...

  4. Hadoop 2.7.1 使用minicluster进行单元测试

    目的是要跑通这个单元测试:hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestClose.java 这个Java文件比较简单: /** * Lic ...

  5. ECShop商品详细页 实现尺码颜色关联显示库存数量

    效果如下: 要开模板文件 goods.dwt  把选择尺码跟颜色的代码替换成如下,(不同模板代码可能不一样,对照去替换) <!-- {foreach from=$spec.values item ...

  6. struts2:拦截器

    拦截器(Interceptor)是Struts 2的核心组件,Struts 2框架的大部分功能都是通过拦截器来完成的,例如数据校验,国际化,文件上传和下载等.为了实现这些功能,Struts 2框架提供 ...

  7. juniper 550M訪问自身公网IP回流内部IP

    拓扑图示意: 网关设备juniper 550M, untrust 区: 公网地址段22.22.22.22/29 trust区:      内部员工PC地址:172.16.4.x /24 trust区: ...

  8. Linux64位服务器编译安装MySQL5.6(CentOS6.4)

    首先到MySQL官网下载MySQL最新版(目前是mysql-5.6.12)上传到服务器上,下面说一下详细的安装过程. 安装依赖包,可以在线更新也可以配置本地源(CentOS本地源配置)yum -y i ...

  9. saiku 展示优化第二步(要诀和技巧)

    经历了上几篇博客的分享,可以无密码登录 : http://www.cnblogs.com/liqiu/p/5246015.html 随着使用的深入,公司需要将现有的报表平台与saiku整合,其中最便捷 ...

  10. Microsoft 2013 新技术学习笔记 一

    有几年没有关注技术了,最近有点时间想把技术重新捡起来,借着重构手上的一个后台管理框架的机会将微软新的几种技术全部应用一下,从目的上来讲并没有希望能对涉及的技术有很深入的了解,所以这个系列的文章(篇幅不 ...