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. RTL8710 Flasher

    https://bitbucket.org/rebane/rtl8710_openocd/ rtl8710_openocd / script / rtl8710.ocd # # OpenOCD scr ...

  2. 文件编辑器 vi

    1.关于文本编辑器: 文本编辑器有很多,比如图形模式的gedit.kwrite.OpenOffice ... ... ,文本模式下的编辑器有vi.vim(vi的增强版本)和nano ... ... v ...

  3. WPF WebBrowser屏蔽弹出alert ,confirm ,prompt ,showModalDialog() ,window.open()

    WPF WebBrowser屏蔽弹出alert ,confirm ,prompt ,showModalDialog() ,window.open()添加Microsoft.mshtml.dll,然后写 ...

  4. Mac 下配置 SSH 免密码安全登录

    Win下个人常使用 SecureCRT ,Mac 下感觉 SecureCRT 并不好使,常用 iTerm2+zsh 搭配使用.A连接B 无密码登陆,则A上面执行 ssh-keygen 一路回车,把 ~ ...

  5. X下轻量级桌面WindowMaker上手指南

    layout: post title: 轻量级桌面WindowMaker上手指南 tags: x11, cygwin, raspi --- 最近工作上需要在远程Linux上运行一个桌面(我需要跑Net ...

  6. [译] 一、为何要推出AppCoda系列?

    声明:本文翻译自AppCoda网站的文章:Why Launching AppCoda?,作者是创建者Simon Ng.如有异议,请联系博主. 去年九月份,我在App Store上发布了自己第一个iPh ...

  7. navicat 链接linux 服务器上的数据库

  8. Python 中Editplus 特别实用的设置方法

    editplus 中输入tab自动变成4个空格打开tools->preference打开面板,files的子栏目->settings & syntax面板中的 tab/indent ...

  9. Kafka - SQL 引擎分享

    1.概述 大多数情况下,我们使用 Kafka 只是作为消息处理.在有些情况下,我们需要多次读取 Kafka 集群中的数据.当然,我们可以通过调用 Kafka 的 API 来完成,但是针对不同的业务需求 ...

  10. Android QQ空间浏览图片动画特效的实现(※)

    1 http://blog.csdn.net/yangblocker/article/details/12680247 2 photoview 3 nineoldandroid