summaryrefslogtreecommitdiff
path: root/sys/src/cmd/aux/antiword/saveas.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/aux/antiword/saveas.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/aux/antiword/saveas.c')
-rwxr-xr-xsys/src/cmd/aux/antiword/saveas.c387
1 files changed, 387 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/antiword/saveas.c b/sys/src/cmd/aux/antiword/saveas.c
new file mode 100755
index 000000000..678ff045d
--- /dev/null
+++ b/sys/src/cmd/aux/antiword/saveas.c
@@ -0,0 +1,387 @@
+/*
+ * saveas.c
+ * Copyright (C) 1998-2001 A.J. van Os; Released under GPL
+ *
+ * Description:
+ * Functions to save the results as a textfile or a drawfile
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "DeskLib:Menu.h"
+#include "DeskLib:Save.h"
+#include "DeskLib:Template.h"
+#include "DeskLib:Window.h"
+#include "drawfile.h"
+#include "antiword.h"
+
+/* The window handle of the save window */
+static window_handle tSaveWindow = 0;
+
+/* Xfer_send box fields */
+#define DRAG_SPRITE 3
+#define OK_BUTTON 0
+#define CANCEL_BUTTON (-1)
+#define FILENAME_ICON 2
+
+
+/*
+ * saveas - a wrapper around Save_InitSaveWindowhandler
+ */
+static void
+saveas(int iFileType, char *szOutfile, size_t tEstSize,
+ save_filesaver save_function, void *pvReference)
+{
+ TRACE_MSG("saveas");
+
+ if (tSaveWindow == 0) {
+ tSaveWindow = Window_Create("xfer_send", template_TITLEMIN);
+ }
+ Icon_SetText(tSaveWindow, FILENAME_ICON, szOutfile);
+ Window_Show(tSaveWindow, open_UNDERPOINTER);
+ (void)Save_InitSaveWindowHandler(tSaveWindow, FALSE, TRUE, TRUE,
+ DRAG_SPRITE, OK_BUTTON, CANCEL_BUTTON, FILENAME_ICON,
+ save_function, NULL, NULL, tEstSize, iFileType, pvReference);
+} /* end of saveas */
+
+static BOOL
+bWrite2File(void *pvBytes, size_t tSize, FILE *pFile, const char *szFilename)
+{
+ if (fwrite(pvBytes, sizeof(char), tSize, pFile) != tSize) {
+ werr(0, "I can't write to '%s'", szFilename);
+ return FALSE;
+ }
+ return TRUE;
+} /* end of bWrite2File */
+
+/*
+ * bText2File - Save the generated draw file to a Text file
+ */
+static BOOL
+bText2File(char *szFilename, void *pvHandle)
+{
+ FILE *pFile;
+ diagram_type *pDiag;
+ drawfile_object *pObj;
+ drawfile_text *pText;
+ const char *pcTmp;
+ int iToGo, iX, iYtopPrev, iHeight, iLines;
+ BOOL bFirst, bIndent, bSuccess;
+
+ TRACE_MSG("bText2File");
+
+ fail(szFilename == NULL || szFilename[0] == '\0');
+ fail(pvHandle == NULL);
+
+ DBG_MSG(szFilename);
+
+ pDiag = (diagram_type *)pvHandle;
+ pFile = fopen(szFilename, "w");
+ if (pFile == NULL) {
+ werr(0, "I can't open '%s' for writing", szFilename);
+ return FALSE;
+ }
+ bFirst = TRUE;
+ iYtopPrev = 0;
+ iHeight = (int)lWord2DrawUnits20(DEFAULT_FONT_SIZE);
+ bSuccess = TRUE;
+ fail(pDiag->tInfo.length < offsetof(drawfile_diagram, objects));
+ iToGo = pDiag->tInfo.length - offsetof(drawfile_diagram, objects);
+ DBG_DEC(iToGo);
+ pcTmp = (const char *)pDiag->tInfo.data +
+ offsetof(drawfile_diagram, objects);
+ while (iToGo > 0 && bSuccess) {
+ pObj = (drawfile_object *)pcTmp;
+ switch (pObj->type) {
+ case drawfile_TYPE_TEXT:
+ pText = &pObj->data.text;
+ /* Compute the number of lines */
+ iLines = (iYtopPrev - pText->bbox.max.y +
+ iHeight / 2) / iHeight;
+ DBG_DEC_C(iLines < 0, iYtopPrev);
+ DBG_DEC_C(iLines < 0, pText->bbox.max.y);
+ fail(iLines < 0);
+ bIndent = iLines > 0 || bFirst;
+ bFirst = FALSE;
+ /* Print the newlines */
+ while (iLines > 0 && bSuccess) {
+ bSuccess = bWrite2File("\n",
+ 1, pFile, szFilename);
+ iLines--;
+ }
+ /* Print the indentation */
+ if (bIndent && bSuccess) {
+ for (iX = Drawfile_ScreenToDraw(8);
+ iX <= pText->bbox.min.x && bSuccess;
+ iX += Drawfile_ScreenToDraw(16)) {
+ bSuccess = bWrite2File(" ",
+ 1, pFile, szFilename);
+ }
+ }
+ if (!bSuccess) {
+ break;
+ }
+ /* Print the text object */
+ bSuccess = bWrite2File(pText->text,
+ strlen(pText->text), pFile, szFilename);
+ /* Setup for the next object */
+ iYtopPrev = pText->bbox.max.y;
+ iHeight = pText->bbox.max.y - pText->bbox.min.y;
+ break;
+ case drawfile_TYPE_FONT_TABLE:
+ case drawfile_TYPE_PATH:
+ case drawfile_TYPE_SPRITE:
+ case drawfile_TYPE_JPEG:
+ /* These are not relevant in a textfile */
+ break;
+ default:
+ DBG_DEC(pObj->type);
+ bSuccess = FALSE;
+ break;
+ }
+ pcTmp += pObj->size;
+ iToGo -= pObj->size;
+ }
+ DBG_DEC_C(iToGo != 0, iToGo);
+ if (bSuccess) {
+ bSuccess = bWrite2File("\n", 1, pFile, szFilename);
+ }
+ (void)fclose(pFile);
+ if (bSuccess) {
+ vSetFiletype(szFilename, FILETYPE_TEXT);
+ } else {
+ (void)remove(szFilename);
+ werr(0, "Unable to save textfile '%s'", szFilename);
+ }
+ return bSuccess;
+} /* end of bText2File */
+
+/*
+ * bSaveTextfile - save the diagram as a text file
+ */
+BOOL
+bSaveTextfile(event_pollblock *pEvent, void *pvReference)
+{
+ diagram_type *pDiag;
+ size_t tRecLen, tNbrRecs, tEstSize;
+
+ TRACE_MSG("bSaveTextfile");
+
+ fail(pEvent == NULL);
+ fail(pvReference == NULL);
+
+ pDiag = (diagram_type *)pvReference;
+
+ switch (pEvent->type) {
+ case event_SEND: /* From a menu */
+ fail(pEvent->data.message.header.action != message_MENUWARN);
+ if (menu_currentopen != pDiag->pSaveMenu ||
+ pEvent->data.message.data.menuwarn.selection[0] !=
+ SAVEMENU_SAVETEXT) {
+ return FALSE;
+ }
+ break;
+ case event_KEY: /* From a key short cut */
+ if (pEvent->data.key.caret.window != pDiag->tMainWindow) {
+ return FALSE;
+ }
+ break;
+ default:
+ DBG_DEC(pEvent->type);
+ return FALSE;
+ }
+
+ tRecLen = sizeof(drawfile_text) + DEFAULT_SCREEN_WIDTH * 2 / 3;
+ tNbrRecs = pDiag->tInfo.length / tRecLen + 1;
+ tEstSize = tNbrRecs * DEFAULT_SCREEN_WIDTH * 2 / 3;
+ DBG_DEC(tEstSize);
+
+ saveas(FILETYPE_TEXT, "WordText", tEstSize, bText2File, pDiag);
+ return TRUE;
+} /* end of bSaveTextfile */
+
+/*
+ * bDraw2File - Save the generated draw file to a Draw file
+ *
+ * Remark: This is not a simple copy action. The origin of the
+ * coordinates (0,0) must move from the top-left corner to the
+ * bottom-left corner.
+ */
+static BOOL
+bDraw2File(char *szFilename, void *pvHandle)
+{
+ FILE *pFile;
+ diagram_type *pDiagram;
+ wimp_box *pBbox;
+ drawfile_object *pObj;
+ drawfile_text *pText;
+ drawfile_path *pPath;
+ drawfile_sprite *pSprite;
+ drawfile_jpeg *pJpeg;
+ int *piPath;
+ char *pcTmp;
+ int iYadd, iToGo, iSize;
+ BOOL bSuccess;
+
+ TRACE_MSG("bDraw2File");
+
+ fail(szFilename == NULL || szFilename[0] == '\0');
+ fail(pvHandle == NULL);
+
+ NO_DBG_MSG(szFilename);
+
+ pDiagram = (diagram_type *)pvHandle;
+ pFile = fopen(szFilename, "wb");
+ if (pFile == NULL) {
+ werr(0, "I can't open '%s' for writing", szFilename);
+ return FALSE;
+ }
+ iToGo = pDiagram->tInfo.length;
+ DBG_DEC(iToGo);
+ pcTmp = pDiagram->tInfo.data;
+ bSuccess = bWrite2File(pcTmp,
+ offsetof(drawfile_diagram, bbox), pFile, szFilename);
+ if (bSuccess) {
+ pcTmp += offsetof(drawfile_diagram, bbox);
+ iToGo -= offsetof(drawfile_diagram, bbox);
+ pBbox = (wimp_box *)pcTmp;
+ iYadd = -pBbox->min.y;
+ pBbox->min.y += iYadd;
+ pBbox->max.y += iYadd;
+ bSuccess = bWrite2File(pcTmp,
+ sizeof(*pBbox), pFile, szFilename);
+ iToGo -= sizeof(*pBbox);
+ DBG_DEC(iToGo);
+ pcTmp += sizeof(*pBbox);
+ } else {
+ iYadd = 0;
+ }
+ while (iToGo > 0 && bSuccess) {
+ pObj = (drawfile_object *)pcTmp;
+ iSize = pObj->size;
+ switch (pObj->type) {
+ case drawfile_TYPE_FONT_TABLE:
+ bSuccess = bWrite2File(pcTmp,
+ iSize, pFile, szFilename);
+ pcTmp += iSize;
+ iToGo -= iSize;
+ break;
+ case drawfile_TYPE_TEXT:
+ pText = &pObj->data.text;
+ /* First correct the coordinates */
+ pText->bbox.min.y += iYadd;
+ pText->bbox.max.y += iYadd;
+ pText->base.y += iYadd;
+ /* Now write the information to file */
+ bSuccess = bWrite2File(pcTmp,
+ iSize, pFile, szFilename);
+ pcTmp += pObj->size;
+ iToGo -= pObj->size;
+ break;
+ case drawfile_TYPE_PATH:
+ pPath = &pObj->data.path;
+ /* First correct the coordinates */
+ pPath->bbox.min.y += iYadd;
+ pPath->bbox.max.y += iYadd;
+ /* Now write the information to file */
+ bSuccess = bWrite2File(pPath,
+ sizeof(*pPath), pFile, szFilename);
+ pcTmp += sizeof(*pPath);
+ iSize = pObj->size - sizeof(*pPath);
+ fail(iSize < 14 * sizeof(int));
+ /* Second correct the path coordinates */
+ piPath = xmalloc(iSize);
+ memcpy(piPath, pcTmp, iSize);
+ piPath[ 2] += iYadd;
+ piPath[ 5] += iYadd;
+ piPath[ 8] += iYadd;
+ piPath[11] += iYadd;
+ if (bSuccess) {
+ bSuccess = bWrite2File(piPath,
+ iSize, pFile, szFilename);
+ pcTmp += iSize;
+ }
+ piPath = xfree(piPath);
+ iToGo -= pObj->size;
+ break;
+ case drawfile_TYPE_SPRITE:
+ pSprite = &pObj->data.sprite;
+ /* First correct the coordinates */
+ pSprite->bbox.min.y += iYadd;
+ pSprite->bbox.max.y += iYadd;
+ /* Now write the information to file */
+ bSuccess = bWrite2File(pcTmp,
+ iSize, pFile, szFilename);
+ pcTmp += pObj->size;
+ iToGo -= pObj->size;
+ break;
+ case drawfile_TYPE_JPEG:
+ pJpeg = &pObj->data.jpeg;
+ /* First correct the coordinates */
+ pJpeg->bbox.min.y += iYadd;
+ pJpeg->bbox.max.y += iYadd;
+ pJpeg->trfm.entries[2][1] += iYadd;
+ /* Now write the information to file */
+ bSuccess = bWrite2File(pcTmp,
+ iSize, pFile, szFilename);
+ pcTmp += pObj->size;
+ iToGo -= pObj->size;
+ break;
+ default:
+ DBG_DEC(pObj->type);
+ bSuccess = FALSE;
+ break;
+ }
+ }
+ DBG_DEC_C(iToGo != 0, iToGo);
+ (void)fclose(pFile);
+ if (bSuccess) {
+ vSetFiletype(szFilename, FILETYPE_DRAW);
+ } else {
+ (void)remove(szFilename);
+ werr(0, "Unable to save drawfile '%s'", szFilename);
+ }
+ return bSuccess;
+} /* end of bDraw2File */
+
+/*
+ * bSaveDrawfile - save the diagram as a draw file
+ */
+BOOL
+bSaveDrawfile(event_pollblock *pEvent, void *pvReference)
+{
+ diagram_type *pDiag;
+ size_t tEstSize;
+
+ TRACE_MSG("bSaveDrawfile");
+
+ fail(pEvent == NULL);
+ fail(pvReference == NULL);
+
+ pDiag = (diagram_type *)pvReference;
+
+ switch (pEvent->type) {
+ case event_SEND: /* From a menu */
+ fail(pEvent->data.message.header.action != message_MENUWARN);
+ if (menu_currentopen != pDiag->pSaveMenu ||
+ pEvent->data.message.data.menuwarn.selection[0] !=
+ SAVEMENU_SAVEDRAW) {
+ return FALSE;
+ }
+ break;
+ case event_KEY: /* From a key short cut */
+ if (pEvent->data.key.caret.window != pDiag->tMainWindow) {
+ return FALSE;
+ }
+ break;
+ default:
+ DBG_DEC(pEvent->type);
+ return FALSE;
+ }
+
+ tEstSize = pDiag->tInfo.length;
+ DBG_DEC(tEstSize);
+
+ saveas(FILETYPE_DRAW, "WordDraw", tEstSize, bDraw2File, pDiag);
+ return TRUE;
+} /* end of bSaveDrawfile */