3 * Copyright (C) 2005 A.J. van Os; Released under GPL
6 * Functions to process with the Draw diagram
10 #include "DeskLib:Error.h"
11 #include "DeskLib:SWI.h"
15 #define DRAWFILE_OBJECT_TOO_SMALL 200
16 #define DRAWFILE_NO_TEXT 201
17 #define DRAWFILE_BAD_CHARACTER 202
18 #define DRAWFILE_SMALL_MEMORY 203
19 #define DRAWFILE_PATH_WITHOUT_LINES 204
20 #define DRAWFILE_BAD_PATH_TYPE 205
21 #define DRAWFILE_PATH_WITHOUT_END 206
22 #define DRAWFILE_BAD_SPRITE_SIZE 207
23 #define DRAWFILE_BAD_JPEG_SIZE 208
24 #define DRAWFILE_TOO_SMALL 209
25 #define DRAWFILE_NOT_A_DRAWFILE 210
26 #define DRAWFILE_OBJECT_SIZE 211
27 #define DRAWFILE_MANY_FONTTABLES 212
28 #define DRAWFILE_TEXT_NO_FONT 213
29 #define DRAWFILE_OBJECT_UNEXPECTED 214
30 #define DRAWFILE_SIZE_ERROR 215
32 typedef struct drawfile_error_tag
{
34 const char *szErrorText
;
35 } drawfile_error_type
;
37 static const drawfile_error_type atErrors
[] = {
38 { DRAWFILE_OBJECT_TOO_SMALL
, "Object too small"},
39 { DRAWFILE_NO_TEXT
, "Text object without text"},
40 { DRAWFILE_BAD_CHARACTER
, "Bad character in string"},
41 { DRAWFILE_SMALL_MEMORY
, "Not enough memory reserved"},
42 { DRAWFILE_PATH_WITHOUT_LINES
, "This path has no lines"},
43 { DRAWFILE_BAD_PATH_TYPE
, "Bad path-type in path"},
44 { DRAWFILE_PATH_WITHOUT_END
, "No end of path seen"},
45 { DRAWFILE_BAD_SPRITE_SIZE
, "Bad sprite size"},
46 { DRAWFILE_BAD_JPEG_SIZE
, "Bad jpeg size"},
47 { DRAWFILE_TOO_SMALL
, "Too small to be a drawfile"},
48 { DRAWFILE_NOT_A_DRAWFILE
, "Not a drawfile"},
49 { DRAWFILE_OBJECT_SIZE
, "Object with incorrect size"},
50 { DRAWFILE_MANY_FONTTABLES
, "More than one font table"},
51 { DRAWFILE_TEXT_NO_FONT
, "Text, but no font table seen"},
52 { DRAWFILE_OBJECT_UNEXPECTED
, "Unexpected object type"},
53 { DRAWFILE_SIZE_ERROR
, "Sizes don't match"},
58 * pFillError - error number to error struct
61 pFillError(int iErrorNumber
)
63 static os_error tError
;
64 const drawfile_error_type
*pTmp
;
65 const char *szErrorText
;
67 szErrorText
= "Unknown error";
68 for (pTmp
= atErrors
; pTmp
< atErrors
+ elementsof(atErrors
); pTmp
++) {
69 if (iErrorNumber
== pTmp
->iErrorNumber
) {
70 szErrorText
= pTmp
->szErrorText
;
74 tError
.errnum
= iErrorNumber
;
75 strncpy(tError
.errmess
, szErrorText
, sizeof(tError
.errmess
) - 1);
76 tError
.errmess
[sizeof(tError
.errmess
) - 1] = '\0';
77 DBG_DEC(tError
.errnum
);
78 DBG_MSG(tError
.errmess
);
80 } /* end of pFillError */
83 * Drawfile_BBox - Find the bounding box of a diagram
86 Drawfile_Bbox(drawfile_bbox_flags flags
,
87 drawfile_diagram
const *diagram
,
92 return SWI(5, 0, DrawFile_BBox
| XOS_Bit
,
93 flags
, diagram
, size
, trfm
, bbox
);
94 } /* end of Drawfile_Bbox */
97 * Drawfile_CreateDiagram - create an empty drawfile diagram
100 Drawfile_CreateDiagram(drawfile_info
*pInfo
, size_t tMemorySize
,
101 const char *szCreator
, wimp_box tBbox
)
103 drawfile_diagram
*pDiag
;
105 if (tMemorySize
< offsetof(drawfile_diagram
, objects
)) {
106 return pFillError(DRAWFILE_SMALL_MEMORY
);
108 pDiag
= (drawfile_diagram
*)pInfo
->data
;
109 strncpy(pDiag
->tag
, "Draw", 4);
110 pDiag
->major_version
= 201;
111 pDiag
->minor_version
= 0;
112 strncpy(pDiag
->source
, szCreator
, sizeof(pDiag
->source
));
115 pInfo
->length
= offsetof(drawfile_diagram
, objects
);
117 } /* end of Drawfile_CreateDiagram */
120 * Drawfile_AppendObject - append an object to a diagram
123 Drawfile_AppendObject(drawfile_info
*pInfo
, size_t tMemorySize
,
124 const drawfile_object
*pObject
, BOOL bRebind
)
127 const wimp_box
*pBbox
;
130 if (tMemorySize
< pInfo
->length
+ pObject
->size
) {
131 return pFillError(DRAWFILE_OBJECT_TOO_SMALL
);
133 /* After the last object */
134 pAfter
= (byte
*)pInfo
->data
+ pInfo
->length
;
135 /* Copy in the new data */
136 memcpy(pAfter
, pObject
, pObject
->size
);
137 /* Rebind if needed */
139 pMainBbox
= &((drawfile_diagram
*)pInfo
->data
)->bbox
;
140 switch (pObject
->type
) {
141 case drawfile_TYPE_FONT_TABLE
:
144 case drawfile_TYPE_TEXT
:
145 pBbox
= &pObject
->data
.text
.bbox
;
147 case drawfile_TYPE_PATH
:
148 pBbox
= &pObject
->data
.path
.bbox
;
150 case drawfile_TYPE_SPRITE
:
151 pBbox
= &pObject
->data
.sprite
.bbox
;
153 case drawfile_TYPE_GROUP
:
154 pBbox
= &pObject
->data
.group
.bbox
;
156 case drawfile_TYPE_TAGGED
:
157 pBbox
= &pObject
->data
.tagged
.bbox
;
159 case drawfile_TYPE_TEXT_AREA
:
160 pBbox
= &pObject
->data
.text_area
.bbox
;
162 case drawfile_TYPE_TEXT_COLUMN
:
165 case drawfile_TYPE_OPTIONS
:
166 pBbox
= &pObject
->data
.options
.bbox
;
168 case drawfile_TYPE_TRFM_TEXT
:
169 pBbox
= &pObject
->data
.trfm_text
.bbox
;
171 case drawfile_TYPE_TRFM_SPRITE
:
172 pBbox
= &pObject
->data
.trfm_sprite
.bbox
;
174 case drawfile_TYPE_JPEG
:
175 pBbox
= &pObject
->data
.jpeg
.bbox
;
182 if (pBbox
->min
.x
< pMainBbox
->min
.x
) {
183 pMainBbox
->min
.x
= pBbox
->min
.x
;
185 if (pBbox
->min
.y
< pMainBbox
->min
.y
) {
186 pMainBbox
->min
.y
= pBbox
->min
.y
;
188 if (pBbox
->max
.x
> pMainBbox
->max
.x
) {
189 pMainBbox
->max
.x
= pBbox
->max
.x
;
191 if (pBbox
->max
.y
> pMainBbox
->max
.y
) {
192 pMainBbox
->max
.y
= pBbox
->max
.y
;
197 pInfo
->length
+= pObject
->size
;
199 } /* end of Drawfile_AppendObject */
202 * Replaces the draw_render_diag function from RISC_OSLib
205 Drawfile_RenderDiagram(drawfile_info
*pInfo
, window_redrawblock
*pRedraw
,
211 fail(pInfo
->data
== NULL
);
212 fail(pRedraw
== NULL
);
215 aiTransform
[0] = (int)(dScale
* 0x10000);
218 aiTransform
[3] = (int)(dScale
* 0x10000);
219 aiTransform
[4] = (pRedraw
->rect
.min
.x
- pRedraw
->scroll
.x
) * 256;
220 aiTransform
[5] = (pRedraw
->rect
.max
.y
- pRedraw
->scroll
.y
) * 256;
222 return SWI(6, 0, DrawFile_Render
| XOS_Bit
,
223 0, pInfo
->data
, pInfo
->length
, aiTransform
, &pRedraw
->rect
, 0);
224 } /* end of Drawfile_RenderDiagram */
227 * pVerifyText - verify a text object
230 pVerifyText(const drawfile_text
*pText
)
232 const unsigned char *pucTmp
;
234 if (pText
->text
[0] == '\0') {
235 return pFillError(DRAWFILE_NO_TEXT
);
237 pucTmp
= (const unsigned char *)pText
->text
;
238 while (*pucTmp
!= '\0') {
239 if (*pucTmp
< 0x20 || *pucTmp
== 0x7f) {
240 return pFillError(DRAWFILE_BAD_CHARACTER
);
245 } /* end of pVerifyText */
248 * pVerifyPath - verify a path object
251 pVerifyPath(const drawfile_path
*pPath
, int iSize
)
258 iElements
= (iSize
- offsetof(drawfile_path
, path
)) / 4;
260 for (piTmp
= pPath
->path
; piTmp
< pPath
->path
+ iElements
; piTmp
++) {
262 case drawfile_PATH_END_PATH
:
266 return pFillError(DRAWFILE_PATH_WITHOUT_LINES
);
267 case drawfile_PATH_LINE_TO
:
271 case drawfile_PATH_MOVE_TO
:
274 case drawfile_PATH_CLOSE_LINE
:
278 return pFillError(DRAWFILE_BAD_PATH_TYPE
);
281 return pFillError(DRAWFILE_PATH_WITHOUT_END
);
282 } /* end of pVerifyPath */
285 * pVerifySprite - verify a sprite object
288 pVerifySprite(const drawfile_sprite
*pSprite
, int iSize
)
290 iSize
-= offsetof(drawfile_sprite
, header
);
291 if (iSize
< pSprite
->header
.offset_next
) {
293 DBG_DEC(pSprite
->header
.offset_next
);
294 return pFillError(DRAWFILE_BAD_SPRITE_SIZE
);
297 } /* end of pVerifySprite */
300 * pVerifyJpeg - verify a jpeg object
303 pVerifyJpeg(const drawfile_jpeg
*pJpeg
, int iSize
)
305 iSize
-= offsetof(drawfile_jpeg
, data
);
306 if (iSize
< pJpeg
->len
) {
309 return pFillError(DRAWFILE_BAD_JPEG_SIZE
);
312 } /* end of pVerifyJpeg */
315 * Drawfile_VerifyDiagram - Verify the diagram generated from the Word file
317 * returns NULL if the diagram is correct
320 Drawfile_VerifyDiagram(drawfile_info
*pInfo
)
322 drawfile_diagram
*pDiag
;
323 drawfile_object
*pObj
;
326 int iToGo
, iFontTables
;
329 TRACE_MSG("Drawfile_VerifyDiagram");
333 if (pInfo
->length
< offsetof(drawfile_diagram
, objects
)) {
334 return pFillError(DRAWFILE_TOO_SMALL
);
337 pDiag
= (drawfile_diagram
*)pInfo
->data
;
338 if (strncmp(pDiag
->tag
, "Draw", 4) != 0 ||
339 pDiag
->major_version
!= 201 ||
340 pDiag
->minor_version
!= 0) {
341 return pFillError(DRAWFILE_NOT_A_DRAWFILE
);
344 iToGo
= pInfo
->length
- offsetof(drawfile_diagram
, objects
);
345 pcTmp
= (const char *)pInfo
->data
+ offsetof(drawfile_diagram
, objects
);
347 bTypeFontTable
= FALSE
;
350 pObj
= (drawfile_object
*)pcTmp
;
351 if (pObj
->size
< 0 || pObj
->size
% 4 != 0) {
352 return pFillError(DRAWFILE_OBJECT_SIZE
);
354 switch (pObj
->type
) {
355 case drawfile_TYPE_FONT_TABLE
:
356 if (bTypeFontTable
) {
357 return pFillError(DRAWFILE_MANY_FONTTABLES
);
359 bTypeFontTable
= TRUE
;
361 case drawfile_TYPE_TEXT
:
362 if (pObj
->data
.text
.style
.font_ref
!= 0 &&
364 return pFillError(DRAWFILE_TEXT_NO_FONT
);
366 pError
= pVerifyText(&pObj
->data
.text
);
367 if (pError
!= NULL
) {
371 case drawfile_TYPE_PATH
:
372 pError
= pVerifyPath(&pObj
->data
.path
,
373 pObj
->size
- offsetof(drawfile_object
, data
));
374 if (pError
!= NULL
) {
378 case drawfile_TYPE_SPRITE
:
379 pError
= pVerifySprite(&pObj
->data
.sprite
,
380 pObj
->size
- offsetof(drawfile_object
, data
));
381 if (pError
!= NULL
) {
385 case drawfile_TYPE_JPEG
:
386 pError
= pVerifyJpeg(&pObj
->data
.jpeg
,
387 pObj
->size
- offsetof(drawfile_object
, data
));
388 if (pError
!= NULL
) {
394 return pFillError(DRAWFILE_OBJECT_UNEXPECTED
);
400 return pFillError(DRAWFILE_SIZE_ERROR
);
403 } /* end of Drawfile_VerifyDiagram */
406 * Drawfile_QueryBox - Find the bounding box of a diagram
409 Drawfile_QueryBox(drawfile_info
*pInfo
, wimp_box
*pRect
, BOOL bScreenUnits
)
414 Error_CheckFatal(Drawfile_Bbox(0,
415 pInfo
->data
, pInfo
->length
, NULL
, pRect
));
417 pRect
->min
.x
= Drawfile_DrawToScreen(pRect
->min
.x
);
418 pRect
->min
.y
= Drawfile_DrawToScreen(pRect
->min
.y
);
419 pRect
->max
.x
= Drawfile_DrawToScreen(pRect
->max
.x
);
420 pRect
->max
.y
= Drawfile_DrawToScreen(pRect
->max
.y
);
422 } /* end of Drawfile_QueryBox */