第17章 文本和字体_17.1-17.2 简单文本输出、 字体的背景知识

17.1 简单文本输出

17.1.1 文本输出函数

(1)TextOut(hdc,xStart,yStart,pString,iCount)

  ①xStart和yStart使用的是逻辑坐标,TextOut并不以NULL来做字符串的结束,需指定字符的个数iCount的值

  ②SetTextAlign会改变xStart和yStart的含义


SetTextAlign


坐标值的含义


TA_LEFT


xStart:第一个字符的左侧坐标


TA_RIGHT


xStart:最后一个字符的右侧坐标


TA_CENTER


xStart:字符串正中间点的坐标


TA_TOP


yStart:所有字符的最高点,即所有字符在yStart的位置之下


TA_BOTTOM


yStart:所有字符都在yStart位置之上


TA_BASELINE


yStart:表示字符串在基线位置,即小写字母q或y下伸部分在基线之下。


TA_UPDATECP


1、忽略xStart和yStart,而是由如MoveToEx或LineTo等一些会改变当前坐标的函数指定的当前值。CP==Current Position?

2、此时TextOut函数也会改变坐标当前值,对于TA_LEFT,新坐标值在字符串结尾位置;对于TA_RIGHT,当前坐标值在新字符串开始位置;对于TA_CENTER,则仍在中间位置,不会改变。

(2)TabbedTextOut(hdc,xStart,yStart,pString,iCount,iNumTabs,piTabStops,xTabOrigin);

  ①当遇到字符串包含制表符(‘\t’或0x09)时,会被转成空白位置和个数由xTabOrign和piTabStops数组里元素共同决定。

  ②iNumTabs指定piTabStops中元素的个数

  ③piTabStops :TabStop位置的数组(逻辑单位),。表示每个制表符开始的位置,元素必须按升序存储。注意,元素表示的是个相对位置,即相对于xTagOrigin的位置偏移,比如元素元素分别为{40,80,120,160,200}表示第1个tab从xTagOrgin+40像素的地方开始输出,第2个从xTagOrgin+80,第3个从xTagOrgin+120开始输出,依此类推…

  ④如果iNumTabs值为0,且piTabStops值为NULL则制表符将会按平均字符宽度的8倍来扩展。

  ⑤iCount为-1时,遇\0自动结束。

  ★先依次输出字符串中的每个字符。遇到第n个\t时,从piTabStops数组依次比较,进而找到这个tab的开始位置(找到的元素索引为i。注意,i不一定等于n),就可以确定tab的位置为xTabOrigin+piTabStops[i]。如果在数组中找不到,就按默认的字符宽度的8倍,去计算出这个tab的位置。若这个tab位置前的字符不够时,则用空格补全。

【实例分析1】——xTabStop==0时(本例用系统等宽字符,每个字符的平均宽度为8像素)

  TCHAR szText[] = TEXT("abcdfg\thi\tjklmnopqrstuvwxyz\th");//3个\t

  TabbedTextOut(hdc,0, 0, szText, -1,0, NULL,0);//默认Tab位置是字符宽度的8倍。

  ①第1个Tab位为刻度8的位置(1*字符宽度的8倍),因刻度8之前只有6个字符,所以补充2个空格字符,然后输出hi两个字符,然后遇第2个Tab。

  ②第2个Tab为16(2*字符宽度的8倍)的位置(即刻度16)处开始,由于字符数不够,得再补充6个空格字符。然后输出jklmnopqrstuvwxyz,此时再遇第3个字符。

  ③第3个Tab开始的位置应为8的倍数,即8、16、24、32或40等,但因8、16、24、32处要么被字符占用,要么被以前的两个Tab占用,所以第3个Tab从40开始,然后输出h字符。

