3 * Copyright (C) 1998-2005 A.J. van Os; Released under GPL
6 * Functions to deal with the Draw format
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"
22 /* The work area must be a little bit larger than the diagram */
23 #define WORKAREA_EXTENSION 5
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)
32 #if !defined(__GNUC__)
34 flex_alloc(flex_ptr anchor
, int n
)
38 TRACE_MSG("flex_alloc");
40 if (anchor
== NULL
|| n
< 0) {
52 } /* end of flex_alloc */
55 flex_free(flex_ptr anchor
)
57 TRACE_MSG("flex_free");
59 if (anchor
== NULL
|| *anchor
== NULL
) {
64 } /* end of flex_free */
67 flex_extend(flex_ptr anchor
, int newsize
)
71 TRACE_MSG("flex_extend");
73 if (anchor
== NULL
|| newsize
< 0) {
79 pvTmp
= realloc(*anchor
, newsize
);
85 } /* end of flex_extend */
86 #endif /* !__GNUC__ */
89 * vCreateMainWindow - create the Main window
91 * remark: does not return if the Main window can't be created
94 tCreateMainWindow(void)
96 window_handle tMainWindow
;
98 TRACE_MSG("tCreateMainWindow");
100 tMainWindow
= Window_Create("MainWindow", template_TITLEMIN
);
101 if (tMainWindow
== 0) {
102 werr(1, "I can't find the 'MainWindow' template");
105 } /* end of tCreateMainWindow */
108 * vCreateScaleWindow - create the Scale view window
110 * remark: does not return if the Scale view window can't be created
113 tCreateScaleWindow(void)
115 window_handle tScaleWindow
;
117 TRACE_MSG("tCreateScaleWindow");
119 tScaleWindow
= Window_Create("ScaleView", template_TITLEMIN
);
120 if (tScaleWindow
== 0) {
121 werr(1, "I can't find the 'ScaleView' template");
124 } /* end of tCreateScaleWindow */
127 * pCreateDiagram - create and initialize a diagram
129 * remark: does not return if the diagram can't be created
132 pCreateDiagram(const char *szTask
, const char *szFilename
)
135 options_type tOptions
;
136 window_handle tMainWindow
, tScaleWindow
;
139 TRACE_MSG("pCreateDiagram");
141 fail(szTask
== NULL
|| szTask
[0] == '\0');
143 /* Create the main window */
144 tMainWindow
= tCreateMainWindow();
146 /* Create the scale view window */
147 tScaleWindow
= tCreateScaleWindow();
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");
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
;
163 tBox
.min
.y
= -(Drawfile_ScreenToDraw(32 + 3) * 8 + 1);
164 tBox
.max
.x
= Drawfile_ScreenToDraw(16) * MIN_SCREEN_WIDTH
+ 1;
166 Error_CheckFatal(Drawfile_CreateDiagram(&pDiag
->tInfo
,
167 pDiag
->tMemorySize
, szTask
, tBox
));
168 DBG_DEC(pDiag
->tInfo
.length
);
171 strncpy(pDiag
->szFilename
,
172 szBasename(szFilename
), sizeof(pDiag
->szFilename
) - 1);
173 pDiag
->szFilename
[sizeof(pDiag
->szFilename
) - 1] = '\0';
176 } /* end of pCreateDiagram */
179 * bDestroyDiagram - remove a diagram by freeing the memory it uses
182 bDestroyDiagram(event_pollblock
*pEvent
, void *pvReference
)
185 window_handle tWindow
;
187 TRACE_MSG("bDestroyDiagram");
189 fail(pEvent
== NULL
);
190 fail(pvReference
== NULL
);
192 if (pEvent
== NULL
|| pvReference
== NULL
) {
196 pDiag
= (diagram_type
*)pvReference
;
198 switch (pEvent
->type
) {
200 tWindow
= pEvent
->data
.openblock
.window
;
203 tWindow
= pEvent
->data
.key
.caret
.window
;
206 DBG_DEC(pEvent
->type
);
209 if (tWindow
!= pDiag
->tMainWindow
) {
213 /* Delete the main window */
214 Window_Delete(pDiag
->tMainWindow
);
215 pDiag
->tMainWindow
= 0;
217 /* Delete the scale window */
218 Window_Delete(pDiag
->tScaleWindow
);
219 pDiag
->tScaleWindow
= 0;
221 #if defined(__GNUC__)
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
226 while (EventMsg_ReleaseSpecific(message_MENUWARNING
, window_ANY
,
227 bSaveTextfile
, pDiag
))
229 while (EventMsg_ReleaseSpecific(message_MENUWARNING
, window_ANY
,
230 bSaveDrawfile
, pDiag
))
232 while (EventMsg_ReleaseSpecific(message_MENUWARNING
, window_ANY
,
233 bScaleOpenAction
, pDiag
))
235 #endif /* __GNUC__ */
237 /* Free the memory */
238 if (pDiag
->tInfo
.data
!= NULL
&& pDiag
->tMemorySize
!= 0) {
239 flex_free((flex_ptr
)&pDiag
->tInfo
.data
);
241 /* Just to be on the save side */
242 pDiag
->tInfo
.data
= NULL
;
243 pDiag
->tInfo
.length
= 0;
244 pDiag
->tMemorySize
= 0;
246 /* Destroy the diagram itself */
247 pDiag
= xfree(pDiag
);
249 } /* end of bDestroyDiagram */
252 * vExtendDiagramSize - make sure the diagram is big enough
255 vExtendDiagramSize(diagram_type
*pDiag
, size_t tSize
)
257 TRACE_MSG("vExtendDiagramSize");
259 fail(pDiag
== NULL
|| tSize
% 4 != 0);
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");
266 pDiag
->tMemorySize
+= EXTENSION_SIZE
;
267 NO_DBG_DEC(pDiag
->tMemorySize
);
269 TRACE_MSG("end of vExtendDiagramSize");
270 } /* end of vExtendDiagramSize */
273 * vPrologue2 - prologue part 2; add a font list to a diagram
276 vPrologue2(diagram_type
*pDiag
, int iWordVersion
)
278 drawfile_object
*pNew
;
279 const font_table_type
*pTmp
;
281 size_t tRealSize
, tSize
;
284 TRACE_MSG("vPrologue2");
288 if (tGetFontTableLength() == 0) {
291 tRealSize
= offsetof(drawfile_object
, data
);
293 while ((pTmp
= pGetNextFontTableRecord(pTmp
)) != NULL
) {
294 tRealSize
+= 2 + strlen(pTmp
->szOurFontname
);
297 tSize
= ROUND4(tRealSize
);
298 vExtendDiagramSize(pDiag
, tSize
);
299 pNew
= xmalloc(tSize
);
300 memset(pNew
, 0, tSize
);
301 pNew
->type
= drawfile_TYPE_FONT_TABLE
;
303 pcTmp
= (char *)&pNew
->data
.font_table
.font_def
[0].font_ref
;
306 while ((pTmp
= pGetNextFontTableRecord(pTmp
)) != NULL
) {
309 strcpy(pcTmp
, pTmp
->szOurFontname
);
310 pcTmp
+= 1 + strlen(pTmp
->szOurFontname
);
312 Error_CheckFatal(Drawfile_AppendObject(&pDiag
->tInfo
,
313 pDiag
->tMemorySize
, pNew
, TRUE
));
315 } /* end of vPrologue2 */
318 * vSubstring2Diagram - put a sub string into a diagram
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
)
326 drawfile_object
*pNew
;
327 long lSizeX
, lSizeY
, lOffset
, l20
, lYMove
;
328 size_t tRealSize
, tSize
;
330 TRACE_MSG("vSubstring2Diagram");
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
);
339 if (szString
[0] == '\0' || tStringLength
== 0) {
344 lOffset
= Drawfile_ScreenToDraw(2);
345 l20
= Drawfile_ScreenToDraw(32 + 3);
346 lSizeX
= Drawfile_ScreenToDraw(16);
347 lSizeY
= Drawfile_ScreenToDraw(32);
349 lOffset
= lToBaseLine(usMaxFontSize
);
350 l20
= lWord2DrawUnits20(usMaxFontSize
);
351 lSizeX
= lWord2DrawUnits00(usFontSize
);
352 lSizeY
= lWord2DrawUnits00(usFontSize
);
357 /* Up for superscript */
358 if (bIsSuperscript(usFontstyle
)) {
359 lYMove
= lMilliPoints2DrawUnits((((long)usFontSize
+ 1) / 2) * 375);
361 /* Down for subscript */
362 if (bIsSubscript(usFontstyle
)) {
363 lYMove
= -lMilliPoints2DrawUnits((long)usFontSize
* 125);
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
;
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
));
393 /*draw_translateText(&pDiag->tInfo);*/
394 pDiag
->lXleft
+= lStringWidth
;
395 TRACE_MSG("leaving vSubstring2Diagram");
396 } /* end of vSubstring2Diagram */
399 * vImage2Diagram - put an image into a diagram
402 vImage2Diagram(diagram_type
*pDiag
, const imagedata_type
*pImg
,
403 UCHAR
*pucImage
, size_t tImageSize
)
405 drawfile_object
*pNew
;
406 long lWidth
, lHeight
;
407 size_t tRealSize
, tSize
;
409 TRACE_MSG("vImage2Diagram");
413 fail(pDiag
->lXleft
< 0);
414 fail(pImg
->eImageType
!= imagetype_is_dib
&&
415 pImg
->eImageType
!= imagetype_is_jpeg
);
417 DBG_DEC_C(pDiag
->lXleft
!= 0, pDiag
->lXleft
);
419 lWidth
= lPoints2DrawUnits(pImg
->iHorSizeScaled
);
420 lHeight
= lPoints2DrawUnits(pImg
->iVerSizeScaled
);
424 pDiag
->lYtop
-= lHeight
;
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
;
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
);
442 case imagetype_is_jpeg
:
444 (void)bGetJpegInfo(pucImage
, tImageSize
);
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
;
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
);
471 DBG_DEC(pImg
->eImageType
);
476 Error_CheckFatal(Drawfile_AppendObject(&pDiag
->tInfo
,
477 pDiag
->tMemorySize
, pNew
, TRUE
));
480 } /* end of vImage2Diagram */
483 * bAddDummyImage - add a dummy image
485 * return TRUE when successful, otherwise FALSE
488 bAddDummyImage(diagram_type
*pDiag
, const imagedata_type
*pImg
)
490 drawfile_object
*pNew
;
492 long lWidth
, lHeight
;
493 size_t tRealSize
, tSize
;
495 TRACE_MSG("bAddDummyImage");
499 fail(pDiag
->lXleft
< 0);
501 if (pImg
->iVerSizeScaled
<= 0 || pImg
->iHorSizeScaled
<= 0) {
505 DBG_DEC_C(pDiag
->lXleft
!= 0, pDiag
->lXleft
);
507 lWidth
= lPoints2DrawUnits(pImg
->iHorSizeScaled
);
508 lHeight
= lPoints2DrawUnits(pImg
->iVerSizeScaled
);
510 pDiag
->lYtop
-= lHeight
;
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
;
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
;
547 Error_CheckFatal(Drawfile_AppendObject(&pDiag
->tInfo
,
548 pDiag
->tMemorySize
, pNew
, TRUE
));
552 } /* end of bAddDummyImage */
555 * vMove2NextLine - move to the next line
558 vMove2NextLine(diagram_type
*pDiag
, drawfile_fontref tFontRef
,
563 TRACE_MSG("vMove2NextLine");
566 fail(usFontSize
< MIN_FONT_SIZE
|| usFontSize
> MAX_FONT_SIZE
);
569 l20
= Drawfile_ScreenToDraw(32 + 3);
571 l20
= lWord2DrawUnits20(usFontSize
);
574 } /* end of vMove2NextLine */
577 * Create an start of paragraph (Phase 1)
580 vStartOfParagraph1(diagram_type
*pDiag
, long lBeforeIndentation
)
582 TRACE_MSG("vStartOfParagraph1");
585 fail(lBeforeIndentation
< 0);
588 pDiag
->lYtop
-= lMilliPoints2DrawUnits(lBeforeIndentation
);
589 } /* end of vStartOfParagraph1 */
592 * Create an start of paragraph (Phase 2)
596 vStartOfParagraph2(diagram_type
*pDiag
)
598 TRACE_MSG("vStartOfParagraph2");
599 } /* end of vStartOfParagraph2 */
602 * Create an end of paragraph
605 vEndOfParagraph(diagram_type
*pDiag
,
606 drawfile_fontref tFontRef
, USHORT usFontSize
, long lAfterIndentation
)
608 TRACE_MSG("vEndOfParagraph");
611 fail(usFontSize
< MIN_FONT_SIZE
|| usFontSize
> MAX_FONT_SIZE
);
612 fail(lAfterIndentation
< 0);
615 pDiag
->lYtop
-= lMilliPoints2DrawUnits(lAfterIndentation
);
616 } /* end of vEndOfParagraph */
619 * Create an end of page
622 vEndOfPage(diagram_type
*pDiag
, long lAfterIndentation
, BOOL bNewSection
)
624 TRACE_MSG("vEndOfPage");
627 fail(lAfterIndentation
< 0);
630 pDiag
->lYtop
-= lMilliPoints2DrawUnits(lAfterIndentation
);
631 } /* end of vEndOfPage */
634 * vSetHeaders - set the headers
638 vSetHeaders(diagram_type
*pDiag
, USHORT usIstd
)
640 TRACE_MSG("vSetHeaders");
641 } /* end of vSetHeaders */
644 * Create a start of list
648 vStartOfList(diagram_type
*pDiag
, UCHAR ucNFC
, BOOL bIsEndOfTable
)
650 TRACE_MSG("vStartOfList");
651 } /* end of vStartOfList */
654 * Create an end of list
658 vEndOfList(diagram_type
*pDiag
)
660 TRACE_MSG("vEndOfList");
661 } /* end of vEndOfList */
664 * Create a start of a list item
668 vStartOfListItem(diagram_type
*pDiag
, BOOL bNoMarks
)
670 TRACE_MSG("vStartOfListItem");
671 } /* end of vStartOfListItem */
674 * Create an end of a table
678 vEndOfTable(diagram_type
*pDiag
)
680 TRACE_MSG("vEndOfTable");
681 } /* end of vEndTable */
687 * Returns TRUE when conversion type is XML
690 bAddTableRow(diagram_type
*pDiag
, char **aszColTxt
,
691 int iNbrOfColumns
, const short *asColumnWidth
, UCHAR ucBorderInfo
)
693 TRACE_MSG("bAddTableRow");
696 } /* end of bAddTableRow */
699 * vForceRedraw - force a redraw of the main window
702 vForceRedraw(diagram_type
*pDiag
)
704 window_state tWindowState
;
705 window_redrawblock tRedraw
;
708 TRACE_MSG("vForceRedraw");
712 DBG_DEC(pDiag
->iScaleFactorCurr
);
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 */
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 */
741 * vShowDiagram - put the diagram on the screen
744 vShowDiagram(diagram_type
*pDiag
)
749 TRACE_MSG("vShowDiagram");
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
);
762 } /* end of vShowDiagram */
765 * vMainButtonClick - handle mouse buttons clicks for the main screen
768 vMainButtonClick(mouse_block
*pMouse
)
773 TRACE_MSG("vMainButtonClick");
775 fail(pMouse
== NULL
);
777 DBG_DEC(pMouse
->button
.data
.select
);
778 DBG_DEC(pMouse
->button
.data
.adjust
);
779 DBG_DEC(pMouse
->window
);
780 DBG_DEC(pMouse
->icon
);
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
;
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);
793 Error_CheckFatal(Wimp_SetCaretPosition(&tCaret
));
795 } /* end of vMainButtonClick */
798 * bMainKeyPressed - handle pressed keys for the main window
801 bMainKeyPressed(event_pollblock
*pEvent
, void *pvReference
)
805 TRACE_MSG("bMainKeyPressed");
807 fail(pEvent
== NULL
);
808 fail(pEvent
->type
!= event_KEY
);
809 fail(pvReference
== NULL
);
811 pDiag
= (diagram_type
*)pvReference
;
813 fail(pEvent
->data
.key
.caret
.window
!= pDiag
->tMainWindow
);
816 switch (pEvent
->data
.key
.code
) {
817 case keycode_CTRL_F2
: /* Ctrl F2 */
818 bDestroyDiagram(pEvent
, pvReference
);
820 case keycode_F3
: /* F3 */
821 bSaveDrawfile(pEvent
, pvReference
);
823 case keycode_SHIFT_F3
: /* Shift F3 */
824 bSaveTextfile(pEvent
, pvReference
);
827 DBG_DEC(pEvent
->data
.key
.code
);
828 Error_CheckFatal(Wimp_ProcessKey(pEvent
->data
.key
.code
));
831 } /* end of bMainKeyPressed */
834 * bRedrawMainWindow - redraw the main window
837 bRedrawMainWindow(event_pollblock
*pEvent
, void *pvReference
)
839 window_redrawblock tBlock
;
841 drawfile_info
*pInfo
;
845 TRACE_MSG("bRedrawMainWindow");
847 fail(pEvent
== NULL
);
848 fail(pEvent
->type
!= event_REDRAW
);
849 fail(pvReference
== NULL
);
851 pDiag
= (diagram_type
*)pvReference
;
853 fail(pDiag
->tMainWindow
!= pEvent
->data
.openblock
.window
);
854 fail(pDiag
->iScaleFactorCurr
< MIN_SCALE_FACTOR
);
855 fail(pDiag
->iScaleFactorCurr
> MAX_SCALE_FACTOR
);
857 dScaleFactor
= (double)pDiag
->iScaleFactorCurr
/ 100.0;
858 pInfo
= &pDiag
->tInfo
;
860 tBlock
.window
= pEvent
->data
.openblock
.window
;
861 Error_CheckFatal(Wimp_RedrawWindow(&tBlock
, &bMore
));
863 /* If there is no real diagram just go thru the motions */
865 if (pInfo
->data
!= NULL
&& pInfo
->length
!= 0) {
866 Error_CheckFatal(Drawfile_RenderDiagram(pInfo
,
867 &tBlock
, dScaleFactor
));
869 Error_CheckFatal(Wimp_GetRectangle(&tBlock
, &bMore
));
872 } /* end of bRedrawMainWindow */
875 * bScaleOpenAction - action to be taken when the Scale view window opens
878 bScaleOpenAction(event_pollblock
*pEvent
, void *pvReference
)
880 window_state tWindowState
;
883 TRACE_MSG("bScaleOpenAction");
885 fail(pEvent
== NULL
);
886 fail(pEvent
->type
!= event_SEND
);
887 fail(pEvent
->data
.message
.header
.action
!= message_MENUWARN
);
888 fail(pvReference
== NULL
);
890 pDiag
= (diagram_type
*)pvReference
;
892 if (menu_currentopen
!= pDiag
->pSaveMenu
||
893 pEvent
->data
.message
.data
.menuwarn
.selection
[0] != SAVEMENU_SCALEVIEW
) {
897 Error_CheckFatal(Wimp_GetWindowState(pDiag
->tScaleWindow
,
899 if (tWindowState
.flags
.data
.open
) {
900 /* The window is already open */
904 DBG_MSG("vScaleOpenAction for real");
906 pDiag
->iScaleFactorTemp
= pDiag
->iScaleFactorCurr
;
907 vUpdateWriteableNumber(pDiag
->tScaleWindow
,
908 SCALE_SCALE_WRITEABLE
, pDiag
->iScaleFactorTemp
);
909 Window_Show(pDiag
->tScaleWindow
, open_UNDERPOINTER
);
911 } /* end of bScaleOpenAction */
914 * vSetTitle - set the title of a window
917 vSetTitle(diagram_type
*pDiag
)
919 char szTitle
[WINDOW_TITLE_LEN
];
921 TRACE_MSG("vSetTitle");
924 fail(pDiag
->szFilename
[0] == '\0');
926 (void)sprintf(szTitle
, "%.*s at %d%%",
929 pDiag
->iScaleFactorCurr
% 1000);
930 if (strlen(pDiag
->szFilename
) > FILENAME_TITLE_LEN
) {
931 szTitle
[FILENAME_TITLE_LEN
- 1] = OUR_ELLIPSIS
;
934 Window_SetTitle(pDiag
->tMainWindow
, szTitle
);
935 } /* end of vSetTitle */
938 * vScaleButtonClick - handle a mouse button click in the Scale view window
941 vScaleButtonClick(mouse_block
*pMouse
, diagram_type
*pDiag
)
943 BOOL bCloseWindow
, bRedraw
;
945 TRACE_MSG("vScaleButtonClick");
947 fail(pMouse
== NULL
|| pDiag
== NULL
);
948 fail(pMouse
->window
!= pDiag
->tScaleWindow
);
950 bCloseWindow
= FALSE
;
952 switch (pMouse
->icon
) {
953 case SCALE_CANCEL_BUTTON
:
955 pDiag
->iScaleFactorTemp
= pDiag
->iScaleFactorCurr
;
957 case SCALE_SCALE_BUTTON
:
959 bRedraw
= pDiag
->iScaleFactorCurr
!= pDiag
->iScaleFactorTemp
;
960 pDiag
->iScaleFactorCurr
= pDiag
->iScaleFactorTemp
;
963 pDiag
->iScaleFactorTemp
= 50;
966 pDiag
->iScaleFactorTemp
= 75;
969 pDiag
->iScaleFactorTemp
= 100;
972 pDiag
->iScaleFactorTemp
= 150;
975 DBG_DEC(pMouse
->icon
);
979 /* Close the scale window */
980 Error_CheckFatal(Wimp_CloseWindow(pMouse
->window
));
982 /* Redraw the main window */
987 vUpdateWriteableNumber(pMouse
->window
,
988 SCALE_SCALE_WRITEABLE
,
989 pDiag
->iScaleFactorTemp
);
991 } /* end of vScaleButtonClick */
994 * bScaleKeyPressed - handle pressed keys for the scale window
997 bScaleKeyPressed(event_pollblock
*pEvent
, void *pvReference
)
1000 diagram_type
*pDiag
;
1001 caret_block
*pCaret
;
1005 TRACE_MSG("bScaleKeyPressed");
1007 fail(pEvent
== NULL
);
1008 fail(pEvent
->type
!= event_KEY
);
1009 fail(pvReference
== NULL
);
1011 pCaret
= &pEvent
->data
.key
.caret
;
1012 pDiag
= (diagram_type
*)pvReference
;
1014 fail(pEvent
->data
.key
.caret
.window
!= pDiag
->tScaleWindow
);
1016 DBG_DEC_C(pCaret
->icon
!= SCALE_SCALE_WRITEABLE
, pCaret
->icon
);
1017 DBG_DEC_C(pCaret
->icon
== SCALE_SCALE_WRITEABLE
, pEvent
->data
.key
.code
);
1019 if (pEvent
->data
.key
.code
!= '\r' ||
1020 pCaret
->icon
!= SCALE_SCALE_WRITEABLE
) {
1021 Error_CheckFatal(Wimp_ProcessKey(pEvent
->data
.key
.code
));
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
);
1029 iTmp
= (int)strtol(tIcon
.data
.indirecttext
.buffer
, &pcChar
, 10);
1030 if (*pcChar
!= '\0' && *pcChar
!= '\r') {
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
;
1037 pDiag
->iScaleFactorTemp
= iTmp
;
1039 pDiag
->iScaleFactorCurr
= pDiag
->iScaleFactorTemp
;
1040 /* Close the scale window */
1041 Error_CheckFatal(Wimp_CloseWindow(pCaret
->window
));
1042 /* Redraw the main window */
1044 vForceRedraw(pDiag
);
1046 } /* end of bScaleKeyPressed */