Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature-vt/sys/src/cmd/aux/antiword/draw.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * draw.c
3
 * Copyright (C) 1998-2005 A.J. van Os; Released under GPL
4
 *
5
 * Description:
6
 * Functions to deal with the Draw format
7
 */
8
 
9
#include <stdlib.h>
10
#include <ctype.h>
11
#include <string.h>
12
#include "DeskLib:KeyCodes.h"
13
#include "DeskLib:Error.h"
14
#include "DeskLib:Menu.h"
15
#include "DeskLib:Template.h"
16
#include "DeskLib:Window.h"
17
#include "DeskLib:EventMsg.h"
18
#include "flexlib:flex.h"
19
#include "drawfile.h"
20
#include "antiword.h"
21
 
22
/* The work area must be a little bit larger than the diagram */
23
#define WORKAREA_EXTENSION	    5
24
/* Diagram memory */
25
#define INITIAL_SIZE		32768	/* 32k */
26
#define EXTENSION_SIZE		 4096	/*  4k */
27
/* Main window title */
28
#define WINDOW_TITLE_LEN	   28
29
#define FILENAME_TITLE_LEN	(WINDOW_TITLE_LEN - 10)
30
 
31
 
32
#if !defined(__GNUC__)
33
int
34
flex_alloc(flex_ptr anchor, int n)
35
{
36
	void	*pvTmp;
37
 
38
	TRACE_MSG("flex_alloc");
39
 
40
	if (anchor == NULL || n < 0) {
41
		return 0;
42
	}
43
	if (n == 0) {
44
		n = 1;
45
	}
46
	pvTmp = malloc(n);
47
	if (pvTmp == NULL) {
48
		return 0;
49
	}
50
	*anchor = pvTmp;
51
	return 1;
52
} /* end of flex_alloc */
53
 
54
void
55
flex_free(flex_ptr anchor)
56
{
57
	TRACE_MSG("flex_free");
58
 
59
	if (anchor == NULL || *anchor == NULL) {
60
		return;
61
	}
62
	free(*anchor);
63
	*anchor = NULL;
64
} /* end of flex_free */
65
 
66
int
67
flex_extend(flex_ptr anchor, int newsize)
68
{
69
	void	*pvTmp;
70
 
71
	TRACE_MSG("flex_extend");
72
 
73
	if (anchor == NULL || newsize < 0) {
74
		return 0;
75
	}
76
	if (newsize == 0) {
77
		newsize = 1;
78
	}
79
	pvTmp = realloc(*anchor, newsize);
80
	if (pvTmp == NULL) {
81
		return 0;
82
	}
83
	*anchor = pvTmp;
84
	return 1;
85
} /* end of flex_extend */
86
#endif /* !__GNUC__ */
87
 
88
/*
89
 * vCreateMainWindow - create the Main window
90
 *
91
 * remark: does not return if the Main window can't be created
92
 */
93
static window_handle
94
tCreateMainWindow(void)
95
{
96
	window_handle	tMainWindow;
97
 
98
	TRACE_MSG("tCreateMainWindow");
99
 
100
	tMainWindow = Window_Create("MainWindow", template_TITLEMIN);
101
	if (tMainWindow == 0) {
102
		werr(1, "I can't find the 'MainWindow' template");
103
	}
104
	return tMainWindow;
105
} /* end of tCreateMainWindow */
106
 
107
/*
108
 * vCreateScaleWindow - create the Scale view window
109
 *
110
 * remark: does not return if the Scale view window can't be created
111
 */
112
static window_handle
113
tCreateScaleWindow(void)
114
{
115
	window_handle	tScaleWindow;
116
 
117
	TRACE_MSG("tCreateScaleWindow");
118
 
119
	tScaleWindow = Window_Create("ScaleView", template_TITLEMIN);
120
	if (tScaleWindow == 0) {
121
		werr(1, "I can't find the 'ScaleView' template");
122
	}
123
	return tScaleWindow;
124
} /* end of tCreateScaleWindow */
125
 
126
/*
127
 * pCreateDiagram - create and initialize a diagram
128
 *
129
 * remark: does not return if the diagram can't be created
130
 */
131
diagram_type *
132
pCreateDiagram(const char *szTask, const char *szFilename)
133
{
134
	diagram_type	*pDiag;
135
	options_type	tOptions;
136
	window_handle	tMainWindow, tScaleWindow;
137
	wimp_box	tBox;
138
 
139
	TRACE_MSG("pCreateDiagram");
140
 
141
	fail(szTask == NULL || szTask[0] == '\0');
142
 
143
	/* Create the main window */
144
	tMainWindow = tCreateMainWindow();
145
 
146
	/* Create the scale view window */
147
	tScaleWindow = tCreateScaleWindow();
148
 
149
	/* Get the necessary memory */
150
	pDiag = xmalloc(sizeof(diagram_type));
151
	if (flex_alloc((flex_ptr)&pDiag->tInfo.data, INITIAL_SIZE) != 1) {
152
		werr(1, "Memory allocation failed, unable to continue");
153
	}
154
 
155
	/* Initialize the diagram */
156
	vGetOptions(&tOptions);
157
	pDiag->tMainWindow = tMainWindow;
158
	pDiag->tScaleWindow = tScaleWindow;
159
	pDiag->iScaleFactorCurr = tOptions.iScaleFactor;
160
	pDiag->iScaleFactorTemp = tOptions.iScaleFactor;
161
	pDiag->tMemorySize = INITIAL_SIZE;
162
	tBox.min.x = 0;
163
	tBox.min.y = -(Drawfile_ScreenToDraw(32 + 3) * 8 + 1);
164
	tBox.max.x = Drawfile_ScreenToDraw(16) * MIN_SCREEN_WIDTH + 1;
165
	tBox.max.y = 0;
166
	Error_CheckFatal(Drawfile_CreateDiagram(&pDiag->tInfo,
167
					pDiag->tMemorySize, szTask, tBox));
168
	DBG_DEC(pDiag->tInfo.length);
169
	pDiag->lXleft = 0;
170
	pDiag->lYtop = 0;
171
	strncpy(pDiag->szFilename,
172
			szBasename(szFilename), sizeof(pDiag->szFilename) - 1);
173
	pDiag->szFilename[sizeof(pDiag->szFilename) - 1] = '\0';
174
	/* Return success */
175
	return pDiag;
176
} /* end of pCreateDiagram */
177
 
178
/*
179
 * bDestroyDiagram - remove a diagram by freeing the memory it uses
180
 */
181
BOOL
182
bDestroyDiagram(event_pollblock *pEvent, void *pvReference)
183
{
184
	diagram_type	*pDiag;
185
	window_handle	tWindow;
186
 
187
	TRACE_MSG("bDestroyDiagram");
188
 
189
	fail(pEvent == NULL);
190
	fail(pvReference == NULL);
191
 
192
	if (pEvent == NULL || pvReference == NULL) {
193
		return FALSE;
194
	}
195
 
196
	pDiag = (diagram_type *)pvReference;
197
 
198
	switch (pEvent->type) {
199
	case event_CLOSE:
200
		tWindow = pEvent->data.openblock.window;
201
		break;
202
	case event_KEY:
203
		tWindow = pEvent->data.key.caret.window;
204
		break;
205
	default:
206
		DBG_DEC(pEvent->type);
207
		return FALSE;
208
	}
209
	if (tWindow != pDiag->tMainWindow) {
210
		return FALSE;
211
	}
212
 
213
	/* Delete the main window */
214
	Window_Delete(pDiag->tMainWindow);
215
	pDiag->tMainWindow = 0;
216
 
217
	/* Delete the scale window */
218
	Window_Delete(pDiag->tScaleWindow);
219
	pDiag->tScaleWindow = 0;
220
 
221
#if defined(__GNUC__)
222
	/*
223
	 * Remove all references to the diagram that will be free-ed
224
	 * by undoing the EventMsg_Claim's from within the Menu_Warn's
225
	 */
226
	while (EventMsg_ReleaseSpecific(message_MENUWARNING, window_ANY,
227
					bSaveTextfile, pDiag))
228
		; /* EMPTY */
229
	while (EventMsg_ReleaseSpecific(message_MENUWARNING, window_ANY,
230
					bSaveDrawfile, pDiag))
231
		; /* EMPTY */
232
	while (EventMsg_ReleaseSpecific(message_MENUWARNING, window_ANY,
233
					bScaleOpenAction, pDiag))
234
		; /* EMPTY */
235
#endif /* __GNUC__ */
236
 
237
	/* Free the memory */
238
	if (pDiag->tInfo.data != NULL && pDiag->tMemorySize != 0) {
239
		flex_free((flex_ptr)&pDiag->tInfo.data);
240
	}
241
	/* Just to be on the save side */
242
	pDiag->tInfo.data = NULL;
243
	pDiag->tInfo.length = 0;
244
	pDiag->tMemorySize = 0;
245
 
246
	/* Destroy the diagram itself */
247
	pDiag = xfree(pDiag);
248
	return TRUE;
249
} /* end of bDestroyDiagram */
250
 
251
/*
252
 * vExtendDiagramSize - make sure the diagram is big enough
253
 */
254
static void
255
vExtendDiagramSize(diagram_type *pDiag, size_t tSize)
256
{
257
	TRACE_MSG("vExtendDiagramSize");
258
 
259
	fail(pDiag == NULL || tSize % 4 != 0);
260
 
261
	while (pDiag->tInfo.length + tSize > pDiag->tMemorySize) {
262
		if (flex_extend((flex_ptr)&pDiag->tInfo.data,
263
				pDiag->tMemorySize + EXTENSION_SIZE) != 1) {
264
			werr(1, "Memory extend failed, unable to continue");
265
		}
266
		pDiag->tMemorySize += EXTENSION_SIZE;
267
		NO_DBG_DEC(pDiag->tMemorySize);
268
	}
269
	TRACE_MSG("end of vExtendDiagramSize");
270
} /* end of vExtendDiagramSize */
271
 
272
/*
273
 * vPrologue2 - prologue part 2; add a font list to a diagram
274
 */
275
void
276
vPrologue2(diagram_type *pDiag, int iWordVersion)
277
{
278
	drawfile_object	*pNew;
279
	const font_table_type	*pTmp;
280
	char	*pcTmp;
281
	size_t	tRealSize, tSize;
282
	int	iCount;
283
 
284
	TRACE_MSG("vPrologue2");
285
 
286
	fail(pDiag == NULL);
287
 
288
	if (tGetFontTableLength() == 0) {
289
		return;
290
	}
291
	tRealSize = offsetof(drawfile_object, data);
292
	pTmp = NULL;
293
	while ((pTmp = pGetNextFontTableRecord(pTmp)) != NULL) {
294
		tRealSize += 2 + strlen(pTmp->szOurFontname);
295
	}
296
	DBG_DEC(tRealSize);
297
	tSize = ROUND4(tRealSize);
298
	vExtendDiagramSize(pDiag, tSize);
299
	pNew = xmalloc(tSize);
300
	memset(pNew, 0, tSize);
301
	pNew->type = drawfile_TYPE_FONT_TABLE;
302
	pNew->size = tSize;
303
	pcTmp = (char *)&pNew->data.font_table.font_def[0].font_ref;
304
	iCount = 0;
305
	pTmp = NULL;
306
	while ((pTmp = pGetNextFontTableRecord(pTmp)) != NULL) {
307
		*pcTmp = ++iCount;
308
		pcTmp++;
309
		strcpy(pcTmp, pTmp->szOurFontname);
310
		pcTmp += 1 + strlen(pTmp->szOurFontname);
311
	}
312
	Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo,
313
			pDiag->tMemorySize, pNew, TRUE));
314
	pNew = xfree(pNew);
315
} /* end of vPrologue2 */
316
 
317
/*
318
 * vSubstring2Diagram - put a sub string into a diagram
319
 */
320
void
321
vSubstring2Diagram(diagram_type *pDiag,
322
	char *szString, size_t tStringLength, long lStringWidth,
323
	UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef,
324
	USHORT usFontSize, USHORT usMaxFontSize)
325
{
326
	drawfile_object	*pNew;
327
	long	lSizeX, lSizeY, lOffset, l20, lYMove;
328
	size_t	tRealSize, tSize;
329
 
330
	TRACE_MSG("vSubstring2Diagram");
331
 
332
	fail(pDiag == NULL || szString == NULL);
333
	fail(pDiag->lXleft < 0);
334
	fail(tStringLength != strlen(szString));
335
	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
336
	fail(usMaxFontSize < MIN_FONT_SIZE || usMaxFontSize > MAX_FONT_SIZE);
337
	fail(usFontSize > usMaxFontSize);
338
 
339
	if (szString[0] == '\0' || tStringLength == 0) {
340
		return;
341
	}
342
 
343
	if (tFontRef == 0) {
344
		lOffset = Drawfile_ScreenToDraw(2);
345
		l20 = Drawfile_ScreenToDraw(32 + 3);
346
		lSizeX = Drawfile_ScreenToDraw(16);
347
		lSizeY = Drawfile_ScreenToDraw(32);
348
	} else {
349
		lOffset = lToBaseLine(usMaxFontSize);
350
		l20 = lWord2DrawUnits20(usMaxFontSize);
351
		lSizeX = lWord2DrawUnits00(usFontSize);
352
		lSizeY = lWord2DrawUnits00(usFontSize);
353
	}
354
 
355
	lYMove = 0;
356
 
357
	/* Up for superscript */
358
	if (bIsSuperscript(usFontstyle)) {
359
		lYMove = lMilliPoints2DrawUnits((((long)usFontSize + 1) / 2) * 375);
360
	}
361
	/* Down for subscript */
362
	if (bIsSubscript(usFontstyle)) {
363
		lYMove = -lMilliPoints2DrawUnits((long)usFontSize * 125);
364
	}
365
 
366
	tRealSize = offsetof(drawfile_object, data);
367
	tRealSize += sizeof(drawfile_text) + tStringLength;
368
	tSize = ROUND4(tRealSize);
369
	vExtendDiagramSize(pDiag, tSize);
370
	pNew = xmalloc(tSize);
371
	memset(pNew, 0, tSize);
372
	pNew->type = drawfile_TYPE_TEXT;
373
	pNew->size = tSize;
374
	pNew->data.text.bbox.min.x = (int)pDiag->lXleft;
375
	pNew->data.text.bbox.min.y = (int)(pDiag->lYtop + lYMove);
376
	pNew->data.text.bbox.max.x = (int)(pDiag->lXleft + lStringWidth);
377
	pNew->data.text.bbox.max.y = (int)(pDiag->lYtop + l20 + lYMove);
378
	pNew->data.text.fill.value = (int)ulColor2Color(ucFontColor);
379
	pNew->data.text.bg_hint.value = 0xffffff00;	/* White */
380
	pNew->data.text.style.font_ref = tFontRef;
381
	pNew->data.text.style.reserved[0] = 0;
382
	pNew->data.text.style.reserved[1] = 0;
383
	pNew->data.text.style.reserved[2] = 0;
384
	pNew->data.text.xsize = (int)lSizeX;
385
	pNew->data.text.ysize = (int)lSizeY;
386
	pNew->data.text.base.x = (int)pDiag->lXleft;
387
	pNew->data.text.base.y = (int)(pDiag->lYtop + lOffset + lYMove);
388
	strncpy(pNew->data.text.text, szString, tStringLength);
389
	pNew->data.text.text[tStringLength] = '\0';
390
	Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo,
391
			pDiag->tMemorySize, pNew, TRUE));
392
	pNew = xfree(pNew);
393
	/*draw_translateText(&pDiag->tInfo);*/
394
	pDiag->lXleft += lStringWidth;
395
	TRACE_MSG("leaving vSubstring2Diagram");
396
} /* end of vSubstring2Diagram */
397
 
398
/*
399
 * vImage2Diagram - put an image into a diagram
400
 */
401
void
402
vImage2Diagram(diagram_type *pDiag, const imagedata_type *pImg,
403
	UCHAR *pucImage, size_t tImageSize)
