第17章 文本和字体_17.6 一些有趣和新奇的内容

 17.6 一些有趣和新奇的内容

17.6.1 GDI路径

(1)路径的创建

  BeginPath(hdc);

        //1、使用任何绘制线的函数在DC上绘制,被存在GDI内部,但不显示出来。

        //2、可以在当前路径中创建一个新的子路径,其中每个子路径都是一系列互相连接的线。

        //3、每个子路径可以是闭合的,也可以是开放的。要闭合子路径时,可以用CloseFigure将子路径闭合,必要时会自动添加一条直线以达到些目的。其后用任何画线函数创建的都是新的子路径。

  EndPath(hdc);

(2)五个与路径有关的函数(注意:下面的函数在用完之后,都会删除被定义的路径!

  ①StokePath(hdc):用当前画笔来绘制出路径出来。

  ②FillPath(hdc):用当前画刷,根据当前的多边形填充模式填充,会先闭合开放的路径。

  ③StrokeAndFillPath(hdc):一次性完成StrokePath和FillPath的功能。

  ④hRgn = PathToRegion(hdc);将路径转换成区域,会先闭合开放的路径。

  ⑤SelectClipPath(hdc,iCombine): 选择当前的路径作为设备环境的一个裁剪区域。

                                                       其中的iCombine指明的路径与当前的裁剪区域如何合并。

(3)路径:对填充与裁剪来说,路径比区域更灵活,因为区域只能由矩形、椭圆和多组合组合来定义,但路径可用包括贝塞尔曲线或弧线定义。

(4)在GDI中,路径和区域的存储截然不同,路径是由一个直线和曲线定义的集合,而区域是一个扫描线的集合。

17.6.2 扩展画笔:hPen = ExtCreatePen(dwStyle, dwWidth,&lplb,0,NULL);

参数

含义

DWORD dwStyle

画笔的类型。与CreatePen函数的画笔类型一样,此外,还可以使用

1、画笔类型:PS_GEOMETRIC、PS_COSMETIC等类型。

2、线端点样式:

  ①PS_ENDCAP_ROUND:圆形

②PS_ENDCAP_SQUARE:方形,线的长度向外延伸了出宽度的一半。

③PS_ENDCAP_FLAT:平面样式

3、线与线连接点的样式

  ①PS_JOIN_ROUND:圆形

②PS_JOIN_BEVEL:斜截,将连接点的末端切断

③PS_JOIN_MITER:斜接,连接点是个尖端。

DWORD dwWidth

画笔的宽度。PS_COSMETIC宽度必须是1。

LOGBRUSH* lplb

画笔的属性。在CreatePen中,该参数是颜色。但扩展画笔函数中,这个参数是画刷,可能为PS_GEOMETRIC样式的内部着色。这个画笔甚至可以是点阵位图。

DWORD dwStyleCount

自定义样式数组的元素个数

DWORD *lpStyle

自定义的样式数组

 【EndJoin程序】

第17章 文本和字体_17.6 一些有趣和新奇的内容

第一个V:端点、连接点都为圆形;
第二个V:端点方形、连接点斜截 ;
第三个V:端点平面、连接点斜接; 

/*------------------------------------------------------------
ENDJOIN.C -- Ends and Joins Demo
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("EndJoin");
    HWND         hwnd;
    MSG          msg;
    WNDCLASSEX     wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.cbSize = sizeof(WNDCLASSEX);
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(hInstance, szAppName);
    wndclass.hIconSm = LoadIcon(hInstance, szAppName);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClassEx(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
                   szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName,                  // window class name
                        TEXT("Ends and Joins Demo"), // window caption
                        WS_OVERLAPPEDWINDOW,        // window style
                        CW_USEDEFAULT,              // initial x position
                        CW_USEDEFAULT,              // initial y position
                        CW_USEDEFAULT,              // initial x size
                        CW_USEDEFAULT,              // initial y size
                        NULL,                       // parent window handle
                        NULL,                       // window menu handle
                        hInstance,                  // program instance handle
                        NULL);                     // creation parameters

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int iEnd[] = { PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE, PS_ENDCAP_FLAT };
    static int iJoin[] = { PS_JOIN_ROUND, PS_JOIN_BEVEL, PS_JOIN_MITER };
    static int cxClient, cyClient;
    HDC         hdc;
    PAINTSTRUCT ps;
    static LOGBRUSH    lb;

    switch (message)
    {
    case WM_CREATE:
        lb.lbStyle = BS_SOLID;
        lb.lbColor = RGB(128, 128, 128);
        lb.lbHatch = 0;
        return 0;
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = LOWORD(lParam);
        return 0;
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        SetMapMode(hdc, MM_ANISOTROPIC);
        SetWindowExtEx(hdc, 100, 100, NULL);
        SetViewportExtEx(hdc, cxClient, cyClient, NULL);
        for (int i = 0; i < 3; i++)
        {
            SelectObject(hdc, ExtCreatePen(PS_SOLID | PS_GEOMETRIC |
                iEnd[i] | iJoin[i], 10, &lb, 0, NULL));
            BeginPath(hdc);
            //用扩展画笔画出来。
            MoveToEx(hdc, 10 + 30 * i, 25, NULL);
            LineTo(hdc, 20 + 30 * i, 75);
            LineTo(hdc, 30 + 30 * i, 25);
            EndPath(hdc);
            StrokePath(hdc);
            DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));

            //写宽度为1为画笔写出3个V
            MoveToEx(hdc, 10 + 30 * i, 25, NULL);
            LineTo(hdc, 20 + 30 * i, 75);
            LineTo(hdc, 30 + 30 * i, 25);

        }

        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

17.6.3 四个范例程序

(1)FontOut1程序

   ①定义路径:

    BeginPath(hdc);

    TextOut(…); //此处是在定义的路径,并不会在GDI中立即显示出来

    EndPath(hdc)

  ②StrokePath(hdc); //用当前画笔描边路径

  ③默认的文本背景模式是OPAQUE,所以文本框和字符轮廓都是路径的一部分。

【FontOut1程序】

 第17章 文本和字体_17.6 一些有趣和新奇的内容

/*------------------------------------------------
FONTOUT1 —— Using Path to Outline Font
(c) Charles Petzold,1998
-------------------------------------------------*/
#include <windows.h>
#include "EzFont.h"
TCHAR szAppName[] = TEXT("FontOut1");
TCHAR szTitle[] = TEXT("FontOut1:Using Path to Outline Font");
void PaintRoutine(HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
    static TCHAR szString[] = TEXT("Outline");
    HFONT  hFont;
    SIZE  size;
    //创建144磅的字体
    hFont = EzCreateFont(hdc, TEXT("Times New Roman"), 1440, 0, 0, TRUE);
    SelectObject(hdc, hFont);

    GetTextExtentPoint32(hdc, szString, lstrlen(szString), &size);
    //开始绘制路径,但保存在GDI内部,并不在DC上显示出来
    BeginPath(hdc);

    //在中间位置显示出来
    //注意:输出文本包含两个部分,1个是文本框,一个是字符部分,所有在默认的SetBkMode(OPAQUE)模式
    //下,文本框的边框也会被当成一条路径来画,因此该示例用画笔描边路径后会有一个边框,也就是
    //文本框的轮廓也得了路径的一部分。
    TextOut(hdc, (cxArea - size.cx) / 2, (cyArea - size.cy) / 2, szString, lstrlen(szString));
    EndPath(hdc);
    StrokePath(hdc);  //用当前画笔描边路径
    SelectObject(hdc, GetStockObject(SYSTEM_FONT));
    DeleteObject(hFont);
}

//FontTest.c

/*------------------------------------------------------------
FONTTEST.C -- Test of FONT
(c) Charles Petzold, 1998
------------------------------------------------------------*/
#include <windows.h>
#include "EzFont.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
extern TCHAR szAppName[];
extern TCHAR szTitle[];
void PaintRoutine(HWND hwnd, HDC hdc, int cxArea, int cyArea);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    HWND         hwnd;
    MSG          msg;
    WNDCLASSEX     wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.cbSize = sizeof(WNDCLASSEX);
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(hInstance, szAppName);
    wndclass.hIconSm = LoadIcon(hInstance, szAppName);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClassEx(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
                   szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName,                  // window class name
                        szTitle, // window caption
                        WS_OVERLAPPEDWINDOW,        // window style
                        CW_USEDEFAULT,              // initial x position
                        CW_USEDEFAULT,              // initial y position
                        CW_USEDEFAULT,              // initial x size
                        CW_USEDEFAULT,              // initial y size
                        NULL,                       // parent window handle
                        NULL,                       // window menu handle
                        hInstance,                  // program instance handle
                        NULL);                     // creation parameters

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC         hdc;
    PAINTSTRUCT ps;
    static int cxClient, cyClient;

    switch (message)
    {
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        return 0;
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        PaintRoutine(hwnd, hdc, cxClient, cyClient);
        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

//EzFont.h

/*----------------------------------------------------------
EZFONT.H  header file
------------------------------------------------------------*/
#pragma  once 
#include <windows.h>
//iDeciPtHeight:字体高度:(单位1/10磅)如,12磅字体时,iDeciPtHeight=120
//iDecPtWidth:字体宽度(与上面单位一样)
//iAttributes:字体属性,如粗、斜、下划线、删除线等
//fLogRes:是否使用逻辑分辨率
HFONT EzCreateFont(HDC hdc, TCHAR* szFaceName, int iDeciPtHeight,
                   int iDeciPtWidth, int iAttributes, BOOL fLogRes);
#define EZ_ATTR_BOLD        1
#define EZ_ATTR_ITATIC      2
#define EZ_ATTR_UNDERLINE   4
#define Ez_ATTR_STRIKEOUT   8

//EzFont.c

/*-------------------------------------------------------------
EZFONT.C -- Easy Font Creation
(c) Charles Petzold, 1998
-------------------------------------------------------------*/
#include <windows.h>
#include <math.h>
#include "EzFont.h"
HFONT EzCreateFont(HDC hdc, TCHAR* szFaceName, int iDeciPtHeight,
                   int iDeciPtWidth, int iAttributes, BOOL fLogRes)
{
    HFONT hFont;
    LOGFONT lf;
    TEXTMETRIC tm;
    FLOAT  cxDpi, cyDpi;
    POINT pt;
    SaveDC(hdc);
    //设置高级图形模式,此模式下可以通过矩阵实现逻辑坐标到设备坐标的转换。
    SetGraphicsMode(hdc, GM_ADVANCED);
    ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); //恢复变换到初始状态
    SetViewportOrgEx(hdc, 0, 0, NULL);
    SetWindowOrgEx(hdc, 0, 0, NULL);
    if (fLogRes)
    {
        //使用逻辑分辨率(单位:像素/英寸)
        cxDpi = (FLOAT)GetDeviceCaps(hdc, LOGPIXELSX);
        cyDpi = (FLOAT)GetDeviceCaps(hdc, LOGPIXELSY);
    } else
    {
        //实际的分辨率(单位:像素/英寸)
        cxDpi = (FLOAT)(25.4 * GetDeviceCaps(hdc, HORZRES) /
                        GetDeviceCaps(hdc, HORZSIZE));
        cyDpi = (FLOAT)(25.4 * GetDeviceCaps(hdc, VERTRES) /
                        GetDeviceCaps(hdc, VERTSIZE));  //vertsize单位为mm
    }
    //求出指定磅值的字体,需要多少像素点
    pt.x = (int)(iDeciPtWidth* cxDpi / 72);  //像素大小(设备单位)
    pt.y = (int)(iDeciPtHeight* cyDpi / 72); //像素大小(设备单位)
    DPtoLP(hdc, &pt, 1); //将像素大小由设备单位转为逻辑单位,也就是字体在逻辑坐标系中的大小
    lf.lfHeight = -(int)(fabs(pt.y) / 10.0 + 0.5); //加0.5是为了向上取整
    lf.lfWidth = 0; //注意这里要先设0,因为系统根据lfHeight匹配字体,会得到其固有的width
    //而iDeciPtWidth会因高级图形模式允许对字体进行拉伸和缩放。
    lf.lfEscapement = 0;
    lf.lfOrientation = 0;
    lf.lfWeight = iAttributes & EZ_ATTR_BOLD ? 700 : 0;
    lf.lfItalic = iAttributes & EZ_ATTR_ITATIC ? 1 : 0;
    lf.lfUnderline = iAttributes& EZ_ATTR_UNDERLINE ? 1 : 0;
    lf.lfStrikeOut = iAttributes& Ez_ATTR_STRIKEOUT ? 1 : 0;
    lf.lfCharSet = DEFAULT_CHARSET; //默认字符集
    lf.lfOutPrecision = 0;
    lf.lfClipPrecision = 0;
    lf.lfQuality = 0;
    lf.lfPitchAndFamily = 0;

    lstrcpy(lf.lfFaceName, szFaceName);
    hFont = CreateFontIndirect(&lf);
    if (iDeciPtWidth != 0)
    {
        hFont = (HFONT)SelectObject(hdc, hFont); //选入,并返回旧字体
        GetTextMetrics(hdc, &tm); //获取新字体信息
        DeleteObject(SelectObject(hdc, hFont));//将旧的选入,交并删除新的字体
        //字体的被左右拉伸,能这样实现的前提是设为高级图形模式,即SetGraphicsMode(hdc, GM_ADVANCED);
        lf.lfWidth = (int)(tm.tmAveCharWidth*fabs(pt.x) / fabs(pt.y) + 0.5);
        hFont = CreateFontIndirect(&lf);
    }
    RestoreDC(hdc, -1);
    return hFont;
}

(2)FontOut2程序

  ①使用ExCreatePen创建的画笔,而不是默认的画笔来描边路径

  ②本例创建一个宽3 个像素(1/24英寸)的红色虚线画笔

  ③也可以给路径填充颜色或图案(用FillPath或StrokeAndFillPath函数)

【FontOut2程序】

 第17章 文本和字体_17.6 一些有趣和新奇的内容

/*------------------------------------------------
FONTOUT2 —— Using Path to Outline Font
(c) Charles Petzold,1998
-------------------------------------------------*/
#include <windows.h>
#include "..\FontOut1\EzFont.h"
TCHAR szAppName[] = TEXT("FontOut2");
TCHAR szTitle[] = TEXT("FontOut2:Using Path to Outline Font");
void PaintRoutine(HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
    static TCHAR szString[] = TEXT("Outline");
    HFONT  hFont;
    SIZE  size;
    LOGBRUSH lb;
    //创建144磅的字体
    hFont = EzCreateFont(hdc, TEXT("Times New Roman"), 1440, 0, 0, TRUE);
    SelectObject(hdc, hFont);
    SetBkMode(hdc, TRANSPARENT);  //设置为透明背景,则文本框(含轮廓线将不被创建)
    GetTextExtentPoint32(hdc, szString, lstrlen(szString), &size);
    //开始绘制路径,但保存在GDI内部,并不在DC上显示出来
    BeginPath(hdc);

    //在中间位置显示出来
    //注意:本例SetBkMode(hdc,TRANSPARENT)为透明模式,所以只有字符的轮廓,而没有文本框的轮廓
    TextOut(hdc, (cxArea - size.cx) / 2, (cyArea - size.cy) / 2, szString, lstrlen(szString));
    EndPath(hdc);
    lb.lbColor = RGB(255, 0, 0);
    lb.lbStyle = BS_SOLID;
    lb.lbHatch = 0;
    SelectObject(hdc, ExtCreatePen(PS_GEOMETRIC | PS_DOT,
        GetDeviceCaps(hdc, LOGPIXELSY) / 24, &lb, 0, NULL));  //创建3像素的点线
    StrokePath(hdc);  //用当前画笔描边路径
    DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));
    SelectObject(hdc, GetStockObject(SYSTEM_FONT));
    DeleteObject(hFont);
}

  //EzFont.h、EzFont.c、FontTest.c与本节中的FontOut1程序相同。

