examples/PIPS/antiword/src/saveas.c

00001 /*
00002  * saveas.c
00003  * Copyright (C) 1998-2001 A.J. van Os; Released under GPL
00004  *
00005  * Description:
00006  * Functions to save the results as a textfile or a drawfile
00007  */
00008 
00009 #include <stdio.h>
00010 #include <string.h>
00011 #include "DeskLib:Menu.h"
00012 #include "DeskLib:Save.h"
00013 #include "DeskLib:Template.h"
00014 #include "DeskLib:Window.h"
00015 #include "drawfile.h"
00016 #include "antiword.h"
00017 
00018 /* The window handle of the save window */
00019 static window_handle    tSaveWindow = 0;
00020 
00021 /* Xfer_send box fields */
00022 #define DRAG_SPRITE     3
00023 #define OK_BUTTON       0
00024 #define CANCEL_BUTTON   (-1)
00025 #define FILENAME_ICON   2
00026 
00027 
00028 /*
00029  * saveas - a wrapper around Save_InitSaveWindowhandler
00030  */
00031 static void
00032 saveas(int iFileType, char *szOutfile, size_t tEstSize,
00033         save_filesaver save_function, void *pvReference)
00034 {
00035         TRACE_MSG("saveas");
00036 
00037         if (tSaveWindow == 0) {
00038                 tSaveWindow = Window_Create("xfer_send", template_TITLEMIN);
00039         }
00040         Icon_SetText(tSaveWindow, FILENAME_ICON, szOutfile);
00041         Window_Show(tSaveWindow, open_UNDERPOINTER);
00042         (void)Save_InitSaveWindowHandler(tSaveWindow, FALSE, TRUE, TRUE,
00043                 DRAG_SPRITE, OK_BUTTON, CANCEL_BUTTON, FILENAME_ICON,
00044                 save_function, NULL, NULL, tEstSize, iFileType, pvReference);
00045 } /* end of saveas */
00046 
00047 static BOOL
00048 bWrite2File(void *pvBytes, size_t tSize, FILE *pFile, const char *szFilename)
00049 {
00050         if (fwrite(pvBytes, sizeof(char), tSize, pFile) != tSize) {
00051                 werr(0, "I can't write to '%s'", szFilename);
00052                 return FALSE;
00053         }
00054         return TRUE;
00055 } /* end of bWrite2File */
00056 
00057 /*
00058  * bText2File - Save the generated draw file to a Text file
00059  */
00060 static BOOL
00061 bText2File(char *szFilename, void *pvHandle)
00062 {
00063         FILE    *pFile;
00064         diagram_type    *pDiag;
00065         drawfile_object *pObj;
00066         drawfile_text   *pText;
00067         const char      *pcTmp;
00068         int     iToGo, iX, iYtopPrev, iHeight, iLines;
00069         BOOL    bFirst, bIndent, bSuccess;
00070 
00071         TRACE_MSG("bText2File");
00072 
00073         fail(szFilename == NULL || szFilename[0] == '\0');
00074         fail(pvHandle == NULL);
00075 
00076         DBG_MSG(szFilename);
00077 
00078         pDiag = (diagram_type *)pvHandle;
00079         pFile = fopen(szFilename, "w");
00080         if (pFile == NULL) {
00081                 werr(0, "I can't open '%s' for writing", szFilename);
00082                 return FALSE;
00083         }
00084         bFirst = TRUE;
00085         iYtopPrev = 0;
00086         iHeight = (int)lWord2DrawUnits20(DEFAULT_FONT_SIZE);
00087         bSuccess = TRUE;
00088         fail(pDiag->tInfo.length < offsetof(drawfile_diagram, objects));
00089         iToGo = pDiag->tInfo.length - offsetof(drawfile_diagram, objects);
00090         DBG_DEC(iToGo);
00091         pcTmp = (const char *)pDiag->tInfo.data +
00092                                 offsetof(drawfile_diagram, objects);
00093         while (iToGo > 0 && bSuccess) {
00094                 pObj = (drawfile_object *)pcTmp;
00095                 switch (pObj->type) {
00096                 case drawfile_TYPE_TEXT:
00097                         pText = &pObj->data.text;
00098                         /* Compute the number of lines */
00099                         iLines = (iYtopPrev - pText->bbox.max.y +
00100                                         iHeight / 2) / iHeight;
00101                         DBG_DEC_C(iLines < 0, iYtopPrev);
00102                         DBG_DEC_C(iLines < 0, pText->bbox.max.y);
00103                         fail(iLines < 0);
00104                         bIndent = iLines > 0 || bFirst;
00105                         bFirst = FALSE;
00106                         /* Print the newlines */
00107                         while (iLines > 0 && bSuccess) {
00108                                 bSuccess = bWrite2File("\n",
00109                                         1, pFile, szFilename);
00110                                 iLines--;
00111                         }
00112                         /* Print the indentation */
00113                         if (bIndent && bSuccess) {
00114                                 for (iX = Drawfile_ScreenToDraw(8);
00115                                      iX <= pText->bbox.min.x && bSuccess;
00116                                      iX += Drawfile_ScreenToDraw(16)) {
00117                                         bSuccess = bWrite2File(" ",
00118                                                 1, pFile, szFilename);
00119                                 }
00120                         }
00121                         if (!bSuccess) {
00122                                 break;
00123                         }
00124                         /* Print the text object */
00125                         bSuccess = bWrite2File(pText->text,
00126                                 strlen(pText->text), pFile, szFilename);
00127                         /* Setup for the next object */
00128                         iYtopPrev = pText->bbox.max.y;
00129                         iHeight = pText->bbox.max.y - pText->bbox.min.y;
00130                         break;
00131                 case drawfile_TYPE_FONT_TABLE:
00132                 case drawfile_TYPE_PATH:
00133                 case drawfile_TYPE_SPRITE:
00134                 case drawfile_TYPE_JPEG:
00135                         /* These are not relevant in a textfile */
00136                         break;
00137                 default:
00138                         DBG_DEC(pObj->type);
00139                         bSuccess = FALSE;
00140                         break;
00141                 }
00142                 pcTmp += pObj->size;
00143                 iToGo -= pObj->size;
00144         }
00145         DBG_DEC_C(iToGo != 0, iToGo);
00146         if (bSuccess) {
00147                 bSuccess = bWrite2File("\n", 1, pFile, szFilename);
00148         }
00149         (void)fclose(pFile);
00150         if (bSuccess) {
00151                 vSetFiletype(szFilename, FILETYPE_TEXT);
00152         } else {
00153                 (void)remove(szFilename);
00154                 werr(0, "Unable to save textfile '%s'", szFilename);
00155         }
00156         return bSuccess;
00157 } /* end of bText2File */
00158 
00159 /*
00160  * bSaveTextfile - save the diagram as a text file
00161  */
00162 BOOL
00163 bSaveTextfile(event_pollblock *pEvent, void *pvReference)
00164 {
00165         diagram_type    *pDiag;
00166         size_t  tRecLen, tNbrRecs, tEstSize;
00167 
00168         TRACE_MSG("bSaveTextfile");
00169 
00170         fail(pEvent == NULL);
00171         fail(pvReference == NULL);
00172 
00173         pDiag = (diagram_type *)pvReference;
00174 
00175         switch (pEvent->type) {
00176         case event_SEND:        /* From a menu */
00177                 fail(pEvent->data.message.header.action != message_MENUWARN);
00178                 if (menu_currentopen != pDiag->pSaveMenu ||
00179                     pEvent->data.message.data.menuwarn.selection[0] !=
00180                                                         SAVEMENU_SAVETEXT) {
00181                         return FALSE;
00182                 }
00183                 break;
00184         case event_KEY:         /* From a key short cut */
00185                 if (pEvent->data.key.caret.window != pDiag->tMainWindow) {
00186                         return FALSE;
00187                 }
00188                 break;
00189         default:
00190                 DBG_DEC(pEvent->type);
00191                 return FALSE;
00192         }
00193 
00194         tRecLen = sizeof(drawfile_text) + DEFAULT_SCREEN_WIDTH * 2 / 3;
00195         tNbrRecs = pDiag->tInfo.length / tRecLen + 1;
00196         tEstSize = tNbrRecs * DEFAULT_SCREEN_WIDTH * 2 / 3;
00197         DBG_DEC(tEstSize);
00198 
00199         saveas(FILETYPE_TEXT, "WordText", tEstSize, bText2File, pDiag);
00200         return TRUE;
00201 } /* end of bSaveTextfile */
00202 
00203 /*
00204  * bDraw2File - Save the generated draw file to a Draw file
00205  *
00206  * Remark: This is not a simple copy action. The origin of the
00207  * coordinates (0,0) must move from the top-left corner to the
00208  * bottom-left corner.
00209  */
00210 static BOOL
00211 bDraw2File(char *szFilename, void *pvHandle)
00212 {
00213         FILE            *pFile;
00214         diagram_type    *pDiagram;
00215         wimp_box        *pBbox;
00216         drawfile_object *pObj;
00217         drawfile_text   *pText;
00218         drawfile_path   *pPath;
00219         drawfile_sprite *pSprite;
00220         drawfile_jpeg   *pJpeg;
00221         int     *piPath;
00222         char    *pcTmp;
00223         int     iYadd, iToGo, iSize;
00224         BOOL    bSuccess;
00225 
00226         TRACE_MSG("bDraw2File");
00227 
00228         fail(szFilename == NULL || szFilename[0] == '\0');
00229         fail(pvHandle == NULL);
00230 
00231         NO_DBG_MSG(szFilename);
00232 
00233         pDiagram = (diagram_type *)pvHandle;
00234         pFile = fopen(szFilename, "wb");
00235         if (pFile == NULL) {
00236                 werr(0, "I can't open '%s' for writing", szFilename);
00237                 return FALSE;
00238         }
00239         iToGo = pDiagram->tInfo.length;
00240         DBG_DEC(iToGo);
00241         pcTmp = pDiagram->tInfo.data;
00242         bSuccess = bWrite2File(pcTmp,
00243                         offsetof(drawfile_diagram, bbox), pFile, szFilename);
00244         if (bSuccess) {
00245                 pcTmp += offsetof(drawfile_diagram, bbox);
00246                 iToGo -= offsetof(drawfile_diagram, bbox);
00247                 pBbox = (wimp_box *)pcTmp;
00248                 iYadd = -pBbox->min.y;
00249                 pBbox->min.y += iYadd;
00250                 pBbox->max.y += iYadd;
00251                 bSuccess = bWrite2File(pcTmp,
00252                                 sizeof(*pBbox), pFile, szFilename);
00253                 iToGo -= sizeof(*pBbox);
00254                 DBG_DEC(iToGo);
00255                 pcTmp += sizeof(*pBbox);
00256         } else {
00257                 iYadd = 0;
00258         }
00259         while (iToGo > 0 && bSuccess) {
00260                 pObj = (drawfile_object *)pcTmp;
00261                 iSize = pObj->size;
00262                 switch (pObj->type) {
00263                 case drawfile_TYPE_FONT_TABLE:
00264                         bSuccess = bWrite2File(pcTmp,
00265                                         iSize, pFile, szFilename);
00266                         pcTmp += iSize;
00267                         iToGo -= iSize;
00268                         break;
00269                 case drawfile_TYPE_TEXT:
00270                         pText = &pObj->data.text;
00271                         /* First correct the coordinates */
00272                         pText->bbox.min.y += iYadd;
00273                         pText->bbox.max.y += iYadd;
00274                         pText->base.y += iYadd;
00275                         /* Now write the information to file */
00276                         bSuccess = bWrite2File(pcTmp,
00277                                         iSize, pFile, szFilename);
00278                         pcTmp += pObj->size;
00279                         iToGo -= pObj->size;
00280                         break;
00281                 case drawfile_TYPE_PATH:
00282                         pPath = &pObj->data.path;
00283                         /* First correct the coordinates */
00284                         pPath->bbox.min.y += iYadd;
00285                         pPath->bbox.max.y += iYadd;
00286                         /* Now write the information to file */
00287                         bSuccess = bWrite2File(pPath,
00288                                 sizeof(*pPath), pFile, szFilename);
00289                         pcTmp += sizeof(*pPath);
00290                         iSize = pObj->size - sizeof(*pPath);
00291                         fail(iSize < 14 * sizeof(int));
00292                         /* Second correct the path coordinates */
00293                         piPath = xmalloc(iSize);
00294                         memcpy(piPath, pcTmp, iSize);
00295                         piPath[ 2] += iYadd;
00296                         piPath[ 5] += iYadd;
00297                         piPath[ 8] += iYadd;
00298                         piPath[11] += iYadd;
00299                         if (bSuccess) {
00300                                 bSuccess = bWrite2File(piPath,
00301                                         iSize, pFile, szFilename);
00302                                 pcTmp += iSize;
00303                         }
00304                         piPath = xfree(piPath);
00305                         iToGo -= pObj->size;
00306                         break;
00307                 case drawfile_TYPE_SPRITE:
00308                         pSprite = &pObj->data.sprite;
00309                         /* First correct the coordinates */
00310                         pSprite->bbox.min.y += iYadd;
00311                         pSprite->bbox.max.y += iYadd;
00312                         /* Now write the information to file */
00313                         bSuccess = bWrite2File(pcTmp,
00314                                         iSize, pFile, szFilename);
00315                         pcTmp += pObj->size;
00316                         iToGo -= pObj->size;
00317                         break;
00318                 case drawfile_TYPE_JPEG:
00319                         pJpeg = &pObj->data.jpeg;
00320                         /* First correct the coordinates */
00321                         pJpeg->bbox.min.y += iYadd;
00322                         pJpeg->bbox.max.y += iYadd;
00323                         pJpeg->trfm.entries[2][1] += iYadd;
00324                         /* Now write the information to file */
00325                         bSuccess = bWrite2File(pcTmp,
00326                                         iSize, pFile, szFilename);
00327                         pcTmp += pObj->size;
00328                         iToGo -= pObj->size;
00329                         break;
00330                 default:
00331                         DBG_DEC(pObj->type);
00332                         bSuccess = FALSE;
00333                         break;
00334                 }
00335         }
00336         DBG_DEC_C(iToGo != 0, iToGo);
00337         (void)fclose(pFile);
00338         if (bSuccess) {
00339                 vSetFiletype(szFilename, FILETYPE_DRAW);
00340         } else {
00341                 (void)remove(szFilename);
00342                 werr(0, "Unable to save drawfile '%s'", szFilename);
00343         }
00344         return bSuccess;
00345 } /* end of bDraw2File */
00346 
00347 /*
00348  * bSaveDrawfile - save the diagram as a draw file
00349  */
00350 BOOL
00351 bSaveDrawfile(event_pollblock *pEvent, void *pvReference)
00352 {
00353         diagram_type    *pDiag;
00354         size_t          tEstSize;
00355 
00356         TRACE_MSG("bSaveDrawfile");
00357 
00358         fail(pEvent == NULL);
00359         fail(pvReference == NULL);
00360 
00361         pDiag = (diagram_type *)pvReference;
00362 
00363         switch (pEvent->type) {
00364         case event_SEND:        /* From a menu */
00365                 fail(pEvent->data.message.header.action != message_MENUWARN);
00366                 if (menu_currentopen != pDiag->pSaveMenu ||
00367                     pEvent->data.message.data.menuwarn.selection[0] !=
00368                                                         SAVEMENU_SAVEDRAW) {
00369                         return FALSE;
00370                 }
00371                 break;
00372         case event_KEY:         /* From a key short cut */
00373                 if (pEvent->data.key.caret.window != pDiag->tMainWindow) {
00374                         return FALSE;
00375                 }
00376                 break;
00377         default:
00378                 DBG_DEC(pEvent->type);
00379                 return FALSE;
00380         }
00381 
00382         tEstSize = pDiag->tInfo.length;
00383         DBG_DEC(tEstSize);
00384 
00385         saveas(FILETYPE_DRAW, "WordDraw", tEstSize, bDraw2File, pDiag);
00386         return TRUE;
00387 } /* end of bSaveDrawfile */

Generated by  doxygen 1.6.2