404
{
405
  	drawfile_object	*pNew;
406
	long	lWidth, lHeight;
407
	size_t	tRealSize, tSize;
408
 
409
	TRACE_MSG("vImage2Diagram");
410
 
411
	fail(pDiag == NULL);
412
	fail(pImg == NULL);
413
	fail(pDiag->lXleft < 0);
414
	fail(pImg->eImageType != imagetype_is_dib &&
415
	     pImg->eImageType != imagetype_is_jpeg);
416
 
417
	DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);
418
 
419
	lWidth = lPoints2DrawUnits(pImg->iHorSizeScaled);
420
	lHeight = lPoints2DrawUnits(pImg->iVerSizeScaled);
421
	DBG_DEC(lWidth);
422
	DBG_DEC(lHeight);
423
 
424
	pDiag->lYtop -= lHeight;
425
 
426
	tRealSize = offsetof(drawfile_object, data);
427
	switch (pImg->eImageType) {
428
	case imagetype_is_dib:
429
		tRealSize += sizeof(drawfile_sprite) + tImageSize;
430
		tSize = ROUND4(tRealSize);
431
		vExtendDiagramSize(pDiag, tSize);
432
		pNew = xmalloc(tSize);
433
		memset(pNew, 0, tSize);
434
		pNew->type = drawfile_TYPE_SPRITE;
435
		pNew->size = tSize;
436
		pNew->data.sprite.bbox.min.x = (int)pDiag->lXleft;
437
		pNew->data.sprite.bbox.min.y = (int)pDiag->lYtop;
438
		pNew->data.sprite.bbox.max.x = (int)(pDiag->lXleft + lWidth);
439
		pNew->data.sprite.bbox.max.y = (int)(pDiag->lYtop + lHeight);
440
		memcpy(&pNew->data.sprite.header, pucImage, tImageSize);
441
		break;
442
	case imagetype_is_jpeg:
443
#if defined(DEBUG)
444
		(void)bGetJpegInfo(pucImage, tImageSize);
445
#endif /* DEBUG */
446
		tRealSize += sizeof(drawfile_jpeg) + tImageSize;
447
		tSize = ROUND4(tRealSize);
448
		vExtendDiagramSize(pDiag, tSize);
449
		pNew = xmalloc(tSize);
450
		memset(pNew, 0, tSize);
451
		pNew->type = drawfile_TYPE_JPEG;
452
		pNew->size = tSize;
453
		pNew->data.jpeg.bbox.min.x = (int)pDiag->lXleft;
454
		pNew->data.jpeg.bbox.min.y = (int)pDiag->lYtop;
455
		pNew->data.jpeg.bbox.max.x = (int)(pDiag->lXleft + lWidth);
456
		pNew->data.jpeg.bbox.max.y = (int)(pDiag->lYtop + lHeight);
457
		pNew->data.jpeg.width = (int)lWidth;
458
		pNew->data.jpeg.height = (int)lHeight;
459
		pNew->data.jpeg.xdpi = 90;
460
		pNew->data.jpeg.ydpi = 90;
461
		pNew->data.jpeg.trfm.entries[0][0] = 0x10000;
462
		pNew->data.jpeg.trfm.entries[0][1] = 0;
463
		pNew->data.jpeg.trfm.entries[1][0] = 0;
464
		pNew->data.jpeg.trfm.entries[1][1] = 0x10000;
465
		pNew->data.jpeg.trfm.entries[2][0] = (int)pDiag->lXleft;
466
		pNew->data.jpeg.trfm.entries[2][1] = (int)pDiag->lYtop;
467
		pNew->data.jpeg.len = tImageSize;
468
		memcpy(pNew->data.jpeg.data, pucImage, tImageSize);
469
		break;
470
	default:
471
		DBG_DEC(pImg->eImageType);
472
		pNew = NULL;
473
		break;
474
	}
475
 
476
	Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo,
477
					pDiag->tMemorySize, pNew, TRUE));
478
	pNew = xfree(pNew);
479
	pDiag->lXleft = 0;
480
} /* end of vImage2Diagram */
481
 
482
/*
483
 * bAddDummyImage - add a dummy image
484
 *
485
 * return TRUE when successful, otherwise FALSE
486
 */
487
BOOL
488
bAddDummyImage(diagram_type *pDiag, const imagedata_type *pImg)
489
{
490
  	drawfile_object	*pNew;
491
	int	*piTmp;
492
	long	lWidth, lHeight;
493
	size_t	tRealSize, tSize;
494
 
495
	TRACE_MSG("bAddDummyImage");
496
 
497
	fail(pDiag == NULL);
498
	fail(pImg == NULL);
499
	fail(pDiag->lXleft < 0);
500
 
501
	if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) {
502
		return FALSE;
503
	}
504
 
505
	DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);
506
 
507
	lWidth = lPoints2DrawUnits(pImg->iHorSizeScaled);
508
	lHeight = lPoints2DrawUnits(pImg->iVerSizeScaled);
509
 
510
	pDiag->lYtop -= lHeight;
511
 
512
	tRealSize = offsetof(drawfile_object, data);
513
	tRealSize += sizeof(drawfile_path) + (14 - 1) * sizeof(int);
514
	tSize = ROUND4(tRealSize);
515
	vExtendDiagramSize(pDiag, tSize);
516
	pNew = xmalloc(tSize);
517
	memset(pNew, 0, tSize);
518
	pNew->type = drawfile_TYPE_PATH;
519
	pNew->size = tSize;
