2025-04-27 07:49:33 -04:00

1069 lines
31 KiB
C

/******************************Module*Header*******************************\
* Module Name: ftgentxt.c
*
* This program prints text using a font from a specified file. The text
* is printed normally, inverse, and clipped. Finally, some text is printed
* through a circular region.
*
* Created: 29-Sep-1991 11:16:42
* Author: Bodin Dresevic [BodinD]
*
* Copyright (c) 1990 Microsoft Corporation
\**************************************************************************/
#include "precomp.h"
#pragma hdrstop
#define MAX_CX 640 // vga
#define MAX_CY 480 // vga
// This is to create a bitmapinfo structure
#define DEFAULT_FACENAME "Tms Rmn"
#define CHAR_BUFFER_SIZE 80
PSZ apszFaceName[] =
{
"Tms Rmn"
, "Helv"
, "Courier"
, "System"
// , "Terminal"
};
VOID TextTest(HDC hdc);
VOID vListCharWidths(HDC hdc);
HRGN hrgnCircle(LONG,LONG,LONG);
ULONG cxSize(HDC hdc, LPSTR psz);
ULONG cBreak(char * psz);
VOID vJustify(HDC hdc, int x, int y, char * ach, ULONG cxLen);
VOID vJustify2(HDC hdc, int x, int y, char * psz1, char * psz2, ULONG cxLen);
VOID vJustify3(HDC hdc, int x, int y, char * psz1, char * psz2, char * psz3, ULONG cxLen);
BOOL bTextOut(HDC hdc, HFONT hfont, int x, int y, char * psz);
VOID DbgPOINT(LPPOINT ppt, char * psz)
{
DbgPrint("%s , x: %ld, y: %ld \n", psz, (LONG)ppt->x, (LONG)ppt->y);
}
#define CX_LEN ((ULONG)400) // justify to this length
void ErrorCodeTest(HDC hdc);
VOID vTestGenText(HWND hwnd, HDC hdc, RECT* prcl)
{
hwnd; prcl;
ErrorCodeTest(hdc);
TextTest(hdc);
}
/******************************Public*Routine******************************\
*
* ErrorCodeTest
*
* Effects:
*
* Warnings:
*
* History:
* 01-May-1992 -by- Bodin Dresevic [BodinD]
* Wrote it.
\**************************************************************************/
void ErrorCodeTest(HDC hdcScreen)
{
char * psz = "This is ExtTextOut error code test";
DWORD err;
RECT rc;
rc.left = 0; // arbitrary values
rc.right = 100;
rc.top = 0;
rc.bottom = 200;
// verify that retrieving error codes works properly:
// SetBatchLimit(1);
ExtTextOut (
hdcScreen,
10,20,
ETO_CLIPPED, // illegal to have null rect and nonzero flags
(LPRECT)NULL,
psz, strlen(psz),
(LPINT)NULL);
GdiFlush();
err = GetLastError();
DbgPrint ("ExtTextOut 1, Last error = 0x%lx = %ld\n", err, err);
ExtTextOut (
hdcScreen,
10,20,
5, // invalid flag
&rc,
psz, strlen(psz),
(LPINT)NULL);
GdiFlush();
err = GetLastError();
DbgPrint ("ExtTextOut 2, Last error = 0x%lx = %ld\n", err, err);
ExtTextOut (
(HDC)0X33344455, // INVALID HANDLE
10,20,
0,
(LPRECT)NULL,
psz, strlen(psz),
(LPINT)NULL);
GdiFlush();
err = GetLastError();
DbgPrint ("ExtTextOut 3, Last error = 0x%lx = %ld\n", err, err);
SetTextAlign (hdcScreen,0x77777777);
GdiFlush();
err = GetLastError();
DbgPrint ("SetTextAlign, Last error = 0x%lx = %ld\n", err, err);
AngleArc(hdcScreen,
100, // x
200, // y
0XFFFFFFFF, // overflows when converted to long // radius
(FLOAT)0,
(FLOAT)30
);
GdiFlush();
err = GetLastError();
DbgPrint ("AngleArc, Last error = 0x%lx = %ld\n", err, err);
vDoPause(0);
}
VOID TextTest(HDC hdc)
{
LOGFONT lfnt; // dummy logical font description
HFONT hfont; // handle to dummy font
HFONT hfontUnderline,hfontStrikeOut; // handle of font originally in DC
HRGN hrgnTmp;
int y;
#ifdef DOS_PLATFORM
#define MAX_LENGTH 80
char aBuffer[MAX_LENGTH];
#endif //DOS_PLATFORM
// Create a logical font
#ifndef DOS_PLATFORM
memset(&lfnt, 0, sizeof(lfnt));
#else
memzero(&lfnt, sizeof(lfnt));
#endif //DOS_PLATFORM
lfnt.lfHeight = 24;
lfnt.lfEscapement = 0; // mapper respects this filed
lfnt.lfUnderline = 0; // no underline
lfnt.lfStrikeOut = 0; // no strike out
lfnt.lfItalic = 0;
lfnt.lfWeight = 400; // normal
strcpy(lfnt.lfFaceName, DEFAULT_FACENAME);
if ((hfont = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
lfnt.lfUnderline = 1; // underline
if ((hfontUnderline = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
lfnt.lfUnderline = 0; // underline
lfnt.lfStrikeOut = 1; // no underline
if ((hfontStrikeOut = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
// Select font into DC
SelectObject(hdc, hfont);
// Set text alignment
SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
//
// List the character widths
vListCharWidths(hdc);
vDoPause(0);
// Clear screen
BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, BLACKNESS);
SetTextColor(hdc, RGB(127,127,0));
SetBkColor(hdc, RGB(0,255,0));
// nonclipped underlined text
// Select font into DC
SelectObject(hdc, hfontUnderline);
TextOut(hdc, 0, 0, "This is normal text.", 20);
SelectObject(hdc, hfont);
// Inverse text
BitBlt(hdc, 0, 30, MAX_CX, 30, (HDC) 0, 0, 0, WHITENESS);
SetROP2(hdc, R2_BLACK);
TextOut(hdc, 0, 30, "This is inverse text.", 21);
SetROP2(hdc, R2_WHITE);
// Clipped text (simple retangular region)
hrgnTmp = CreateRectRgn(10, 70, MAX_CX, 90);
SelectClipRgn(hdc, hrgnTmp);
DeleteObject(hrgnTmp);
TextOut(hdc, 0, 60, "This is clipped text.", 21);
// Clipped text (circular region)
hrgnTmp = hrgnCircle(150, 240, 150);
SelectClipRgn(hdc, hrgnTmp);
DeleteObject(hrgnTmp);
BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS);
SetROP2(hdc, R2_BLACK);
SelectObject(hdc, hfontStrikeOut);
TextOut(hdc, 0, 120, "There was a young man from Wight,", 33);
TextOut(hdc, 0, 150, "Who travelled much faster then light.", 37);
SelectObject(hdc, hfontUnderline);
TextOut(hdc, 0, 180, "He left home one day", 20);
TextOut(hdc, 0, 210, "In a relative way,", 18);
TextOut(hdc, 0, 240, "And arrived home the previous night.", 36);
hrgnTmp = CreateRectRgn(0, 0, MAX_CX, MAX_CY);
SelectClipRgn(hdc, hrgnTmp);
DeleteObject(hrgnTmp);
SelectObject(hdc, hfont);
SetTextColor(hdc, RGB(127,127,0));
{
// check that update current position mode works properly
SIZE size;
POINT pt;
PSZ pszExtent;
LOGFONT lfntEsc;
HFONT hfntOld, hfntEsc;
vDoPause(0);
BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS);
y = 30;
TextOut(hdc, 0, y , "Once upon a time there was a young man from Wight,", strlen("Once upon a time there was a young man from Wight,"));
y += 30;
GetCurrentPositionEx(hdc,&pt);
DbgPOINT(&pt,"before MoveToEx");
SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_UPDATECP);
MoveToEx(hdc, 0, y, &pt);
GetCurrentPositionEx(hdc,&pt);
DbgPOINT(&pt,"before " );
TextOut(hdc, 0, 0 , "Once upon a time ", strlen("Once upon a time "));
GetCurrentPositionEx(hdc,&pt);
DbgPOINT(&pt,"after " );
// change bk color to observe another textOut call
SetBkColor(hdc, RGB(0,0,255));
TextOut(hdc, 0, 0 , "there was a young man from Wight,", strlen("there was a young man from Wight,"));
SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
SetBkColor(hdc, RGB(0,255,0));
// get text extent test,
pszExtent = "iiiiiiiiii";
TextOut(hdc,200,100, pszExtent, strlen(pszExtent));
GetTextExtentPoint(hdc, pszExtent, strlen(pszExtent), &size);
DbgPrint("%s, cx = %ld, cy = %ld\n", pszExtent, size.cx, size.cy);
pszExtent = "iiiiWWiiii";
TextOut(hdc,200,150, pszExtent, strlen(pszExtent));
GetTextExtentPoint(hdc, pszExtent, strlen(pszExtent), &size);
DbgPrint("%s, cx = %ld, cy = %ld\n", pszExtent, size.cx, size.cy);
// see whether text extent works with font with escapement
// Create a logical font
#ifndef DOS_PLATFORM
memset(&lfntEsc, 0, sizeof(lfnt));
#else
memzero(&lfntEsc, sizeof(lfnt));
#endif //DOS_PLATFORM
lfntEsc.lfHeight = 18;
lfntEsc.lfEscapement = 450; // 45 degrees
lfntEsc.lfUnderline = 0; // no underline
lfntEsc.lfStrikeOut = 0; // no strike out
lfntEsc.lfItalic = 0;
lfntEsc.lfWeight = 400; // normal
if ((hfntEsc = CreateFontIndirect(&lfntEsc)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
hfntOld = SelectObject(hdc, hfntEsc);
pszExtent = "iiiiiiiiii";
TextOut(hdc,100,200, pszExtent, strlen(pszExtent));
GetTextExtentPoint(hdc, pszExtent, strlen(pszExtent), &size);
DbgPrint("%s, cx = %ld, cy = %ld\n", pszExtent, size.cx, size.cy);
Rectangle(hdc,100,300,100 + size.cx,300 + size.cy);
pszExtent = "iiiiWWiiii";
TextOut(hdc,400,200, pszExtent, strlen(pszExtent));
GetTextExtentPoint(hdc, pszExtent, strlen(pszExtent), &size);
DbgPrint("%s, cx = %ld, cy = %ld\n", pszExtent, size.cx, size.cy);
Rectangle(hdc,400,300,400 + size.cx,300 + size.cy);
SelectObject(hdc, hfntOld);
}
{
// test for emboldening and italicizing
char ach[] = {0,1,2,4,32,88};
HFONT hfontBold, hfontItalic, hfontBoldItalic, hfontOld;
char * pszString = "string";
vDoPause(0);
BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS);
lfnt.lfStrikeOut = 0;
lfnt.lfWeight = 700; // bold
if ((hfontBold = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
lfnt.lfWeight = 400; // normal
lfnt.lfItalic = 1;
if ((hfontItalic = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
lfnt.lfWeight = 700; // bold
if ((hfontBoldItalic = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
lfnt.lfWeight = 400; // normal
lfnt.lfItalic = 0;
// trying a string of chars with couple of chars out of range of the font
TextOut
(
hdc,
40,
40,
"trying a string of chars with couple of chars out of range of the font",
strlen("trying a string of chars with couple of chars out of range of the font")
);
TextOut(hdc, 80, 80, (LPSTR)ach, sizeof(ach));
vDoPause(0);
BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS);
y = 40;
TextOut(hdc, 0, y, "string" , strlen("string"));
y += 40;
bTextOut(hdc,hfontBold, 0, y, pszString);
y += 40;
bTextOut(hdc,hfontItalic, 0, y, pszString);
y += 40;
bTextOut(hdc,hfontBoldItalic, 0, y, pszString);
// couple of more strings, just for the fun of it
y += 80;
bTextOut(hdc,hfontItalic, 0, y, "These are funny italic strings:" );
y += 40;
bTextOut(hdc,hfontItalic, 0, y, "UuuuU" );
bTextOut(hdc,hfontItalic, 100, y, "WvvvW" );
bTextOut(hdc,hfontItalic, 200, y, "VvvvV" );
bTextOut(hdc,hfontItalic, 300, y, "YyyyY" );
bTextOut(hdc,hfontItalic, 400, y, " 2 break chars " );
y += 80;
bTextOut(hdc,hfontBoldItalic, 0, y, "These are silly bold italic strings:" );
y += 40;
bTextOut(hdc,hfontBoldItalic, 0, y, "UuuuU" );
bTextOut(hdc,hfontBoldItalic, 100, y, "WvvvW" );
bTextOut(hdc,hfontBoldItalic, 200, y, "VvvvV" );
bTextOut(hdc,hfontBoldItalic, 300, y, "YyyyY" );
bTextOut(hdc,hfontBoldItalic, 400, y, " 2 break chars " );
DeleteObject(hfontBold);
DeleteObject(hfontItalic);
DeleteObject(hfontBoldItalic);
}
{
// test fonts that are both emboldened and/or
// italicized and striked out and/or outlined
HFONT hfontBoldStrikeUnder,
hfontItalicUnder,
hfontBoldItalicUnder,
hfontItalicStrike,
hfontBoldItalicStrikeUnder; // wow, what a font !!!
char * pszString = "string";
vDoPause(0);
BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS);
lfnt.lfItalic = 0;
lfnt.lfWeight = 700; // bold
lfnt.lfStrikeOut = 1;
lfnt.lfUnderline = 1;
if ((hfontBoldStrikeUnder = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
lfnt.lfItalic = 1;
lfnt.lfWeight = 400;
lfnt.lfStrikeOut = 0;
lfnt.lfUnderline = 1;
if ((hfontItalicUnder = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
lfnt.lfItalic = 1;
lfnt.lfWeight = 700;
lfnt.lfStrikeOut = 0;
lfnt.lfUnderline = 1;
if ((hfontBoldItalicUnder = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
lfnt.lfItalic = 1;
lfnt.lfWeight = 400;
lfnt.lfStrikeOut = 1;
lfnt.lfUnderline = 0;
if ((hfontItalicStrike = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
lfnt.lfItalic = 1;
lfnt.lfWeight = 700;
lfnt.lfStrikeOut = 1;
lfnt.lfUnderline = 1;
if ((hfontBoldItalicStrikeUnder = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
// "clear" logfont
lfnt.lfItalic = 0;
lfnt.lfWeight = 400;
lfnt.lfStrikeOut = 0;
lfnt.lfUnderline = 0;
y = 40;
bTextOut(hdc,hfont, 20, y, "Normal font : YYYYYY");
y += 40;
bTextOut(hdc,hfontBoldStrikeUnder, 20, y, "Bold Striked Out and Underlined font : YYYY");
y += 40;
bTextOut(hdc,hfontItalicUnder, 20, y, "Italicized Underlined font: YYYY");
y += 40;
bTextOut(hdc,hfontBoldItalicUnder, 20, y, "Underlined Bold Italic font :askpW");
y += 40;
bTextOut(hdc,hfontItalicStrike, 20, y, "Striked Out Italic font :askpW");
y += 40;
bTextOut(hdc,hfontBoldItalicStrikeUnder, 20, y, "Underlined and Striked Out Bold Italic font :askpW");
DeleteObject(hfontBoldStrikeUnder);
DeleteObject(hfontItalicUnder);
DeleteObject(hfontBoldItalicUnder);
DeleteObject(hfontItalicStrike);
DeleteObject(hfontBoldItalicStrikeUnder);
}
{
// check whether mapper can select different sizes from an *.fon file
// and choose bold, italic and bold_italic fonts
HFONT hfontHt;
short alfHeight[6] = {13, 16, 19, 23, 27, 35};
int iHt;
int iName;
PSZ pszComment = "Trying to map to the face name: ";
for (iName = 0; iName < sizeof(apszFaceName)/4; iName++)
{
#ifndef DOS_PLATFORM
memset(&lfnt, 0, sizeof(lfnt));
#else
memzero(&lfnt, sizeof(lfnt));
#endif //DOS_PLATFORM
strcpy(lfnt.lfFaceName, apszFaceName[iName]);
vDoPause(0);
BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS);
lfnt.lfItalic = 0;
lfnt.lfWeight = 400;
lfnt.lfStrikeOut = 0;
lfnt.lfUnderline = 0;
SetTextAlign(hdc, TA_UPDATECP);
MoveToEx(hdc,60,40,NULL);
TextOut(hdc,0,0,pszComment, strlen(pszComment));
TextOut(hdc, 0, 0, apszFaceName[iName], strlen(apszFaceName[iName]));
SetTextAlign(hdc, TA_NOUPDATECP);
y = 80;
for (iHt = 0L; iHt < 6L; iHt++)
{
lfnt.lfHeight = alfHeight[iHt];
if ((hfontHt = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
bTextOut(hdc,hfontHt, 20, y, "Normal: Different font sizes from an *.fon file");
y += 40;
DeleteObject(hfontHt);
}
vDoPause(0);
BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS);
SetTextAlign(hdc, TA_UPDATECP);
MoveToEx(hdc,60,40,NULL);
TextOut(hdc,0,0,pszComment, strlen(pszComment));
TextOut(hdc, 0, 0, apszFaceName[iName], strlen(apszFaceName[iName]));
SetTextAlign(hdc, TA_NOUPDATECP);
lfnt.lfItalic = 1;
lfnt.lfWeight = 700;
lfnt.lfStrikeOut = 0;
lfnt.lfUnderline = 0;
y = 80;
for (iHt = 0L; iHt < 6L; iHt++)
{
lfnt.lfHeight = alfHeight[iHt];
if ((hfontHt = CreateFontIndirect(&lfnt)) == NULL)
{
DbgPrint("Logical font creation failed.\n");
return;
}
bTextOut(hdc,hfontHt, 20, y, "Bold Italic: Different font sizes from an *.fon file");
y += 40;
DeleteObject(hfontHt);
}
}
}
{
vDoPause(0);
// this part of the test tests the SetTextJustification functionality
BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS);
y = 30;
// first print strings without justification to see how long they are
TextOut(hdc, 0, y , "There was a young man from Wight,", 33); // 120
TextOut(hdc, 0, y + 30 , "Who travelled much faster then light.", 37); // 150
TextOut(hdc, 0, y + 60 , "He left home one day", 20); // 180
TextOut(hdc, 0, y + 90 , "In a relative way,", 18); // 210
TextOut(hdc, 0, y + 120 , "And arrived home the previous night.", 36); // 240
y += 190;
// coerce strings to have total length CX_LEN by addjusting spaces that
// correspond to break chars
// add more space to break chars (positive dda) (CX_LEN > text extent)
vJustify(hdc, 0, y , "There was a young man from Wight,", CX_LEN); // 120
vJustify(hdc, 0, y + 30 , "Who travelled much faster then light.",CX_LEN); // 150
vJustify(hdc, 0, y + 60 , "He left home one day", CX_LEN); // 180
vJustify(hdc, 0, y + 90 , "In a relative way,", CX_LEN); // 210
vJustify(hdc, 0, y + 120 , "And arrived home the previous night.", CX_LEN); // 240
}
{
vDoPause(0);
// add more space to break chars (positive dda) (CX_LEN > text extent)
BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS);
y = 30;
// first print strings without justification to see how long they are
TextOut(hdc, 0, y , "Once upon a time there was a young man from Wight,", strlen("Once upon a time there was a young man from Wight,"));
TextOut(hdc, 0, y + 30 , "Who travelled much much much faster then light." , strlen("Who travelled much much much faster then light." ));
TextOut(hdc, 0, y + 60 , "Nobody knows why he left home one day" , strlen("Nobody knows why he left home one day" )); // 180
TextOut(hdc, 0, y + 90 , "Nor why he did it in a very relative way," , strlen("Nor why he did it in a very relative way," )); // 210
TextOut(hdc, 0, y + 120 , "And arrived back home the previous night." , strlen("And arrived back home the previous night." ));
y += 190;
vJustify(hdc, 0, y , "Once upon a time there was a young man from Wight," ,CX_LEN);
vJustify(hdc, 0, y + 30 , "Who travelled much much much faster then light." ,CX_LEN);
vJustify(hdc, 0, y + 60 , "Nobody knows why he left home one day" ,CX_LEN);
vJustify(hdc, 0, y + 90 , "Nor why he did it in a very relative way," ,CX_LEN); // 210
vJustify(hdc, 0, y + 120 , "And arrived back home the previous night." ,CX_LEN);
}
{
vDoPause(0);
// justifying two or more strings with a single set text justification
BitBlt(hdc, 0, 0, MAX_CX, MAX_CY, (HDC) 0, 0, 0, WHITENESS);
y = 30;
TextOut(hdc, 0, y , "Once upon a time there was a young man from Wight,", strlen("Once upon a time there was a young man from Wight,"));
y += 30;
vJustify(hdc, 0, y , "Once upon a time there was a young man from Wight," ,CX_LEN);
y += 30;
vJustify2(hdc, 0, y , "Once upon a time there", " was a young man from Wight," ,CX_LEN);
y += 30;
vJustify3(hdc, 0, y , "Once upon a ti","me there was a young"," man from Wight," ,CX_LEN);
y += 30;
vJustify3(hdc, 0, y , "Once ","upon a time there was a young"," man from Wight," ,CX_LEN);
y += 90;
// this string is shorter than CX_LEN
TextOut(hdc, 0, y , "There was a young man from Wight,", 33); // 120
y += 30;
vJustify(hdc, 0, y , "There was a young man from Wight,", CX_LEN); // 120
y += 30;
vJustify2(hdc, 0, y , "There was a y","oung man from Wight,", CX_LEN); // 120
y += 30;
vJustify3(hdc, 0, y , "The","re was a young"," man from Wight,", CX_LEN); // 120
y += 30;
vJustify3(hdc, 0, y , "There wa","s a young"," man from Wight,", CX_LEN); // 120
}
}
/******************************Public*Routine******************************\
* VOID vListCharWidths(HDC hdc) *
* *
* Prints out the character widths *
* *
* History: *
* Thu 07-Mar-1991 07:57:00 by Kirk Olynyk [kirko] *
* Wrote it. *
\**************************************************************************/
VOID vListCharWidths(HDC hdc)
{
int aiCharWidth[256];
POINT pt;
char achBuffer[5];
int i,iRowSpacing,iWidthCol;
ULONG ulOldTextColor,ulOldBkColor;
SIZE szScreen;
TEXTMETRIC tm;
HBRUSH hBrush,hBrushOld;
hBrush = CreateSolidBrush(RGB(0,0,255));
hBrushOld = SelectObject(hdc,hBrush);
ulOldTextColor = SetTextColor(hdc,RGB(255,255,255));
ulOldBkColor = SetBkColor(hdc,RGB(0,0,255));
GetTextMetrics(hdc,(LPTEXTMETRIC) &tm);
iRowSpacing = tm.tmHeight + tm.tmExternalLeading;
szScreen.cx = GetDeviceCaps(hdc,HORZRES);
szScreen.cy = GetDeviceCaps(hdc,VERTRES);
#define FIRST_CHAR tm.tmFirstChar
GetCharWidth(hdc,FIRST_CHAR,tm.tmLastChar,aiCharWidth);
BitBlt(hdc,
0,
0,
szScreen.cx,
szScreen.cy,
(HDC) 0,
0,
0,
PATCOPY);
TextOut(hdc, 0, 0, "GLYPH WIDTH", 11);
// Calculate the width of the of a column
for (i = 0, iWidthCol = 0; i < 10; i++)
iWidthCol = max(iWidthCol,aiCharWidth['0' + i - FIRST_CHAR]);
iWidthCol *= 2;
iWidthCol += tm.tmMaxCharWidth;
iWidthCol += 2 * aiCharWidth[' ' - FIRST_CHAR];
achBuffer[1] = ' ';
achBuffer[2] = ' ';
i = 0;
while (i < tm.tmLastChar - FIRST_CHAR + 1)
{
pt.x = 0;
pt.y = 2*iRowSpacing;
BitBlt(hdc,
0,
2*iRowSpacing,
szScreen.cx,
szScreen.cy-2*iRowSpacing,
(HDC) 0,
0,
0,
PATCOPY);
while (
i < tm.tmLastChar - FIRST_CHAR + 1 &&
pt.x < szScreen.cx - iWidthCol)
{
int jTemp, iTemp;
achBuffer[0] = (char) (i + FIRST_CHAR);
iTemp = aiCharWidth[i]/10;
jTemp = aiCharWidth[i] % 10;
achBuffer[3] = iTemp == 0 ? (char)' ' : (char)('0' + iTemp);
achBuffer[4] = (char)('0' + jTemp);
TextOut(hdc,pt.x,pt.y,&achBuffer[0],1);
TextOut(hdc,pt.x + tm.tmMaxCharWidth,pt.y,&achBuffer[1],4);
i++;
pt.y += iRowSpacing;
if (pt.y > szScreen.cy - iRowSpacing)
{
pt.x += iWidthCol + 3*tm.tmMaxCharWidth;
pt.y = 2*iRowSpacing;
}
}
}
ulOldTextColor = SetTextColor(hdc,ulOldTextColor);
ulOldBkColor = SetBkColor(hdc,ulOldBkColor);
}
ULONG cxSize(HDC hdc, LPSTR psz)
{
SIZE size;
BOOL bOk = GetTextExtentPoint(hdc, psz, strlen(psz), &size);
if (!bOk)
vDoPause(0);
return(size.cx);
}
/******************************Public*Routine******************************\
*
* ULONG cBreak(char * psz)
*
*
* Effects: counts break chars in the string
*
* History:
* 10-Apr-1991 -by- Bodin Dresevic [BodinD]
* Wrote it.
\**************************************************************************/
ULONG cBreak(char * psz)
{
ULONG c = 0L;
ULONG i;
for (i = 0; i < strlen(psz); i++)
{
if (psz[i] == 32) // if break char
c++;
}
return(c);
}
/******************************Public*Routine******************************\
*
* VOID vJustify(HDC hdc, int x, int y, char * ach, ULONG cxLen)
*
* coerces the string to have the length cxLen by adding or subtracting
* space from break chars
*
* History:
* 10-Apr-1991 -by- Bodin Dresevic [BodinD]
* Wrote it.
\**************************************************************************/
VOID vJustify(HDC hdc, int x, int y, char * ach, ULONG cxLen)
{
ULONG cBrk = cBreak(ach);
ULONG cx = cxSize(hdc,ach);
BOOL bOk;
// DbgPrint("cBrk = %ld, cxSize = %ld\n", cBrk, cx);
bOk = SetTextJustification(hdc, (int)(cxLen - cx), cBrk);
if(!bOk)
vDoPause(0);
bOk = TextOut(hdc, x, y, ach, strlen(ach));
if(!bOk)
vDoPause(0);
bOk = SetTextJustification(hdc,0,0);
if(!bOk)
vDoPause(0);
}
/******************************Public*Routine******************************\
*
* VOID vJustify2(HDC hdc, int x, int y, char * psz1, char * psz2, ULONG cxLen)
*
* coerces the string to have the length cxLen by adding or subtracting
* space from break chars
*
* History:
* 10-Apr-1991 -by- Bodin Dresevic [BodinD]
* Wrote it.
\**************************************************************************/
VOID vJustify2(HDC hdc, int x, int y, char * psz1, char * psz2, ULONG cxLen)
{
ULONG cBrk = cBreak(psz1) + cBreak(psz2);
ULONG cx = cxSize(hdc,psz1) + cxSize(hdc,psz2);
BOOL bOk;
POINT pt;
MoveToEx(hdc,x,y,&pt);
SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_UPDATECP);
// DbgPrint("cBrk = %ld, cxSize = %ld\n", cBrk, cx);
bOk = SetTextJustification(hdc, (int)(cxLen - cx), cBrk);
if(!bOk)
vDoPause(0);
bOk = TextOut(hdc, 0, 0, psz1, strlen(psz1));
if(!bOk)
vDoPause(0);
// change bk color to observe which part of the string is written
// by the second call
SetBkColor(hdc, RGB(0,0,255));
bOk = TextOut(hdc, 0, 0, psz2, strlen(psz2));
if(!bOk)
vDoPause(0);
bOk = SetTextJustification(hdc,0,0);
if(!bOk)
vDoPause(0);
SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
SetBkColor(hdc, RGB(0,255,0)); // restore old color
}
VOID vJustify3(HDC hdc, int x, int y, char * psz1, char * psz2, char * psz3, ULONG cxLen)
{
ULONG cBrk = cBreak(psz1) + cBreak(psz2) + cBreak(psz3);
ULONG cx = cxSize(hdc,psz1) + cxSize(hdc,psz2) + cxSize(hdc,psz3);
BOOL bOk;
POINT pt;
MoveToEx(hdc,x,y,&pt);
SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_UPDATECP);
// DbgPrint("cBrk = %ld, cxSize = %ld\n", cBrk, cx);
bOk = SetTextJustification(hdc, (int)(cxLen - cx), cBrk);
if(!bOk)
vDoPause(0);
bOk = TextOut(hdc, 0, 0, psz1, strlen(psz1));
if(!bOk)
vDoPause(0);
SetBkColor(hdc, RGB(0,0,255));
bOk = TextOut(hdc, 0, 0, psz2, strlen(psz2));
if(!bOk)
vDoPause(0);
SetBkColor(hdc, RGB(255,0,0));
bOk = TextOut(hdc, 0, 0, psz3, strlen(psz3));
if(!bOk)
vDoPause(0);
bOk = SetTextJustification(hdc,0,0);
if(!bOk)
vDoPause(0);
SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
SetBkColor(hdc, RGB(0,255,0));
}
/******************************Public*Routine******************************\
*
* VOID vTextOut(HDC hdc, HFONT hfont, int x, int y, char * psz)
* select font into dc and do text output at a given location
*
* Effects:
*
* Warnings:
*
* History:
* 30-Apr-1991 -by- Bodin Dresevic [BodinD]
* Wrote it.
\**************************************************************************/
BOOL bTextOut(HDC hdc, HFONT hfont, int x, int y, char * psz)
{
HFONT hfontOld;
BOOL bOk;
hfontOld = SelectObject(hdc, hfont);
bOk = TextOut(hdc,x,y,psz,strlen(psz));
SelectObject(hdc, hfontOld);
return(bOk);
}