Direct2D教程(十)绘制文本

简介:

概述

在Direct2D中,文本的绘制是通过DirectWrite来实现的,DirectWrite实际上已经是一个独立的DirectX组件了。关于DirectWrite,我摘录了MSDN的一段文字。

DirectWrite介绍

当今的应用程序应提供高质量的文本渲染,分辨率无关的字体及完整的Unicode文本和布局支持,DirectWrite提供了这些功能,甚至比这更多。下面是DirectWrite的特性

  • 设备无关的文本布局系统,提高了文本的可读性(包括文档及UI上的文本)
  • 高质量的,子像素,ClearType文本的渲染(可以使用GDI及Direct2D或应用程序指定的渲染技术)
  • 硬件加速的文本渲染(和Direct2D一起使用时)
  • 支持多格式文本
  • 支持OpenType fonts的高级typography特性
  • 对所支持语言文本的渲染及布局。
  • GDI兼容的布局及渲染

DirectWrite API支持多格式文本的度量,绘制及命中测试。DirectWrite处理所有支持语言的文本,包括global及localized应用程序(构建于Windows7核心语言基础之上)。DirectWrite也提供了底层的glyph渲染。

Direct2D提供了如下两个绘制文本的函数,稍后的代码使用第一个函数。

  • ID2D1RenderTarget::DrawText
  • ID2D1RenderTarget::DrawTextLayout

主要步骤

这里介绍的步骤都是与绘制文本相关的核心步骤,其它步骤比如创建render target或者画刷,处理Windows消息等是每个Direct2D程序都会涉及的,这里就不再介绍了。

创建ID2D1Factory接口对象

凡事都有个根源,程序也是一样,在Direct2D中也有一个根源对象,那就是ID2D1Factory接口,它是所有其它资源的根源,包括设备相关的资源及设备无关的资源,有了这个接口,就可以创建其它的D2D对象了,比如render target,画刷等。所以首要任务是创建一个ID2D1Factory对象。

复制代码
D2D1Factory* g_pD2DFactory = NULL;

HRESULT hr = D2D1CreateFactory(
    D2D1_FACTORY_TYPE_SINGLE_THREADED,
    &g_pD2DFactory
    );
if(FAILED(hr))
{
    MessageBox(NULL, L"Create Direct2D factory failed!", L"Error", 0);
    return;
}
复制代码

创建IDWriteFactory接口对象

前面说了,在Direct2D中绘制文本实际上是通过DirectWrite来实现的,一切和文本相关的接口也都是由这个接口来创建的,所以接下来要创建一个IDWriteFactory接口对象,代码如下。

复制代码
IDWriteFactory* g_pDWriteFactory = NULL;

// Create DirectWrite Factory
hr = DWriteCreateFactory(
    DWRITE_FACTORY_TYPE_SHARED, 
    __uuidof(IDWriteFactory),
    reinterpret_cast<IUnknown**>(&g_pDWriteFactory)
    );
if(FAILED(hr))
{
    MessageBox(NULL, L"Create DirectWrite factory failed!", L"Error", 0);
    return;
}
复制代码

创建IDWriteTextFormat接口对象

文本有一系列属性,比如字体类型,Arial还是Consolas?字体大小,14px还是16px? 字体风格,倾斜或加粗?在D2D中,用IDWriteTextFormat来描述文本的这些属性,所以,下一步需要创建IDWriteTextFormat对象了。需要注意的是文本的颜色并不是由该接口来控制的,而是由画刷来控制。

复制代码
IDWriteTextFormat* g_pTextFormat = NULL;

hr = g_pDWriteFactory->CreateTextFormat(
    L"Gabriola",                   // Font family name
    NULL,                          // Font collection(NULL sets it to the system font collection)
    DWRITE_FONT_WEIGHT_REGULAR,    // Weight
    DWRITE_FONT_STYLE_NORMAL,      // Style
    DWRITE_FONT_STRETCH_NORMAL,    // Stretch
    50.0f,                         // Size    
    L"en-us",                      // Local
    &g_pTextFormat                 // Pointer to recieve the created object
    );
if(FAILED(hr))
{
    MessageBox(NULL, L"Create IDWriteTextFormat failed!", L"Error", 0);
    return;
}
复制代码

定义文本绘制区域

下一步,需要确定文本的绘制区域,也就是在哪里绘制文本,这个区域通常是一个矩形结构。所以,只需简单定义一个rect即可。