520
	pNew->data.path.bbox.min.x = (int)pDiag->lXleft;
521
	pNew->data.path.bbox.min.y = (int)pDiag->lYtop;
522
	pNew->data.path.bbox.max.x = (int)(pDiag->lXleft + lWidth);
523
	pNew->data.path.bbox.max.y = (int)(pDiag->lYtop + lHeight);
524
	pNew->data.path.fill.value = -1;
525
	pNew->data.path.outline.value = 0x4d4d4d00;	/* Gray 70 percent */
526
	pNew->data.path.width = (int)lMilliPoints2DrawUnits(500);
527
	pNew->data.path.style.flags = 0;
528
	pNew->data.path.style.reserved = 0;
529
	pNew->data.path.style.cap_width = 0;
530
	pNew->data.path.style.cap_length = 0;
531
	piTmp = pNew->data.path.path;
532
	*piTmp++ = drawfile_PATH_MOVE_TO;
533
	*piTmp++ = pNew->data.path.bbox.min.x;
534
	*piTmp++ = pNew->data.path.bbox.min.y;
535
	*piTmp++ = drawfile_PATH_LINE_TO;
536
	*piTmp++ = pNew->data.path.bbox.min.x;
537
	*piTmp++ = pNew->data.path.bbox.max.y;
538
	*piTmp++ = drawfile_PATH_LINE_TO;
539
	*piTmp++ = pNew->data.path.bbox.max.x;
540
	*piTmp++ = pNew->data.path.bbox.max.y;
541
	*piTmp++ = drawfile_PATH_LINE_TO;
542
	*piTmp++ = pNew->data.path.bbox.max.x;
543
	*piTmp++ = pNew->data.path.bbox.min.y;
544
	*piTmp++ = drawfile_PATH_CLOSE_LINE;
545
	*piTmp++ = drawfile_PATH_END_PATH;
546
 
547
	Error_CheckFatal(Drawfile_AppendObject(&pDiag->tInfo,
548
					pDiag->tMemorySize, pNew, TRUE));
549
	pNew = xfree(pNew);
550
	pDiag->lXleft = 0;
551
	return TRUE;
552
} /* end of bAddDummyImage */
553
 
554
/*
555
 * vMove2NextLine - move to the next line
556
 */
557
void
558
vMove2NextLine(diagram_type *pDiag, drawfile_fontref tFontRef,
559
	USHORT usFontSize)
560
{
561
	long	l20;
562
 
563
	TRACE_MSG("vMove2NextLine");
564
 
565
	fail(pDiag == NULL);
566
	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
567
 
568
	if (tFontRef == 0) {
569
		l20 = Drawfile_ScreenToDraw(32 + 3);
570
	} else {
571
		l20 = lWord2DrawUnits20(usFontSize);
572
	}
573
	pDiag->lYtop -= l20;
574
} /* end of vMove2NextLine */
575
 
576
/*
577
 * Create an start of paragraph (Phase 1)
578
 */
579
void
580
vStartOfParagraph1(diagram_type *pDiag, long lBeforeIndentation)
581
{
582
	TRACE_MSG("vStartOfParagraph1");
583
 
584
	fail(pDiag == NULL);
585
	fail(lBeforeIndentation < 0);
586
 
587
	pDiag->lXleft = 0;
588
	pDiag->lYtop -= lMilliPoints2DrawUnits(lBeforeIndentation);
589
} /* end of vStartOfParagraph1 */
590
 
591
/*
592
 * Create an start of paragraph (Phase 2)
593
 * DUMMY function
594
 */
595
void
596
vStartOfParagraph2(diagram_type *pDiag)
597
{
598
	TRACE_MSG("vStartOfParagraph2");
599
} /* end of vStartOfParagraph2 */
600
 
601
/*
602
 * Create an end of paragraph
603
 */
604
void
605
vEndOfParagraph(diagram_type *pDiag,
606
	drawfile_fontref tFontRef, USHORT usFontSize, long lAfterIndentation)
607
{
608
	TRACE_MSG("vEndOfParagraph");
609
 
610
	fail(pDiag == NULL);
611
	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
612
	fail(lAfterIndentation < 0);
613
 
614
	pDiag->lXleft = 0;
615
	pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation);
616
} /* end of vEndOfParagraph */
617
 
618
/*
619
 * Create an end of page
620
 */
621
void
622
vEndOfPage(diagram_type *pDiag, long lAfterIndentation, BOOL bNewSection)
623
{
624
	TRACE_MSG("vEndOfPage");
625
 
626
	fail(pDiag == NULL);
627
	fail(lAfterIndentation < 0);
628
 
629
	pDiag->lXleft = 0;
630
	pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation);
631
} /* end of vEndOfPage */
632
 
633
/*
634
 * vSetHeaders - set the headers
635
 * DUMMY function
636
 */
637
void
638
vSetHeaders(diagram_type *pDiag, USHORT usIstd)
639
{
640
	TRACE_MSG("vSetHeaders");
641
} /* end of vSetHeaders */
642
 
643
/*
644
 * Create a start of list
645
 * DUMMY function
646
 */
647
void
648
vStartOfList(diagram_type *pDiag, UCHAR ucNFC, BOOL bIsEndOfTable)
649
{
650
	TRACE_MSG("vStartOfList");
651
} /* end of vStartOfList */
652
 
653
/*
654
 * Create an end of list
655
 * DUMMY function
656
 */
657
void
658
vEndOfList(diagram_type *pDiag)
659
{
660
	TRACE_MSG("vEndOfList");
661
} /* end of vEndOfList */
662
 