(3)FillFont程序

  ①使用默认画笔绘制路径轮廓,用HS_DIAGCROSS样式创建红色阴影线填充

  ②创建路径时,设置背影为TRANSPARENT。即路径只保存字符的轮廓,不保留文本框的轮廓。

  ③描边并填充路径时,使用OPAQUE模式,因为路径内部的区域,其要用阴影线填充。

  ④注意:当路径转为区域时,会根据将路径包围的范围,划分成若干个区域。如本例中当绘制路径并设置为OPAQUE里,整个文本框内部并被文字划分成若干个区域,若干个区域的并集就是文本框的大小。所以当本例中第1个SetBkMode被注释掉,也就是默认的OPAQUE时,则填充区域视多边形的填充模式而定,如果设为WINDING模式,则填充整个文本框,若设为ALTERNATE,则填充文本框内部除去字符以外的部分。
【FillFont程序】

 第17章 文本和字体_17.6 一些有趣和新奇的内容

/*------------------------------------------------
FONTFILL —— Using Path to Fill Font
(c) Charles Petzold,1998
-------------------------------------------------*/
#include <windows.h>
#include "..\FontOut1\EzFont.h"

TCHAR szAppName[] = TEXT("FontOut2");
TCHAR szTitle[] = TEXT("FontOut2:Using Path to Outline Font");
void PaintRoutine(HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
    static TCHAR szString[] = TEXT("FillFont");
    HFONT  hFont;
    SIZE  size;
    //创建144磅的字体
    hFont = EzCreateFont(hdc, TEXT("Times New Roman"), 1440, 0, 0, TRUE);
    SelectObject(hdc, hFont);
    //设置为透明背景,则文本框(含轮廓线将不被创建)
    SetBkMode(hdc, TRANSPARENT);  //如果该句被注释掉,则路径中包含文本框和字符轮廓
    GetTextExtentPoint32(hdc, szString, lstrlen(szString), &size);
    //开始绘制路径,但保存在GDI内部,并不在DC上显示出来
    BeginPath(hdc);

    //在中间位置显示出来
    //注意:本例SetBkMode(hdc,TRANSPARENT)为透明模式,所以只有字符的轮廓,而没有文本框的轮廓
    TextOut(hdc, (cxArea - size.cx) / 2, (cyArea - size.cy) / 2, szString, lstrlen(szString));
    EndPath(hdc);
    //创建带阴影线的画刷
    SelectObject(hdc, CreateHatchBrush(HS_DIAGCROSS, RGB(255, 0, 0)));
    SetBkMode(hdc, OPAQUE);
    //SetPolyFillMode(hdc, WINDING);  //默认的填充模式为ALTERNATE(交替)填充
    //当第1个SetBkMode为OPAQUE,而此处为WINDING
    //时,会填充整个文本框(含字符内部),如果
    //为ALTERNATE,则填充文本框内部除(字符的部分)
    //当第1个SetBkMode为TRANSPARENT时,不管此处为
    //WINDING还是ALTERNATE,则只填充字体内部区域。
    StrokeAndFillPath(hdc);  //用默认画笔描边,并用刚创建的画刷填充路径。
    DeleteObject(SelectObject(hdc, GetStockObject(WHITE_BRUSH)));
    SelectObject(hdc, GetStockObject(SYSTEM_FONT));
    DeleteObject(hFont);
}
   //EzFont.h、EzFont.c、FontTest.c与本节中的FontOut1程序相同。

