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

  1. //// DspMetric.CPP - Display font metrics
  2. //
  3. //
  4. #include "precomp.hxx"
  5. #include "global.h"
  6. void AnnotateHeight(
  7. Graphics &g,
  8. Color c,
  9. Font &f,
  10. REAL x,
  11. REAL y1,
  12. REAL y2,
  13. WCHAR *id
  14. )
  15. {
  16. SolidBrush brush(c);
  17. Pen pen(&brush, 2.0);
  18. pen.SetLineCap(LineCapArrowAnchor, LineCapArrowAnchor, DashCapFlat);
  19. g.DrawLine(&pen, x,y1, x,y2);
  20. g.DrawString(id,-1, &f, PointF(x,(y1+y2)/2), NULL, &brush);
  21. }
  22. void PaintMetrics(
  23. HDC hdc,
  24. int *piY,
  25. RECT *prc,
  26. int iLineHeight) {
  27. int icpLineStart; // First character of line
  28. int icpLineEnd; // End of line (end of buffer or index of CR character)
  29. HFONT hFont;
  30. HFONT hOldFont;
  31. LOGFONT lf;
  32. INT row;
  33. INT column;
  34. // Establish available width and height in device coordinates
  35. int DrawingWidth = prc->right - prc->left;
  36. int DrawingHeight = prc->bottom - *piY;
  37. // Establish a Graphics with 0,0 at the top left of the drawing area
  38. Graphics g(hdc);
  39. Matrix matrix;
  40. g.ResetTransform();
  41. g.SetPageUnit(UnitPixel);
  42. g.TranslateTransform(REAL(prc->left), REAL(*piY));
  43. // Clear the background
  44. RectF rEntire(0, 0, REAL(DrawingWidth), REAL(DrawingHeight));
  45. SolidBrush whiteBrush(Color(0xff, 0xff, 0xff));
  46. g.FillRectangle(&whiteBrush, rEntire);
  47. // Leave a little space for right and bottom margins
  48. DrawingWidth -= DrawingWidth/40;
  49. DrawingHeight -= DrawingHeight/40;
  50. Color blackColor(0, 0, 0);
  51. SolidBrush blackBrush(blackColor);
  52. Pen blackPen(&blackBrush, 2.0);
  53. Color grayColor(0xc0, 0xc0, 0xc0);
  54. SolidBrush grayBrush(grayColor);
  55. Pen grayPen(&grayBrush, 2.0);
  56. // Measure the string to see how wide it would be
  57. FontFamily family(g_style[0].faceName);
  58. StringFormat format(StringFormat::GenericTypographic());
  59. format.SetFormatFlags(g_formatFlags | StringFormatFlagsNoWrap | StringFormatFlagsLineLimit);
  60. format.SetAlignment(g_align);
  61. RectF bounds;
  62. // Since we've chosen a size of 1.0 for the font height, MeasureString
  63. // will return the width as a multiple of the em height in bounds.Width.
  64. g.MeasureString(
  65. g_wcBuf,
  66. g_iTextLen,
  67. &Font(&family, 1.0, g_style[0].style, UnitWorld),
  68. PointF(0, 0),
  69. &format,
  70. &bounds
  71. );
  72. // Establish font metrics
  73. if (family.IsStyleAvailable(g_style[0].style))
  74. {
  75. // Establish line and cell dimensions in units
  76. INT emHeight = family.GetEmHeight(g_style[0].style);
  77. INT cellAscent = family.GetCellAscent(g_style[0].style);
  78. INT cellDescent = family.GetCellDescent(g_style[0].style);
  79. INT lineSpacing = family.GetLineSpacing(g_style[0].style);
  80. #if TEXTV2
  81. INT typoAscent = family.GetTypographicAscent(g_style[0].style);
  82. INT typoDescent = family.GetTypographicDescent(g_style[0].style);
  83. INT typoLineGap = family.GetTypographicLineGap(g_style[0].style);
  84. if (typoDescent < 0)
  85. {
  86. typoDescent = -typoDescent;
  87. }
  88. INT typoLineSpacing = typoAscent + typoDescent + typoLineGap;
  89. #endif
  90. INT cellHeight = cellAscent + cellDescent;
  91. // We will display two lines from top of upper cell to bottom of lower
  92. // cell, with the lines separated by the typographic ascent + descent +
  93. // line gap.
  94. INT totalHeightInUnits = lineSpacing + cellHeight;
  95. REAL scale = REAL(DrawingHeight) / REAL(totalHeightInUnits);
  96. REAL worldEmHeight = emHeight * scale;
  97. // Now allow for the width of the string - if it would be wider than
  98. // the available DrawingWIdth, reduce the font size proportionately.
  99. if (worldEmHeight * bounds.Width > DrawingWidth)
  100. {
  101. REAL reduceBy = DrawingWidth / (worldEmHeight * bounds.Width);
  102. scale *= reduceBy;
  103. worldEmHeight = emHeight * scale;
  104. }
  105. Font font(&family, worldEmHeight, g_style[0].style, UnitWorld);
  106. // Draw two lines of text
  107. g.DrawString(
  108. g_wcBuf,
  109. g_iTextLen,
  110. &font,
  111. RectF(0, 0, REAL(DrawingWidth), REAL(DrawingHeight)),
  112. &format,
  113. &blackBrush
  114. );
  115. g.DrawString(
  116. g_wcBuf,
  117. g_iTextLen,
  118. &font,
  119. RectF(0, lineSpacing * scale, REAL(DrawingWidth), REAL(DrawingHeight)),
  120. &format,
  121. &grayBrush
  122. );
  123. // Draw lines
  124. REAL y=0; g.DrawLine(&blackPen, 0.0,y, REAL(DrawingWidth-1),y);
  125. // Draw lines for second row first, in case they're oblitereated by first row.
  126. y = scale * (lineSpacing); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
  127. y = scale * (lineSpacing + cellAscent); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
  128. y = scale * (lineSpacing + cellHeight); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
  129. g.DrawLine(&blackPen, 0.0,0.0, REAL(DrawingWidth-1),0.0);
  130. y = scale * (cellAscent); g.DrawLine(&blackPen, 0.0,y, REAL(DrawingWidth-1),y);
  131. y = scale * (cellHeight); g.DrawLine(&blackPen, 0.0,y, REAL(DrawingWidth-1),y);
  132. // Add construction lines.
  133. Font annotationFont(FontFamily::GenericSansSerif(), 10, 0, UnitPoint);
  134. Color darkGrayColor(0x80, 0x80, 0x80);
  135. AnnotateHeight(g, darkGrayColor, annotationFont, REAL(DrawingWidth/100.0), 0, scale*cellAscent, L"ascent");
  136. AnnotateHeight(g, darkGrayColor, annotationFont, REAL(DrawingWidth/100.0), scale*cellAscent, scale*cellHeight, L"descent");
  137. AnnotateHeight(g, darkGrayColor, annotationFont, REAL(95*DrawingWidth/100.0), 0, scale*lineSpacing, L"line spacing");
  138. AnnotateHeight(g, darkGrayColor, annotationFont, REAL(DrawingWidth/10.0), scale*(cellHeight-emHeight), scale*cellHeight, L"Em Height");
  139. #if TEXTV2
  140. y = scale * (cellAscent - typoAscent); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
  141. y = scale * (cellAscent + typoDescent); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
  142. y = scale * (lineSpacing + cellAscent - typoAscent); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
  143. y = scale * (lineSpacing + cellAscent + typoDescent); g.DrawLine(&grayPen, 0.0,y, REAL(DrawingWidth-1),y);
  144. #endif
  145. // Test font.GetHeight
  146. REAL fontHeight = font.GetHeight(&g);
  147. g.DrawLine(&blackPen, REAL(DrawingWidth-1),0.0, REAL(DrawingWidth-1),fontHeight);
  148. }
  149. *piY += 41*DrawingHeight/40;
  150. }