663
/*
664
 * Create a start of a list item
665
 * DUMMY function
666
 */
667
void
668
vStartOfListItem(diagram_type *pDiag, BOOL bNoMarks)
669
{
670
	TRACE_MSG("vStartOfListItem");
671
} /* end of vStartOfListItem */
672
 
673
/*
674
 * Create an end of a table
675
 * DUMMY function
676
 */
677
void
678
vEndOfTable(diagram_type *pDiag)
679
{
680
	TRACE_MSG("vEndOfTable");
681
} /* end of vEndTable */
682
 
683
/*
684
 * Add a table row
685
 * DUMMY function
686
 *
687
 * Returns TRUE when conversion type is XML
688
 */
689
BOOL
690
bAddTableRow(diagram_type *pDiag, char **aszColTxt,
691
	int iNbrOfColumns, const short *asColumnWidth, UCHAR ucBorderInfo)
692
{
693
	TRACE_MSG("bAddTableRow");
694
 
695
	return FALSE;
696
} /* end of bAddTableRow */
697
 
698
/*
699
 * vForceRedraw - force a redraw of the main window
700
 */
701
static void
702
vForceRedraw(diagram_type *pDiag)
703
{
704
	window_state		tWindowState;
705
	window_redrawblock	tRedraw;
706
	int	x0, y0, x1, y1;
707
 
708
	TRACE_MSG("vForceRedraw");
709
 
710
	fail(pDiag == NULL);
711
 
712
	DBG_DEC(pDiag->iScaleFactorCurr);
713
 
714
	/* Read the size of the current diagram */
715
	Drawfile_QueryBox(&pDiag->tInfo, &tRedraw.rect, TRUE);
716
	/* Adjust the size of the work area */
717
	x0 = tRedraw.rect.min.x * pDiag->iScaleFactorCurr / 100 - 1;
718
	y0 = tRedraw.rect.min.y * pDiag->iScaleFactorCurr / 100 - 1;
719
	x1 = tRedraw.rect.max.x * pDiag->iScaleFactorCurr / 100 + 1;
720
	y1 = tRedraw.rect.max.y * pDiag->iScaleFactorCurr / 100 + 1;
721
	/* Work area extension */
722
	x0 -= WORKAREA_EXTENSION;
723
	y0 -= WORKAREA_EXTENSION;
724
	x1 += WORKAREA_EXTENSION;
725
	y1 += WORKAREA_EXTENSION;
726
	Window_SetExtent(pDiag->tMainWindow, x0, y0, x1, y1);
727
	/* Widen the box slightly to be sure all the edges are drawn */
728
	x0 -= 5;
729
	y0 -= 5;
730
	x1 += 5;
731
	y1 += 5;
732
	/* Force the redraw */
733
	Window_ForceRedraw(pDiag->tMainWindow, x0, y0, x1, y1);
734
	/* Reopen the window to show the correct size */
735
	Error_CheckFatal(Wimp_GetWindowState(pDiag->tMainWindow, &tWindowState));
736
	tWindowState.openblock.behind = -1;
737
	Error_CheckFatal(Wimp_OpenWindow(&tWindowState.openblock));
738
} /* end of vForceRedraw */
739
 
740
/*
741
 * vShowDiagram - put the diagram on the screen
742
 */
743
void
744
vShowDiagram(diagram_type *pDiag)
745
{
746
	wimp_box	tRect;
747
	int	x0, y0, x1, y1;
748
 
749
	TRACE_MSG("vShowDiagram");
750
 
751
	fail(pDiag == NULL);
752
 
753
	Window_Show(pDiag->tMainWindow, open_NEARLAST);
754
	Drawfile_QueryBox(&pDiag->tInfo, &tRect, TRUE);
755
	/* Work area extension */
756
	x0 = tRect.min.x - WORKAREA_EXTENSION;
757
	y0 = tRect.min.y - WORKAREA_EXTENSION;
758
	x1 = tRect.max.x + WORKAREA_EXTENSION;
759
	y1 = tRect.max.y + WORKAREA_EXTENSION;
760
	Window_SetExtent(pDiag->tMainWindow, x0, y0, x1, y1);
761
	vForceRedraw(pDiag);
762
} /* end of vShowDiagram */
763
 
764
/*
765
 * vMainButtonClick - handle mouse buttons clicks for the main screen
766
 */
767
void
768
vMainButtonClick(mouse_block *pMouse)
769
{
770
	caret_block	tCaret;
771
	window_state	ws;
772
 
773
	TRACE_MSG("vMainButtonClick");
774
 
775
	fail(pMouse == NULL);
776
 
777
	DBG_DEC(pMouse->button.data.select);
778
	DBG_DEC(pMouse->button.data.adjust);
779
	DBG_DEC(pMouse->window);
780
	DBG_DEC(pMouse->icon);
781
 
782
	if (pMouse->window >= 0 &&
783
	    pMouse->icon == -1 &&
784
	    (pMouse->button.data.select || pMouse->button.data.adjust)) {
785
		/* Get the input focus */
786
		Error_CheckFatal(Wimp_GetWindowState(pMouse->window, &ws));
787
		tCaret.window = pMouse->window;
788
		tCaret.icon = -1;
789
		tCaret.offset.x = pMouse->pos.x - ws.openblock.screenrect.min.x;
790
		tCaret.offset.y = pMouse->pos.y - ws.openblock.screenrect.max.y;
791
		tCaret.height = (int)BIT(25);
792
		tCaret.index = 0;
793
		Error_CheckFatal(Wimp_SetCaretPosition(&tCaret));
794
	}
795
} /* end of vMainButtonClick */
796
 
