]> git.saurik.com Git - apple/icu.git/blob - icuSources/samples/layout/layout.cpp
ICU-64252.0.1.tar.gz
[apple/icu.git] / icuSources / samples / layout / layout.cpp
1 /*
2 *******************************************************************************
3 *
4 * © 2016 and later: Unicode, Inc. and others.
5 * License & terms of use: http://www.unicode.org/copyright.html#License
6 *
7 *******************************************************************************
8 *******************************************************************************
9 *
10 * Copyright (C) 1999-2007, International Business Machines
11 * Corporation and others. All Rights Reserved.
12 *
13 *******************************************************************************
14 * file name: Layout.cpp
15 *
16 * created on: 08/03/2000
17 * created by: Eric R. Mader
18 */
19
20 #include <windows.h>
21 #include <stdio.h>
22
23 #include "paragraph.h"
24
25 #include "GDIGUISupport.h"
26 #include "GDIFontMap.h"
27 #include "UnicodeReader.h"
28 #include "ScriptCompositeFontInstance.h"
29
30 #include "resource.h"
31
32 #define ARRAY_LENGTH(array) (sizeof array / sizeof array[0])
33
34 struct Context
35 {
36 le_int32 width;
37 le_int32 height;
38 Paragraph *paragraph;
39 };
40
41 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
42
43 #define APP_NAME "LayoutSample"
44
45 TCHAR szAppName[] = TEXT(APP_NAME);
46
47 void PrettyTitle(HWND hwnd, char *fileName)
48 {
49 char title[MAX_PATH + 64];
50
51 sprintf(title, "%s - %s", APP_NAME, fileName);
52
53 SetWindowTextA(hwnd, title);
54 }
55
56 void InitParagraph(HWND hwnd, Context *context)
57 {
58 SCROLLINFO si;
59
60 if (context->paragraph != NULL) {
61 // FIXME: does it matter what we put in the ScrollInfo
62 // if the window's been minimized?
63 if (context->width > 0 && context->height > 0) {
64 context->paragraph->breakLines(context->width, context->height);
65 }
66
67 si.cbSize = sizeof si;
68 si.fMask = SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL;
69 si.nMin = 0;
70 si.nMax = context->paragraph->getLineCount() - 1;
71 si.nPage = context->height / context->paragraph->getLineHeight();
72 SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
73 }
74 }
75
76 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
77 {
78 HWND hwnd;
79 HACCEL hAccel;
80 MSG msg;
81 WNDCLASS wndclass;
82 LEErrorCode status = LE_NO_ERROR;
83
84 wndclass.style = CS_HREDRAW | CS_VREDRAW;
85 wndclass.lpfnWndProc = WndProc;
86 wndclass.cbClsExtra = 0;
87 wndclass.cbWndExtra = sizeof(LONG);
88 wndclass.hInstance = hInstance;
89 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
90 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
91 wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
92 wndclass.lpszMenuName = szAppName;
93 wndclass.lpszClassName = szAppName;
94
95 if (!RegisterClass(&wndclass)) {
96 MessageBox(NULL, TEXT("This demo only runs on Windows 2000!"), szAppName, MB_ICONERROR);
97
98 return 0;
99 }
100
101 hAccel = LoadAccelerators(hInstance, szAppName);
102
103 hwnd = CreateWindow(szAppName, NULL,
104 WS_OVERLAPPEDWINDOW | WS_VSCROLL,
105 CW_USEDEFAULT, CW_USEDEFAULT,
106 600, 400,
107 NULL, NULL, hInstance, NULL);
108
109 ShowWindow(hwnd, iCmdShow);
110 UpdateWindow(hwnd);
111
112 while (GetMessage(&msg, NULL, 0, 0)) {
113 if (!TranslateAccelerator(hwnd, hAccel, &msg)) {
114 TranslateMessage(&msg);
115 DispatchMessage(&msg);
116 }
117 }
118
119 UnregisterClass(szAppName, hInstance);
120 return msg.wParam;
121 }
122
123 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
124 {
125 HDC hdc;
126 Context *context;
127 static le_int32 windowCount = 0;
128 static GDIFontMap *fontMap = NULL;
129 static GDISurface *surface = NULL;
130 static GDIGUISupport *guiSupport = new GDIGUISupport();
131 static ScriptCompositeFontInstance *font = NULL;
132
133 switch (message) {
134 case WM_CREATE:
135 {
136 LEErrorCode fontStatus = LE_NO_ERROR;
137
138 hdc = GetDC(hwnd);
139 surface = new GDISurface(hdc);
140
141 fontMap = new GDIFontMap(surface, "FontMap.GDI", 24, guiSupport, fontStatus);
142 font = new ScriptCompositeFontInstance(fontMap);
143
144 if (LE_FAILURE(fontStatus)) {
145 ReleaseDC(hwnd, hdc);
146 return -1;
147 }
148
149 context = new Context();
150
151 context->width = 600;
152 context->height = 400;
153
154 context->paragraph = Paragraph::paragraphFactory("Sample.txt", font, guiSupport);
155 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) context);
156
157 windowCount += 1;
158 ReleaseDC(hwnd, hdc);
159
160 PrettyTitle(hwnd, "Sample.txt");
161 return 0;
162 }
163
164 case WM_SIZE:
165 {
166 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
167 context->width = LOWORD(lParam);
168 context->height = HIWORD(lParam);
169
170 InitParagraph(hwnd, context);
171 return 0;
172 }
173
174 case WM_VSCROLL:
175 {
176 SCROLLINFO si;
177 le_int32 vertPos;
178
179 si.cbSize = sizeof si;
180 si.fMask = SIF_ALL;
181 GetScrollInfo(hwnd, SB_VERT, &si);
182
183 vertPos = si.nPos;
184
185 switch (LOWORD(wParam))
186 {
187 case SB_TOP:
188 si.nPos = si.nMin;
189 break;
190
191 case SB_BOTTOM:
192 si.nPos = si.nMax;
193 break;
194
195 case SB_LINEUP:
196 si.nPos -= 1;
197 break;
198
199 case SB_LINEDOWN:
200 si.nPos += 1;
201 break;
202
203 case SB_PAGEUP:
204 si.nPos -= si.nPage;
205 break;
206
207 case SB_PAGEDOWN:
208 si.nPos += si.nPage;
209 break;
210
211 case SB_THUMBTRACK:
212 si.nPos = si.nTrackPos;
213 break;
214
215 default:
216 break;
217 }
218
219 si.fMask = SIF_POS;
220 SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
221 GetScrollInfo(hwnd, SB_VERT, &si);
222
223 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
224
225 if (context->paragraph != NULL && si.nPos != vertPos) {
226 ScrollWindow(hwnd, 0, context->paragraph->getLineHeight() * (vertPos - si.nPos), NULL, NULL);
227 UpdateWindow(hwnd);
228 }
229
230 return 0;
231 }
232
233 case WM_PAINT:
234 {
235 PAINTSTRUCT ps;
236 SCROLLINFO si;
237 le_int32 firstLine, lastLine;
238
239 hdc = BeginPaint(hwnd, &ps);
240 SetBkMode(hdc, TRANSPARENT);
241
242 si.cbSize = sizeof si;
243 si.fMask = SIF_ALL;
244 GetScrollInfo(hwnd, SB_VERT, &si);
245
246 firstLine = si.nPos;
247
248 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
249
250 if (context->paragraph != NULL) {
251 surface->setHDC(hdc);
252
253 // NOTE: si.nPos + si.nPage may include a partial line at the bottom
254 // of the window. We need this because scrolling assumes that the
255 // partial line has been painted.
256 lastLine = min (si.nPos + (le_int32) si.nPage, context->paragraph->getLineCount() - 1);
257
258 context->paragraph->draw(surface, firstLine, lastLine);
259 }
260
261 EndPaint(hwnd, &ps);
262 return 0;
263 }
264
265 case WM_COMMAND:
266 switch (LOWORD(wParam)) {
267 case IDM_FILE_OPEN:
268 {
269 OPENFILENAMEA ofn;
270 char szFileName[MAX_PATH], szTitleName[MAX_PATH];
271 static char szFilter[] = "Text Files (.txt)\0*.txt\0"
272 "All Files (*.*)\0*.*\0\0";
273
274 ofn.lStructSize = sizeof (OPENFILENAMEA);
275 ofn.hwndOwner = hwnd;
276 ofn.hInstance = NULL;
277 ofn.lpstrFilter = szFilter;
278 ofn.lpstrCustomFilter = NULL;
279 ofn.nMaxCustFilter = 0;
280 ofn.nFilterIndex = 0;
281 ofn.lpstrFile = szFileName;
282 ofn.nMaxFile = MAX_PATH;
283 ofn.lpstrFileTitle = szTitleName;
284 ofn.nMaxFileTitle = MAX_PATH;
285 ofn.lpstrInitialDir = NULL;
286 ofn.lpstrTitle = NULL;
287 ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
288 ofn.nFileOffset = 0;
289 ofn.nFileExtension = 0;
290 ofn.lpstrDefExt = "txt";
291 ofn.lCustData = 0L;
292 ofn.lpfnHook = NULL;
293 ofn.lpTemplateName = NULL;
294
295 szFileName[0] = '\0';
296
297 if (GetOpenFileNameA(&ofn)) {
298 hdc = GetDC(hwnd);
299 surface->setHDC(hdc);
300
301 Paragraph *newParagraph = Paragraph::paragraphFactory(szFileName, font, guiSupport);
302
303 if (newParagraph != NULL) {
304 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
305
306 if (context->paragraph != NULL) {
307 delete context->paragraph;
308 }
309
310 context->paragraph = newParagraph;
311 InitParagraph(hwnd, context);
312 PrettyTitle(hwnd, szTitleName);
313 InvalidateRect(hwnd, NULL, TRUE);
314
315 }
316 }
317
318 //ReleaseDC(hwnd, hdc);
319
320 return 0;
321 }
322
323 case IDM_FILE_EXIT:
324 case IDM_FILE_CLOSE:
325 SendMessage(hwnd, WM_CLOSE, 0, 0);
326 return 0;
327
328 case IDM_HELP_ABOUTLAYOUTSAMPLE:
329 MessageBox(hwnd, TEXT("Windows Layout Sample 0.1\n")
330 TEXT("Copyright (C) 1998-2005 By International Business Machines Corporation and others.\n")
331 TEXT("Author: Eric Mader"),
332 szAppName, MB_ICONINFORMATION | MB_OK);
333 return 0;
334
335 }
336 break;
337
338
339 case WM_DESTROY:
340 {
341 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
342
343 if (context != NULL && context->paragraph != NULL) {
344 delete context->paragraph;
345 }
346
347 delete context;
348
349 if (--windowCount <= 0) {
350 delete font;
351 delete surface;
352
353 PostQuitMessage(0);
354 }
355
356 return 0;
357 }
358
359 default:
360 return DefWindowProc(hwnd, message, wParam, lParam);
361 }
362
363 return 0;
364 }