第22章TrueType矢量字体
本期教程跟大家讲解矢量字体的相关知识,矢量字体最大的好处就是可以任意放大或者缩小字体,而且字体的显示效果不失真。矢量字体的缺点就是不适合用在小型嵌入式系统中,极其消耗内存。
22. 1  XBF格式字体生成方法
22. 2 移植到开发板显示
22. 3 总结
22.1矢量字体介绍
下面的内容来自百度百科和wiki百科(两个内容居然一模一样),讲的非常好,特此转载过来。
目前主流的矢量字体格式有3种:Type1,TrueType和OpenType,这三种格式都是与平台无关的。
Type1全称PostScript Type1,是1985年由Adobe公司提出的一套矢量字体标准,由于这个标准是基于PostScript Description Language(PDL),而PDL又是高端打印机首选的打印描述语言,所以Type1迅速流行起来。但是Type1是非开放字体,Adobe对使用Type1的公司征收高额的使用费。
TrueType是1991年由Apple公司与Microsoft公司联合提出另一套矢量字标准。
Type1使用三次贝塞尔曲线来描述字形,TrueType则使用二次贝塞尔曲线来描述字形。所以Type1的字体比TrueType字体更加精确美观。一个误解是,Type1字体比TrueType字体占用空间多。这是因为同样描述一个圆形,二次贝塞尔曲线只需要8个关键点和7段二次曲线;而三次贝塞尔曲线则需要12个关键点和11段三次曲线。然而实际情况是一般来说 Type1比TrueType要小10%左右。这是因为对于稍微复杂的字形,为了保持平滑,TrueType必须使用更多的关键点。由于现代大部分打印机都是使用PDL作为打印描述语言,所以Type1字体打印的时候不会产生形变,速度快;而TrueType则需要翻译成PDL,由于曲线方程的变化,还会产生一定的形变,不如Type1美观。
这么说来,Type1应该比TrueType更具有优势,为什么如今的计算机上TrueType反而比Type1使用更广泛呢?这是因为第一:Type1由于字体方程的复杂,所以在屏幕上渲染的时候,花费的时间多,解决方案是大部分Type1字体嵌入了点阵字体,这样渲染快,但是边缘不光滑,比较难看。很多ps文档和ps 转换的pdf文档都是这样,在计算机上浏览的时候字体很难看,但是打印出来很美观。TrueType则渲染比较快,可以平滑的显示在屏幕上,看上去很美观。
第二个原因是Type1的高额使用费,使得Type1没有被所有的操作系统所支持。Windows家族只有OS/2和windows 2000及之后的版本从操作系统级别开始支持Type1。由于这个问题,Adobe只好在其所有的产品中嵌入Adobe Type Manager(ATM)作为渲染引擎。
OpenType则是Type1与TrueType之争的最终产物。1995年,Adobe公司和Microsoft公司开始联手开发一种兼容Type1和TrueType,并且真正支持Unicode的字体,后来在发布的时候,正式命名为
OpenType。OpenType可以嵌入Type1和TrueType,这样就兼有了二者的特点,无论是在屏幕上察看还是打印,质量都非常优秀。可以说OpenType是一个三赢的结局,无论是Adobe、Microsoft还是最终用户,都从OpenType中得到了好处。Windows家族从Windows 2000开始,正式支持OpenType。打开系统的字体目录(一般是C:\Windows\Fonts\或C:\Winnt\Fonts),可以看到:一个红A的图标的是点阵字体,两个重叠的T的图标是TrueType字体,一个O的图标就是OpenType字体。
矢量字体扩展名ttf。点阵字体的扩展名是fon.
下面是XP系统中字体的部分截图:
22.2STemWin对矢量字体的支持
TrueType为字体开发人员提供对在各种字体高度下字体显示方式的高度控制。与位图字体(基于每个字
符的位图)不同,TrueType字体基于矢量图形。矢量表示的优势在于无损的可扩展性。这意味着,每个字符在绘制前需要光栅化为位图。为避免每次绘制字符时都进行光栅化,通常用字体引擎缓存位图数据。这要求CPU速度快、RAM足够。发货时不含emWin TTF包。该项内容可在www.segger/link/emwin_freetype.zip下免费获得。
emWin对TTF支持的实施基于来自David Turner、Robert Wilhelm和Werner Lembergr的FreeType字体库,该库可在下免费获得。emWin对该库的使用符合GUI\TrueType\FTL. txt下的FreeType许可。emWin对该库进行了少许改编,添加了带有GUI函数的 “粘贴”层。
TrueType矢量字体的硬件要求如下:
CPU TTF支持仅适用于32位CPU。我们对32位CPU的定义为:sizeof(int)= 4。 ROM TTF引擎的ROM要求大约为250 K。确切大小取决于CPU、编译器以及编译
器的优化水平。
RAM 该库的RAM要求主要取决于使用的字体。TTF引擎的基本RAM要求大约为50 K。在使用GUI_TTF_CreateFont()创建GUI字体时,字体引擎会加载生成字符
所需的TTF文件中定义的所有字体表。不同字体之间的表大小有所差异。创建
字体额外要求的RAM量可能介于几个KB到1 MB以上之间。一般字体需要
80-300 kb。取决于使用的字体文件需要多少RAM。至少,TTF引擎需要位图
缓存。默认情况下,引擎使用200 K的缓存。足够大多数应用使用。TTF引擎
通过非emWin函数malloc()和free()分配内存。使用TTF引擎之前,必须确保
能够运行这些函数。
从SEGGER下载的矢量库主要有以下文件:
TrueType相关的文件还是很多的,这里只贴了部分源码。
22.3模拟器上面运行矢量字体
在emWin模拟器中,官方专门做了一个例子用于运行矢量字体,程序DEMO位置如下:
这个DEMO程序的代码如下:
#ifndef SKIP_TEST
#include <windows.h>
#include <stdio.h>
#include "GUI.h"
/*********************************************************************
*
*      Static data
*
**********************************************************************
*/
static unsigned    _aHeight  [] = {16, 20, 32, 48};  // Array of heights used to show text
static GUI_TTF_CS  _aCS      [GUI_COUNTOF(_aHeight)]; // Each GUI font needs its own GUI_TTF_CS structure static GUI_FONT    _aFont    [GUI_COUNTOF(_aHeight)]; // Array of GUI fonts
static char        _acFamily [200];
static char        _acStyle  [200];
/*********************************************************************
*
*      Static code
*
**********************************************************************
*/
/*********************************************************************
*
*      _ShowText
*/
static void _ShowText(void) {(1)
int i;
GUI_Clear();
i = 0;
GUI_TTF_GetFamilyName(&_aFont[i], _acFamily, sizeof(_acFamily));(2)
GUI_TTF_GetStyleName(&_aFont[i],  _acStyle,  sizeof(_acStyle));
GUI_SetFont(&GUI_Font20_1);
GUI_DispString(_acFamily);
GUI_DispString(", ");
GUI_DispString(_acStyle);
GUI_DispNextLine();
GUI_DrawHLine(GUI_GetDispPosY(), 0, 0xfff);
GUI_SetFont(&_aFont[i]);
GUI_DispString("abcdefghijklmnopqrstuvwxyz\n");
字体样式免费下载应用
GUI_DispString("ABCDEFGHIJKLMNOPQRSTUVWXYZ\n");
GUI_DispString("123456789.:,;(:*!?')\n");
GUI_DrawHLine(GUI_GetDispPosY(), 0, 0xfff);
for (i = 0; i < GUI_COUNTOF(_aHeight); i++) {
GUI_SetFont(&_aFont[i]);
GUI_DispString("The quick brown fox jumps over the lazy dog. 1234567890\n");
}
GUI_Delay(1000);
}
/*********************************************************************
*
*      _CreateFonts
*/
static int _CreateFonts(const U8 * pData, U32 NumBytes) {(3)
int i;
GUI_TTF_DATA TTF_Data;        // Only one GUI_TTF_DATA structure is used per font face
TTF_Data.pData    = pData;    // Set pointer to file data
TTF_Data.NumBytes = NumBytes; // Set size of file
for (i = 0; i < GUI_COUNTOF(_aHeight); i++) {
//
// Initialize GUI_TTF_CS members
//
_aCS[i].PixelHeight = _aHeight[i];
_aCS[i].pTTF        = &TTF_Data;
//
// Create GUI font
//
if (GUI_TTF_CreateFont(&_aFont[i], &_aCS[i])) {(4)
return 1;
}
}
return 0;
}
/*********************************************************************
*
*      _cbFontDemo
*
* Function description
*  The function uses the given pointer to a true type font for creating
*  a couple of GUI fonts and showing the outline of the TTF font.
*
* Parameters:
*  pData    - Location of font file
*  NumBytes - Size of font file
*/
static void _cbFontDemo(const U8 * pData, U32 NumBytes) {(5)
_CreateFonts(pData, NumBytes); // Create fonts
_ShowText();                  // Show some text
GUI_TTF_DestroyCache();        // Clear the TTF cache
}
/*********************************************************************
*
*      _IterateOverAllFiles
*
* Function description
*  The function iterates over all files of the given folder and the
*  given mask, reads the contents of the file and calls the function
*  pfDoSomething() with location and size of file data.
*  Can be used under Win32 environment only.
*/
static void _IterateOverAllFiles(const char * sFolder, const char * sMask, void (* pfDoSomething)(const U8 * pData, U32 NumBytes)) {(6)
GUI_RECT Rect = {0, 10, 1000, 1000};
char              acMask[_MAX_PATH];
char              acFile[_MAX_PATH];
WIN32_FIND_DATA  Context;
HANDLE            hFind;
HANDLE            hFile;
U8              * pData;
DWORD            NumBytes;
DWORD            NumBytesRead;
sprintf(acMask, "%s\\%s", sFolder, sMask);
hFind = FindFirstFile(acMask, &Context);
if (hFind != INVALID_HANDLE_VALUE) {
do {
sprintf(acFile, "%s\\%s", sFolder, Context.cFileName);
hFile = CreateFile(acFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);      if (hFile != INVALID_HANDLE_VALUE) {
NumBytes = GetFileSize(hFile, NULL);
pData = (U8 *)malloc(NumBytes);
ReadFile(hFile, pData, NumBytes, &NumBytesRead, NULL);
pfDoSomething(pData, NumBytes);
free(pData);
}
CloseHandle(hFile);
} while (FindNextFile(hFind, &Context));
}
}
/*********************************************************************
*
*      Public code
*
**********************************************************************
*/
/*********************************************************************
*
*      MainTask
*/
void MainTask(void) {
char acPath[200];

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。