797
/*
798
 * bMainKeyPressed - handle pressed keys for the main window
799
 */
800
BOOL
801
bMainKeyPressed(event_pollblock *pEvent, void *pvReference)
802
{
803
	diagram_type 	*pDiag;
804
 
805
	TRACE_MSG("bMainKeyPressed");
806
 
807
	fail(pEvent == NULL);
808
	fail(pEvent->type != event_KEY);
809
	fail(pvReference == NULL);
810
 
811
	pDiag = (diagram_type *)pvReference;
812
 
813
	fail(pEvent->data.key.caret.window != pDiag->tMainWindow);
814
 
815
 
816
	switch (pEvent->data.key.code) {
817
	case keycode_CTRL_F2:		/* Ctrl F2 */
818
		bDestroyDiagram(pEvent, pvReference);
819
		break;
820
	case keycode_F3:		/* F3 */
821
		bSaveDrawfile(pEvent, pvReference);
822
		break;
823
	case keycode_SHIFT_F3:		/* Shift F3 */
824
		bSaveTextfile(pEvent, pvReference);
825
		break;
826
	default:
827
		DBG_DEC(pEvent->data.key.code);
828
		Error_CheckFatal(Wimp_ProcessKey(pEvent->data.key.code));
829
	}
830
	return TRUE;
831
} /* end of bMainKeyPressed */
832
 
833
/*
834
 * bRedrawMainWindow - redraw the main window
835
 */
836
BOOL
837
bRedrawMainWindow(event_pollblock *pEvent, void *pvReference)
838
{
839
	window_redrawblock	tBlock;
840
	diagram_type	*pDiag;
841
	drawfile_info	*pInfo;
842
	double		dScaleFactor;
843
	BOOL		bMore;
844
 
845
	TRACE_MSG("bRedrawMainWindow");
846
 
847
	fail(pEvent == NULL);
848
	fail(pEvent->type != event_REDRAW);
849
	fail(pvReference == NULL);
850
 
851
	pDiag = (diagram_type *)pvReference;
852
 
853
	fail(pDiag->tMainWindow != pEvent->data.openblock.window);
854
	fail(pDiag->iScaleFactorCurr < MIN_SCALE_FACTOR);
855
	fail(pDiag->iScaleFactorCurr > MAX_SCALE_FACTOR);
856
 
857
	dScaleFactor = (double)pDiag->iScaleFactorCurr / 100.0;
858
	pInfo = &pDiag->tInfo;
859
 
860
	tBlock.window = pEvent->data.openblock.window;
861
	Error_CheckFatal(Wimp_RedrawWindow(&tBlock, &bMore));
862
 
863
	/* If there is no real diagram just go thru the motions */
864
	while (bMore) {
865
		if (pInfo->data != NULL && pInfo->length != 0) {
866
			Error_CheckFatal(Drawfile_RenderDiagram(pInfo,
867
						&tBlock, dScaleFactor));
868
		}
869
		Error_CheckFatal(Wimp_GetRectangle(&tBlock, &bMore));
870
	}
871
	return TRUE;
872
} /* end of bRedrawMainWindow */
873
 
874
/*
875
 * bScaleOpenAction - action to be taken when the Scale view window opens
876
 */
877
BOOL
878
bScaleOpenAction(event_pollblock *pEvent, void *pvReference)
879
{
880
	window_state	tWindowState;
881
	diagram_type	*pDiag;
882
 
883
	TRACE_MSG("bScaleOpenAction");
884
 
885
	fail(pEvent == NULL);
886
	fail(pEvent->type != event_SEND);
887
	fail(pEvent->data.message.header.action != message_MENUWARN);
888
	fail(pvReference == NULL);
889
 
890
	pDiag = (diagram_type *)pvReference;
891
 
892
	if (menu_currentopen != pDiag->pSaveMenu ||
893
	    pEvent->data.message.data.menuwarn.selection[0] != SAVEMENU_SCALEVIEW) {
894
		return FALSE;
895
	}
896
 
897
	Error_CheckFatal(Wimp_GetWindowState(pDiag->tScaleWindow,
898
						&tWindowState));
899
	if (tWindowState.flags.data.open) {
900
		/* The window is already open */
901
		return TRUE;
902
	}
903
 
904
	DBG_MSG("vScaleOpenAction for real");
905
 
906
	pDiag->iScaleFactorTemp = pDiag->iScaleFactorCurr;
907
	vUpdateWriteableNumber(pDiag->tScaleWindow,
908
			SCALE_SCALE_WRITEABLE, pDiag->iScaleFactorTemp);
909
	Window_Show(pDiag->tScaleWindow, open_UNDERPOINTER);
910
	return TRUE;
911
} /* end of bScaleOpenAction */
912
 
913
/*
914
 * vSetTitle - set the title of a window
915
 */
