/* ******************************************************************************* * * Copyright (C) 1999-2001, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* * file name: Layout.cpp * * created on: 08/03/2000 * created by: Eric R. Mader */ #include //#include "LETypes.h" //#include "LEFontInstance.h" //#include "LayoutEngine.h" //#include "unicode/loengine.h" #include "unicode/uscript.h" //#include "LEScripts.h" #include "GDIFontInstance.h" #include "paragraph.h" #include "GDIGUISupport.h" #include "GDIFontMap.h" #include "UnicodeReader.h" #include "scrptrun.h" #define ARRAY_LENGTH(array) (sizeof array / sizeof array[0]) LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd; MSG msg; WNDCLASS wndclass; TCHAR szAppName[] = TEXT("LayoutDemo"); TCHAR szTitle[] = TEXT("LayoutDemo: Demo of LayoutEngine"); RFIErrorCode status = RFI_NO_ERROR; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = sizeof(LONG); wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("This demo only runs on Windows 2000!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, szTitle, WS_OVERLAPPEDWINDOW | WS_VSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, 600, 400, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; Paragraph *paragraph; static le_int32 windowCount = 0; static GDIFontMap *fontMap = NULL; static GDIGUISupport *guiSupport = new GDIGUISupport(); switch (message) { case WM_CREATE: { RFIErrorCode fontStatus = RFI_NO_ERROR; hdc = GetDC(hwnd); fontMap = new GDIFontMap(hdc, "FontMap.GDI", 24, guiSupport, fontStatus); if (LE_FAILURE(fontStatus)) { ReleaseDC(hwnd, hdc); return 0; } paragraph = Paragraph::paragraphFactory("Sample.utf8", fontMap, guiSupport, hdc); SetWindowLong(hwnd, 0, (LONG) paragraph); windowCount += 1; ReleaseDC(hwnd, hdc); return 0; } case WM_SIZE: { le_int32 width = LOWORD(lParam); le_int32 height = HIWORD(lParam); SCROLLINFO si; paragraph = (Paragraph *) GetWindowLong(hwnd, 0); if (paragraph != NULL) { // FIXME: does it matter what we put in the ScrollInfo // if the window's been minimized? if (width > 0 && height > 0) { paragraph->breakLines(width, height); } si.cbSize = sizeof si; si.fMask = SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL; si.nMin = 0; si.nMax = paragraph->getLineCount() - 1; si.nPage = height / paragraph->getLineHeight(); SetScrollInfo(hwnd, SB_VERT, &si, true); } return 0; } case WM_VSCROLL: { SCROLLINFO si; le_int32 vertPos; si.cbSize = sizeof si; si.fMask = SIF_ALL; GetScrollInfo(hwnd, SB_VERT, &si); vertPos = si.nPos; switch (LOWORD(wParam)) { case SB_TOP: si.nPos = si.nMin; break; case SB_BOTTOM: si.nPos = si.nMax; break; case SB_LINEUP: si.nPos -= 1; break; case SB_LINEDOWN: si.nPos += 1; break; case SB_PAGEUP: si.nPos -= si.nPage; break; case SB_PAGEDOWN: si.nPos += si.nPage; break; case SB_THUMBTRACK: si.nPos = si.nTrackPos; break; default: break; } si.fMask = SIF_POS; SetScrollInfo(hwnd, SB_VERT, &si, true); GetScrollInfo(hwnd, SB_VERT, &si); paragraph = (Paragraph *) GetWindowLong(hwnd, 0); if (paragraph != NULL && si.nPos != vertPos) { ScrollWindow(hwnd, 0, paragraph->getLineHeight() * (vertPos - si.nPos), NULL, NULL); UpdateWindow(hwnd); } return 0; } case WM_PAINT: { PAINTSTRUCT ps; SCROLLINFO si; le_int32 firstLine, lastLine; hdc = BeginPaint(hwnd, &ps); si.cbSize = sizeof si; si.fMask = SIF_ALL; GetScrollInfo(hwnd, SB_VERT, &si); firstLine = si.nPos; paragraph = (Paragraph *) GetWindowLong(hwnd, 0); if (paragraph != NULL) { // NOTE: si.nPos + si.nPage may include a partial line at the bottom // of the window. We need this because scrolling assumes that the // partial line has been painted. lastLine = min (si.nPos + (le_int32) si.nPage, paragraph->getLineCount() - 1); paragraph->draw(hdc, firstLine, lastLine); } EndPaint(hwnd, &ps); return 0; } case WM_DESTROY: { paragraph = (Paragraph *) GetWindowLong(hwnd, 0); if (paragraph != NULL) { delete paragraph; } if (--windowCount <= 0) { delete fontMap; PostQuitMessage(0); } return 0; } default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }