[GDI32_APITEST] Strengthen TextTransform more (#1568)
[reactos.git] / modules / rostests / apitests / gdi32 / TextTransform.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for World Transformation and font rendering
5 * PROGRAMMERS: Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8 #include "precomp.h"
9
10 typedef struct tagBITMAPINFOEX
11 {
12 BITMAPINFOHEADER bmiHeader;
13 RGBQUAD bmiColors[256];
14 } BITMAPINFOEX, FAR *LPBITMAPINFOEX;
15
16 #if 1
17 #define SaveBitmapToFile(f, h)
18 #else
19 static BOOL SaveBitmapToFile(LPCWSTR pszFileName, HBITMAP hbm)
20 {
21 BOOL f;
22 BITMAPFILEHEADER bf;
23 BITMAPINFOEX bmi;
24 BITMAPINFOHEADER *pbmih;
25 DWORD cb, cbColors;
26 HDC hDC;
27 HANDLE hFile;
28 LPVOID pBits;
29 BITMAP bm;
30
31 if (!GetObjectW(hbm, sizeof(BITMAP), &bm))
32 return FALSE;
33
34 pbmih = &bmi.bmiHeader;
35 ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER));
36 pbmih->biSize = sizeof(BITMAPINFOHEADER);
37 pbmih->biWidth = bm.bmWidth;
38 pbmih->biHeight = bm.bmHeight;
39 pbmih->biPlanes = 1;
40 pbmih->biBitCount = bm.bmBitsPixel;
41 pbmih->biCompression = BI_RGB;
42 pbmih->biSizeImage = bm.bmWidthBytes * bm.bmHeight;
43
44 if (bm.bmBitsPixel < 16)
45 cbColors = (1 << bm.bmBitsPixel) * sizeof(RGBQUAD);
46 else
47 cbColors = 0;
48
49 bf.bfType = 0x4d42;
50 bf.bfReserved1 = 0;
51 bf.bfReserved2 = 0;
52 cb = sizeof(BITMAPFILEHEADER) + pbmih->biSize + cbColors;
53 bf.bfOffBits = cb;
54 bf.bfSize = cb + pbmih->biSizeImage;
55
56 pBits = HeapAlloc(GetProcessHeap(), 0, pbmih->biSizeImage);
57 if (pBits == NULL)
58 return FALSE;
59
60 f = FALSE;
61 hDC = CreateCompatibleDC(NULL);
62 if (hDC)
63 {
64 if (GetDIBits(hDC, hbm, 0, bm.bmHeight, pBits, (BITMAPINFO *)&bmi,
65 DIB_RGB_COLORS))
66 {
67 hFile = CreateFileW(pszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
68 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL |
69 FILE_FLAG_WRITE_THROUGH, NULL);
70 if (hFile != INVALID_HANDLE_VALUE)
71 {
72 f = WriteFile(hFile, &bf, sizeof(BITMAPFILEHEADER), &cb, NULL) &&
73 WriteFile(hFile, &bmi, sizeof(BITMAPINFOHEADER), &cb, NULL) &&
74 WriteFile(hFile, bmi.bmiColors, cbColors, &cb, NULL) &&
75 WriteFile(hFile, pBits, pbmih->biSizeImage, &cb, NULL);
76 CloseHandle(hFile);
77
78 if (!f)
79 DeleteFileW(pszFileName);
80 }
81 }
82 DeleteDC(hDC);
83 }
84 HeapFree(GetProcessHeap(), 0, pBits);
85 return f;
86 }
87 #endif
88
89 typedef struct TEST_ENTRY
90 {
91 INT line; // line number
92 INT GraphicsMode; // GM_COMPATIBLE or GM_ADVANCED
93 POINT ptRef; // reference point
94 INT TextAlign;
95 XFORM xform;
96 BOOL xform_ok;
97 LPCWSTR filename;
98 INT cWhitePoints; // number of white points
99 POINT WhitePoints[4];
100 INT cBlackPoints; // number of black points
101 POINT BlackPoints[4];
102 } TEST_ENTRY;
103
104 #define WIDTH 400
105 #define HEIGHT 400
106 #define XCENTER (WIDTH / 2)
107 #define YCENTER (HEIGHT / 2)
108 #define BLACK RGB(0, 0, 0)
109 #define WHITE RGB(255, 255, 255)
110 #define LFHEIGHT -100
111
112 static const RECT s_rc = {0, 0, WIDTH, HEIGHT};
113 static HBRUSH s_hWhiteBrush = NULL;
114 static HPEN s_hRedPen = NULL;
115
116 #define POS(ix, iy) {XCENTER + (ix) * WIDTH/8, YCENTER + (iy) * HEIGHT/8}
117
118 #define NO_TRANS_1 \
119 3, {POS(1, 1), POS(-1, 1), POS(-1, -1)}, 1, {POS(1, -1)}
120
121 #define NO_TRANS_2 \
122 3, {POS(1, -1), POS(-1, 1), POS(-1, -1)}, 1, {POS(1, 1)}
123
124 static const TEST_ENTRY s_entries[] =
125 {
126 // GM_COMPATIBLE TA_BOTTOM
127 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {1, 0, 0, 1, 0, 0}, FALSE, L"000.bmp", NO_TRANS_1},
128 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {1.5, 0, 0, 1, 0, 0}, FALSE, L"001.bmp", NO_TRANS_1},
129 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {1, 0, 0, 1.5, 0, 0}, FALSE, L"002.bmp", NO_TRANS_1},
130 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {-1, 0, 0, 1, 0, 0}, FALSE, L"003.bmp", NO_TRANS_1},
131 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {1, 0, 0, -1, 0, 0}, FALSE, L"004.bmp", NO_TRANS_1},
132 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {0, 1, 1, 0, 0, 0}, FALSE, L"005.bmp", NO_TRANS_1},
133 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {0, -1, 1, 0, 0, 0}, FALSE, L"006.bmp", NO_TRANS_1},
134 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {0, 1, -1, 0, 0, 0}, FALSE, L"007.bmp", NO_TRANS_1},
135 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {0, -1, -1, 0, 0, 0}, FALSE, L"009.bmp", NO_TRANS_1},
136 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {0, 1, 0, 1, 0, 0}, FALSE, L"009.bmp", NO_TRANS_1},
137 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {1, 1, 1, 1, 0, 0}, FALSE, L"010.bmp", NO_TRANS_1},
138 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {0, 0, 0, 0, 0, 0}, FALSE, L"011.bmp", NO_TRANS_1},
139
140 // GM_COMPATIBLE TA_TOP
141 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_TOP, {1, 0, 0, 1, 0, 0}, FALSE, L"100.bmp", NO_TRANS_2},
142 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_TOP, {1.5, 0, 0, 1, 0, 0}, FALSE, L"101.bmp", NO_TRANS_2},
143 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_TOP, {1, 0, 0, 1.5, 0, 0}, FALSE, L"102.bmp", NO_TRANS_2},
144 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_TOP, {-1, 0, 0, 1, 0, 0}, FALSE, L"103.bmp", NO_TRANS_2},
145 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_TOP, {1, 0, 0, -1, 0, 0}, FALSE, L"104.bmp", NO_TRANS_2},
146 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_TOP, {0, 1, 1, 0, 0, 0}, FALSE, L"105.bmp", NO_TRANS_2},
147 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_TOP, {0, -1, 1, 0, 0, 0}, FALSE, L"106.bmp", NO_TRANS_2},
148 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_TOP, {0, 1, -1, 0, 0, 0}, FALSE, L"107.bmp", NO_TRANS_2},
149 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_TOP, {0, -1, -1, 0, 0, 0}, FALSE, L"109.bmp", NO_TRANS_2},
150 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_TOP, {0, 1, 0, 1, 0, 0}, FALSE, L"109.bmp", NO_TRANS_2},
151 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_TOP, {1, 1, 1, 1, 0, 0}, FALSE, L"110.bmp", NO_TRANS_2},
152 {__LINE__, GM_COMPATIBLE, {XCENTER, YCENTER}, TA_LEFT | TA_TOP, {0, 0, 0, 0, 0, 0}, FALSE, L"111.bmp", NO_TRANS_2},
153
154 // GM_ADVANCED TA_LEFT TA_BOTTOM
155 {__LINE__, GM_ADVANCED, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {1, 0, 0, 1, 0, 0}, TRUE, L"200.bmp", NO_TRANS_1},
156 {__LINE__, GM_ADVANCED, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {1.5, 0, 0, 1, 0, 0}, TRUE, L"201.bmp",
157 4, {POS(-1, -1), POS(1, -1), POS(-1, 1), POS(1, 1)}, 1, {POS(3, -1)}},
158 {__LINE__, GM_ADVANCED, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {1, 0, 0, 1.5, 0, 0}, TRUE, L"202.bmp",
159 3, {POS(-1, -1), POS(-1, 1), POS(1, -1)}, 1, {POS(1, 1)}},
160 {__LINE__, GM_ADVANCED, {-XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {-1, 0, 0, 1, 0, 0}, TRUE, L"203.bmp",
161 3, {POS(1, -1), POS(-1, 1), POS(1, -1)}, 1, {POS(-1, -1)}},
162 {__LINE__, GM_ADVANCED, {XCENTER, -YCENTER}, TA_LEFT | TA_BOTTOM, {1, 0, 0, -1, 0, 0}, TRUE, L"204.bmp",
163 3, {POS(-1, -1), POS(-1, 1), POS(1, -1)}, 1, {POS(1, 1)}},
164 {__LINE__, GM_ADVANCED, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {0, 1, 1, 0, 0, 0}, TRUE, L"205.bmp",
165 3, {POS(-1, -1), POS(1, 1), POS(1, -1)}, 1, {POS(-1, 1)}},
166 {__LINE__, GM_ADVANCED, {-XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {0, -1, 1, 0, 0, 0}, TRUE, L"206.bmp",
167 3, {POS(-1, 1), POS(1, 1), POS(1, -1)}, 1, {POS(-1, -1)}},
168 {__LINE__, GM_ADVANCED, {XCENTER, -YCENTER}, TA_LEFT | TA_BOTTOM, {0, 1, -1, 0, 0, 0}, TRUE, L"207.bmp",
169 3, {POS(-1, 1), POS(-1, -1), POS(1, -1)}, 1, {POS(1, 1)}},
170 {__LINE__, GM_ADVANCED, {-XCENTER, -YCENTER}, TA_LEFT | TA_BOTTOM, {0, -1, -1, 0, 0, 0}, TRUE, L"208.bmp",
171 3, {POS(-1, 1), POS(-1, -1), POS(1, 1)}, 1, {POS(1, -1)}},
172 {__LINE__, GM_ADVANCED, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {0, 1, 0, 1, 0, 0}, FALSE, L"209.bmp", NO_TRANS_1},
173 {__LINE__, GM_ADVANCED, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {1, 1, 1, 1, 0, 0}, FALSE, L"210.bmp", NO_TRANS_1},
174 {__LINE__, GM_ADVANCED, {XCENTER, YCENTER}, TA_LEFT | TA_BOTTOM, {0, 0, 0, 0, 0, 0}, FALSE, L"211.bmp", NO_TRANS_1},
175
176 // GM_ADVANCED TA_LEFT TA_TOP
177 {__LINE__, GM_ADVANCED, {0, 0}, TA_LEFT | TA_TOP, {2, 0, 0, 1, 0, 0}, TRUE, L"300.bmp",
178 4, {POS(-1, -1), POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, -3), POS(-1, -3)}},
179 {__LINE__, GM_ADVANCED, {0, 0}, TA_LEFT | TA_TOP, {1, 0, 0, 2, 0, 0}, TRUE, L"301.bmp",
180 4, {POS(-1, -1), POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, -3), POS(-3, -1)}},
181 {__LINE__, GM_ADVANCED, {0, 0}, TA_LEFT | TA_TOP, {2, 0, 0, 1, WIDTH/4, 0}, TRUE, L"302.bmp",
182 3, {POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-1, -3), POS(1, -3)}},
183 {__LINE__, GM_ADVANCED, {0, 0}, TA_LEFT | TA_TOP, {1, 0, 0, 2, WIDTH/4, 0}, TRUE, L"303.bmp",
184 3, {POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-1, -3), POS(-1, -1)}},
185 {__LINE__, GM_ADVANCED, {0, 0}, TA_LEFT | TA_TOP, {2, 0, 0, 1, 0, HEIGHT/4}, TRUE, L"304.bmp",
186 3, {POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, -1), POS(-1, -1)}},
187 {__LINE__, GM_ADVANCED, {0, 0}, TA_LEFT | TA_TOP, {1, 0, 0, 2, 0, HEIGHT/4}, TRUE, L"305.bmp",
188 4, {POS(-1, -1), POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, -1), POS(-3, 1)}},
189 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_LEFT | TA_TOP, {2, 0, 0, 1, 0, 0}, TRUE, L"306.bmp",
190 3, {POS(-1, -1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, 1), POS(-1, 1)}},
191 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_LEFT | TA_TOP, {1, 0, 0, 2, 0, -HEIGHT/2}, TRUE, L"307.bmp",
192 4, {POS(-1, -1), POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, 3), POS(-3, 1)}},
193 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_LEFT | TA_TOP, {2, 0, 0, 1, WIDTH/4, 0}, TRUE, L"308.bmp",
194 2, {POS(-1, -1), POS(1, -1)}, 2, {POS(-1, 1), POS(1, 1)}},
195 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_LEFT | TA_TOP, {1, 0, 0, 2, WIDTH/4, -HEIGHT/2}, TRUE, L"309.bmp",
196 3, {POS(-1, -1), POS(1, -1), POS(1, 1)}, 2, {POS(-1, 1), POS(-1, 3)}},
197 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_LEFT | TA_TOP, {2, 0, 0, 1, 0, HEIGHT/4}, TRUE, L"310.bmp",
198 4, {POS(-1, -1), POS(1, -1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, 3), POS(-1, 3)}},
199 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_LEFT | TA_TOP, {1, 0, 0, 2, 0, -HEIGHT/2}, TRUE, L"311.bmp",
200 4, {POS(-1, -1), POS(1, -1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, 3), POS(-3, 1)}},
201
202 // GM_ADVANCED TA_CENTER TA_TOP
203 {__LINE__, GM_ADVANCED, {XCENTER, 0}, TA_CENTER | TA_TOP, {2, 0, 0, 1, -WIDTH/4, 0}, TRUE, L"400.bmp",
204 4, {POS(-1, -1), POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(1, -3), POS(3, -3)}},
205 {__LINE__, GM_ADVANCED, {XCENTER, 0}, TA_CENTER | TA_TOP, {1, 0, 0, 2, WIDTH/8, 0}, TRUE, L"401.bmp",
206 3, {POS(-1, -1), POS(-1, 1), POS(1, 1)}, 2, {POS(1, -3), POS(1, -1)}},
207 {__LINE__, GM_ADVANCED, {XCENTER, 0}, TA_CENTER | TA_TOP, {2, 0, 0, 2, -WIDTH/4, HEIGHT/4}, TRUE, L"402.bmp",
208 2, {POS(-1, 1), POS(-1, -1)}, 4, {POS(1, -1), POS(3, -1), POS(1, 1), POS(3, 1)}},
209 {__LINE__, GM_ADVANCED, {XCENTER, 0}, TA_CENTER | TA_TOP, {1, 0, 0, 2, WIDTH/8, 0}, TRUE, L"403.bmp",
210 3, {POS(-1, -1), POS(-1, 1), POS(1, 1)}, 2, {POS(1, -1), POS(1, -3)}},
211 {__LINE__, GM_ADVANCED, {XCENTER, 0}, TA_CENTER | TA_TOP, {2, 0, 0, 1, -WIDTH/4, HEIGHT/4}, TRUE, L"404.bmp",
212 2, {POS(-1, 1), POS(1, 1)}, 2, {POS(1, -1), POS(3, -1)}},
213 {__LINE__, GM_ADVANCED, {XCENTER, 0}, TA_CENTER | TA_TOP, {1, 0, 0, 2, WIDTH/8, HEIGHT/4}, TRUE, L"405.bmp",
214 2, {POS(-1, -1), POS(-1, 1)}, 2, {POS(1, -1), POS(1, 1)}},
215 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_CENTER | TA_TOP, {1, 0, 0, 2, WIDTH/8, -HEIGHT/2}, TRUE, L"406.bmp",
216 4, {POS(-1, -1), POS(1, -1), POS(-1, 1), POS(1, 1)}, 2, {POS(-3, 1), POS(-3, 3)}},
217 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_CENTER | TA_TOP, {2, 0, 0, 1, WIDTH/4, -HEIGHT/2}, TRUE, L"407.bmp",
218 4, {POS(-1, -1), POS(1, -1), POS(-1, 1), POS(1, 1)}, 2, {POS(-3, -3), POS(-1, -3)}},
219 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_CENTER | TA_TOP, {2, 0, 0, 2, WIDTH/4, -HEIGHT/2}, TRUE, L"408.bmp",
220 3, {POS(-1, -1), POS(1, -1), POS(1, 1)}, 4, {POS(-3, 3), POS(-3, 1), POS(-3, 1), POS(-1, 1)}},
221 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_CENTER | TA_TOP, {1, 0, 0, 2, WIDTH/8, -HEIGHT/2}, TRUE, L"409.bmp",
222 4, {POS(-1, -1), POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, 3), POS(-3, 1)}},
223 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_CENTER | TA_TOP, {2, 0, 0, 1, WIDTH/4, -HEIGHT/2}, TRUE, L"410.bmp",
224 4, {POS(-1, -1), POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, -3), POS(-1, -3)}},
225 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_CENTER | TA_TOP, {1, 0, 0, 2, WIDTH/8, -HEIGHT/2}, TRUE, L"411.bmp",
226 4, {POS(-1, -1), POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, 1), POS(-3, 3)}},
227
228 // GM_ADVANCED TA_RIGHT TA_TOP
229 {__LINE__, GM_ADVANCED, {XCENTER, 0}, TA_RIGHT | TA_TOP, {2, 0, 0, 1, -WIDTH/4, 0}, TRUE, L"500.bmp",
230 4, {POS(-1, -1), POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-1, -3), POS(1, -3)}},
231 {__LINE__, GM_ADVANCED, {XCENTER, 0}, TA_RIGHT | TA_TOP, {1, 0, 0, 2, WIDTH/4, 0}, TRUE, L"501.bmp",
232 3, {POS(-1, -1), POS(-1, 1), POS(1, 1)}, 2, {POS(1, -3), POS(1, -1)}},
233 {__LINE__, GM_ADVANCED, {XCENTER, 0}, TA_RIGHT | TA_TOP, {2, 0, 0, 2, -WIDTH/4, HEIGHT/4}, TRUE, L"502.bmp",
234 0, {POS(0, 0)}, 4, {POS(-1, -1), POS(1, -1), POS(1, -1), POS(-1, -1)}},
235 {__LINE__, GM_ADVANCED, {XCENTER, 0}, TA_RIGHT | TA_TOP, {1, 0, 0, 2, WIDTH/4, 0}, TRUE, L"503.bmp",
236 3, {POS(-1, 1), POS(1, 1), POS(-1, -1)}, 2, {POS(1, -1), POS(1, -3)}},
237 {__LINE__, GM_ADVANCED, {XCENTER, 0}, TA_RIGHT | TA_TOP, {2, 0, 0, 1, -WIDTH/4, HEIGHT/4}, TRUE, L"504.bmp",
238 2, {POS(-1, 1), POS(1, 1)}, 2, {POS(-1, -1), POS(1, -1)}},
239 {__LINE__, GM_ADVANCED, {XCENTER, 0}, TA_RIGHT | TA_TOP, {1, 0, 0, 2, WIDTH/4, HEIGHT/4}, TRUE, L"505.bmp",
240 2, {POS(-1, -1), POS(-1, 1)}, 2, {POS(1, -1), POS(1, 1)}},
241 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_RIGHT | TA_TOP, {2, 0, 0, 1, WIDTH/2, -HEIGHT/2}, TRUE, L"506.bmp",
242 4, {POS(-1, -1), POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, -3), POS(-1, -3)}},
243 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_RIGHT | TA_TOP, {1, 0, 0, 2, WIDTH/2, -HEIGHT/2}, TRUE, L"507.bmp",
244 3, {POS(-1, -1), POS(1, -1), POS(1, 1)}, 2, {POS(-1, 3), POS(-1, 1)}},
245 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_RIGHT | TA_TOP, {2, 0, 0, 2, WIDTH, -HEIGHT/2}, TRUE, L"508.bmp",
246 3, {POS(-1, -1), POS(-1, 1), POS(1, -1)}, 4, {POS(1, 1), POS(3, 1), POS(1, 3), POS(3, 3)}},
247 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_RIGHT | TA_TOP, {1, 0, 0, 2, WIDTH/2, -HEIGHT/2}, TRUE, L"509.bmp",
248 3, {POS(-1, -1), POS(1, -1), POS(1, 1)}, 2, {POS(-1, 1), POS(-1, 3)}},
249 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_RIGHT | TA_TOP, {2, 0, 0, 1, WIDTH/2, -HEIGHT/4}, TRUE, L"510.bmp",
250 3, {POS(-1, 1), POS(1, -1), POS(1, 1)}, 2, {POS(-3, -1), POS(-1, -1)}},
251 {__LINE__, GM_ADVANCED, {0, YCENTER}, TA_RIGHT | TA_TOP, {1, 0, 0, 2, WIDTH/2, -HEIGHT/2}, TRUE, L"511.bmp",
252 3, {POS(-1, -1), POS(1, -1), POS(1, 1)}, 2, {POS(-1, 1), POS(-1, 3)}},
253 };
254 static const INT s_entry_count = (INT)(sizeof(s_entries) / sizeof(s_entries[0]));
255
256 static void DoTestEntry(const TEST_ENTRY *entry, HDC hDC, HBITMAP hbm)
257 {
258 HGDIOBJ hbmOld, hPenOld;
259 INT i;
260 COLORREF rgb;
261 BOOL ret;
262 static const WCHAR s_chBlackBox = L'g';
263
264 SetGraphicsMode(hDC, entry->GraphicsMode);
265
266 hbmOld = SelectObject(hDC, hbm);
267 {
268 ModifyWorldTransform(hDC, NULL, MWT_IDENTITY);
269
270 FillRect(hDC, &s_rc, s_hWhiteBrush);
271
272 hPenOld = SelectObject(hDC, s_hRedPen);
273 {
274 MoveToEx(hDC, XCENTER / 2, 0, NULL);
275 LineTo(hDC, XCENTER / 2, HEIGHT);
276
277 MoveToEx(hDC, XCENTER, 0, NULL);
278 LineTo(hDC, XCENTER, HEIGHT);
279
280 MoveToEx(hDC, XCENTER * 3 / 2, 0, NULL);
281 LineTo(hDC, XCENTER * 3 / 2, HEIGHT);
282
283 MoveToEx(hDC, 0, YCENTER / 2, NULL);
284 LineTo(hDC, WIDTH, YCENTER / 2);
285
286 MoveToEx(hDC, 0, YCENTER, NULL);
287 LineTo(hDC, WIDTH, YCENTER);
288
289 MoveToEx(hDC, 0, YCENTER * 3 / 2, NULL);
290 LineTo(hDC, WIDTH, YCENTER * 3 / 2);
291 }
292 SelectObject(hDC, hPenOld);
293
294 ret = SetWorldTransform(hDC, &entry->xform);
295 ok(ret == entry->xform_ok, "Line %d: SetWorldTransform returned %d\n", entry->line, ret);
296
297 SetTextAlign(hDC, entry->TextAlign);
298
299 TextOutW(hDC, entry->ptRef.x, entry->ptRef.y, &s_chBlackBox, 1);
300
301 ModifyWorldTransform(hDC, NULL, MWT_IDENTITY);
302
303 for (i = 0; i < entry->cWhitePoints; ++i)
304 {
305 rgb = GetPixel(hDC, entry->WhitePoints[i].x, entry->WhitePoints[i].y);
306 ok(rgb == WHITE, "Line %d: %d: (%ld, %ld) is not white\n", entry->line, i,
307 entry->WhitePoints[i].x, entry->WhitePoints[i].y);
308 }
309
310 for (i = 0; i < entry->cBlackPoints; ++i)
311 {
312 rgb = GetPixel(hDC, entry->BlackPoints[i].x, entry->BlackPoints[i].y);
313 ok(rgb == BLACK, "Line %d: %d: (%ld, %ld) is not black\n", entry->line, i,
314 entry->BlackPoints[i].x, entry->BlackPoints[i].y);
315 }
316 }
317 SelectObject(hDC, hbmOld);
318
319 SaveBitmapToFile(entry->filename, hbm);
320 }
321
322 START_TEST(TextTransform)
323 {
324 HDC hDC;
325 BITMAPINFO bmi;
326 LPVOID pvBits;
327 HBITMAP hbm;
328 LOGFONTA lf;
329 HFONT hFont;
330 HGDIOBJ hFontOld;
331 INT i;
332
333 s_hWhiteBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
334 s_hRedPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
335
336 hDC = CreateCompatibleDC(NULL);
337 ok(hDC != NULL, "hDC was NULL.\n");
338
339 SetBkMode(hDC, TRANSPARENT);
340 SetMapMode(hDC, MM_ANISOTROPIC);
341
342 ZeroMemory(&bmi, sizeof(bmi));
343 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
344 bmi.bmiHeader.biWidth = WIDTH;
345 bmi.bmiHeader.biHeight = HEIGHT;
346 bmi.bmiHeader.biPlanes = 1;
347 bmi.bmiHeader.biBitCount = 24;
348 hbm = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0);
349 ok(hbm != NULL, "hbm was NULL.\n");
350
351 ZeroMemory(&lf, sizeof(lf));
352 lf.lfHeight = LFHEIGHT;
353 lf.lfCharSet = DEFAULT_CHARSET;
354 lstrcpyA(lf.lfFaceName, "Marlett");
355 hFont = CreateFontIndirectA(&lf);
356 ok(hFont != NULL, "hFont was NULL.\n");
357
358 hFontOld = SelectObject(hDC, hFont);
359 for (i = 0; i < s_entry_count; ++i)
360 {
361 DoTestEntry(&s_entries[i], hDC, hbm);
362 }
363 SelectObject(hDC, hFontOld);
364
365 DeleteObject(hFont);
366 DeleteObject(hbm);
367
368 DeleteObject(s_hWhiteBrush);
369 DeleteObject(s_hRedPen);
370
371 DeleteDC(hDC);
372 }