examples/PIPS/antiword/src/draw.c

00001 /*
00002  * draw.c
00003  * Copyright (C) 1998-2005 A.J. van Os; Released under GPL
00004  *
00005  * Description:
00006  * Functions to deal with the Draw format
00007  */
00008 
00009 #include <stdlib.h>
00010 #include <ctype.h>
00011 #include <string.h>
00012 #include "DeskLib:KeyCodes.h"
00013 #include "DeskLib:Error.h"
00014 #include "DeskLib:Menu.h"
00015 #include "DeskLib:Template.h"
00016 #include "DeskLib:Window.h"
00017 #include "DeskLib:EventMsg.h"
00018 #include "flexlib:flex.h"
00019 #include "drawfile.h"
00020 #include "antiword.h"
00021 
00022 /* The work area must be a little bit larger than the diagram */
00023 #define WORKAREA_EXTENSION          5
00024 /* Diagram memory */
00025 #define INITIAL_SIZE            32768   /* 32k */
00026 #define EXTENSION_SIZE           4096   /*  4k */
00027 /* Main window title */
00028 #define WINDOW_TITLE_LEN           28
00029 #define FILENAME_TITLE_LEN      (WINDOW_TITLE_LEN - 10)
00030 
00031 
00032 #if !defined(__GNUC__)
00033 int
00034 flex_alloc(flex_ptr anchor, int n)
00035 {
00036         void    *pvTmp;
00037 
00038         TRACE_MSG("flex_alloc");
00039 
00040         if (anchor == NULL || n < 0) {
00041                 return 0;
00042         }
00043         if (n == 0) {
00044                 n = 1;
00045         }
00046         pvTmp = malloc(n);
00047         if (pvTmp == NULL) {
00048                 return 0;
00049         }
00050         *anchor = pvTmp;
00051         return 1;
00052 } /* end of flex_alloc */
00053 
00054 void
00055 flex_free(flex_ptr anchor)
00056 {
00057         TRACE_MSG("flex_free");
00058 
00059         if (anchor == NULL || *anchor == NULL) {
00060                 return;
00061         }
00062         free(*anchor);
00063         *anchor = NULL;
00064 } /* end of flex_free */
00065 
00066 int
00067 flex_extend(flex_ptr anchor, int newsize)
00068 {
00069         void    *pvTmp;
00070 
00071         TRACE_MSG("flex_extend");
00072 
00073         if (anchor == NULL || newsize < 0) {
00074                 return 0;
00075         }
00076         if (newsize == 0) {
00077                 newsize = 1;
00078         }
00079         pvTmp = realloc(*anchor, newsize);
00080         if (pvTmp == NULL) {
00081                 return 0;
00082         }
00083         *anchor = pvTmp;
00084         return 1;
00085 } /* end of flex_extend */
00086 #endif /* !__GNUC__ */
00087 
00088 /*
00089  * vCreateMainWindow - create the Main window
00090  *
00091  * remark: does not return if the Main window can't be created
00092  */
00093 static window_handle
00094 tCreateMainWindow(void)
00095 {
00096         window_handle   tMainWindow;
00097 
00098         TRACE_MSG("tCreateMainWindow");
00099 
00100         tMainWindow = Window_Create("MainWindow", template_TITLEMIN);
00101         if (tMainWindow == 0) {
00102                 werr(1, "I can't find the 'MainWindow' template");
00103         }
00104         return tMainWindow;
00105 } /* end of tCreateMainWindow */
00106 
00107 /*
00108  * vCreateScaleWindow - create the Scale view window
00109  *
00110  * remark: does not return if the Scale view window can't be created
00111  */
00112 static window_handle
00113 tCreateScaleWindow(void)
00114 {
00115         window_handle   tScaleWindow;
00116 
00117         TRACE_MSG("tCreateScaleWindow");
00118 
00119         tScaleWindow = Window_Create("ScaleView", template_TITLEMIN);
00120         if (tScaleWindow == 0) {
00121                 werr(1, "I can't find the 'ScaleView' template");
00122         }
00123         return tScaleWindow;
00124 } /* end of tCreateScaleWindow */
00125 
00126 /*
00127  * pCreateDiagram - create and initialize a diagram
00128  *
00129  * remark: does not return if the diagram can't be created
00130  */
00131 diagram_type *
00132 pCreateDiagram(const char *szTask, const char *szFilename)
00133 {
00134         diagram_type    *pDiag;
00135         options_type    tOptions;
00136         window_handle   tMainWindow, tScaleWindow;
00137         wimp_box        tBox;
00138 
00139         TRACE_MSG("pCreateDiagram");
00140 
00141         fail(szTask == NULL || szTask[0] == '\0');
00142 
00143         /* Create the main window */
00144         tMainWindow = tCreateMainWindow();
00145 
00146         /* Create the scale view window */
00147         tScaleWindow = tCreateScaleWindow();
00148 
00149         /* Get the necessary memory */
00150         pDiag = xmalloc(sizeof(diagram_type));
00151         if (flex_alloc((flex_ptr)&pDiag->tInfo.data, INITIAL_SIZE) != 1) {
00152                 werr(1, "Memory allocation failed, unable to continue");
00153         }
00154 
00155         /* Initialize the diagram */
00156         vGetOptions(&tOptions);
00157         pDiag->tMainWindow = tMainWindow;
00158         pDiag->tScaleWindow = tScaleWindow;
00159         pDiag->iScaleFactorCurr = tOptions.iScaleFactor;
00160         pDiag->iScaleFactorTemp = tOptions.iScaleFactor;
00161         pDiag->tMemorySize = INITIAL_SIZE;
00162         tBox.min.x = 0;
00163         tBox.min.y = -(Drawfile_ScreenToDraw(32 + 3) * 8 + 1);
00164         tBox.max.x = Drawfile_ScreenToDraw(16) * MIN_SCREEN_WIDTH + 1;
00165         tBox.max.y = 0;
00166         Error_CheckFatal(Drawfile_CreateDiagram(&pDiag->tInfo,
00167                                         pDiag->tMemorySize, szTask, tBox));
00168         DBG_DEC(pDiag->tInfo.length);
00169         pDiag->lXleft = 0;
00170         pDiag->lYtop = 0;
00171         strncpy(pDiag->szFilename,
00172                         szBasename(szFilename), sizeof(pDiag->szFilename) - 1);
00173         pDiag->szFilename[sizeof(pDiag->szFilename) - 1] = '\0';
00174         /* Return success */
00175         return pDiag;
00176 } /* end of pCreateDiagram */
00177 
00178 /*
00179  * bDestroyDiagram - remove a diagram by freeing the memory it uses
00180  */
00181 BOOL
00182 bDestroyDiagram(event_pollblock *pEvent, void *pvReference)
00183 {
00184         diagram_type    *pDiag;
00185         window_handle   tWindow;
00186 
00187         TRACE_MSG("bDestroyDiagram");
00188 
00189         fail(pEvent == NULL);
00190         fail(pvReference == NULL);
00191 
00192         if (pEvent == NULL || pvReference == NULL) {
00193                 return FALSE;
00194         }
00195 
00196         pDiag = (diagram_type *)pvReference;
00197 
00198         switch (pEvent->type) {
00199         case event_CLOSE:
00200                 tWindow = pEvent->data.openblock.window;
00201                 break;
00202         case event_KEY:
00203                 tWindow = pEvent->data.key.caret.window;
00204                 break;
00205         default:
00206                 DBG_DEC(pEvent->type);
00207                 return FALSE;
00208         }
00209         if (tWindow != pDiag->tMainWindow) {
00210                 return FALSE;
00211         }
00212 
00213         /* Delete the main window */
00214         Window_Delete(pDiag->tMainWindow);
00215         pDiag->tMainWindow = 0;
00216 
00217         /* Delete the scale window */
00218         Window_Delete(pDiag->tScaleWindow);
00219         pDiag->tScaleWindow = 0;
00220 
00221 #if defined(__GNUC__)
00222         /*
00223          * Remove all references to the diagram that will be free-ed
00224          * by undoing the EventMsg_Claim's from within the Menu_Warn's
00225          */
00226         while (EventMsg_ReleaseSpecific(message_MENUWARNING, window_ANY,
00227                                         bSaveTextfile, pDiag))
00228                 ; /* EMPTY */
00229         while (EventMsg_ReleaseSpecific(message_MENUWARNING, window_ANY,
00230                                         bSaveDrawfile, pDiag))
00231                 ; /* EMPTY */
00232         while (EventMsg_ReleaseSpecific(message_MENUWARNING, window_ANY,
00233                                         bScaleOpenAction, pDiag))
00234                 ; /* EMPTY */
00235 #endif /* __GNUC__ */
00236 
00237         /* Free the memory */
00238         if (pDiag->tInfo.data != NULL && pDiag->tMemorySize != 0) {
00239                 flex_free((flex_ptr)&pDiag->tInfo.data);
00240         }
00241         /* Just to be on the save side */
00242         pDiag->tInfo.data = NULL;
00243         pDiag->tInfo.length = 0;
00244         pDiag->tMemorySize = 0;
00245 
00246         /* Destroy the diagram itself */
00247         pDiag = xfree(pDiag);
00248         return TRUE;
00249 } /* end of bDestroyDiagram */
00250 
00251 /*
00252  * vExtendDiagramSize - make sure the diagram is big enough
00253  */
00254 static void
00255 vExtendDiagramSize(diagram_type *pDiag, size_t tSize)
00256 {
00257         TRACE_MSG("vExtendDiagramSize");
00258 
00259         fail(pDiag == NULL || tSize % 4 != 0);
00260 
00261         while (pDiag->tInfo.length + tSize > pDiag->tMemorySize) {
00262                 if (flex_extend((flex_ptr)&pDiag->tInfo.data,
00263                                 pDiag->tMemorySize + EXTENSION_SIZE) != 1) {
00264                         werr(1, "Memory extend failed, unable to continue");
00265                 }
00266                 pDiag->tMemorySize += EXTENSION_SIZE;
00267                 NO_DBG_DEC(pDiag->tMemorySize);
00268         }
00269         TRACE_MSG("end of vExtendDiagramSize");
00270 } /* end of vExtendDiagramSize */
00271 
00272 /*
00273  * vPrologue2 - prologue part 2; add a font list to a diagram
00274  */
00275 void
00276 vPrologue2(diagram_type *pDiag, int iWordVersion)
00277 {
00278         drawfile_object *pNew;
00279         const font_table_type   *pTmp;
00280         char    *pcTmp;
00281         size_t  tRealSize, tSize;
00282         int     iCount;
00283 
00284         TRACE_MSG("vPrologue2");
00285 
00286         fail(pDiag == NULL);
00287 
00288         if (tGetFontTableLength() == 0) {
00289                 return;
00290         }
00291         tRealSize = offsetof(drawfile_object, data);
00292         pTmp = NULL;
00293         while ((pTmp = pGetNextFontTableRecord(pTmp)) != NULL) {
00294                 tRealSize += 2 + strlen(pTmp->szOurFontname);
00295         }
00296         DBG_DEC(tRealSize);
00297         tSize = ROUND4(tRealSize);
00298         vExtendDiagramSize(pDiag, tSize);
00299         pNew = xmalloc(tSize);
00300         memset(pNew, 0, tSize);
00301         pNew->type = drawfile_TYPE_FONT_TABLE;
00302         pNew->size = tSize;
00303         pcTmp = (char *)&pNew->data.font_table.font_def[0].font_ref;
00304         iCount = 0;
00305         pTmp = NULL;
00306         while ((pTmp = pGetNextFontTableRecord(pTmp)) != NULL) {
00307                 *pcTmp = ++iCount;
00308                 pcTmp++;
00309                 strcpy(pcTmp, pTmp->szOurFontname);
00310                 pcTmp += 1 + strlen(pTmp->szOurFontname);
00311         }
00312         Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo,
00313                         pDiag->tMemorySize, pNew, TRUE));
00314         pNew = xfree(pNew);
00315 } /* end of vPrologue2 */
00316 
00317 /*
00318  * vSubstring2Diagram - put a sub string into a diagram
00319  */
00320 void
00321 vSubstring2Diagram(diagram_type *pDiag,
00322         char *szString, size_t tStringLength, long lStringWidth,
00323         UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef,
00324         USHORT usFontSize, USHORT usMaxFontSize)
00325 {
00326         drawfile_object *pNew;
00327         long    lSizeX, lSizeY, lOffset, l20, lYMove;
00328         size_t  tRealSize, tSize;
00329 
00330         TRACE_MSG("vSubstring2Diagram");
00331 
00332         fail(pDiag == NULL || szString == NULL);
00333         fail(pDiag->lXleft < 0);
00334         fail(tStringLength != strlen(szString));
00335         fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
00336         fail(usMaxFontSize < MIN_FONT_SIZE || usMaxFontSize > MAX_FONT_SIZE);
00337         fail(usFontSize > usMaxFontSize);
00338 
00339         if (szString[0] == '\0' || tStringLength == 0) {
00340                 return;
00341         }
00342 
00343         if (tFontRef == 0) {
00344                 lOffset = Drawfile_ScreenToDraw(2);
00345                 l20 = Drawfile_ScreenToDraw(32 + 3);
00346                 lSizeX = Drawfile_ScreenToDraw(16);
00347                 lSizeY = Drawfile_ScreenToDraw(32);
00348         } else {
00349                 lOffset = lToBaseLine(usMaxFontSize);
00350                 l20 = lWord2DrawUnits20(usMaxFontSize);
00351                 lSizeX = lWord2DrawUnits00(usFontSize);
00352                 lSizeY = lWord2DrawUnits00(usFontSize);
00353         }
00354 
00355         lYMove = 0;
00356 
00357         /* Up for superscript */
00358         if (bIsSuperscript(usFontstyle)) {
00359                 lYMove = lMilliPoints2DrawUnits((((long)usFontSize + 1) / 2) * 375);
00360         }
00361         /* Down for subscript */
00362         if (bIsSubscript(usFontstyle)) {
00363                 lYMove = -lMilliPoints2DrawUnits((long)usFontSize * 125);
00364         }
00365 
00366         tRealSize = offsetof(drawfile_object, data);
00367         tRealSize += sizeof(drawfile_text) + tStringLength;
00368         tSize = ROUND4(tRealSize);
00369         vExtendDiagramSize(pDiag, tSize);
00370         pNew = xmalloc(tSize);
00371         memset(pNew, 0, tSize);
00372         pNew->type = drawfile_TYPE_TEXT;
00373         pNew->size = tSize;
00374         pNew->data.text.bbox.min.x = (int)pDiag->lXleft;
00375         pNew->data.text.bbox.min.y = (int)(pDiag->lYtop + lYMove);
00376         pNew->data.text.bbox.max.x = (int)(pDiag->lXleft + lStringWidth);
00377         pNew->data.text.bbox.max.y = (int)(pDiag->lYtop + l20 + lYMove);
00378         pNew->data.text.fill.value = (int)ulColor2Color(ucFontColor);
00379         pNew->data.text.bg_hint.value = 0xffffff00;     /* White */
00380         pNew->data.text.style.font_ref = tFontRef;
00381         pNew->data.text.style.reserved[0] = 0;
00382         pNew->data.text.style.reserved[1] = 0;
00383         pNew->data.text.style.reserved[2] = 0;
00384         pNew->data.text.xsize = (int)lSizeX;
00385         pNew->data.text.ysize = (int)lSizeY;
00386         pNew->data.text.base.x = (int)pDiag->lXleft;
00387         pNew->data.text.base.y = (int)(pDiag->lYtop + lOffset + lYMove);
00388         strncpy(pNew->data.text.text, szString, tStringLength);
00389         pNew->data.text.text[tStringLength] = '\0';
00390         Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo,
00391                         pDiag->tMemorySize, pNew, TRUE));
00392         pNew = xfree(pNew);
00393         /*draw_translateText(&pDiag->tInfo);*/
00394         pDiag->lXleft += lStringWidth;
00395         TRACE_MSG("leaving vSubstring2Diagram");
00396 } /* end of vSubstring2Diagram */
00397 
00398 /*
00399  * vImage2Diagram - put an image into a diagram
00400  */
00401 void
00402 vImage2Diagram(diagram_type *pDiag, const imagedata_type *pImg,
00403         UCHAR *pucImage, size_t tImageSize)
00404 {
00405         drawfile_object *pNew;
00406         long    lWidth, lHeight;
00407         size_t  tRealSize, tSize;
00408 
00409         TRACE_MSG("vImage2Diagram");
00410 
00411         fail(pDiag == NULL);
00412         fail(pImg == NULL);
00413         fail(pDiag->lXleft < 0);
00414         fail(pImg->eImageType != imagetype_is_dib &&
00415              pImg->eImageType != imagetype_is_jpeg);
00416 
00417         DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);
00418 
00419         lWidth = lPoints2DrawUnits(pImg->iHorSizeScaled);
00420         lHeight = lPoints2DrawUnits(pImg->iVerSizeScaled);
00421         DBG_DEC(lWidth);
00422         DBG_DEC(lHeight);
00423 
00424         pDiag->lYtop -= lHeight;
00425 
00426         tRealSize = offsetof(drawfile_object, data);
00427         switch (pImg->eImageType) {
00428         case imagetype_is_dib:
00429                 tRealSize += sizeof(drawfile_sprite) + tImageSize;
00430                 tSize = ROUND4(tRealSize);
00431                 vExtendDiagramSize(pDiag, tSize);
00432                 pNew = xmalloc(tSize);
00433                 memset(pNew, 0, tSize);
00434                 pNew->type = drawfile_TYPE_SPRITE;
00435                 pNew->size = tSize;
00436                 pNew->data.sprite.bbox.min.x = (int)pDiag->lXleft;
00437                 pNew->data.sprite.bbox.min.y = (int)pDiag->lYtop;
00438                 pNew->data.sprite.bbox.max.x = (int)(pDiag->lXleft + lWidth);
00439                 pNew->data.sprite.bbox.max.y = (int)(pDiag->lYtop + lHeight);
00440                 memcpy(&pNew->data.sprite.header, pucImage, tImageSize);
00441                 break;
00442         case imagetype_is_jpeg:
00443 #if defined(DEBUG)
00444                 (void)bGetJpegInfo(pucImage, tImageSize);
00445 #endif /* DEBUG */
00446                 tRealSize += sizeof(drawfile_jpeg) + tImageSize;
00447                 tSize = ROUND4(tRealSize);
00448                 vExtendDiagramSize(pDiag, tSize);
00449                 pNew = xmalloc(tSize);
00450                 memset(pNew, 0, tSize);
00451                 pNew->type = drawfile_TYPE_JPEG;
00452                 pNew->size = tSize;
00453                 pNew->data.jpeg.bbox.min.x = (int)pDiag->lXleft;
00454                 pNew->data.jpeg.bbox.min.y = (int)pDiag->lYtop;
00455                 pNew->data.jpeg.bbox.max.x = (int)(pDiag->lXleft + lWidth);
00456                 pNew->data.jpeg.bbox.max.y = (int)(pDiag->lYtop + lHeight);
00457                 pNew->data.jpeg.width = (int)lWidth;
00458                 pNew->data.jpeg.height = (int)lHeight;
00459                 pNew->data.jpeg.xdpi = 90;
00460                 pNew->data.jpeg.ydpi = 90;
00461                 pNew->data.jpeg.trfm.entries[0][0] = 0x10000;
00462                 pNew->data.jpeg.trfm.entries[0][1] = 0;
00463                 pNew->data.jpeg.trfm.entries[1][0] = 0;
00464                 pNew->data.jpeg.trfm.entries[1][1] = 0x10000;
00465                 pNew->data.jpeg.trfm.entries[2][0] = (int)pDiag->lXleft;
00466                 pNew->data.jpeg.trfm.entries[2][1] = (int)pDiag->lYtop;
00467                 pNew->data.jpeg.len = tImageSize;
00468                 memcpy(pNew->data.jpeg.data, pucImage, tImageSize);
00469                 break;
00470         default:
00471                 DBG_DEC(pImg->eImageType);
00472                 pNew = NULL;
00473                 break;
00474         }
00475 
00476         Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo,
00477                                         pDiag->tMemorySize, pNew, TRUE));
00478         pNew = xfree(pNew);
00479         pDiag->lXleft = 0;
00480 } /* end of vImage2Diagram */
00481 
00482 /*
00483  * bAddDummyImage - add a dummy image
00484  *
00485  * return TRUE when successful, otherwise FALSE
00486  */
00487 BOOL
00488 bAddDummyImage(diagram_type *pDiag, const imagedata_type *pImg)
00489 {
00490         drawfile_object *pNew;
00491         int     *piTmp;
00492         long    lWidth, lHeight;
00493         size_t  tRealSize, tSize;
00494 
00495         TRACE_MSG("bAddDummyImage");
00496 
00497         fail(pDiag == NULL);
00498         fail(pImg == NULL);
00499         fail(pDiag->lXleft < 0);
00500 
00501         if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) {
00502                 return FALSE;
00503         }
00504 
00505         DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);
00506 
00507         lWidth = lPoints2DrawUnits(pImg->iHorSizeScaled);
00508         lHeight = lPoints2DrawUnits(pImg->iVerSizeScaled);
00509 
00510         pDiag->lYtop -= lHeight;
00511 
00512         tRealSize = offsetof(drawfile_object, data);
00513         tRealSize += sizeof(drawfile_path) + (14 - 1) * sizeof(int);
00514         tSize = ROUND4(tRealSize);
00515         vExtendDiagramSize(pDiag, tSize);
00516         pNew = xmalloc(tSize);
00517         memset(pNew, 0, tSize);
00518         pNew->type = drawfile_TYPE_PATH;
00519         pNew->size = tSize;
00520         pNew->data.path.bbox.min.x = (int)pDiag->lXleft;
00521         pNew->data.path.bbox.min.y = (int)pDiag->lYtop;
00522         pNew->data.path.bbox.max.x = (int)(pDiag->lXleft + lWidth);
00523         pNew->data.path.bbox.max.y = (int)(pDiag->lYtop + lHeight);
00524         pNew->data.path.fill.value = -1;
00525         pNew->data.path.outline.value = 0x4d4d4d00;     /* Gray 70 percent */
00526         pNew->data.path.width = (int)lMilliPoints2DrawUnits(500);
00527         pNew->data.path.style.flags = 0;
00528         pNew->data.path.style.reserved = 0;
00529         pNew->data.path.style.cap_width = 0;
00530         pNew->data.path.style.cap_length = 0;
00531         piTmp = pNew->data.path.path;
00532         *piTmp++ = drawfile_PATH_MOVE_TO;
00533         *piTmp++ = pNew->data.path.bbox.min.x;
00534         *piTmp++ = pNew->data.path.bbox.min.y;
00535         *piTmp++ = drawfile_PATH_LINE_TO;
00536         *piTmp++ = pNew->data.path.bbox.min.x;
00537         *piTmp++ = pNew->data.path.bbox.max.y;
00538         *piTmp++ = drawfile_PATH_LINE_TO;
00539         *piTmp++ = pNew->data.path.bbox.max.x;
00540         *piTmp++ = pNew->data.path.bbox.max.y;
00541         *piTmp++ = drawfile_PATH_LINE_TO;
00542         *piTmp++ = pNew->data.path.bbox.max.x;
00543         *piTmp++ = pNew->data.path.bbox.min.y;
00544         *piTmp++ = drawfile_PATH_CLOSE_LINE;
00545         *piTmp++ = drawfile_PATH_END_PATH;
00546 
00547         Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo,
00548                                         pDiag->tMemorySize, pNew, TRUE));
00549         pNew = xfree(pNew);
00550         pDiag->lXleft = 0;
00551         return TRUE;
00552 } /* end of bAddDummyImage */
00553 
00554 /*
00555  * vMove2NextLine - move to the next line
00556  */
00557 void
00558 vMove2NextLine(diagram_type *pDiag, drawfile_fontref tFontRef,
00559         USHORT usFontSize)
00560 {
00561         long    l20;
00562 
00563         TRACE_MSG("vMove2NextLine");
00564 
00565         fail(pDiag == NULL);
00566         fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
00567 
00568         if (tFontRef == 0) {
00569                 l20 = Drawfile_ScreenToDraw(32 + 3);
00570         } else {
00571                 l20 = lWord2DrawUnits20(usFontSize);
00572         }
00573         pDiag->lYtop -= l20;
00574 } /* end of vMove2NextLine */
00575 
00576 /*
00577  * Create an start of paragraph (Phase 1)
00578  */
00579 void
00580 vStartOfParagraph1(diagram_type *pDiag, long lBeforeIndentation)
00581 {
00582         TRACE_MSG("vStartOfParagraph1");
00583 
00584         fail(pDiag == NULL);
00585         fail(lBeforeIndentation < 0);
00586 
00587         pDiag->lXleft = 0;
00588         pDiag->lYtop -= lMilliPoints2DrawUnits(lBeforeIndentation);
00589 } /* end of vStartOfParagraph1 */
00590 
00591 /*
00592  * Create an start of paragraph (Phase 2)
00593  * DUMMY function
00594  */
00595 void
00596 vStartOfParagraph2(diagram_type *pDiag)
00597 {
00598         TRACE_MSG("vStartOfParagraph2");
00599 } /* end of vStartOfParagraph2 */
00600 
00601 /*
00602  * Create an end of paragraph
00603  */
00604 void
00605 vEndOfParagraph(diagram_type *pDiag,
00606         drawfile_fontref tFontRef, USHORT usFontSize, long lAfterIndentation)
00607 {
00608         TRACE_MSG("vEndOfParagraph");
00609 
00610         fail(pDiag == NULL);
00611         fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
00612         fail(lAfterIndentation < 0);
00613 
00614         pDiag->lXleft = 0;
00615         pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation);
00616 } /* end of vEndOfParagraph */
00617 
00618 /*
00619  * Create an end of page
00620  */
00621 void
00622 vEndOfPage(diagram_type *pDiag, long lAfterIndentation, BOOL bNewSection)
00623 {
00624         TRACE_MSG("vEndOfPage");
00625 
00626         fail(pDiag == NULL);
00627         fail(lAfterIndentation < 0);
00628 
00629         pDiag->lXleft = 0;
00630         pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation);
00631 } /* end of vEndOfPage */
00632 
00633 /*
00634  * vSetHeaders - set the headers
00635  * DUMMY function
00636  */
00637 void
00638 vSetHeaders(diagram_type *pDiag, USHORT usIstd)
00639 {
00640         TRACE_MSG("vSetHeaders");
00641 } /* end of vSetHeaders */
00642 
00643 /*
00644  * Create a start of list
00645  * DUMMY function
00646  */
00647 void
00648 vStartOfList(diagram_type *pDiag, UCHAR ucNFC, BOOL bIsEndOfTable)
00649 {
00650         TRACE_MSG("vStartOfList");
00651 } /* end of vStartOfList */
00652 
00653 /*
00654  * Create an end of list
00655  * DUMMY function
00656  */
00657 void
00658 vEndOfList(diagram_type *pDiag)
00659 {
00660         TRACE_MSG("vEndOfList");
00661 } /* end of vEndOfList */
00662 
00663 /*
00664  * Create a start of a list item
00665  * DUMMY function
00666  */
00667 void
00668 vStartOfListItem(diagram_type *pDiag, BOOL bNoMarks)
00669 {
00670         TRACE_MSG("vStartOfListItem");
00671 } /* end of vStartOfListItem */
00672 
00673 /*
00674  * Create an end of a table
00675  * DUMMY function
00676  */
00677 void
00678 vEndOfTable(diagram_type *pDiag)
00679 {
00680         TRACE_MSG("vEndOfTable");
00681 } /* end of vEndTable */
00682 
00683 /*
00684  * Add a table row
00685  * DUMMY function
00686  *
00687  * Returns TRUE when conversion type is XML
00688  */
00689 BOOL
00690 bAddTableRow(diagram_type *pDiag, char **aszColTxt,
00691         int iNbrOfColumns, const short *asColumnWidth, UCHAR ucBorderInfo)
00692 {
00693         TRACE_MSG("bAddTableRow");
00694 
00695         return FALSE;
00696 } /* end of bAddTableRow */
00697 
00698 /*
00699  * vForceRedraw - force a redraw of the main window
00700  */
00701 static void
00702 vForceRedraw(diagram_type *pDiag)
00703 {
00704         window_state            tWindowState;
00705         window_redrawblock      tRedraw;
00706         int     x0, y0, x1, y1;
00707 
00708         TRACE_MSG("vForceRedraw");
00709 
00710         fail(pDiag == NULL);
00711 
00712         DBG_DEC(pDiag->iScaleFactorCurr);
00713 
00714         /* Read the size of the current diagram */
00715         Drawfile_QueryBox(&pDiag->tInfo, &tRedraw.rect, TRUE);
00716         /* Adjust the size of the work area */
00717         x0 = tRedraw.rect.min.x * pDiag->iScaleFactorCurr / 100 - 1;
00718         y0 = tRedraw.rect.min.y * pDiag->iScaleFactorCurr / 100 - 1;
00719         x1 = tRedraw.rect.max.x * pDiag->iScaleFactorCurr / 100 + 1;
00720         y1 = tRedraw.rect.max.y * pDiag->iScaleFactorCurr / 100 + 1;
00721         /* Work area extension */
00722         x0 -= WORKAREA_EXTENSION;
00723         y0 -= WORKAREA_EXTENSION;
00724         x1 += WORKAREA_EXTENSION;
00725         y1 += WORKAREA_EXTENSION;
00726         Window_SetExtent(pDiag->tMainWindow, x0, y0, x1, y1);
00727         /* Widen the box slightly to be sure all the edges are drawn */
00728         x0 -= 5;
00729         y0 -= 5;
00730         x1 += 5;
00731         y1 += 5;
00732         /* Force the redraw */
00733         Window_ForceRedraw(pDiag->tMainWindow, x0, y0, x1, y1);
00734         /* Reopen the window to show the correct size */
00735         Error_CheckFatal(Wimp_GetWindowState(pDiag->tMainWindow, &tWindowState));
00736         tWindowState.openblock.behind = -1;
00737         Error_CheckFatal(Wimp_OpenWindow(&tWindowState.openblock));
00738 } /* end of vForceRedraw */
00739 
00740 /*
00741  * vShowDiagram - put the diagram on the screen
00742  */
00743 void
00744 vShowDiagram(diagram_type *pDiag)
00745 {
00746         wimp_box        tRect;
00747         int     x0, y0, x1, y1;
00748 
00749         TRACE_MSG("vShowDiagram");
00750 
00751         fail(pDiag == NULL);
00752 
00753         Window_Show(pDiag->tMainWindow, open_NEARLAST);
00754         Drawfile_QueryBox(&pDiag->tInfo, &tRect, TRUE);
00755         /* Work area extension */
00756         x0 = tRect.min.x - WORKAREA_EXTENSION;
00757         y0 = tRect.min.y - WORKAREA_EXTENSION;
00758         x1 = tRect.max.x + WORKAREA_EXTENSION;
00759         y1 = tRect.max.y + WORKAREA_EXTENSION;
00760         Window_SetExtent(pDiag->tMainWindow, x0, y0, x1, y1);
00761         vForceRedraw(pDiag);
00762 } /* end of vShowDiagram */
00763 
00764 /*
00765  * vMainButtonClick - handle mouse buttons clicks for the main screen
00766  */
00767 void
00768 vMainButtonClick(mouse_block *pMouse)
00769 {
00770         caret_block     tCaret;
00771         window_state    ws;
00772 
00773         TRACE_MSG("vMainButtonClick");
00774 
00775         fail(pMouse == NULL);
00776 
00777         DBG_DEC(pMouse->button.data.select);
00778         DBG_DEC(pMouse->button.data.adjust);
00779         DBG_DEC(pMouse->window);
00780         DBG_DEC(pMouse->icon);
00781 
00782         if (pMouse->window >= 0 &&
00783             pMouse->icon == -1 &&
00784             (pMouse->button.data.select || pMouse->button.data.adjust)) {
00785                 /* Get the input focus */
00786                 Error_CheckFatal(Wimp_GetWindowState(pMouse->window, &ws));
00787                 tCaret.window = pMouse->window;
00788                 tCaret.icon = -1;
00789                 tCaret.offset.x = pMouse->pos.x - ws.openblock.screenrect.min.x;
00790                 tCaret.offset.y = pMouse->pos.y - ws.openblock.screenrect.max.y;
00791                 tCaret.height = (int)BIT(25);
00792                 tCaret.index = 0;
00793                 Error_CheckFatal(Wimp_SetCaretPosition(&tCaret));
00794         }
00795 } /* end of vMainButtonClick */
00796 
00797 /*
00798  * bMainKeyPressed - handle pressed keys for the main window
00799  */
00800 BOOL
00801 bMainKeyPressed(event_pollblock *pEvent, void *pvReference)
00802 {
00803         diagram_type    *pDiag;
00804 
00805         TRACE_MSG("bMainKeyPressed");
00806 
00807         fail(pEvent == NULL);
00808         fail(pEvent->type != event_KEY);
00809         fail(pvReference == NULL);
00810 
00811         pDiag = (diagram_type *)pvReference;
00812 
00813         fail(pEvent->data.key.caret.window != pDiag->tMainWindow);
00814 
00815 
00816         switch (pEvent->data.key.code) {
00817         case keycode_CTRL_F2:           /* Ctrl F2 */
00818                 bDestroyDiagram(pEvent, pvReference);
00819                 break;
00820         case keycode_F3:                /* F3 */
00821                 bSaveDrawfile(pEvent, pvReference);
00822                 break;
00823         case keycode_SHIFT_F3:          /* Shift F3 */
00824                 bSaveTextfile(pEvent, pvReference);
00825                 break;
00826         default:
00827                 DBG_DEC(pEvent->data.key.code);
00828                 Error_CheckFatal(Wimp_ProcessKey(pEvent->data.key.code));
00829         }
00830         return TRUE;
00831 } /* end of bMainKeyPressed */
00832 
00833 /*
00834  * bRedrawMainWindow - redraw the main window
00835  */
00836 BOOL
00837 bRedrawMainWindow(event_pollblock *pEvent, void *pvReference)
00838 {
00839         window_redrawblock      tBlock;
00840         diagram_type    *pDiag;
00841         drawfile_info   *pInfo;
00842         double          dScaleFactor;
00843         BOOL            bMore;
00844 
00845         TRACE_MSG("bRedrawMainWindow");
00846 
00847         fail(pEvent == NULL);
00848         fail(pEvent->type != event_REDRAW);
00849         fail(pvReference == NULL);
00850 
00851         pDiag = (diagram_type *)pvReference;
00852 
00853         fail(pDiag->tMainWindow != pEvent->data.openblock.window);
00854         fail(pDiag->iScaleFactorCurr < MIN_SCALE_FACTOR);
00855         fail(pDiag->iScaleFactorCurr > MAX_SCALE_FACTOR);
00856 
00857         dScaleFactor = (double)pDiag->iScaleFactorCurr / 100.0;
00858         pInfo = &pDiag->tInfo;
00859 
00860         tBlock.window = pEvent->data.openblock.window;
00861         Error_CheckFatal(Wimp_RedrawWindow(&tBlock, &bMore));
00862 
00863         /* If there is no real diagram just go thru the motions */
00864         while (bMore) {
00865                 if (pInfo->data != NULL && pInfo->length != 0) {
00866                         Error_CheckFatal(Drawfile_RenderDiagram(pInfo,
00867                                                 &tBlock, dScaleFactor));
00868                 }
00869                 Error_CheckFatal(Wimp_GetRectangle(&tBlock, &bMore));
00870         }
00871         return TRUE;
00872 } /* end of bRedrawMainWindow */
00873 
00874 /*
00875  * bScaleOpenAction - action to be taken when the Scale view window opens
00876  */
00877 BOOL
00878 bScaleOpenAction(event_pollblock *pEvent, void *pvReference)
00879 {
00880         window_state    tWindowState;
00881         diagram_type    *pDiag;
00882 
00883         TRACE_MSG("bScaleOpenAction");
00884 
00885         fail(pEvent == NULL);
00886         fail(pEvent->type != event_SEND);
00887         fail(pEvent->data.message.header.action != message_MENUWARN);
00888         fail(pvReference == NULL);
00889 
00890         pDiag = (diagram_type *)pvReference;
00891 
00892         if (menu_currentopen != pDiag->pSaveMenu ||
00893             pEvent->data.message.data.menuwarn.selection[0] != SAVEMENU_SCALEVIEW) {
00894                 return FALSE;
00895         }
00896 
00897         Error_CheckFatal(Wimp_GetWindowState(pDiag->tScaleWindow,
00898                                                 &tWindowState));
00899         if (tWindowState.flags.data.open) {
00900                 /* The window is already open */
00901                 return TRUE;
00902         }
00903 
00904         DBG_MSG("vScaleOpenAction for real");
00905 
00906         pDiag->iScaleFactorTemp = pDiag->iScaleFactorCurr;
00907         vUpdateWriteableNumber(pDiag->tScaleWindow,
00908                         SCALE_SCALE_WRITEABLE, pDiag->iScaleFactorTemp);
00909         Window_Show(pDiag->tScaleWindow, open_UNDERPOINTER);
00910         return TRUE;
00911 } /* end of bScaleOpenAction */
00912 
00913 /*
00914  * vSetTitle - set the title of a window
00915  */
00916 void
00917 vSetTitle(diagram_type *pDiag)
00918 {
00919         char    szTitle[WINDOW_TITLE_LEN];
00920 
00921         TRACE_MSG("vSetTitle");
00922 
00923         fail(pDiag == NULL);
00924         fail(pDiag->szFilename[0] == '\0');
00925 
00926         (void)sprintf(szTitle, "%.*s at %d%%",
00927                                 FILENAME_TITLE_LEN,
00928                                 pDiag->szFilename,
00929                                 pDiag->iScaleFactorCurr % 1000);
00930         if (strlen(pDiag->szFilename) > FILENAME_TITLE_LEN) {
00931                 szTitle[FILENAME_TITLE_LEN - 1] = OUR_ELLIPSIS;
00932         }
00933 
00934         Window_SetTitle(pDiag->tMainWindow, szTitle);
00935 } /* end of vSetTitle */
00936 
00937 /*
00938  * vScaleButtonClick - handle a mouse button click in the Scale view window
00939  */
00940 void
00941 vScaleButtonClick(mouse_block *pMouse, diagram_type *pDiag)
00942 {
00943         BOOL    bCloseWindow, bRedraw;
00944 
00945         TRACE_MSG("vScaleButtonClick");
00946 
00947         fail(pMouse == NULL || pDiag == NULL);
00948         fail(pMouse->window != pDiag->tScaleWindow);
00949 
00950         bCloseWindow = FALSE;
00951         bRedraw = FALSE;
00952         switch (pMouse->icon) {
00953         case SCALE_CANCEL_BUTTON:
00954                 bCloseWindow = TRUE;
00955                 pDiag->iScaleFactorTemp = pDiag->iScaleFactorCurr;
00956                 break;
00957         case SCALE_SCALE_BUTTON:
00958                 bCloseWindow = TRUE;
00959                 bRedraw = pDiag->iScaleFactorCurr != pDiag->iScaleFactorTemp;
00960                 pDiag->iScaleFactorCurr = pDiag->iScaleFactorTemp;
00961                 break;
00962         case SCALE_50_PCT:
00963                 pDiag->iScaleFactorTemp = 50;
00964                 break;
00965         case SCALE_75_PCT:
00966                 pDiag->iScaleFactorTemp = 75;
00967                 break;
00968         case SCALE_100_PCT:
00969                 pDiag->iScaleFactorTemp = 100;
00970                 break;
00971         case SCALE_150_PCT:
00972                 pDiag->iScaleFactorTemp = 150;
00973                 break;
00974         default:
00975                 DBG_DEC(pMouse->icon);
00976                 break;
00977         }
00978         if (bCloseWindow) {
00979                 /* Close the scale window */
00980                 Error_CheckFatal(Wimp_CloseWindow(pMouse->window));
00981                 if (bRedraw) {
00982                         /* Redraw the main window */
00983                         vSetTitle(pDiag);
00984                         vForceRedraw(pDiag);
00985                 }
00986         } else {
00987                 vUpdateWriteableNumber(pMouse->window,
00988                                 SCALE_SCALE_WRITEABLE,
00989                                 pDiag->iScaleFactorTemp);
00990         }
00991 } /* end of vScaleButtonClick */
00992 
00993 /*
00994  * bScaleKeyPressed - handle pressed keys for the scale window
00995  */
00996 BOOL
00997 bScaleKeyPressed(event_pollblock *pEvent, void *pvReference)
00998 {
00999         icon_block      tIcon;
01000         diagram_type    *pDiag;
01001         caret_block     *pCaret;
01002         char            *pcChar;
01003         int             iTmp;
01004 
01005         TRACE_MSG("bScaleKeyPressed");
01006 
01007         fail(pEvent == NULL);
01008         fail(pEvent->type != event_KEY);
01009         fail(pvReference == NULL);
01010 
01011         pCaret = &pEvent->data.key.caret;
01012         pDiag = (diagram_type *)pvReference;
01013 
01014         fail(pEvent->data.key.caret.window != pDiag->tScaleWindow);
01015 
01016         DBG_DEC_C(pCaret->icon != SCALE_SCALE_WRITEABLE, pCaret->icon);
01017         DBG_DEC_C(pCaret->icon == SCALE_SCALE_WRITEABLE, pEvent->data.key.code);
01018 
01019         if (pEvent->data.key.code != '\r' ||
01020             pCaret->icon != SCALE_SCALE_WRITEABLE) {
01021                 Error_CheckFatal(Wimp_ProcessKey(pEvent->data.key.code));
01022                 return TRUE;
01023         }
01024 
01025         Error_CheckFatal(Wimp_GetIconState(pCaret->window, pCaret->icon, &tIcon));
01026         if (!tIcon.flags.data.text || !tIcon.flags.data.indirected) {
01027                 werr(1, "Icon %d must be indirected text", (int)pCaret->icon);
01028         }
01029         iTmp = (int)strtol(tIcon.data.indirecttext.buffer, &pcChar, 10);
01030         if (*pcChar != '\0' && *pcChar != '\r') {
01031                 DBG_DEC(*pcChar);
01032         } else if (iTmp < MIN_SCALE_FACTOR) {
01033                 pDiag->iScaleFactorTemp = MIN_SCALE_FACTOR;
01034         } else if (iTmp > MAX_SCALE_FACTOR) {
01035                 pDiag->iScaleFactorTemp = MAX_SCALE_FACTOR;
01036         } else {
01037                 pDiag->iScaleFactorTemp = iTmp;
01038         }
01039         pDiag->iScaleFactorCurr = pDiag->iScaleFactorTemp;
01040         /* Close the scale window */
01041         Error_CheckFatal(Wimp_CloseWindow(pCaret->window));
01042         /* Redraw the main window */
01043         vSetTitle(pDiag);
01044         vForceRedraw(pDiag);
01045         return TRUE;
01046 } /* end of bScaleKeyPressed */
01047 

Generated by  doxygen 1.6.2