Home | History | Annotate | Download | only in layout
      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 
     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 
     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 
     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 
    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