|
|
//// DspScaling.CPP - DIsplay effect of hinting on text scaling
//
// Tests for clipping and alignment problems in scaled text
//
// Fixed pitch font misalignment
// Leading space alignment
// Overhang sufficient for italic and other overhanging glyphs
//
#include "precomp.hxx"
#include "global.h"
#include "gdiplus.h"
// Makebitmap
void MakeBitmap( IN INT width, IN INT height, OUT HBITMAP *bitmap, OUT DWORD **bits ) { struct { BITMAPINFOHEADER bmih; RGBQUAD rgbquad[2]; } bmi;
bmi.bmih.biSize = sizeof(bmi.bmih); bmi.bmih.biWidth = width; bmi.bmih.biHeight = height; bmi.bmih.biPlanes = 1; bmi.bmih.biBitCount = 32; bmi.bmih.biCompression = BI_RGB; bmi.bmih.biSizeImage = 0; bmi.bmih.biXPelsPerMeter = 3780; // 96 dpi
bmi.bmih.biYPelsPerMeter = 3780; // 96 dpi
bmi.bmih.biClrUsed = 0; bmi.bmih.biClrImportant = 0;
memset(bmi.rgbquad, 0, 2 * sizeof(RGBQUAD));
*bitmap = CreateDIBSection( NULL, (BITMAPINFO*)&bmi, DIB_RGB_COLORS, (void**)bits, NULL, NULL ); // Initialise bitmap to white
memset(*bits, 0xFF, width*height*sizeof(DWORD)); }
void PaintStringAsDots( HDC hdc, INT x, INT *y, INT displayWidth, INT ppem, BOOL useGdi ) {
HBITMAP glyphs; DWORD *gbits;
INT height = (ppem * 3) / 2; INT width = height * 16;
MakeBitmap(width, height, &glyphs, &gbits);
HDC hdcg = CreateCompatibleDC(hdc);
if (!(glyphs && hdcg)) { return; }
SelectObject(hdcg, glyphs); if (useGdi) { // Output with GDI
HFONT oldFont = (HFONT)SelectObject(hdcg, CreateFontW( -ppem, // height of font
0, // average character width
0, // angle of escapement
0, // base-line orientation angle
g_style[0].style & FontStyleBold ? 700 : 400, // font weight
g_style[0].style & FontStyleItalic ? 1 : 0, // italic attribute option
0, // underline attribute option
0, // strikeout attribute option
DEFAULT_CHARSET, // character set identifier
0, // output precision
0, // clipping precision
0, // output quality
0, // pitch and family
g_style[0].faceName // typeface name
)); SetBkMode(hdcg, TRANSPARENT); ExtTextOutW(hdcg, 0,0, ETO_IGNORELANGUAGE, NULL, g_wcBuf, g_iTextLen, NULL); DeleteObject(SelectObject(hdcg, oldFont)); } else { // Output with Gdiplus
Graphics g(hdcg);
Font( &FontFamily(g_style[0].faceName), REAL(ppem), g_style[0].style, UnitPixel );
StringFormat format(g_typographic ? StringFormat::GenericTypographic() : StringFormat::GenericDefault()); format.SetFormatFlags(g_formatFlags); format.SetTrimming(g_lineTrim); format.SetAlignment(g_align); format.SetLineAlignment(g_lineAlign); format.SetHotkeyPrefix(g_hotkey);
g.DrawString( g_wcBuf, g_iTextLen, &Font( &FontFamily(g_style[0].faceName), REAL(ppem), g_style[0].style, UnitPixel ), RectF(0,0, REAL(width), REAL(height)), &format, g_textBrush ); }
// Display scaled bitmap
StretchBlt(hdc, x, *y, displayWidth, displayWidth/16, hdcg, 0, 0, width, height, SRCCOPY); *y += displayWidth/16;
DeleteObject(hdcg); DeleteObject(glyphs); }
void PaintScaling( HDC hdc, int *piY, RECT *prc, int iLineHeight) {
// Establish available width and height in device coordinates
int plainTextWidth = prc->right - prc->left; int plainTextHeight = prc->bottom - *piY;
// Paint eqach resolution first with GDI, then again with GdiPlus
PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 11, TRUE); // 96 dpi 8pt
PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 11, FALSE); // 96 dpi 8pt
PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 13, TRUE); // 120 dpi 8pt
PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 13, FALSE); // 120 dpi 8pt
PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 17, TRUE); // 150 dpi 8pt
PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 17, FALSE); // 150 dpi 8pt
PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 33, TRUE); // 300 dpi 8pt
PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 33, FALSE); // 300 dpi 8pt
PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 67, TRUE); // 600 dpi 8pt
PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 67, FALSE); // 600 dpi 8pt
}
void DummyPaintScaling( HDC hdc, int *piY, RECT *prc, int iLineHeight ) { int icpLineStart; // First character of line
int icpLineEnd; // End of line (end of buffer or index of CR character)
// Establish available width and height in device coordinates
int plainTextWidth = prc->right - prc->left; int plainTextHeight = prc->bottom - *piY;
Graphics g(hdc); Matrix matrix;
g.ResetTransform(); g.SetPageUnit(UnitPixel); g.TranslateTransform(REAL(prc->left), REAL(*piY));
g.SetSmoothingMode(g_SmoothingMode);
g.SetTextContrast(g_GammaValue); g.SetTextRenderingHint(g_TextMode);
SolidBrush whiteBrush(Color(0xff, 0xff, 0xff));
Color grayColor(0xc0, 0xc0, 0xc0); SolidBrush grayBrush(grayColor); Pen grayPen(&grayBrush, 1.0);
Color blackColor(0, 0, 0); SolidBrush blackBrush(blackColor); Pen blackPen(&blackBrush, 1.0);
// Clear the background
RectF rEntire(0, 0, REAL(plainTextWidth), REAL(plainTextHeight)); g.FillRectangle(g_textBackBrush, rEntire);
// Apply selected world transform, adjusted to middle of the plain text
// area.
g.SetTransform(&g_WorldTransform); g.TranslateTransform( REAL(prc->left + plainTextWidth/2), REAL(*piY + plainTextHeight/2), MatrixOrderAppend);
// Preset a StringFormat with user settings
StringFormat format(g_formatFlags); format.SetAlignment(g_align); format.SetLineAlignment(g_lineAlign); format.SetHotkeyPrefix(g_hotkey);
double columnWidth = 50*plainTextWidth/300;
REAL tab[3] = {REAL(columnWidth/4), REAL(columnWidth*3/16), REAL(columnWidth*1/8)};
format.SetTabStops(0.0, sizeof(tab)/sizeof(REAL), tab);
// Display string at a range of sizes
double x = -25*plainTextWidth/100; double y = -25*plainTextHeight/100;
for (INT i=6; i<20; i++) { Font font( &FontFamily(g_style[0].faceName), REAL(i), g_style[0].style, g_fontUnit );
REAL cellHeight = font.GetHeight(&g);
if (y+cellHeight > 25*plainTextHeight/100) { // Start a new column ...
y = -25*plainTextWidth/100; x += columnWidth; }
RectF textRect(REAL(x), REAL(y), REAL(9*columnWidth/10), cellHeight); g.DrawString(g_wcBuf, g_iTextLen, &font, textRect, &format, g_textBrush);
// Draw formatting rectangle around box
g.DrawRectangle(&grayPen, textRect);
y += cellHeight + 5; }
*piY += plainTextHeight; }
|