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