(4)FontClip程序

   ①先用TextOut画出路径,再将路径通过SelectClipPath设为裁剪区域

   ②如果绘制路径时,将SetBkMode设为TRANSPARENT,则区域为字体轮廓的内部。如果设为OPAQUE,则区域为整个文本框。
【FontClip程序】

 第17章 文本和字体_17.6 一些有趣和新奇的内容

/*------------------------------------------------
FONTCLIP —— Using Path for Clipping on Font
(c) Charles Petzold,1998
-------------------------------------------------*/
#include <windows.h>
#include "..\FontOut1\EzFont.h"

TCHAR szAppName[] = TEXT("FontClip");
TCHAR szTitle[] = TEXT("FontClip:Using Path for Clipping on Font");
void PaintRoutine(HWND hwnd, HDC hdc, int cxArea, int cyArea)
{
    static TCHAR szString[] = TEXT("FillClip");
    HFONT  hFont;
    SIZE  size;
    int y, iOffset;
    POINT pt[4];
    //创建120磅的字体
    hFont = EzCreateFont(hdc, TEXT("Times New Roman"), 1200, 0, 0, TRUE);
    SelectObject(hdc, hFont);
    //设置为透明背景,则文本框(含轮廓线将不被创建)
    //SetBkMode(hdc,TRANSPARENT);  //如果该句被注释掉,则路径中包含文本框和字符轮廓
    GetTextExtentPoint32(hdc, szString, lstrlen(szString), &size);
    //开始绘制路径,但保存在GDI内部,并不在DC上显示出来
    BeginPath(hdc);

    //在中间位置显示出来
    //注意:本例SetBkMode(hdc,TRANSPARENT)为透明模式,所以只有字符的轮廓,而没有文本框的轮廓
    TextOut(hdc, (cxArea - size.cx) / 2, (cyArea - size.cy) / 2, szString, lstrlen(szString));
    EndPath(hdc);
    //将路径设为裁剪区域
    //SetPolyFillMode(hdc, WINDING);  
    SelectClipPath(hdc, RGN_COPY);  //1、如果SetBkMode(OPAQUE),当WINDING模式时,则整个文本框为裁剪区域
    //设为ALTERNATE时,则文本框除文字部分以外的区域为裁剪区域
    //2、如果SetBkMode(TRANSPARENT),不管是ALTERNATE或WINDING模式,
    //裁剪区域均为字符内部的区域。(与上面FontFill程序的原理是一样的。)
    //绘制Bezier样条线
    iOffset = (cxArea + cyArea) / 4;
    for (y = -iOffset; y < cyArea + iOffset; y++)
    {
        pt[0].x = 0;
        pt[0].y = y;
        pt[1].x = cxArea / 3;
        pt[1].y = y + iOffset;
        pt[2].x = 2 * cxArea / 3;
        pt[2].y = y - iOffset;
        pt[3].x = cxArea;
        pt[3].y = y;
        SelectObject(hdc, CreatePen(PS_SOLID, 1, RGB(rand() % 256, rand() % 256, rand() % 256)));
        PolyBezier(hdc, pt, 4);
        DeleteObject(SelectObject(hdc, GetStockObject(BLACK_PEN)));
    }
    SelectObject(hdc, GetStockObject(SYSTEM_FONT));
    DeleteObject(hFont);
}

   //EzFont.h、EzFont.c、FontTest.c与本节中的FontOut1程序相同。

原文链接: https://www.cnblogs.com/5iedu/p/4701553.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    第17章 文本和字体_17.6 一些有趣和新奇的内容

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/394715

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月3日 下午3:53
下一篇 2023年4月3日 下午3:53

相关推荐