Imported from antiword-0.37.tar.gz.
[antiword.git] / saveas.c
blob678ff045d7241227602daa4646f10e0d5ebf1dea
1 /*
2 * saveas.c
3 * Copyright (C) 1998-2001 A.J. van Os; Released under GPL
5 * Description:
6 * Functions to save the results as a textfile or a drawfile
7 */
9 #include <stdio.h>
10 #include <string.h>
11 #include "DeskLib:Menu.h"
12 #include "DeskLib:Save.h"
13 #include "DeskLib:Template.h"
14 #include "DeskLib:Window.h"
15 #include "drawfile.h"
16 #include "antiword.h"
18 /* The window handle of the save window */
19 static window_handle tSaveWindow = 0;
21 /* Xfer_send box fields */
22 #define DRAG_SPRITE 3
23 #define OK_BUTTON 0
24 #define CANCEL_BUTTON (-1)
25 #define FILENAME_ICON 2
29 * saveas - a wrapper around Save_InitSaveWindowhandler
31 static void
32 saveas(int iFileType, char *szOutfile, size_t tEstSize,
33 save_filesaver save_function, void *pvReference)
35 TRACE_MSG("saveas");
37 if (tSaveWindow == 0) {
38 tSaveWindow = Window_Create("xfer_send", template_TITLEMIN);
40 Icon_SetText(tSaveWindow, FILENAME_ICON, szOutfile);
41 Window_Show(tSaveWindow, open_UNDERPOINTER);
42 (void)Save_InitSaveWindowHandler(tSaveWindow, FALSE, TRUE, TRUE,
43 DRAG_SPRITE, OK_BUTTON, CANCEL_BUTTON, FILENAME_ICON,
44 save_function, NULL, NULL, tEstSize, iFileType, pvReference);
45 } /* end of saveas */
47 static BOOL
48 bWrite2File(void *pvBytes, size_t tSize, FILE *pFile, const char *szFilename)
50 if (fwrite(pvBytes, sizeof(char), tSize, pFile) != tSize) {
51 werr(0, "I can't write to '%s'", szFilename);
52 return FALSE;
54 return TRUE;
55 } /* end of bWrite2File */
58 * bText2File - Save the generated draw file to a Text file
60 static BOOL
61 bText2File(char *szFilename, void *pvHandle)
63 FILE *pFile;
64 diagram_type *pDiag;
65 drawfile_object *pObj;
66 drawfile_text *pText;
67 const char *pcTmp;
68 int iToGo, iX, iYtopPrev, iHeight, iLines;
69 BOOL bFirst, bIndent, bSuccess;
71 TRACE_MSG("bText2File");
73 fail(szFilename == NULL || szFilename[0] == '\0');
74 fail(pvHandle == NULL);
76 DBG_MSG(szFilename);
78 pDiag = (diagram_type *)pvHandle;
79 pFile = fopen(szFilename, "w");
80 if (pFile == NULL) {
81 werr(0, "I can't open '%s' for writing", szFilename);
82 return FALSE;
84 bFirst = TRUE;
85 iYtopPrev = 0;
86 iHeight = (int)lWord2DrawUnits20(DEFAULT_FONT_SIZE);
87 bSuccess = TRUE;
88 fail(pDiag->tInfo.length < offsetof(drawfile_diagram, objects));
89 iToGo = pDiag->tInfo.length - offsetof(drawfile_diagram, objects);
90 DBG_DEC(iToGo);
91 pcTmp = (const char *)pDiag->tInfo.data +
92 offsetof(drawfile_diagram, objects);
93 while (iToGo > 0 && bSuccess) {
94 pObj = (drawfile_object *)pcTmp;
95 switch (pObj->type) {
96 case drawfile_TYPE_TEXT:
97 pText = &pObj->data.text;
98 /* Compute the number of lines */
99 iLines = (iYtopPrev - pText->bbox.max.y +
100 iHeight / 2) / iHeight;
101 DBG_DEC_C(iLines < 0, iYtopPrev);
102 DBG_DEC_C(iLines < 0, pText->bbox.max.y);
103 fail(iLines < 0);
104 bIndent = iLines > 0 || bFirst;
105 bFirst = FALSE;
106 /* Print the newlines */
107 while (iLines > 0 && bSuccess) {
108 bSuccess = bWrite2File("\n",
109 1, pFile, szFilename);
110 iLines--;
112 /* Print the indentation */
113 if (bIndent && bSuccess) {
114 for (iX = Drawfile_ScreenToDraw(8);
115 iX <= pText->bbox.min.x && bSuccess;
116 iX += Drawfile_ScreenToDraw(16)) {
117 bSuccess = bWrite2File(" ",
118 1, pFile, szFilename);
121 if (!bSuccess) {
122 break;
124 /* Print the text object */
125 bSuccess = bWrite2File(pText->text,
126 strlen(pText->text), pFile, szFilename);
127 /* Setup for the next object */
128 iYtopPrev = pText->bbox.max.y;
129 iHeight = pText->bbox.max.y - pText->bbox.min.y;
130 break;
131 case drawfile_TYPE_FONT_TABLE:
132 case drawfile_TYPE_PATH:
133 case drawfile_TYPE_SPRITE:
134 case drawfile_TYPE_JPEG:
135 /* These are not relevant in a textfile */
136 break;
137 default:
138 DBG_DEC(pObj->type);
139 bSuccess = FALSE;
140 break;
142 pcTmp += pObj->size;
143 iToGo -= pObj->size;
145 DBG_DEC_C(iToGo != 0, iToGo);
146 if (bSuccess) {
147 bSuccess = bWrite2File("\n", 1, pFile, szFilename);
149 (void)fclose(pFile);
150 if (bSuccess) {
151 vSetFiletype(szFilename, FILETYPE_TEXT);
152 } else {
153 (void)remove(szFilename);
154 werr(0, "Unable to save textfile '%s'", szFilename);
156 return bSuccess;
157 } /* end of bText2File */
160 * bSaveTextfile - save the diagram as a text file
162 BOOL
163 bSaveTextfile(event_pollblock *pEvent, void *pvReference)
165 diagram_type *pDiag;
166 size_t tRecLen, tNbrRecs, tEstSize;
168 TRACE_MSG("bSaveTextfile");
170 fail(pEvent == NULL);
171 fail(pvReference == NULL);
173 pDiag = (diagram_type *)pvReference;
175 switch (pEvent->type) {
176 case event_SEND: /* From a menu */
177 fail(pEvent->data.message.header.action != message_MENUWARN);
178 if (menu_currentopen != pDiag->pSaveMenu ||
179 pEvent->data.message.data.menuwarn.selection[0] !=
180 SAVEMENU_SAVETEXT) {
181 return FALSE;
183 break;
184 case event_KEY: /* From a key short cut */
185 if (pEvent->data.key.caret.window != pDiag->tMainWindow) {
186 return FALSE;
188 break;
189 default:
190 DBG_DEC(pEvent->type);
191 return FALSE;
194 tRecLen = sizeof(drawfile_text) + DEFAULT_SCREEN_WIDTH * 2 / 3;
195 tNbrRecs = pDiag->tInfo.length / tRecLen + 1;
196 tEstSize = tNbrRecs * DEFAULT_SCREEN_WIDTH * 2 / 3;
197 DBG_DEC(tEstSize);
199 saveas(FILETYPE_TEXT, "WordText", tEstSize, bText2File, pDiag);
200 return TRUE;
201 } /* end of bSaveTextfile */
204 * bDraw2File - Save the generated draw file to a Draw file
206 * Remark: This is not a simple copy action. The origin of the
207 * coordinates (0,0) must move from the top-left corner to the
208 * bottom-left corner.
210 static BOOL
211 bDraw2File(char *szFilename, void *pvHandle)
213 FILE *pFile;
214 diagram_type *pDiagram;
215 wimp_box *pBbox;
216 drawfile_object *pObj;
217 drawfile_text *pText;
218 drawfile_path *pPath;
219 drawfile_sprite *pSprite;
220 drawfile_jpeg *pJpeg;
221 int *piPath;
222 char *pcTmp;
223 int iYadd, iToGo, iSize;
224 BOOL bSuccess;
226 TRACE_MSG("bDraw2File");
228 fail(szFilename == NULL || szFilename[0] == '\0');
229 fail(pvHandle == NULL);
231 NO_DBG_MSG(szFilename);
233 pDiagram = (diagram_type *)pvHandle;
234 pFile = fopen(szFilename, "wb");
235 if (pFile == NULL) {
236 werr(0, "I can't open '%s' for writing", szFilename);
237 return FALSE;
239 iToGo = pDiagram->tInfo.length;
240 DBG_DEC(iToGo);
241 pcTmp = pDiagram->tInfo.data;
242 bSuccess = bWrite2File(pcTmp,
243 offsetof(drawfile_diagram, bbox), pFile, szFilename);
244 if (bSuccess) {
245 pcTmp += offsetof(drawfile_diagram, bbox);
246 iToGo -= offsetof(drawfile_diagram, bbox);
247 pBbox = (wimp_box *)pcTmp;
248 iYadd = -pBbox->min.y;
249 pBbox->min.y += iYadd;
250 pBbox->max.y += iYadd;
251 bSuccess = bWrite2File(pcTmp,
252 sizeof(*pBbox), pFile, szFilename);
253 iToGo -= sizeof(*pBbox);
254 DBG_DEC(iToGo);
255 pcTmp += sizeof(*pBbox);
256 } else {
257 iYadd = 0;
259 while (iToGo > 0 && bSuccess) {
260 pObj = (drawfile_object *)pcTmp;
261 iSize = pObj->size;
262 switch (pObj->type) {
263 case drawfile_TYPE_FONT_TABLE:
264 bSuccess = bWrite2File(pcTmp,
265 iSize, pFile, szFilename);
266 pcTmp += iSize;
267 iToGo -= iSize;
268 break;
269 case drawfile_TYPE_TEXT:
270 pText = &pObj->data.text;
271 /* First correct the coordinates */
272 pText->bbox.min.y += iYadd;
273 pText->bbox.max.y += iYadd;
274 pText->base.y += iYadd;
275 /* Now write the information to file */
276 bSuccess = bWrite2File(pcTmp,
277 iSize, pFile, szFilename);
278 pcTmp += pObj->size;
279 iToGo -= pObj->size;
280 break;
281 case drawfile_TYPE_PATH:
282 pPath = &pObj->data.path;
283 /* First correct the coordinates */
284 pPath->bbox.min.y += iYadd;
285 pPath->bbox.max.y += iYadd;
286 /* Now write the information to file */
287 bSuccess = bWrite2File(pPath,
288 sizeof(*pPath), pFile, szFilename);
289 pcTmp += sizeof(*pPath);
290 iSize = pObj->size - sizeof(*pPath);
291 fail(iSize < 14 * sizeof(int));
292 /* Second correct the path coordinates */
293 piPath = xmalloc(iSize);
294 memcpy(piPath, pcTmp, iSize);
295 piPath[ 2] += iYadd;
296 piPath[ 5] += iYadd;
297 piPath[ 8] += iYadd;
298 piPath[11] += iYadd;
299 if (bSuccess) {
300 bSuccess = bWrite2File(piPath,
301 iSize, pFile, szFilename);
302 pcTmp += iSize;
304 piPath = xfree(piPath);
305 iToGo -= pObj->size;
306 break;
307 case drawfile_TYPE_SPRITE:
308 pSprite = &pObj->data.sprite;
309 /* First correct the coordinates */
310 pSprite->bbox.min.y += iYadd;
311 pSprite->bbox.max.y += iYadd;
312 /* Now write the information to file */
313 bSuccess = bWrite2File(pcTmp,
314 iSize, pFile, szFilename);
315 pcTmp += pObj->size;
316 iToGo -= pObj->size;
317 break;
318 case drawfile_TYPE_JPEG:
319 pJpeg = &pObj->data.jpeg;
320 /* First correct the coordinates */
321 pJpeg->bbox.min.y += iYadd;
322 pJpeg->bbox.max.y += iYadd;
323 pJpeg->trfm.entries[2][1] += iYadd;
324 /* Now write the information to file */
325 bSuccess = bWrite2File(pcTmp,
326 iSize, pFile, szFilename);
327 pcTmp += pObj->size;
328 iToGo -= pObj->size;
329 break;
330 default:
331 DBG_DEC(pObj->type);
332 bSuccess = FALSE;
333 break;
336 DBG_DEC_C(iToGo != 0, iToGo);
337 (void)fclose(pFile);
338 if (bSuccess) {
339 vSetFiletype(szFilename, FILETYPE_DRAW);
340 } else {
341 (void)remove(szFilename);
342 werr(0, "Unable to save drawfile '%s'", szFilename);
344 return bSuccess;
345 } /* end of bDraw2File */
348 * bSaveDrawfile - save the diagram as a draw file
350 BOOL
351 bSaveDrawfile(event_pollblock *pEvent, void *pvReference)
353 diagram_type *pDiag;
354 size_t tEstSize;
356 TRACE_MSG("bSaveDrawfile");
358 fail(pEvent == NULL);
359 fail(pvReference == NULL);
361 pDiag = (diagram_type *)pvReference;
363 switch (pEvent->type) {
364 case event_SEND: /* From a menu */
365 fail(pEvent->data.message.header.action != message_MENUWARN);
366 if (menu_currentopen != pDiag->pSaveMenu ||
367 pEvent->data.message.data.menuwarn.selection[0] !=
368 SAVEMENU_SAVEDRAW) {
369 return FALSE;
371 break;
372 case event_KEY: /* From a key short cut */
373 if (pEvent->data.key.caret.window != pDiag->tMainWindow) {
374 return FALSE;
376 break;
377 default:
378 DBG_DEC(pEvent->type);
379 return FALSE;
382 tEstSize = pDiag->tInfo.length;
383 DBG_DEC(tEstSize);
385 saveas(FILETYPE_DRAW, "WordDraw", tEstSize, bDraw2File, pDiag);
386 return TRUE;
387 } /* end of bSaveDrawfile */