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.

205 lines
5.9 KiB

  1. //// DspDraws.CPP - Display plaintext using DrawString API
  2. //
  3. //
  4. #include "precomp.hxx"
  5. #include "global.h"
  6. #include "gdiplus.h"
  7. void PaintGlyphs(
  8. HDC hdc,
  9. int *piY,
  10. RECT *prc,
  11. int iLineHeight) {
  12. int icpLineStart; // First character of line
  13. int icpLineEnd; // End of line (end of buffer or index of CR character)
  14. HFONT hFont;
  15. HFONT hOldFont;
  16. LOGFONT lf;
  17. INT row;
  18. INT column;
  19. // Establish available width and height in device coordinates
  20. int DrawingWidth = prc->right - prc->left;
  21. int DrawingHeight = prc->bottom - *piY;
  22. // Establish a Graphics with 0,0 at the top left of the drawing area
  23. Graphics g(hdc);
  24. Matrix matrix;
  25. g.ResetTransform();
  26. g.SetPageUnit(UnitPixel);
  27. g.TranslateTransform(REAL(prc->left), REAL(*piY));
  28. // Clear the background
  29. RectF rEntire(0, 0, REAL(DrawingWidth), REAL(DrawingHeight));
  30. SolidBrush whiteBrush(Color(0xff, 0xff, 0xff));
  31. g.FillRectangle(&whiteBrush, rEntire);
  32. // Leave a little space for right and bottom margins
  33. DrawingWidth -= DrawingWidth/40;
  34. DrawingHeight -= DrawingHeight/40;
  35. // Fill in a grid
  36. SolidBrush grayBrush(Color(0xc0, 0xc0, 0xc0));
  37. Pen grayPen(&grayBrush, 2.0);
  38. SolidBrush darkGrayBrush(Color(0x80, 0x80, 0x80));
  39. Pen darkGrayPen(&darkGrayBrush, 2.0);
  40. Color blackColor(0, 0, 0);
  41. SolidBrush blackBrush(blackColor);
  42. Pen blackPen(&blackBrush, 2.0);
  43. for (row = 0; row <= g_GlyphRows; row++)
  44. {
  45. g.DrawLine(&grayPen,
  46. 0, row*(DrawingHeight-1)/g_GlyphRows,
  47. DrawingWidth-1, row*(DrawingHeight-1)/g_GlyphRows);
  48. }
  49. for (column = 0; column <= g_GlyphColumns; column++)
  50. {
  51. g.DrawLine(&grayPen,
  52. column*(DrawingWidth-1)/g_GlyphColumns, 0,
  53. column*(DrawingWidth-1)/g_GlyphColumns, DrawingHeight-1);
  54. }
  55. // Identify cell dimensions
  56. INT cellHeight = (DrawingHeight-1)/g_GlyphRows;
  57. INT cellWidth = (DrawingWidth-1)/g_GlyphColumns;
  58. Font font(&FontFamily(g_style[0].faceName), REAL(cellHeight)*2/3, 0, UnitWorld);
  59. REAL zero = 0;
  60. INT DriverStringFlags = 0;
  61. if (g_CmapLookup)
  62. {
  63. DriverStringFlags |= DriverStringOptionsCmapLookup;
  64. }
  65. if (g_VerticalForms)
  66. {
  67. DriverStringFlags |= DriverStringOptionsVertical;
  68. }
  69. // Loop through each character cell
  70. for (row = 0; row < g_GlyphRows; row++)
  71. {
  72. for (column = 0; column < g_GlyphColumns; column++)
  73. {
  74. UINT16 glyphIndex;
  75. if (g_HorizontalChart)
  76. {
  77. glyphIndex = g_GlyphFirst + row*g_GlyphColumns + column;
  78. }
  79. else
  80. {
  81. glyphIndex = g_GlyphFirst + column*g_GlyphRows + row;
  82. }
  83. // Set world transform to apply to individual glyphs (excludes translation)
  84. g.ResetTransform();
  85. g.SetTransform(&g_WorldTransform);
  86. // Translate world transform to centre of glyph cell
  87. REAL cellOriginX = float(prc->left + column*(DrawingWidth-1)/g_GlyphColumns) + float(cellWidth)/2;
  88. REAL cellOriginY = float(*piY + row*(DrawingHeight-1)/g_GlyphRows) + float(cellHeight)/2;
  89. g.TranslateTransform(cellOriginX, cellOriginY, MatrixOrderAppend);
  90. // Get glyph bounding box
  91. RectF untransformedBoundingBox; // Without font transform
  92. RectF transformedBoundingBox; // With font transform
  93. g.MeasureDriverString(
  94. &glyphIndex, 1,
  95. &font,
  96. &PointF(0,0),
  97. DriverStringFlags,
  98. NULL,
  99. &untransformedBoundingBox
  100. );
  101. g.MeasureDriverString(
  102. &glyphIndex, 1,
  103. &font,
  104. &PointF(0,0),
  105. DriverStringFlags,
  106. &g_FontTransform,
  107. &transformedBoundingBox
  108. );
  109. REAL glyphOriginX = - transformedBoundingBox.Width/2 - transformedBoundingBox.X;
  110. REAL glyphOriginY = - transformedBoundingBox.Height/2 - transformedBoundingBox.Y;
  111. if (g_ShowCell)
  112. {
  113. // Show cell around transformed glyph
  114. transformedBoundingBox.X = - transformedBoundingBox.Width/2;
  115. transformedBoundingBox.Y = - transformedBoundingBox.Height/2;
  116. g.DrawRectangle(&darkGrayPen, transformedBoundingBox);
  117. }
  118. // Display the glyph
  119. g.DrawDriverString(
  120. &glyphIndex, 1,
  121. &font,
  122. &blackBrush,
  123. &PointF(glyphOriginX, glyphOriginY),
  124. DriverStringFlags,
  125. &g_FontTransform
  126. );
  127. if (g_ShowCell)
  128. {
  129. // Show transformed cell around untransformed glyph
  130. g.MultiplyTransform(&g_FontTransform);
  131. glyphOriginX = - untransformedBoundingBox.Width/2 - untransformedBoundingBox.X;
  132. glyphOriginY = - untransformedBoundingBox.Height/2 - untransformedBoundingBox.Y;
  133. untransformedBoundingBox.X = - untransformedBoundingBox.Width/2;
  134. untransformedBoundingBox.Y = - untransformedBoundingBox.Height/2;
  135. g.DrawRectangle(&darkGrayPen, untransformedBoundingBox);
  136. // Show baseline
  137. g.DrawLine(
  138. &darkGrayPen,
  139. glyphOriginX - cellWidth/20,
  140. glyphOriginY,
  141. glyphOriginX + untransformedBoundingBox.Width + cellWidth/20 + 1,
  142. glyphOriginY
  143. );
  144. }
  145. }
  146. }
  147. *piY += DrawingHeight;
  148. }