Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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 "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"
17
 
18
/* The window handle of the save window */
19
static window_handle	tSaveWindow = 0;
20
 
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
26
 
27
 
28
/*
29
 * saveas - a wrapper around Save_InitSaveWindowhandler
30
 */
31
static void
32
saveas(int iFileType, char *szOutfile, size_t tEstSize,
33
	save_filesaver save_function, void *pvReference)
34
{
35
	TRACE_MSG("saveas");
36
 
37
	if (tSaveWindow == 0) {
38
		tSaveWindow = Window_Create("xfer_send", template_TITLEMIN);
39
	}
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 */
46
 
47
static BOOL
48
bWrite2File(void *pvBytes, size_t tSize, FILE *pFile, const char *szFilename)
49
{
50
	if (fwrite(pvBytes, sizeof(char), tSize, pFile) != tSize) {
51
		werr(0, "I can't write to '%s'", szFilename);
52
		return FALSE;
53
	}
54
	return TRUE;
55
} /* end of bWrite2File */
56
 
57
/*
58
 * bText2File - Save the generated draw file to a Text file
59
 */
60
static BOOL
61
bText2File(char *szFilename, void *pvHandle)
62
{
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;
70
 
71
	TRACE_MSG("bText2File");
72
 
73
	fail(szFilename == NULL || szFilename[0] == '\0');
74
	fail(pvHandle == NULL);
75
 
76
	DBG_MSG(szFilename);
77
 
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;
83
	}
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--;
111
			}
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);
119
				}
120
			}
121
			if (!bSuccess) {
122
				break;
123
			}
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;
141
		}
142
		pcTmp += pObj->size;
143
		iToGo -= pObj->size;
144
	}
145
	DBG_DEC_C(iToGo != 0, iToGo);
146
	if (bSuccess) {
147
		bSuccess = bWrite2File("\n", 1, pFile, szFilename);
148
	}
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);
155
	}
156
	return bSuccess;
157
} /* end of bText2File */
158
 
159
/*
160
 * bSaveTextfile - save the diagram as a text file
161
 */
162
BOOL
163
bSaveTextfile(event_pollblock *pEvent, void *pvReference)
164
{
165
	diagram_type	*pDiag;
166
	size_t	tRecLen, tNbrRecs, tEstSize;
167
 
168
	TRACE_MSG("bSaveTextfile");
169
 
170
	fail(pEvent == NULL);
171
	fail(pvReference == NULL);
172
 
173
	pDiag = (diagram_type *)pvReference;
174
 
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;
182
		}
183
		break;
184
	case event_KEY:		/* From a key short cut */
185
		if (pEvent->data.key.caret.window != pDiag->tMainWindow) {
186
			return FALSE;
187
		}
188
		break;
189
	default:
190
		DBG_DEC(pEvent->type);
191
		return FALSE;
192
	}
193
 
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);
198
 
199
	saveas(FILETYPE_TEXT, "WordText", tEstSize, bText2File, pDiag);
200
	return TRUE;
201
} /* end of bSaveTextfile */
202
 
203
/*
204
 * bDraw2File - Save the generated draw file to a Draw file
205
 *
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.
209
 */
210
static BOOL
211
bDraw2File(char *szFilename, void *pvHandle)
212
{
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;
225
 
226
	TRACE_MSG("bDraw2File");
227
 
228
	fail(szFilename == NULL || szFilename[0] == '\0');
229
	fail(pvHandle == NULL);
230
 
231
	NO_DBG_MSG(szFilename);
232
 
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;
238
	}
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;
258
	}
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;
303
			}
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;
334
		}
335
	}
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);
343
	}
344
	return bSuccess;
345
} /* end of bDraw2File */
346
 
347
/*
348
 * bSaveDrawfile - save the diagram as a draw file
349
 */
350
BOOL
351
bSaveDrawfile(event_pollblock *pEvent, void *pvReference)
352
{
353
	diagram_type	*pDiag;
354
	size_t		tEstSize;
355
 
356
	TRACE_MSG("bSaveDrawfile");
357
 
358
	fail(pEvent == NULL);
359
	fail(pvReference == NULL);
360
 
361
	pDiag = (diagram_type *)pvReference;
362
 
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;
370
		}
371
		break;
372
	case event_KEY:		/* From a key short cut */
373
		if (pEvent->data.key.caret.window != pDiag->tMainWindow) {
374
			return FALSE;
375
		}
376
		break;
377
	default:
378
		DBG_DEC(pEvent->type);
379
		return FALSE;
380
	}
381
 
382
	tEstSize = pDiag->tInfo.length;
383
	DBG_DEC(tEstSize);
384
 
385
	saveas(FILETYPE_DRAW, "WordDraw", tEstSize, bDraw2File, pDiag);
386
	return TRUE;
387
} /* end of bSaveDrawfile */