【实例分析2】——xTabStop==10*8时,即Tab位的原点在图中刻度10的位置。

  TCHAR szText[] = TEXT("abcdfg\thi\tjklmnopqrstuvwxyz\th");//3个\t

  TabbedTextOut(hdc,0, 0, szText, -1,0, NULL,10*8);//与上例唯一的不同,xTabStop

  ①第1个Tab位为10+8的位置(其中10为xTabStop,8与例一样),即上图中刻度的18开始,因刻度18之前只有6个字符,所以补充12个空格字符,然后输出hi两个字符,然后遇第2个Tab。

  ②第2个Tab为(10+16)的位置(其中10为xTabStop)处开始,由于字符数不够得再补充6个空格字符。然后输出jklmnopqrstuvwxyz,此时再遇第3个字符。

  ③第3个Tab开始的位置应为10+(8的倍数),即18、26、34、42或50等,但因8、18、26、34、42处要么被字符占用,要么被以前的两个Tab占用,所以第3个Tab从50开始,然后输出h字符。

【实例分析3】——讨论xTabStop==0时

  TCHAR szText[] = TEXT("abcdfg\thi\tjklmnopqrstuvwxyz\th");//3个\t

  int iTabStops[] = { 5 * 8, 6 * 8, 15 * 8, 30 * 8,45 * 8 };//每个字符宽度是8

//元素的含义表示Tab位在第5、6、15、30、45刻度处

  TabbedTextOut(hdc,0, 0, szText, -1,iLen, iTabStops,0);

  ①第1个Tab位为15的位置(iTabStops的第3个元素),即上图中刻度的15开始,

因为第1个元素5,但其位置己被字符f占用,第2个元素6,其位置己被g占用,所以第1个Tab从第3个元素,即刻度15的位置开始,因前面只有6个字符,得补9个空格。

  ②第2个Tab为刻度30的位置(即第4个元素)处开始,由于字符数不够得再补充13个空格字符。然后输出jklmnopqrstuvwxyz,此时再遇第3个字符。

  ③第3个Tab本应从刻度45开始,但被占用,而此时数组中的元素己经用尽,所以按默认的8的倍数,即刻度48的位置开始,所以补1个0,然后输出h。

【实例分析4】——讨论xTabStop==10*8时,即xTabStop从10的刻度开始

  TCHAR szText[] = TEXT("abcdfg\thi\tjklmnopqrstuvwxyz\th");//3个\t

  int iTabStops[] = { 5 * 8, 6 * 8, 15 * 8, 30 * 8, 45 * 8 };//每个字符宽度是8

 //元素的含义表示Tab位为xTabStop加5、6、15、30、45这些偏移开始

  TabbedTextOut(hdc,0, 0, szText, -1,iLen, iTabStops,10*8);

  ①第1个Tab位为10+5的位置(其中10为xTabStop,5为iTabStops的第1个元素),即上图中刻度的15开始,因a到g只有6个字符,得补9个空格。然后输出hi

  ②第2个Tab为10+15的位置(即第3个元素),而不是10+6(因为16位置被h占用),由于字符数不够得再补充8个空格字符。然后输出jklmnopqrstuvwxyz,此时再遇第3个字符。

  ③第3个Tab本应从刻度10+45开始(因为10+30被占用),所以补13个0,然后输出h。

(3)ExtTextOut(hdc,xStart,yStart,iOptions,&rect,pString,iCount,pxDistance);

  ①rect参数:当iOption==ETO_CLIPPED时,rect为剪切框;当iOption==ETO_OPAQUE时,rect为文本的背景框。这两个选项可以同时使用,也可以一个都不用。

  ②pxDistance是指向一个整型数组,指定了字符串中相邻字符间的像素间距。如果为NULL,则为默认字符间距。→可自由定制紧凑或宽松的字符间距。(注意:数组元素的个数要大于等于字符间隔的个数,即数组元素个数≥字符个数-1)。

(4)DrawText(hdc,pString,iCount,&rect,iFormat);

  ①iCount为-1时,自动计算字符串长度。

  ②iFormat


iForamt参数


含义


0


将以回车\r(或0x0D)及换行\n(或0x0A)分隔成多行文本。


DT_LEFT、

DT_RIGHT、

DT_CENTER

DT_VCENTER等


文本对齐标志


DT_SINGLELINE


单行文本,此时回车换行符无效。


DT_WORDBREAK


在临近边框的两个单词中换行


DT_EXTERNALLEADING


多行文本时,字符高度不含字体的外部间距,如果希望行间距包括这个外部间距,就要使用该标志。


DT_EXPANDTABS


默认两个制表位之间为八个字符宽度

17.1.2  文本的设备环境属性

