zoukankan      html  css  js  c++  java
  • 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/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    ubuntu lock
    ubuntu 源
    ubuntu server版 ssh配置有时没有sshd_config文件或者空文件的情况
    pip3 install tensorflow==2.2
    tensorflow安装提示load 失败
    wXgame上某游戏封包分析
    lazarus 使用微软detour库 delphi
    dll函数导出
    Error: Duplicate resource: Type = 24, Name = 1, Lang ID = 0000
    Tests run: 3, Failures: 0, Errors: 3, Skipped: 0, Time elapsed: 0.065 s <<< FAILURE!
  • 原文地址:https://www.cnblogs.com/graphics/p/2764870.html
Copyright © 2011-2022 走看看