Imported from antiword-0.34.tar.gz.
[antiword.git] / saveas.c
blob99442140053bbeb0bcee5a83ed2aab560d7a78ea
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 "saveas.h"
12 #include "event.h"
13 #include "antiword.h"
15 static BOOL
16 bWrite2File(void *pvBytes, size_t tSize, FILE *pFile, const char *szFilename)
18 if (fwrite(pvBytes, sizeof(char), tSize, pFile) != tSize) {
19 werr(0, "I can't write to '%s'", szFilename);
20 return FALSE;
22 return TRUE;
23 } /* end of bWrite2File */
26 * bText2File - Save the generated draw file to a Text file
28 static BOOL
29 bText2File(char *szFilename, void *pvHandle)
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;
38 fail(szFilename == NULL || szFilename[0] == '\0');
39 fail(pvHandle == NULL);
41 DBG_MSG("bText2File");
42 DBG_MSG(szFilename);
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;
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--;
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);
88 if (!bSuccess) {
89 break;
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;
120 DBG_DEC_C(iToGo != 0, iToGo);
121 if (bSuccess) {
122 bSuccess = bWrite2File("\n", 1, pFile, szFilename);
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);
131 return bSuccess;
132 } /* end of bText2File */
135 * vSaveTextfile
137 void
138 vSaveTextfile(diagram_type *pDiagram)
140 wimp_emask tMask;
141 int iRecLen, iNbrRecs, iEstSize;
143 fail(pDiagram == NULL);
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);
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 */
160 * bDraw2File - Save the generated draw file to a Draw file
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.
166 static BOOL
167 bDraw2File(char *szFilename, void *pvHandle)
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;
181 fail(szFilename == NULL || szFilename[0] == '\0');
182 fail(pvHandle == NULL);
184 DBG_MSG("bDraw2File");
185 NO_DBG_MSG(szFilename);
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;
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;
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;
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;
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;
290 iToGo -= tJpeg.size;
291 break;
292 default:
293 DBG_DEC(tText.tag);
294 bSuccess = FALSE;
295 break;
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);
306 return bSuccess;
307 } /* end of bDraw2File */
310 * vSaveDrawfile
312 void
313 vSaveDrawfile(diagram_type *pDiagram)
315 wimp_emask tMask;
316 int iEstSize;
318 fail(pDiagram == NULL);
320 DBG_MSG("vSaveDrawfile");
321 iEstSize = pDiagram->tInfo.length;
322 DBG_DEC(iEstSize);
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 */