(1)SetTextColor(hdc,rgbColor)或GetTextColor(hdc);//设置或获取文字颜色

(2)SetBkMode(hdc,iMode);设置背景模式:OPAQUE时表示不透明;TRANSPARENT(透明)

★当为TRANSPARENT时,会用背景色给虚线或点划线中间的空白部分着色。

(3)SetBkColor(hdc,rgbColor)//设置背景颜色

  ★调用当前系统颜色设定文本颜色或背景

SetTextColor(hdc,GetSysColor(COLOR_WINDOWTEXT));

SetBkColor(hdc,GetSysColor(COLOR_WINDOW));

★响应WM_SYSCOLORCHANGE消息:——随系统颜色的更改自动更改文本和背景色。

Case WM_SYSCOLORCHANGE:InvalidateRect(hwnd,NULL,TRUE);break;

(4)SetTextCharacterExtra(hdc,iExtra);——字符间距,默认为0,否则为iExtra

①iExtra为负数时,会被自动取绝对值,所以不能利用该函数让字符紧缩一点。

②iExtra是个逻辑单位。可以通过GetTextCharacterExtra取得当前字符间距。

17.1.3 使用库存字体

(1)获取特定库存字体:hFont= GetStockObject(iFont);//iFont为系统预定义标识符

(2)选入设置环境SelectObject(hdc,hFont);

(3)利用GetTextMetrics函数获取当前字体信息。

【TabbedTextOut程序】

#include "stdafx.h"
#include "TabbedTextOut.h"

#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst;                                // 当前实例
TCHAR szTitle[MAX_LOADSTRING];                  // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名
// 此代码模块中包含的函数的前向声明:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                       _In_opt_ HINSTANCE hPrevInstance,
                       _In_ LPTSTR    lpCmdLine,
                       _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    // TODO:  在此放置代码。
    MSG msg;
    HACCEL hAccelTable;
    // 初始化全局字符串
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_TABBEDTEXTOUT, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);
    // 执行应用程序初始化:
    if (!InitInstance(hInstance, nCmdShow))
    {
        return FALSE;
    }
    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TABBEDTEXTOUT));
    // 主消息循环:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return (int)msg.wParam;
}
//
//  函数:  MyRegisterClass()
//
//  目的:  注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDC_TABBEDTEXTOUT));
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = NULL;//MAKEINTRESOURCE(IDC_TEST);
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    return RegisterClassEx(&wcex);
}
//
//   函数:  InitInstance(HINSTANCE, int)
//
//   目的:  保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;
    hInst = hInstance; // 将实例句柄存储在全局变量中
    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    if (!hWnd)
    {
        return FALSE;
    }
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    return TRUE;
}
//
//  函数:  WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    处理主窗口的消息。
//
//  WM_COMMAND  - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY  - 发送退出消息并返回
//
//
int iTabStops[] = { 5 * 8, 6 * 8, 15 * 8, 30 * 8, 45 * 8 };
int iLen = sizeof(iTabStops) / sizeof(iTabStops[0]);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    RECT rc;
    TEXTMETRIC tm;
    int yPos = 50;
    TCHAR szBuf[50];
    int k = 0;
    static int cxClient, cyClient;
    static TCHAR szText[] = TEXT("abcdfg\thi\tjklmnopqrstuvwxyz\th");
    switch (message)
    {
    case WM_CREATE:
        break;
    case WM_COMMAND:
        wmId = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // 分析菜单选择:
        switch (wmId)
        {

        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
        GetTextMetrics(hdc, &tm);
        GetClientRect(hWnd, &rc);
        //画刻度尺
        MoveToEx(hdc, 0, yPos, NULL);
        LineTo(hdc, rc.right, yPos);
        SetTextAlign(hdc, TA_CENTER);
        for (k = 0; k < 300; k++)
        {
            MoveToEx(hdc, k*tm.tmAveCharWidth, yPos, NULL);
            LineTo(hdc, k*tm.tmAveCharWidth, yPos + 10);
            if (k % 5 == 0)
            {
                TextOut(hdc, k*tm.tmAveCharWidth, yPos + 20, szBuf, wsprintf(szBuf, TEXT("%d"), k));
            }
        }
        for (k = 0; k < 300; k++)
        {
            MoveToEx(hdc, 10 * k*tm.tmAveCharWidth, yPos, NULL);
            LineTo(hdc, 10 * k*tm.tmAveCharWidth, yPos + 20);
            if ((k % 5) == 0)
            {
                MoveToEx(hdc, k*tm.tmAveCharWidth, yPos, NULL);
                LineTo(hdc, k*tm.tmAveCharWidth, yPos + 16);
            }
            SetBkMode(hdc, TRANSPARENT);
            SetTextAlign(hdc, TA_LEFT);
            //TextOut(hdc, cxClient / 2, cyClient / 2, szText, lstrlen(szText));
            //TabbedTextOut(hdc, 0, yPos - tm.tmHeight, szText, -1, 0, 0, 0);
            TabbedTextOut(hdc, 0, yPos - tm.tmHeight, szText, -1, iLen, iTabStops, 10 * 8);
            EndPaint(hWnd, &ps);
            break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
        }
    }
    return 0;
}

