• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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