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.

309 lines
8.2 KiB

  1. //// DspScaling.CPP - DIsplay effect of hinting on text scaling
  2. //
  3. // Tests for clipping and alignment problems in scaled text
  4. //
  5. // Fixed pitch font misalignment
  6. // Leading space alignment
  7. // Overhang sufficient for italic and other overhanging glyphs
  8. //
  9. #include "precomp.hxx"
  10. #include "global.h"
  11. #include "gdiplus.h"
  12. // Makebitmap
  13. void MakeBitmap(
  14. IN INT width,
  15. IN INT height,
  16. OUT HBITMAP *bitmap,
  17. OUT DWORD **bits
  18. )
  19. {
  20. struct {
  21. BITMAPINFOHEADER bmih;
  22. RGBQUAD rgbquad[2];
  23. } bmi;
  24. bmi.bmih.biSize = sizeof(bmi.bmih);
  25. bmi.bmih.biWidth = width;
  26. bmi.bmih.biHeight = height;
  27. bmi.bmih.biPlanes = 1;
  28. bmi.bmih.biBitCount = 32;
  29. bmi.bmih.biCompression = BI_RGB;
  30. bmi.bmih.biSizeImage = 0;
  31. bmi.bmih.biXPelsPerMeter = 3780; // 96 dpi
  32. bmi.bmih.biYPelsPerMeter = 3780; // 96 dpi
  33. bmi.bmih.biClrUsed = 0;
  34. bmi.bmih.biClrImportant = 0;
  35. memset(bmi.rgbquad, 0, 2 * sizeof(RGBQUAD));
  36. *bitmap = CreateDIBSection(
  37. NULL,
  38. (BITMAPINFO*)&bmi,
  39. DIB_RGB_COLORS,
  40. (void**)bits,
  41. NULL,
  42. NULL
  43. );
  44. // Initialise bitmap to white
  45. memset(*bits, 0xFF, width*height*sizeof(DWORD));
  46. }
  47. void PaintStringAsDots(
  48. HDC hdc,
  49. INT x,
  50. INT *y,
  51. INT displayWidth,
  52. INT ppem,
  53. BOOL useGdi
  54. )
  55. {
  56. HBITMAP glyphs;
  57. DWORD *gbits;
  58. INT height = (ppem * 3) / 2;
  59. INT width = height * 16;
  60. MakeBitmap(width, height, &glyphs, &gbits);
  61. HDC hdcg = CreateCompatibleDC(hdc);
  62. if (!(glyphs && hdcg))
  63. {
  64. return;
  65. }
  66. SelectObject(hdcg, glyphs);
  67. if (useGdi)
  68. {
  69. // Output with GDI
  70. HFONT oldFont = (HFONT)SelectObject(hdcg, CreateFontW(
  71. -ppem, // height of font
  72. 0, // average character width
  73. 0, // angle of escapement
  74. 0, // base-line orientation angle
  75. g_style[0].style & FontStyleBold ? 700 : 400, // font weight
  76. g_style[0].style & FontStyleItalic ? 1 : 0, // italic attribute option
  77. 0, // underline attribute option
  78. 0, // strikeout attribute option
  79. DEFAULT_CHARSET, // character set identifier
  80. 0, // output precision
  81. 0, // clipping precision
  82. 0, // output quality
  83. 0, // pitch and family
  84. g_style[0].faceName // typeface name
  85. ));
  86. SetBkMode(hdcg, TRANSPARENT);
  87. ExtTextOutW(hdcg, 0,0, ETO_IGNORELANGUAGE, NULL, g_wcBuf, g_iTextLen, NULL);
  88. DeleteObject(SelectObject(hdcg, oldFont));
  89. }
  90. else
  91. {
  92. // Output with Gdiplus
  93. Graphics g(hdcg);
  94. Font(
  95. &FontFamily(g_style[0].faceName),
  96. REAL(ppem),
  97. g_style[0].style,
  98. UnitPixel
  99. );
  100. StringFormat format(g_typographic ? StringFormat::GenericTypographic() : StringFormat::GenericDefault());
  101. format.SetFormatFlags(g_formatFlags);
  102. format.SetTrimming(g_lineTrim);
  103. format.SetAlignment(g_align);
  104. format.SetLineAlignment(g_lineAlign);
  105. format.SetHotkeyPrefix(g_hotkey);
  106. g.DrawString(
  107. g_wcBuf,
  108. g_iTextLen,
  109. &Font(
  110. &FontFamily(g_style[0].faceName),
  111. REAL(ppem),
  112. g_style[0].style,
  113. UnitPixel
  114. ),
  115. RectF(0,0, REAL(width), REAL(height)),
  116. &format,
  117. g_textBrush
  118. );
  119. }
  120. // Display scaled bitmap
  121. StretchBlt(hdc, x, *y, displayWidth, displayWidth/16, hdcg, 0, 0, width, height, SRCCOPY);
  122. *y += displayWidth/16;
  123. DeleteObject(hdcg);
  124. DeleteObject(glyphs);
  125. }
  126. void PaintScaling(
  127. HDC hdc,
  128. int *piY,
  129. RECT *prc,
  130. int iLineHeight) {
  131. // Establish available width and height in device coordinates
  132. int plainTextWidth = prc->right - prc->left;
  133. int plainTextHeight = prc->bottom - *piY;
  134. // Paint eqach resolution first with GDI, then again with GdiPlus
  135. PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 11, TRUE); // 96 dpi 8pt
  136. PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 11, FALSE); // 96 dpi 8pt
  137. PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 13, TRUE); // 120 dpi 8pt
  138. PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 13, FALSE); // 120 dpi 8pt
  139. PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 17, TRUE); // 150 dpi 8pt
  140. PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 17, FALSE); // 150 dpi 8pt
  141. PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 33, TRUE); // 300 dpi 8pt
  142. PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 33, FALSE); // 300 dpi 8pt
  143. PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 67, TRUE); // 600 dpi 8pt
  144. PaintStringAsDots(hdc, prc->left, piY, plainTextWidth, 67, FALSE); // 600 dpi 8pt
  145. }
  146. void DummyPaintScaling(
  147. HDC hdc,
  148. int *piY,
  149. RECT *prc,
  150. int iLineHeight
  151. )
  152. {
  153. int icpLineStart; // First character of line
  154. int icpLineEnd; // End of line (end of buffer or index of CR character)
  155. // Establish available width and height in device coordinates
  156. int plainTextWidth = prc->right - prc->left;
  157. int plainTextHeight = prc->bottom - *piY;
  158. Graphics g(hdc);
  159. Matrix matrix;
  160. g.ResetTransform();
  161. g.SetPageUnit(UnitPixel);
  162. g.TranslateTransform(REAL(prc->left), REAL(*piY));
  163. g.SetSmoothingMode(g_SmoothingMode);
  164. g.SetTextContrast(g_GammaValue);
  165. g.SetTextRenderingHint(g_TextMode);
  166. SolidBrush whiteBrush(Color(0xff, 0xff, 0xff));
  167. Color grayColor(0xc0, 0xc0, 0xc0);
  168. SolidBrush grayBrush(grayColor);
  169. Pen grayPen(&grayBrush, 1.0);
  170. Color blackColor(0, 0, 0);
  171. SolidBrush blackBrush(blackColor);
  172. Pen blackPen(&blackBrush, 1.0);
  173. // Clear the background
  174. RectF rEntire(0, 0, REAL(plainTextWidth), REAL(plainTextHeight));
  175. g.FillRectangle(g_textBackBrush, rEntire);
  176. // Apply selected world transform, adjusted to middle of the plain text
  177. // area.
  178. g.SetTransform(&g_WorldTransform);
  179. g.TranslateTransform(
  180. REAL(prc->left + plainTextWidth/2),
  181. REAL(*piY + plainTextHeight/2),
  182. MatrixOrderAppend);
  183. // Preset a StringFormat with user settings
  184. StringFormat format(g_formatFlags);
  185. format.SetAlignment(g_align);
  186. format.SetLineAlignment(g_lineAlign);
  187. format.SetHotkeyPrefix(g_hotkey);
  188. double columnWidth = 50*plainTextWidth/300;
  189. REAL tab[3] = {REAL(columnWidth/4),
  190. REAL(columnWidth*3/16),
  191. REAL(columnWidth*1/8)};
  192. format.SetTabStops(0.0, sizeof(tab)/sizeof(REAL), tab);
  193. // Display string at a range of sizes
  194. double x = -25*plainTextWidth/100;
  195. double y = -25*plainTextHeight/100;
  196. for (INT i=6; i<20; i++)
  197. {
  198. Font font(
  199. &FontFamily(g_style[0].faceName),
  200. REAL(i),
  201. g_style[0].style,
  202. g_fontUnit
  203. );
  204. REAL cellHeight = font.GetHeight(&g);
  205. if (y+cellHeight > 25*plainTextHeight/100)
  206. {
  207. // Start a new column ...
  208. y = -25*plainTextWidth/100;
  209. x += columnWidth;
  210. }
  211. RectF textRect(REAL(x), REAL(y), REAL(9*columnWidth/10), cellHeight);
  212. g.DrawString(g_wcBuf, g_iTextLen, &font, textRect, &format, g_textBrush);
  213. // Draw formatting rectangle around box
  214. g.DrawRectangle(&grayPen, textRect);
  215. y += cellHeight + 5;
  216. }
  217. *piY += plainTextHeight;
  218. }