第17章 文本和字体_17.2 字体的背景知识

17.2 字体的背景知识

17.2.1 GDI字体分类

(1)点阵字体RasterFont(也称为位图字体)——不可缩放,但显示速度极快


字样名称


用途


System


用于SYSTEM_FONT字体


FixedSys


用于SYSTEM_FIXED_FONT字体


Terminal


用于OEM_FIXED_FONT字体


Courier


等宽的


MS Serif


MS Sans Serif


用于DEFAULT_GUI_FONT


Small Fonts

(2)笔画字体(StrokeFont)——有时也称为绘图仪字体

①由一系列的点和连接点的线段组成,可缩放

②当字号很小时,文本不清晰,很大时,笔画是单线条的,显得单薄。

③笔画字体的字样名称有:Modern、Roman、Script

17.2.2 TrueType字体


字样名称


字样名称


Courier New


Times New Roman Bold Italic


Courier New Bold


Arial


Courier New Italic


Arial Bold


Courier New Bold Italic


Arial Italic


Times New Roman


Arial Bold Italic


Times New Roman Bold


Symbol


Times New Roman Italic

17.2.3 属性和样式的区别

(1)TrueType字体中,粗体、斜体的Courier、Times New Roman和Arial都有单独的名称,是独立的字体。

(2)但是一般认为粗体或斜体只是同一种字体的不同属性,而不是不同的字体。Windows并没有完全解决这一问题。也就是设置斜体或粗体时即可以用属性,也可以用字样名称。从而也导致了在枚举系统可用字体列表时,必须要进行双重处理,增加了难度。

17.2.4 行间距和字间距

(1)点值(磅):1磅 =1/72英寸。

10磅字号:指“bq”的完整高度(不含字母上的重音符号),即=tmHeight –tmInternalLeading;

(2)行间距示意图

17.2.5 逻辑英寸问题

(1)逻辑英寸:定义显示器上96个或120个像素占据的距离为一个“逻辑英寸”

(2)使用特定点(磅)值显示文本的方法——“逻辑缇”(每个逻辑单位为1/1440英寸)

SetMapMode(hdc,MM_ANSIOTROPIC);

SetWindowExtEx(hdc,1440,1440,NULL); //表示1440个单位到对应1逻辑英寸,即

//1个逻辑单位为1/1440英寸。

SetViewportExt(hdc,GetDeviceCaps(hdc,LOGPIXELSX),  //1逻辑英寸

GetDeviceCaps(hdc,LOGPIXELSX),NULL)://1逻辑英寸

如12磅的字体 =12*1/72(英寸)=1440*12/72(逻辑单位)=240逻辑单位。即点值的20倍

时间: 2024-10-03 02:44:51

第17章 文本和字体_17.1-17.2 简单文本输出、 字体的背景知识的相关文章

第17章 string基本字符序列容器

/* 第17章 string基本字符序列容器 17.1 string技术原理 17.2 string应用基础 17.3 本章小结 */ // 第17章 string基本字符序列容器 // 17.1 string技术原理 -------------------------------------------------------------------------------------- // 17.2 string应用基础 ----------------------------------

第17章 文本和字体_17.3 逻辑字体

