2 *******************************************************************************
4 * Copyright (C) 2016 and later: Unicode, Inc. and others.
5 * License & terms of use: http://www.unicode.org/copyright.html#License
7 *******************************************************************************
8 *******************************************************************************
10 * Copyright (C) 1999-2007, International Business Machines
11 * Corporation and others. All Rights Reserved.
13 *******************************************************************************
14 * file name: Layout.cpp
16 * created on: 08/03/2000
17 * created by: Eric R. Mader
23 #include "paragraph.h"
25 #include "GDIGUISupport.h"
26 #include "GDIFontMap.h"
27 #include "UnicodeReader.h"
28 #include "ScriptCompositeFontInstance.h"
32 #define ARRAY_LENGTH(array) (sizeof array / sizeof array[0])
41 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
43 #define APP_NAME "LayoutSample"
45 TCHAR szAppName[] = TEXT(APP_NAME);
47 void PrettyTitle(HWND hwnd, char *fileName)
49 char title[MAX_PATH + 64];
51 sprintf(title, "%s - %s", APP_NAME, fileName);
53 SetWindowTextA(hwnd, title);
56 void InitParagraph(HWND hwnd, Context *context)
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);
67 si.cbSize = sizeof si;
68 si.fMask = SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL;
70 si.nMax = context->paragraph->getLineCount() - 1;
71 si.nPage = context->height / context->paragraph->getLineHeight();
72 SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
76 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
82 LEErrorCode status = LE_NO_ERROR;
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;
95 if (!RegisterClass(&wndclass)) {
96 MessageBox(NULL, TEXT("This demo only runs on Windows 2000!"), szAppName, MB_ICONERROR);
101 hAccel = LoadAccelerators(hInstance, szAppName);
103 hwnd = CreateWindow(szAppName, NULL,
104 WS_OVERLAPPEDWINDOW | WS_VSCROLL,
105 CW_USEDEFAULT, CW_USEDEFAULT,
107 NULL, NULL, hInstance, NULL);
109 ShowWindow(hwnd, iCmdShow);
112 while (GetMessage(&msg, NULL, 0, 0)) {
113 if (!TranslateAccelerator(hwnd, hAccel, &msg)) {
114 TranslateMessage(&msg);
115 DispatchMessage(&msg);
119 UnregisterClass(szAppName, hInstance);
123 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
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;
136 LEErrorCode fontStatus = LE_NO_ERROR;
139 surface = new GDISurface(hdc);
141 fontMap = new GDIFontMap(surface, "FontMap.GDI", 24, guiSupport, fontStatus);
142 font = new ScriptCompositeFontInstance(fontMap);
144 if (LE_FAILURE(fontStatus)) {
145 ReleaseDC(hwnd, hdc);
149 context = new Context();
151 context->width = 600;
152 context->height = 400;
154 context->paragraph = Paragraph::paragraphFactory("Sample.txt", font, guiSupport);
155 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) context);
158 ReleaseDC(hwnd, hdc);
160 PrettyTitle(hwnd, "Sample.txt");
166 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
167 context->width = LOWORD(lParam);
168 context->height = HIWORD(lParam);
170 InitParagraph(hwnd, context);
179 si.cbSize = sizeof si;
181 GetScrollInfo(hwnd, SB_VERT, &si);
185 switch (LOWORD(wParam))
212 si.nPos = si.nTrackPos;
220 SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
221 GetScrollInfo(hwnd, SB_VERT, &si);
223 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
225 if (context->paragraph != NULL && si.nPos != vertPos) {
226 ScrollWindow(hwnd, 0, context->paragraph->getLineHeight() * (vertPos - si.nPos), NULL, NULL);
237 le_int32 firstLine, lastLine;
239 hdc = BeginPaint(hwnd, &ps);
240 SetBkMode(hdc, TRANSPARENT);
242 si.cbSize = sizeof si;
244 GetScrollInfo(hwnd, SB_VERT, &si);
248 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
250 if (context->paragraph != NULL) {
251 surface->setHDC(hdc);
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);
258 context->paragraph->draw(surface, firstLine, lastLine);
266 switch (LOWORD(wParam)) {
270 char szFileName[MAX_PATH], szTitleName[MAX_PATH];
271 static char szFilter[] = "Text Files (.txt)\0*.txt\0"
272 "All Files (*.*)\0*.*\0\0";
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;
289 ofn.nFileExtension = 0;
290 ofn.lpstrDefExt = "txt";
293 ofn.lpTemplateName = NULL;
295 szFileName[0] = '\0';
297 if (GetOpenFileNameA(&ofn)) {
299 surface->setHDC(hdc);
301 Paragraph *newParagraph = Paragraph::paragraphFactory(szFileName, font, guiSupport);
303 if (newParagraph != NULL) {
304 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
306 if (context->paragraph != NULL) {
307 delete context->paragraph;
310 context->paragraph = newParagraph;
311 InitParagraph(hwnd, context);
312 PrettyTitle(hwnd, szTitleName);
313 InvalidateRect(hwnd, NULL, TRUE);
318 //ReleaseDC(hwnd, hdc);
325 SendMessage(hwnd, WM_CLOSE, 0, 0);
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);
341 context = (Context *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
343 if (context != NULL && context->paragraph != NULL) {
344 delete context->paragraph;
349 if (--windowCount <= 0) {
360 return DefWindowProc(hwnd, message, wParam, lParam);