zoukankan      html  css  js  c++  java
  • DirectWrite文字排版——字符串去尾

    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     // 字体格式1:不使用去尾
     2     if (SUCCEEDED(hr))
     3     {
     4         DWRITE_TRIMMING trim1;
     5         IDWriteInlineObject* trim2 = NULL;
     6         hr = m_pDWriteFactory->CreateTextFormat( L"Arial Black", NULL, DWRITE_FONT_WEIGHT_NORMAL, 
     7             DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 20.0, L"en-us",&m_pTF1);
     8 
     9         if (SUCCEEDED(hr))
    10         {                    // 换行模式(DWRITE_WORD_WRAPPING)设置为不换行
    11             hr = m_pTF1->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
    12         }
    13 
    14         if (SUCCEEDED(hr))
    15         {
    16             trim1.granularity = DWRITE_TRIMMING_GRANULARITY_NONE;
    17             trim1.delimiter = 1;
    18             trim1.delimiterCount = 10;
    19             hr = m_pTF1->SetTrimming(&trim1,trim2);
    20         }
    21     }
    b)以字符为单位去尾
     1     // 字体格式2:以字符为单位去尾
     2     if (SUCCEEDED(hr))
     3     {
     4         DWRITE_TRIMMING trim1;
     5         IDWriteInlineObject* trim2 = NULL;
     6         hr = m_pDWriteFactory->CreateTextFormat( L"Arial Black", NULL, DWRITE_FONT_WEIGHT_NORMAL, 
     7             DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 20.0, L"en-us",&m_pTF2);
     8 
     9         if (SUCCEEDED(hr))
    10         {                        // 换行模式(DWRITE_WORD_WRAPPING)设置为不换行
    11             hr = m_pTF2->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
    12         }
    13 
    14         if (SUCCEEDED(hr))
    15         {
    16             trim1.granularity = DWRITE_TRIMMING_GRANULARITY_CHARACTER;
    17             trim1.delimiter = 1;
    18             trim1.delimiterCount = 10;
    19             hr = m_pTF2->SetTrimming(&trim1,trim2);
    20         }
    21     }
    c)以单词为单位去尾
     1     // 字体格式3:以单词为单位去尾
     2     if (SUCCEEDED(hr))
     3     {
     4         DWRITE_TRIMMING trim1;
     5         IDWriteInlineObject* trim2 = NULL;
     6         hr = m_pDWriteFactory->CreateTextFormat( L"Arial Black", NULL, DWRITE_FONT_WEIGHT_NORMAL, 
     7             DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 20.0, L"en-us",&m_pTF3);
     8 
     9         if (SUCCEEDED(hr))
    10         {                        // 换行模式(DWRITE_WORD_WRAPPING)设置为不换行
    11             hr = m_pTF3->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
    12         }
    13 
    14         if (SUCCEEDED(hr))
    15         {
    16             trim1.granularity = DWRITE_TRIMMING_GRANULARITY_WORD;
    17             trim1.delimiter = 1;
    18             trim1.delimiterCount = 10;
    19             hr = m_pTF3->SetTrimming(&trim1,trim2);
    20         }
    21     }
    d)以字符为单位去尾,用省略号代替略去部分
     1     // 字体格式4:以字符为单位去尾,用省略号代替略去部分
     2     if (SUCCEEDED(hr))
     3     {
     4         DWRITE_TRIMMING trim1;
     5         IDWriteInlineObject* trim2 = NULL;
     6         hr = m_pDWriteFactory->CreateTextFormat( L"Arial Black", NULL, DWRITE_FONT_WEIGHT_NORMAL, 
     7             DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 20.0, L"en-us",&m_pTF4);
     8 
     9         if (SUCCEEDED(hr))
    10         {                        // 换行模式(DWRITE_WORD_WRAPPING)设置为不换行
    11             hr = m_pTF4->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
    12         }
    13 
    14         if (SUCCEEDED(hr))
    15         {              // 
    16             m_pDWriteFactory->CreateEllipsisTrimmingSign(m_pTF4,&trim2);
    17         }
    18 
    19         if (SUCCEEDED(hr))
    20         {
    21             trim1.granularity = DWRITE_TRIMMING_GRANULARITY_CHARACTER;
    22             trim1.delimiter = 1;
    23             trim1.delimiterCount = 10;
    24             hr = m_pTF4->SetTrimming(&trim1,trim2);
    25         }
    26     }
    e)以单词为单位去尾,用省略号代替略去部分
     1     // 字体格式4:以字符为单位去尾,用省略号代替略去部分
     2     if (SUCCEEDED(hr))
     3     {
     4         DWRITE_TRIMMING trim1;
     5         IDWriteInlineObject* trim2 = NULL;
     6         hr = m_pDWriteFactory->CreateTextFormat( L"Arial Black", NULL, DWRITE_FONT_WEIGHT_NORMAL, 
     7             DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 20.0, L"en-us",&m_pTF4);
     8 
     9         if (SUCCEEDED(hr))
    10         {                        // 换行模式(DWRITE_WORD_WRAPPING)设置为不换行
    11             hr = m_pTF4->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
    12         }
    13 
    14         if (SUCCEEDED(hr))
    15         {
    16             m_pDWriteFactory->CreateEllipsisTrimmingSign(m_pTF4,&trim2);
    17         }
    18 
    19         if (SUCCEEDED(hr))
    20         {
    21             trim1.granularity = DWRITE_TRIMMING_GRANULARITY_CHARACTER;
    22             trim1.delimiter = 1;
    23             trim1.delimiterCount = 10;
    24             hr = m_pTF4->SetTrimming(&trim1,trim2);
    25         }
    26     }
     
    根据我们的实验发现,如果要实现“字符串去尾”的显示效果,必须先将换行模式(DWRITE_WORD_WRAPPING)设置为不换行;注意让显示的字符串长度超出目标矩形宽度,这样才能看出字符串去尾的效果。
     
    在此Demo中,为了更好的展示出字符串去尾的视觉效果,我们将字符串绘制的目标矩形范围使用绿色画刷绘制出来,如下:

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

  • 相关阅读:
    SSH 转发学习【转】
    JAVA 垃圾笔记一溜堆
    PHP CURL 伪造IP和来路
    PHP CURL 抓取失败 自己调试
    Tomcat 基本配置
    windows 64位 下 安装 tomcat
    UBUNTU下MONGODB出现PHP Fatal error: Uncaught exception 'MongoConnectionException' with message 和 Authentication failed on database 'admin' with username
    汽车牌牌知识
    一个用pyton写的监控服务端进程的软件hcm
    Python3.x和Python2.x的区别
  • 原文地址:https://www.cnblogs.com/Ray1024/p/5660490.html
Copyright © 2011-2022 走看看