Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

225 lines
7.0 KiB

//// DspMetric.CPP - Display font metrics
//
//
#include "precomp.hxx"
#include "global.h"
void AnnotateHeight(
Graphics &g,
Color c,
Font &f,
REAL x,
REAL y1,
REAL y2,
WCHAR *id
)
{
SolidBrush brush(c);
Pen pen(&brush, 2.0);
pen.SetLineCap(LineCapArrowAnchor, LineCapArrowAnchor, DashCapFlat);
g.DrawLine(&pen, x,y1, x,y2);
g.DrawString(id,-1, &f, PointF(x,(y1+y2)/2), NULL, &brush);
}
void PaintMetrics(
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)
HFONT hFont;
HFONT hOldFont;
LOGFONT lf;
INT row;
INT column;
// Establish available width and height in device coordinates
int DrawingWidth = prc->right - prc->left;
int DrawingHeight = prc->bottom - *piY;
// Establish a Graphics with 0,0 at the top left of the drawing area
Graphics g(hdc);
Matrix matrix;
g.ResetTransform();
g.SetPageUnit(UnitPixel);
g.TranslateTransform(REAL(prc->left), REAL(*piY));
// Clear the background
RectF rEntire(0, 0, REAL(DrawingWidth), REAL(DrawingHeight));
SolidBrush whiteBrush(Color(0xff, 0xff, 0xff));
g.FillRectangle(&whiteBrush, rEntire);
// Leave a little space for right and bottom margins
DrawingWidth -= DrawingWidth/40;
DrawingHeight -= DrawingHeight/40;
Color blackColor(0, 0, 0);
SolidBrush blackBrush(blackColor);
Pen blackPen(&blackBrush, 2.0);
Color grayColor(0xc0, 0xc0, 0xc0);
SolidBrush grayBrush(grayColor);
Pen grayPen(&grayBrush, 2.0);
// Measure the string to see how wide it would be
FontFamily family(g_style[0].faceName);
StringFormat format(StringFormat::GenericTypographic());
format.SetFormatFlags(g_formatFlags | StringFormatFlagsNoWrap | StringFormatFlagsLineLimit);
format.SetAlignment(g_align);
RectF bounds;
// Since we've chosen a size of 1.0 for the font height, MeasureString
// will return the width as a multiple of the em height in bounds.Width.
g.MeasureString(
g_wcBuf,
g_iTextLen,
&Font(&family, 1.0, g_style[0].style, UnitWorld),
PointF(0, 0),
&format,
&bounds
);
// Establish font metrics
if (family.IsStyleAvailable(g_style[0].style))
{
// Establish line and cell dimensions in units
INT emHeight = family.GetEmHeight(g_style[0].style);
INT cellAscent = family.GetCellAscent(g_style[0].style);
INT cellDescent = family.GetCellDescent(g_style[0].style);
INT lineSpacing = family.GetLineSpacing(g_style[0].style);
#if TEXTV2
INT typoAscent = family.GetTypographicAscent(g_style[0].style);
INT typoDescent = family.GetTypographicDescent(g_style[0].style);
INT typoLineGap = family.GetTypographicLineGap(g_style[0].style);
if (typoDescent < 0)
{
typoDescent = -typoDescent;
}
INT typoLineSpacing = typoAscent + typoDescent + typoLineGap;
#endif
INT cellHeight = cellAscent + cellDescent;
// We will display two lines from top of upper cell to bottom of lower
// cell, with the lines separated by the typographic ascent + descent +
// line gap.
INT totalHeightInUnits = lineSpacing + cellHeight;
REAL scale = REAL(DrawingHeight) / REAL(totalHeightInUnits);
REAL worldEmHeight = emHeight * scale;
// Now allow for the width of the string - if it would be wider than
// the available DrawingWIdth, reduce the font size proportionately.
if (worldEmHeight * bounds.Width > DrawingWidth)
{
REAL reduceBy = DrawingWidth / (worldEmHeight * bounds.Width);
scale *= reduceBy;
worldEmHeight = emHeight * scale;
}
Font font(&family, worldEmHeight, g_style[0].style, UnitWorld);
// Draw two lines of text
g.DrawString(
g_wcBuf,
g_iTextLen,
&font,
RectF(0, 0, REAL(DrawingWidth), REAL(DrawingHeight)),
&format,
&blackBrush
);
g.DrawString(
g_wcBuf,
g_iTextLen,
&font,
RectF(0, lineSpacing * scale, REAL(DrawingWidth), REAL(DrawingHeight)),
&format,
&grayBrush
);
// Draw lines
REAL y=0; g.DrawLine(&blackPen, 0.0,y, REAL(DrawingWidth-1),y);
// Draw lines for second row first, in case they're oblitereated by first row.
y = scale * (lineSpacing); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
y = scale * (lineSpacing + cellAscent); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
y = scale * (lineSpacing + cellHeight); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
g.DrawLine(&blackPen, 0.0,0.0, REAL(DrawingWidth-1),0.0);
y = scale * (cellAscent); g.DrawLine(&blackPen, 0.0,y, REAL(DrawingWidth-1),y);
y = scale * (cellHeight); g.DrawLine(&blackPen, 0.0,y, REAL(DrawingWidth-1),y);
// Add construction lines.
Font annotationFont(FontFamily::GenericSansSerif(), 10, 0, UnitPoint);
Color darkGrayColor(0x80, 0x80, 0x80);
AnnotateHeight(g, darkGrayColor, annotationFont, REAL(DrawingWidth/100.0), 0, scale*cellAscent, L"ascent");
AnnotateHeight(g, darkGrayColor, annotationFont, REAL(DrawingWidth/100.0), scale*cellAscent, scale*cellHeight, L"descent");
AnnotateHeight(g, darkGrayColor, annotationFont, REAL(95*DrawingWidth/100.0), 0, scale*lineSpacing, L"line spacing");
AnnotateHeight(g, darkGrayColor, annotationFont, REAL(DrawingWidth/10.0), scale*(cellHeight-emHeight), scale*cellHeight, L"Em Height");
#if TEXTV2
y = scale * (cellAscent - typoAscent); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
y = scale * (cellAscent + typoDescent); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
y = scale * (lineSpacing + cellAscent - typoAscent); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
y = scale * (lineSpacing + cellAscent + typoDescent); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
#endif
// Test font.GetHeight
REAL fontHeight = font.GetHeight(&g);
g.DrawLine(&blackPen, REAL(DrawingWidth-1),0.0, REAL(DrawingWidth-1),fontHeight);
}
*piY += 41*DrawingHeight/40;
}