17.3 逻辑字体 17.3.1 逻辑字体的创建和选择 (1)创建逻辑字体 hFont= CreateFontIndirect(&lf); //其中LOGFONT为结构体 (2)SelectObject(hdc,hFont); //选入并匹配字体或使用从ChooseFont中选择的字体 (3)返回选入设备环境的字体信息: ①GetTextFace(hdc,sizeof(szFaceName)/sizeof(TCHAR),szFaceName);//返回字样名称 ②GetTextMetrics(h

CSS3秘笈第三版涵盖HTML5学习笔记13~17章

第13章,构建基于浮动的布局 使用的是float(浮动)属性 注:float:none值将取消所有浮动,通常只用来取消元素中已经应用的浮动. 切记:不需要给正文的div设计宽度,即使设计成固定宽度也不用 用浮动进行布局 LayoutGala网站(http://blog.html.it/layoutgala/)上提供了40种不同的CSS设计,但大多只是基本框架,里面只有<div>标签及其定位用的CSS代码 布局生成器,Cridinator(http://gridinator.com)提供了简单的

JavaScript高级程序设计(第三版)学习笔记11、12、17章

第11章, DOM扩展 选择符 API Selector API Level1核心方法querySelector .querySelectorAll,兼容的浏览器可以使用 Document,Element 实例调用它们,支持浏览器:IE8+,Firefox3.5+,Safari3.1+,chrome,Opera10+ querySelector方法 接收一个 CSS选择符,返回与该模式匹配的第一个元素 通过 Document类型调用该函数,会在文档范围查找匹配元素,通过 Element类型调用该

第17章 CSS边框与背景(上)

第 17章 CSS边框和背景[上]学习要点:1.声明边框2.边框样式3.圆角边框 本章主要探讨 HTML5中 CSS边框和背景,通过边框和背景的样式设置,给元素增加更丰富的外观.一.声明边框边框的声明有三个属性设置,样式表如下:属性 值 说明 CSS版本border-width 长度值 设置边框的宽度,可选 1border-style 样式名称 设置边框的样式,必选 1border-color 颜色值 设置边框的颜色,可选 1 这三个属性值,只有 border-style是必须声明,才可以出现边

4.13日第12次作业,16章外包,17章需求,19章组织级与大型项目

29-高项-田哲琦 16章.外包管理 1.外包的形式有哪五种?什么是利益关系?P346-348 答:企业现行采用的主要外包形式如下: 1).活动外包 2).服务外包 3).内包 4).合包 5).利益关系. 利益关系(benfit-based relationship),这是一种长期合作关系,双方先为此关系进行投资,再根据预先拟定的协议分享利益,共同承担风险,同时共享利益. 2.外包管理的目标是什么?要实现这个目标,对外包管理提出哪四个方面的要求?P348 答:软件外包管理总的目标是用强有力的手

《构建之法》13,14,15,16,17章读后感

1.13章说的是软件测试,怎么样去测试是最有效率的? 2.14章说到质量保障,具体的花费是多少? 3.15章说到ZBB,如果一个软件遇到了不可修复的bug,还算是一个稳定的软件么? 4.16章说到创新,有实际例子吗? 5.17章的职业道德指的是什么?

C++ Primer Plus 第17章 输入,输出和文件

第17章 输入.输出和文件 1.当到达输入语句时,他将刷新输出缓冲区中当前所有的输出 2.streambuf类 提供了对缓冲区的各种操作 ios_base类表示流的一般特征 ios类基于ios_base,包含了一个指向streambuf对象的指针 ostream类从ios派生,提供可输出方法 istream类从ios派生,提供可输入方法 iostream类基于ostream和istream,继承了输入和输出方法 3.包含iostream则自动创建了8个流对象 cin 标准输入 wcin 宽字符流

《Cracking the Coding Interview》——第17章:普通题——题目13

2014-04-29 00:15 题目:将二叉搜索树展开成一个双向链表,要求这个链表仍是有序的,而且不能另外分配对象,就地完成. 解法:Leetcode上也有,递归解法. 代码: 1 // 17.13 Flatten a binary search tree into a doubly linked list by inorder traversal order. 2 // Use postorder traversal to do the flattening job. 3 #include