锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C#开源技术 / C#开源英语 / 使用GDI绘制OpenType字体文本
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
技术分类
讨论组翻译
GDI绘制文本错误
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

锐英源精品开源心得,转载请注明:“锐英源www.wisestudy.cn,孙老师作品,电话13803810136。需要全文内容也请联系孙老师。

使用GDI绘制OpenType字体文本

Introduction 介绍

As you will probably encounter this problem in WinForm development--you can't create System.Drawing.Font instances from OpenType fonts. That's because the implementation of that class has used GDI+, which provides very limited support for OpenType fonts.

你可能在WinForm开发中遇到这样的问题——你不能从OpenType字体创建System.Drawing字体实例。这是因为该类使用GDI+来实现,它提供对OpenType字体提供的支持非常有限。

There are several way-outs. One is to switch to WPF from WinForm, which supports OpenType fonts, but I guess you won't do so easily, especially when the other parts of your code are fine and nice and the only missing feature is just the OpenType font files support. The second way is to use FreeType, a fabulous font rendering engine. It is viable but you have some good stuff to learn.

有几种途径。一种是从WinForm的,它支持OpenType字体切换到WPF,,但我猜你做起来不会那么容易,尤其是当您的代码的其他部分都很好,唯一缺失的功能就是对OpenType字体文件的支持。第二种方法是使用FreeType,令人难以置信的字体绘制引擎。它是可行的,但是你有一些好东西要学。

Hereby, this tip provides a method of rendering text with OpenType fonts by P/Invoking the system API. 在此,本文提供一种通过API系统调用来实现OpenType字体绘制文本。

绘制文本

Background 背景

The GDI+ API used by the .NET platform does not support OpenType fonts well, but the system wide API, GDI (without the plus sign, but does more here), supports OpenType much better. We can use Platform Invoke to call functions exposed by the GDI and render texts with OpenType fonts.

GDI + API使用的网络平台不支持OpenType字体,但系统级API,如GDI(没有加号,但能做更多),能更好的支持OpenType。我们可以使用平台调用来调用公开的GDI函数和绘制文本的OpenType字体。

The procedure is listed below. The major functions to use are the CreateFont function and the DrawText function. 该过程如下。所使用的主要功能是CreateFont函数和DrawText函数。

Get the device context (DC) from the graphics. 从图形获取设备描述表(DC)。

Call the CreateFont function and create the GDI font. 调用CreateFont函数并创建GDI字体。

Use the font in the DC by calling SelectObject. 通过调用选择对象使用DC的字体

Call the DrawText function and draw the text onto the specific region of the DC. 调用DrawText函数并且绘制文本的特定区域。

Release the resources by calling DeleteObject. 通过调用DeleteObject释放资源。

The C# code is listed below, there are some other functions involved, but they are just listed for your reference. 下面列出的c#代码,还有一些其他的功能,但他们只是列出,供您参考。

 public static void RenderText(IDeviceContext hdc, string text, 
    string fontFamily, Color color, Rectangle region, int size) {
    // create the handle of DC
    var h = new HandleRef (null, hdc.GetHdc ());
    // create the font
    var p = new HandleRef (null, NativeMethods.CreateFont 
    (size, 0, 0, 0, 0, 0, 0, 0, 1/*Ansi_encoding*/, 0, 0, 4, 0, fontFamily));
    try {
    // use the font in the DC
    NativeMethods.SelectObject (h, p.Handle);
    // set the background to transparent
    NativeMethods.SetBkMode (h, 1);
    // set the color of the text
    NativeMethods.SetTextColor (h, color);
    // draw the text to the region
    NativeMethods.DrawText (h, text, region, 0x0100);
    }
    finally {
    // release the resources
    NativeMethods.DeleteObject (p);
    hdc.ReleaseHdc ();
     }
   }

We should firstly prepare our P/Invoke code for use. The protocol of the CreateFont function and DrawText function can be found out from MSDN.

我们应该首先准备P/ Invoke代码备用。该协议CreateFont函数和DrawText函数可以从MSDN找到。

HFONT CreateFont(
    __in  int nHeight,
    __in  int nWidth,
    __in  int nEscapement,
    __in  int nOrientation,
    __in  int fnWeight,
    __in  DWORD fdwItalic,
    __in  DWORD fdwUnderline,
    __in  DWORD fdwStrikeOut,
    __in  DWORD fdwCharSet,
    __in  DWORD fdwOutputPrecision,
    __in  DWORD fdwClipPrecision,
    __in  DWORD fdwQuality,
    __in  DWORD fdwPitchAndFamily,
    __in  LPCTSTR lpszFace
        );    
        int DrawText(
    __in     HDC hDC,
    __inout  LPCTSTR lpchText,
    __in     int nCount,
    __inout  LPRECT lpRect,
    __in     UINT uFormat
    );

And the corresponding P/Invoke code can be the following: 相应的 P/Invoke 代码如下:

const string GDI32 = "gdi32.dll";
    struct Rect
    {
    public long Left, Top, Right, Bottom;
    public Rect (Rectangle rect) {
    this.Left = rect.Left;
    this.Top = rect.Top;
    this.Right = rect.Right;
    this.Bottom = rect.Bottom;
    }
    }
    [DllImport (GDI32)]
    internal static extern IntPtr CreateFont (
    int nHeight,
    int nWidth,
    int nEscapement,
    int nOrientation,
    int fnWeight,
    uint fdwItalic,
    uint fdwUnderline,
    uint fdwStrikeOut,
    uint fdwCharSet,
    uint fdwOutputPrecision,
    uint fdwClipPrecision,
    uint fdwQuality,
    uint fdwPitchAndFamily,
    string lpszFace
    );
    [DllImport (USER32, CharSet = CharSet.Auto)]
    static extern int DrawText 
    (HandleRef hDC, string lpchText, int nCount, ref Rect lpRect, uint uFormat);
    internal static int DrawText (HandleRef hDC, string text, Rectangle rect, uint format) {
    var r = new Rect (rect);
    return DrawText (hDC, text, text.Length, ref r, format);
       }

Using the Code 使用的代码

With the above stuff ready, the rest is quite easy. You just need to gather the parameters and call the RenderText method, like the following code shows:

上面的东西准备好了,剩下的就很容易了。你只需要收集参数并调用RenderText方法,就像下面的代码显示:

private void panel1_Paint (object sender, PaintEventArgs e) {
   int size;
   if (Int32.TryParse (comboBox1.Text, out size) == false) {
   size = (int)SystemFonts.DefaultFont.Size;
   }
   RenderText (e.Graphics, textBox1.Text, textBox2.Text, 
   Color.Red, panel1.ClientRectangle, size);
   }

You can download the demo application and see how it works. The screen shot at the top of this tip shows an OpenType font LiheiPro is used to render some Chinese and Japanese fonts, which is impossible with the managed .NET API that calls GDI+.

你可以下载演示应用程序,看看它是如何工作的。本文章的顶部屏幕截图显示一个OpenType字体LiheiPro用于绘制一些中国和日本的字体,.托管的NET API 调用GDI+是不可能w完成的。

Points of Interest 兴趣点

The GDI methods can return error codes. However, our demo application just assumes everything will go well. You shall refer to the documentation on MSDN and see how to deal with them.

GDI方法可以返回错误代码。然而,我们演示的应用程序一切顺利。你要参考MSDN文档,看看如何处理它们。

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内