916
void
917
vSetTitle(diagram_type *pDiag)
918
{
919
	char	szTitle[WINDOW_TITLE_LEN];
920
 
921
	TRACE_MSG("vSetTitle");
922
 
923
	fail(pDiag == NULL);
924
	fail(pDiag->szFilename[0] == '\0');
925
 
926
	(void)sprintf(szTitle, "%.*s at %d%%",
927
				FILENAME_TITLE_LEN,
928
				pDiag->szFilename,
929
				pDiag->iScaleFactorCurr % 1000);
930
	if (strlen(pDiag->szFilename) > FILENAME_TITLE_LEN) {
931
		szTitle[FILENAME_TITLE_LEN - 1] = OUR_ELLIPSIS;
932
	}
933
 
934
	Window_SetTitle(pDiag->tMainWindow, szTitle);
935
} /* end of vSetTitle */
936
 
937
/*
938
 * vScaleButtonClick - handle a mouse button click in the Scale view window
939
 */
940
void
941
vScaleButtonClick(mouse_block *pMouse, diagram_type *pDiag)
942
{
943
	BOOL	bCloseWindow, bRedraw;
944
 
945
	TRACE_MSG("vScaleButtonClick");
946
 
947
	fail(pMouse == NULL || pDiag == NULL);
948
	fail(pMouse->window != pDiag->tScaleWindow);
949
 
950
	bCloseWindow = FALSE;
951
	bRedraw = FALSE;
952
	switch (pMouse->icon) {
953
	case SCALE_CANCEL_BUTTON:
954
		bCloseWindow = TRUE;
955
		pDiag->iScaleFactorTemp = pDiag->iScaleFactorCurr;
956
		break;
957
	case SCALE_SCALE_BUTTON:
958
		bCloseWindow = TRUE;
959
		bRedraw = pDiag->iScaleFactorCurr != pDiag->iScaleFactorTemp;
960
		pDiag->iScaleFactorCurr = pDiag->iScaleFactorTemp;
961
		break;
962
	case SCALE_50_PCT:
963
		pDiag->iScaleFactorTemp = 50;
964
		break;
965
	case SCALE_75_PCT:
966
		pDiag->iScaleFactorTemp = 75;
967
		break;
968
	case SCALE_100_PCT:
969
		pDiag->iScaleFactorTemp = 100;
970
		break;
971
	case SCALE_150_PCT:
972
		pDiag->iScaleFactorTemp = 150;
973
		break;
974
	default:
975
		DBG_DEC(pMouse->icon);
976
		break;
977
	}
978
	if (bCloseWindow) {
979
		/* Close the scale window */
980
		Error_CheckFatal(Wimp_CloseWindow(pMouse->window));
981
		if (bRedraw) {
982
			/* Redraw the main window */
983
			vSetTitle(pDiag);
984
			vForceRedraw(pDiag);
985
		}
986
	} else {
987
		vUpdateWriteableNumber(pMouse->window,
988
				SCALE_SCALE_WRITEABLE,
989
				pDiag->iScaleFactorTemp);
990
	}
991
} /* end of vScaleButtonClick */
992
 
993
/*
994
 * bScaleKeyPressed - handle pressed keys for the scale window
995
 */
996
BOOL
997
bScaleKeyPressed(event_pollblock *pEvent, void *pvReference)
998
{
999
	icon_block	tIcon;
1000
	diagram_type	*pDiag;
1001
	caret_block	*pCaret;
1002
	char		*pcChar;
1003
	int		iTmp;
1004
 
1005
	TRACE_MSG("bScaleKeyPressed");
1006
 
1007
        fail(pEvent == NULL);
1008
        fail(pEvent->type != event_KEY);
1009
        fail(pvReference == NULL);
1010
 
1011
	pCaret = &pEvent->data.key.caret;
1012
	pDiag = (diagram_type *)pvReference;
1013
 
1014
        fail(pEvent->data.key.caret.window != pDiag->tScaleWindow);
1015
 
1016
	DBG_DEC_C(pCaret->icon != SCALE_SCALE_WRITEABLE, pCaret->icon);
1017
	DBG_DEC_C(pCaret->icon == SCALE_SCALE_WRITEABLE, pEvent->data.key.code);
1018
 
1019
	if (pEvent->data.key.code != '\r' ||
1020
	    pCaret->icon != SCALE_SCALE_WRITEABLE) {
1021
		Error_CheckFatal(Wimp_ProcessKey(pEvent->data.key.code));
1022
		return TRUE;
1023
	}
1024
 
1025
	Error_CheckFatal(Wimp_GetIconState(pCaret->window, pCaret->icon, &tIcon));
1026
	if (!tIcon.flags.data.text || !tIcon.flags.data.indirected) {
1027
		werr(1, "Icon %d must be indirected text", (int)pCaret->icon);
1028
	}
1029
	iTmp = (int)strtol(tIcon.data.indirecttext.buffer, &pcChar, 10);
1030
	if (*pcChar != '\0' && *pcChar != '\r') {
1031
		DBG_DEC(*pcChar);
1032
	} else if (iTmp < MIN_SCALE_FACTOR) {
1033
		pDiag->iScaleFactorTemp = MIN_SCALE_FACTOR;
1034
	} else if (iTmp > MAX_SCALE_FACTOR) {
1035
		pDiag->iScaleFactorTemp = MAX_SCALE_FACTOR;
1036
	} else {
1037
		pDiag->iScaleFactorTemp = iTmp;
1038
	}
1039
	pDiag->iScaleFactorCurr = pDiag->iScaleFactorTemp;
1040
	/* Close the scale window */
1041
	Error_CheckFatal(Wimp_CloseWindow(pCaret->window));
1042
	/* Redraw the main window */
1043
	vSetTitle(pDiag);
1044
	vForceRedraw(pDiag);
1045
	return TRUE;
1046
} /* end of bScaleKeyPressed */
1047