复制代码
// Create text layout rect
RECT rc;
GetClientRect(hwnd, &rc);
D2D1_RECT_F textLayoutRect = D2D1::RectF(
    static_cast<FLOAT>(rc.left),
    static_cast<FLOAT>(rc.top),
    static_cast<FLOAT>(rc.right - rc.left),
    static_cast<FLOAT>(rc.bottom - rc.top)
    );
复制代码

绘制

万事俱备,只欠东风!下面就是最后一步也是最重要的一步,渲染文本,这里使用接口ID2D1HwndRenderTarget中的函数DrawText来完成具体的绘制工作,这个函数的具体定义如下:

复制代码
virtual void DrawText(
  [in]  WCHAR *string,
  UINT stringLength,
  [in]  IDWriteTextFormat *textFormat,
  [in]  const D2D1_RECT_F *layoutRect,
  [in]  ID2D1Brush *defaultForegroundBrush,
  D2D1_DRAW_TEXT_OPTIONS options = D2D1_DRAW_TEXT_OPTIONS_NONE,
  DWRITE_MEASURING_MODE measuringMode = DWRITE_MEASURING_MODE_NATURAL
) = 0;
复制代码

参数说明:

  • string,                               待绘制的文本,unicode编码。
  • stringLength,                     文本长度。
  • textFormat,                       文本的格式化信息(属性),上面提到过。
  • layoutRect,                        绘制区域对应的矩形。
  • defaultForegroundBrush,    绘制文本所用的画刷

最后两个参数暂时用不到,而且有默认参数,这里就不考虑了。调用代码如下。

复制代码
// Draw text
g_pRenderTarget->DrawText(
    wszText,           // Text to render
    cTextLength,       // Text length
    g_pTextFormat,     // Text format
    textLayoutRect,    // The region of the window where the text will be rendered
    g_pBlackBrush      // The brush used to draw the text
);
复制代码

效果图

然后呢?

这篇只是对于文本绘做一个简单的介绍,在Direct2D与文本相关的东西远不止这些,在后续的DirectWrite系列中会详细阐述每个方面,敬请关注!


本文转自zdd博客园博客,原文链接:http://www.cnblogs.com/graphics/archive/2013/03/01/2764870.html,如需转载请自行联系原作者

相关文章
|
4月前
|
Android开发
Android Studio入门之图像显示解析及实战(附源码 超详细必看)(包括图像视图、图像按钮、同时展示文本与图像)
Android Studio入门之图像显示解析及实战(附源码 超详细必看)(包括图像视图、图像按钮、同时展示文本与图像)
66 1
video播放中页面上画线条-坐标点画图demo效果(整理)
video播放中页面上画线条-坐标点画图demo效果(整理)
|
定位技术
egret纹理填充模式(上下填充)
egret纹理填充模式(上下填充)
egret纹理填充模式(上下填充)
|
存储
使用Dynamic Data Display控件绘图时无法删除已经画好的曲线
最近在使用Dynamic Data Display画图的时候发现,多次画图时,之前画的图无法清除,造成图像混乱。找了好久发现这样可以消除。 在调用AddLineGraph时,使用一个全局的变量来存储这个方法返回的对象(LineGraph), 点击...
855 0
【音视频连载-002】基础学习篇-SDL 创建窗口并显示颜色
在前面的文章中我们已经完成了 SDL 的工程配置,接下来就是 SDL 相关功能的开发。 本篇文章主要是创建一个应用程序窗口并显示。
219 0
【音视频连载-002】基础学习篇-SDL 创建窗口并显示颜色
|
图形学
unity3d曲线text文本
测试.png using System; using System.Collections.Generic; namespace UnityEngine.UI.Extensions { /// /// Curved text.让文本按照曲线进行显示 【注意对Image的变形 也是可以的】 /// 说明: 对Text的操作就和 shadow 和 outline 组件类似。
1355 0
|
C#
C# 如何在PDF中绘制不同风格类型的文本
通过对控件Spire.PDF的测试,我们可以创建PDF文件并向文档中绘制文本、图片、表格、图形等内容,其中,对于绘制文本这一部分,Spire.PDF提供了三种字体类型来绘制文本,即: Standard fonts TrueType fonts Chinese, Japanese and Korean (CJK) fonts 从以上类中我们可以发现,是可以支持中、日、韩、英等字体类的,这为我们在操作PDF文件上提供了更多可能。
1109 0