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