home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / anwor032.zip / antiword.0.32 / saveas.c < prev    next >
C/C++ Source or Header  |  2001-02-02  |  8KB  |  331 lines

  1. /*
  2.  * saveas.c
  3.  * Copyright (C) 1998-2001 A.J. van Os; Released under GPL
  4.  *
  5.  * Description:
  6.  * Functions to save the results as a textfile or a drawfile
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "saveas.h"
  12. #include "event.h"
  13. #include "antiword.h"
  14.  
  15. static BOOL
  16. bWrite2File(void *pvBytes, size_t tSize, FILE *pFile, const char *szFilename)
  17. {
  18.     if (fwrite(pvBytes, sizeof(char), tSize, pFile) != tSize) {
  19.         werr(0, "I can't write to '%s'", szFilename);
  20.         return FALSE;
  21.     }
  22.     return TRUE;
  23. } /* end of bWrite2File */
  24.  
  25. /*
  26.  * bText2File - Save the generated draw file to a Text file
  27.  */
  28. static BOOL
  29. bText2File(char *szFilename, void *pvHandle)
  30. {
  31.     FILE    *pFile;
  32.     diagram_type    *pDiag;
  33.     draw_textstrhdr    tText;
  34.     char    *pcTmp;
  35.     int    iToGo, iSize, iX, iYtopPrev, iHeight, iLines;
  36.     BOOL    bFirst, bIndent, bSuccess;
  37.  
  38.     fail(szFilename == NULL || szFilename[0] == '\0');
  39.     fail(pvHandle == NULL);
  40.  
  41.     DBG_MSG("bText2File");
  42.     DBG_MSG(szFilename);
  43.  
  44.     pDiag = (diagram_type *)pvHandle;
  45.     pFile = fopen(szFilename, "w");
  46.     if (pFile == NULL) {
  47.         werr(0, "I can't open '%s' for writing", szFilename);
  48.         return FALSE;
  49.     }
  50.     bFirst = TRUE;
  51.     iYtopPrev = 0;
  52.     iHeight = (int)lWord2DrawUnits20(DEFAULT_FONT_SIZE);
  53.     bSuccess = TRUE;
  54.     iToGo = pDiag->tInfo.length - sizeof(draw_fileheader);
  55.     DBG_DEC(iToGo);
  56.     pcTmp = pDiag->tInfo.data + sizeof(draw_fileheader);
  57.     while (iToGo > 0 && bSuccess) {
  58.         tText = *(draw_textstrhdr *)pcTmp;
  59.         switch (tText.tag) {
  60.         case draw_OBJFONTLIST:
  61.             /* These are not relevant in a textfile */
  62.             iSize = ((draw_fontliststrhdr *)pcTmp)->size;
  63.             pcTmp += iSize;
  64.             iToGo -= iSize;
  65.             break;
  66.         case draw_OBJTEXT:
  67.             /* Compute the number of lines */
  68.             iLines =
  69.             (iYtopPrev - tText.bbox.y1 + iHeight / 2) / iHeight;
  70.             fail(iLines < 0);
  71.             bIndent = iLines > 0 || bFirst;
  72.             bFirst = FALSE;
  73.             /* Print the newlines */
  74.             while (iLines > 0 && bSuccess) {
  75.                 bSuccess = bWrite2File("\n",
  76.                     1, pFile, szFilename);
  77.                 iLines--;
  78.             }
  79.             /* Print the indentation */
  80.             if (bIndent && bSuccess) {
  81.                 for (iX = draw_screenToDraw(8);
  82.                      iX <= tText.bbox.x0 && bSuccess;
  83.                      iX += draw_screenToDraw(16)) {
  84.                     bSuccess = bWrite2File(" ",
  85.                         1, pFile, szFilename);
  86.                 }
  87.             }
  88.             if (!bSuccess) {
  89.                 break;
  90.             }
  91.             /* Print the text object */
  92.             pcTmp += sizeof(tText);
  93.             bSuccess = bWrite2File(pcTmp,
  94.                 strlen(pcTmp), pFile, szFilename);
  95.             pcTmp += tText.size - sizeof(tText);
  96.             /* Setup for the next text object */
  97.             iToGo -= tText.size;
  98.             iYtopPrev = tText.bbox.y1;
  99.             iHeight = tText.bbox.y1 - tText.bbox.y0;
  100.             break;
  101.         case draw_OBJPATH:
  102.             /* These are not relevant in a textfile */
  103.             iSize = ((draw_pathstrhdr *)pcTmp)->size;
  104.             pcTmp += iSize;
  105.             iToGo -= iSize;
  106.             break;
  107.         case draw_OBJSPRITE:
  108.         case draw_OBJJPEG:
  109.             /* These are not relevant in a textfile */
  110.             iSize = ((draw_spristrhdr *)pcTmp)->size;
  111.             pcTmp += iSize;
  112.             iToGo -= iSize;
  113.             break;
  114.         default:
  115.             DBG_DEC(tText.tag);
  116.             bSuccess = FALSE;
  117.             break;
  118.         }
  119.     }
  120.     DBG_DEC_C(iToGo != 0, iToGo);
  121.     if (bSuccess) {
  122.         bSuccess = bWrite2File("\n", 1, pFile, szFilename);
  123.     }
  124.     (void)fclose(pFile);
  125.     if (bSuccess) {
  126.         vSetFiletype(szFilename, FILETYPE_TEXT);
  127.     } else {
  128.         (void)remove(szFilename);
  129.         werr(0, "Unable to save textfile '%s'", szFilename);
  130.     }
  131.     return bSuccess;
  132. } /* end of bText2File */
  133.  
  134. /*
  135.  * vSaveTextfile
  136.  */
  137. void
  138. vSaveTextfile(diagram_type *pDiagram)
  139. {
  140.     wimp_emask    tMask;
  141.     int        iRecLen, iNbrRecs, iEstSize;
  142.  
  143.     fail(pDiagram == NULL);
  144.  
  145.     DBG_MSG("vSaveTextfile");
  146.     iRecLen = sizeof(draw_textstrhdr) + DEFAULT_SCREEN_WIDTH * 2 / 3;
  147.     iNbrRecs = pDiagram->tInfo.length / iRecLen + 1;
  148.     iEstSize = iNbrRecs * DEFAULT_SCREEN_WIDTH * 2 / 3;
  149.     DBG_DEC(iEstSize);
  150.  
  151.     tMask = event_getmask();
  152.     event_setmask(0);
  153.     saveas(FILETYPE_TEXT, "WordText",
  154.         iEstSize, bText2File,
  155.         NULL, NULL, pDiagram);
  156.     event_setmask(tMask);
  157. } /* end of vSaveTextfile */
  158.  
  159. /*
  160.  * bDraw2File - Save the generated draw file to a Draw file
  161.  *
  162.  * Remark: This is not a simple copy action. The origin of the
  163.  * coordinates (0,0) must move from the top-left corner to the
  164.  * bottom-left corner.
  165.  */
  166. static BOOL
  167. bDraw2File(char *szFilename, void *pvHandle)
  168. {
  169.     FILE        *pFile;
  170.     diagram_type    *pDiagram;
  171.     draw_fileheader tHdr;
  172.     draw_textstrhdr    tText;
  173.     draw_pathstrhdr    tPath;
  174.     draw_spristrhdr    tSprite;
  175.     draw_jpegstrhdr tJpeg;
  176.     int    *piPath;
  177.     char    *pcTmp;
  178.     int    iYadd, iToGo, iSize;
  179.     BOOL    bSuccess;
  180.  
  181.     fail(szFilename == NULL || szFilename[0] == '\0');
  182.     fail(pvHandle == NULL);
  183.  
  184.     DBG_MSG("bDraw2File");
  185.     NO_DBG_MSG(szFilename);
  186.  
  187.     pDiagram = (diagram_type *)pvHandle;
  188.     pFile = fopen(szFilename, "wb");
  189.     if (pFile == NULL) {
  190.         werr(0, "I can't open '%s' for writing", szFilename);
  191.         return FALSE;
  192.     }
  193.     iToGo = pDiagram->tInfo.length;
  194.     DBG_DEC(iToGo);
  195.     pcTmp = pDiagram->tInfo.data;
  196.     tHdr = *(draw_fileheader *)pcTmp;
  197.     iYadd = -tHdr.bbox.y0;
  198.     tHdr.bbox.y0 += iYadd;
  199.     tHdr.bbox.y1 += iYadd;
  200.     bSuccess = bWrite2File(&tHdr, sizeof(tHdr), pFile, szFilename);
  201.     iToGo -= sizeof(tHdr);
  202.     DBG_DEC(iToGo);
  203.     pcTmp += sizeof(tHdr);
  204.     while (iToGo > 0 && bSuccess) {
  205.         tText = *(draw_textstrhdr *)pcTmp;
  206.         switch (tText.tag) {
  207.         case draw_OBJFONTLIST:
  208.             iSize = ((draw_fontliststrhdr *)pcTmp)->size;
  209.             bSuccess = bWrite2File(pcTmp,
  210.                     iSize, pFile, szFilename);
  211.             pcTmp += iSize;
  212.             iToGo -= iSize;
  213.             break;
  214.         case draw_OBJTEXT:
  215.             /* First correct the coordinates */
  216.             tText.bbox.y0 += iYadd;
  217.             tText.bbox.y1 += iYadd;
  218.             tText.coord.y += iYadd;
  219.             /* Now write the information to file */
  220.             bSuccess = bWrite2File(&tText,
  221.                 sizeof(tText), pFile, szFilename);
  222.             pcTmp += sizeof(tText);
  223.             iSize = tText.size - sizeof(tText);
  224.             if (bSuccess) {
  225.                 bSuccess = bWrite2File(pcTmp,
  226.                     iSize, pFile, szFilename);
  227.                 pcTmp += iSize;
  228.             }
  229.             iToGo -= tText.size;
  230.             break;
  231.         case draw_OBJPATH:
  232.             tPath = *(draw_pathstrhdr *)pcTmp;
  233.             /* First correct the coordinates */
  234.             tPath.bbox.y0 += iYadd;
  235.             tPath.bbox.y1 += iYadd;
  236.             /* Now write the information to file */
  237.             bSuccess = bWrite2File(&tPath,
  238.                 sizeof(tPath), pFile, szFilename);
  239.             pcTmp += sizeof(tPath);
  240.             iSize = tPath.size - sizeof(tPath);
  241.             fail(iSize < 14 * sizeof(int));
  242.             /* Second correct the path coordinates */
  243.             piPath = xmalloc(iSize);
  244.             memcpy(piPath, pcTmp, iSize);
  245.             piPath[ 2] += iYadd;
  246.             piPath[ 5] += iYadd;
  247.             piPath[ 8] += iYadd;
  248.             piPath[11] += iYadd;
  249.             if (bSuccess) {
  250.                 bSuccess = bWrite2File(piPath,
  251.                     iSize, pFile, szFilename);
  252.                 pcTmp += iSize;
  253.             }
  254.             piPath = xfree(piPath);
  255.             iToGo -= tPath.size;
  256.             break;
  257.         case draw_OBJSPRITE:
  258.             tSprite = *(draw_spristrhdr *)pcTmp;
  259.             /* First correct the coordinates */
  260.             tSprite.bbox.y0 += iYadd;
  261.             tSprite.bbox.y1 += iYadd;
  262.             /* Now write the information to file */
  263.             bSuccess = bWrite2File(&tSprite,
  264.                 sizeof(tSprite), pFile, szFilename);
  265.             pcTmp += sizeof(tSprite);
  266.             iSize = tSprite.size - sizeof(tSprite);
  267.             if (bSuccess) {
  268.                 bSuccess = bWrite2File(pcTmp,
  269.                     iSize, pFile, szFilename);
  270.                 pcTmp += iSize;
  271.             }
  272.             iToGo -= tSprite.size;
  273.             break;
  274.         case draw_OBJJPEG:
  275.             tJpeg = *(draw_jpegstrhdr *)pcTmp;
  276.             /* First correct the coordinates */
  277.             tJpeg.bbox.y0 += iYadd;
  278.             tJpeg.bbox.y1 += iYadd;
  279.             tJpeg.trfm[5] += iYadd;
  280.             /* Now write the information to file */
  281.             bSuccess = bWrite2File(&tJpeg,
  282.                 sizeof(tJpeg), pFile, szFilename);
  283.             pcTmp += sizeof(tJpeg);
  284.             iSize = tJpeg.size - sizeof(tJpeg);
  285.             if (bSuccess) {
  286.                 bSuccess = bWrite2File(pcTmp,
  287.                     iSize, pFile, szFilename);
  288.                 pcTmp += iSize;
  289.             }
  290.             iToGo -= tJpeg.size;
  291.             break;
  292.         default:
  293.             DBG_DEC(tText.tag);
  294.             bSuccess = FALSE;
  295.             break;
  296.         }
  297.     }
  298.     DBG_DEC_C(iToGo != 0, iToGo);
  299.     (void)fclose(pFile);
  300.     if (bSuccess) {
  301.         vSetFiletype(szFilename, FILETYPE_DRAW);
  302.     } else {
  303.         (void)remove(szFilename);
  304.         werr(0, "Unable to save drawfile '%s'", szFilename);
  305.     }
  306.     return bSuccess;
  307. } /* end of bDraw2File */
  308.  
  309. /*
  310.  * vSaveDrawfile
  311.  */
  312. void
  313. vSaveDrawfile(diagram_type *pDiagram)
  314. {
  315.     wimp_emask    tMask;
  316.     int        iEstSize;
  317.  
  318.     fail(pDiagram == NULL);
  319.  
  320.     DBG_MSG("vSaveDrawfile");
  321.     iEstSize = pDiagram->tInfo.length;
  322.     DBG_DEC(iEstSize);
  323.  
  324.     tMask = event_getmask();
  325.     event_setmask(0);
  326.     saveas(FILETYPE_DRAW, "WordDraw",
  327.         iEstSize, bDraw2File,
  328.         NULL, NULL, pDiagram);
  329.     event_setmask(tMask);
  330. } /* end of vSaveDrawfile */
  331.