1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 #include "precompile.h"
28 #include <osl/diagnose.h>
30 #include <comphelper/newarray.hxx>
48 BEGIN_GRADATION
= 0, LINEAR
, RADIAL
, CONICAL
, SQUARE
,
49 END_GRADATION
, BITMAP_PATTERN
52 #define OBJRET_FILE_OK 0
53 #define OBJRET_FILE_ERROR (-1)
54 #define OBJRET_FILE_NO_PRIVATE_BLOCK (-2)
55 #define OBJRET_FILE_NO_PRIVATE_BLOCK_2 (-3)
57 typedef int (*HWPDOFuncType
) (int, HWPDrawingObject
*, int, void *, int);
59 #define HWPDOFunc(hdo, cmd, argp, argv) \
60 (HWPDOFuncTbl[(hdo)->type]((hdo)->type, (hdo), (cmd), (argp), (argv)))
61 #define HWPDOFunc2(type, cmd, argp, argv) \
62 (HWPDOFuncTbl[(type)]((type), NULL, (cmd), (argp), (argv)))
64 static int HWPDOLineFunc(int, HWPDrawingObject
*, int, void *, int);
65 static int HWPDORectFunc(int, HWPDrawingObject
*, int, void *, int);
66 static int HWPDOEllipseFunc(int, HWPDrawingObject
*, int, void *, int);
67 static int HWPDOArcFunc(int, HWPDrawingObject
*, int, void *, int);
68 static int HWPDOFreeFormFunc(int, HWPDrawingObject
*, int, void *, int);
69 static int HWPDOTextBoxFunc(int, HWPDrawingObject
*, int, void *, int);
70 static int HWPDOEllipse2Func(int, HWPDrawingObject
*, int, void *, int);
71 static int HWPDOArc2Func(int, HWPDrawingObject
*, int, void *, int);
72 static int HWPDOContainerFunc(int, HWPDrawingObject
*, int, void *, int);
73 static HWPPara
*LoadParaList();
75 HWPDOFuncType HWPDOFuncTbl
[] =
90 static HMemIODev
*hmem
= 0;
94 inline bool HAVE_FCOLOR(HWPDrawingObject
* hdo
)
96 return hdo
->property
.fill_color
!= HWPDO_COLOR_NONE
;
100 inline bool HAVE_PATTERN(HWPDrawingObject
* hdo
)
102 return (hdo
->property
.pattern_type
& HWPDO_PAT_TYPE_BITS
)
103 != HWPDO_PAT_SOLID
&& hdo
->property
.pattern_color
!= HWPDO_COLOR_NONE
;
107 inline bool HAVE_GRADATION(HWPDrawingObject
* hdo
)
109 return hdo
->property
.gstyle
> BEGIN_GRADATION
&&
110 hdo
->property
.gstyle
< END_GRADATION
&&
111 hdo
->property
.fromcolor
!= HWPDO_COLOR_NONE
&&
112 hdo
->property
.tocolor
!= HWPDO_COLOR_NONE
;
116 inline bool HAVE_BITMAP_PATTERN(HWPDrawingObject
* hdo
)
118 return hdo
->property
.gstyle
== BITMAP_PATTERN
&&
119 hdo
->property
.szPatternFile
[0];
123 inline bool HAS_PAT(HWPDrawingObject
* hdo
)
125 return HAVE_FCOLOR(hdo
) || HAVE_PATTERN(hdo
) ||
126 HAVE_GRADATION(hdo
) || HAVE_BITMAP_PATTERN(hdo
);
130 static void SetHdoParallRgn(HWPDrawingObject
* hdo
, int width
, int height
)
132 hdo
->property
.parall
.pt
[0].x
= 0;
133 hdo
->property
.parall
.pt
[0].y
= 0;
134 hdo
->property
.parall
.pt
[1].x
= width
;
135 hdo
->property
.parall
.pt
[1].y
= 0;
136 hdo
->property
.parall
.pt
[2].x
= width
;
137 hdo
->property
.parall
.pt
[2].y
= height
;
141 static bool SkipPrivateBlock(int type
)
145 if (type
== OBJRET_FILE_NO_PRIVATE_BLOCK
)
148 if (hmem
->state() || hmem
->skipBlock(n
) != n
)
154 return hmem
->skipBlock(n
) == n
;
158 static int SizeExpected
;
161 static int ReadSizeField(int size
)
164 SizeRead
= hmem
->read4b();
171 static bool SkipUnusedField(void)
173 return (SizeExpected
< SizeRead
) ?
174 hmem
->skipBlock(SizeRead
- SizeExpected
) != 0 : true;
178 #define HDOFILE_HEADER_SIZE (2*4+16) // 16=sizeof(ZZRect)
179 #define HDOFILE_COMMON_SIZE (7*4+16+44)
181 #define HDOFILE_HAS_NEXT 0x01
182 #define HDOFILE_HAS_CHILD 0x02
184 static bool LoadCommonHeader(HWPDrawingObject
* hdo
, WORD
* link_info
)
186 uint size
, common_size
;
190 size
= hmem
->read4b();
195 if (size
< HDOFILE_COMMON_SIZE
)
200 common_size
= HDOFILE_COMMON_SIZE
;
201 hdo
->type
= hmem
->read2b();
202 *link_info
= sal::static_int_cast
<WORD
>(hmem
->read2b());
203 hdo
->offset
.x
= hmem
->read4b();
204 hdo
->offset
.y
= hmem
->read4b();
205 hdo
->extent
.w
= hmem
->read4b();
206 hdo
->extent
.h
= hmem
->read4b();
207 hdo
->offset2
.x
= hmem
->read4b();
208 hdo
->offset2
.y
= hmem
->read4b();
213 hdo
->vrect
.x
= hmem
->read4b();
214 hdo
->vrect
.y
= hmem
->read4b();
215 hdo
->vrect
.w
= hmem
->read4b();
216 hdo
->vrect
.h
= hmem
->read4b();
218 // read bare property 44 bytes
219 hdo
->property
.line_pstyle
= hmem
->read4b();
220 hdo
->property
.line_hstyle
= hmem
->read4b();
221 hdo
->property
.line_tstyle
= hmem
->read4b();
222 hdo
->property
.line_color
= hmem
->read4b();
223 hdo
->property
.line_width
= (hunit
) hmem
->read4b();
224 hdo
->property
.fill_color
= hmem
->read4b();
225 hdo
->property
.pattern_type
= hmem
->read4b();
226 hdo
->property
.pattern_color
= hmem
->read4b();
227 hdo
->property
.hmargin
= (hunit
) hmem
->read4b();
228 hdo
->property
.vmargin
= (hunit
) hmem
->read4b();
229 hdo
->property
.flag
= hmem
->read4b();
230 // read ratation property 32 bytes
231 if ((size
>= common_size
+ 32)
232 && (hdo
->property
.flag
& HWPDO_FLAG_ROTATION
))
234 hdo
->property
.rot_originx
= hmem
->read4b();
235 hdo
->property
.rot_originy
= hmem
->read4b();
236 for (int ii
= 0; ii
< 3; ii
++)
238 hdo
->property
.parall
.pt
[ii
].x
= hmem
->read4b();
239 hdo
->property
.parall
.pt
[ii
].y
= hmem
->read4b();
244 SetHdoParallRgn(hdo
, hdo
->extent
.w
, hdo
->extent
.h
);
246 // read gradient property 28 bytes
247 if ((size
>= common_size
+ 28) &&
248 (hdo
->property
.flag
& HWPDO_FLAG_GRADATION
))
250 hdo
->property
.fromcolor
= hmem
->read4b();
251 hdo
->property
.tocolor
= hmem
->read4b();
252 hdo
->property
.gstyle
= hmem
->read4b();
253 hdo
->property
.angle
= hmem
->read4b();
254 hdo
->property
.center_x
= hmem
->read4b();
255 hdo
->property
.center_y
= hmem
->read4b();
256 hdo
->property
.nstep
= hmem
->read4b();
260 // read bitmap property 278 bytes
261 if ((size
>= common_size
+ 278) && \
262 (hdo
->property
.flag
& HWPDO_FLAG_BITMAP
))
264 hdo
->property
.offset1
.x
= hmem
->read4b();
265 hdo
->property
.offset1
.y
= hmem
->read4b();
266 hdo
->property
.offset2
.x
= hmem
->read4b();
267 hdo
->property
.offset2
.y
= hmem
->read4b();
268 if (!hmem
->readBlock(hdo
->property
.szPatternFile
, 261))
270 hdo
->property
.pictype
= sal::static_int_cast
<char>(hmem
->read1b());
273 if( ( size
>= common_size
+ 3 ) && ( hdo
->property
.flag
& HWPDO_FLAG_WATERMARK
) )
274 //if( ( size >= common_size ) && ( hdo->property.flag >> 20 & 0x01 ) )
276 if( size
- common_size
>= 5 )
277 hmem
->skipBlock( 2 );
278 hdo
->property
.luminance
= hmem
->read1b();
279 hdo
->property
.contrast
= hmem
->read1b();
280 hdo
->property
.greyscale
= hmem
->read1b();
284 hdo
->property
.luminance
= 0;
285 hdo
->property
.contrast
= 0;
286 hdo
->property
.greyscale
= 0;
288 hdo
->property
.pPara
= 0L;
290 if( ( size
> common_size
) && (hdo
->property
.flag
& HWPDO_FLAG_AS_TEXTBOX
) )
293 hdo
->property
.pPara
= LoadParaList();
294 if( hdo
->property
.pPara
)
300 if( size
<= common_size
)
302 return hmem
->skipBlock(size
- common_size
) != 0;
306 static HWPDrawingObject
*LoadDrawingObject(void)
308 HWPDrawingObject
*hdo
, *head
, *prev
;
316 if ((hdo
= new HWPDrawingObject
) == NULL
)
320 if (!LoadCommonHeader(hdo
, &link_info
))
324 if (hdo
->type
< 0 || hdo
->type
>= HWPDO_NITEMS
)
326 hdo
->type
= HWPDO_RECT
;
327 if (!SkipPrivateBlock(OBJRET_FILE_NO_PRIVATE_BLOCK
))
334 switch (res
= HWPDOFunc(hdo
, OBJFUNC_LOAD
, NULL
, 0))
336 case OBJRET_FILE_ERROR
:
340 case OBJRET_FILE_NO_PRIVATE_BLOCK
:
341 case OBJRET_FILE_NO_PRIVATE_BLOCK_2
:
342 if (!SkipPrivateBlock(res
))
347 if (link_info
& HDOFILE_HAS_CHILD
)
349 hdo
->child
= LoadDrawingObject();
350 if (hdo
->child
== NULL
)
361 while (link_info
& HDOFILE_HAS_NEXT
);
365 // drawing object can be list.
366 // hdo = current item, head = list;
370 HWPDOFunc(hdo
, OBJFUNC_FREE
, NULL
, 0);
383 static bool LoadDrawingObjectBlock(Picture
* pic
)
385 int size
= hmem
->read4b();
387 if (hmem
->state() || size
< HDOFILE_HEADER_SIZE
)
390 pic
->picinfo
.picdraw
.zorder
= hmem
->read4b();
391 pic
->picinfo
.picdraw
.mbrcnt
= hmem
->read4b();
392 pic
->picinfo
.picdraw
.vrect
.x
= hmem
->read4b();
393 pic
->picinfo
.picdraw
.vrect
.y
= hmem
->read4b();
394 pic
->picinfo
.picdraw
.vrect
.w
= hmem
->read4b();
395 pic
->picinfo
.picdraw
.vrect
.h
= hmem
->read4b();
397 if (size
> HDOFILE_HEADER_SIZE
&&
398 !hmem
->skipBlock(size
- HDOFILE_HEADER_SIZE
))
401 pic
->picinfo
.picdraw
.hdo
= LoadDrawingObject();
402 if (pic
->picinfo
.picdraw
.hdo
== 0)
408 // object manipulation function
411 HWPDODefaultFunc(int , HWPDrawingObject
* , int cmd
, void *, int)
413 if (cmd
== OBJFUNC_LOAD
)
414 return OBJRET_FILE_NO_PRIVATE_BLOCK
;
420 HWPDOLineFunc(int type
, HWPDrawingObject
* hdo
, int cmd
, void *argp
, int argv
)
426 if (ReadSizeField(4) < 4)
427 return OBJRET_FILE_ERROR
;
428 hdo
->u
.line_arc
.flip
= hmem
->read4b();
430 return OBJRET_FILE_ERROR
;
431 if (!SkipUnusedField())
432 return OBJRET_FILE_ERROR
;
433 ret
= OBJRET_FILE_NO_PRIVATE_BLOCK_2
;
436 ret
= HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
446 HWPDORectFunc(int type
, HWPDrawingObject
* hdo
, int cmd
, void *argp
, int argv
)
448 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
455 HWPDOEllipseFunc(int type
, HWPDrawingObject
* hdo
,
456 int cmd
, void *argp
, int argv
)
458 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
461 #define WTMM(x) ((double)(x) / 1800. * 25.4)
463 HWPDOEllipse2Func(int type
, HWPDrawingObject
* hdo
,
464 int cmd
, void *argp
, int argv
)
469 if (ReadSizeField(16) < 16)
470 return OBJRET_FILE_ERROR
;
471 hdo
->u
.arc
.radial
[0].x
= hmem
->read4b();
472 hdo
->u
.arc
.radial
[0].y
= hmem
->read4b();
473 hdo
->u
.arc
.radial
[1].x
= hmem
->read4b();
474 hdo
->u
.arc
.radial
[1].y
= hmem
->read4b();
476 if (ReadSizeField(0) < 0)
477 return OBJRET_FILE_ERROR
;
480 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
489 HWPDOArcFunc(int type
, HWPDrawingObject
* hdo
, int cmd
, void *argp
, int argv
)
494 if (ReadSizeField(4) < 4)
495 return OBJRET_FILE_ERROR
;
496 hdo
->u
.line_arc
.flip
= hmem
->read4b();
498 return OBJRET_FILE_ERROR
;
499 if (!SkipUnusedField())
500 return OBJRET_FILE_ERROR
;
503 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
510 HWPDOArc2Func(int type
, HWPDrawingObject
* hdo
, int cmd
, void *argp
, int argv
)
516 ret
= OBJRET_FILE_NO_PRIVATE_BLOCK
;
519 ret
= HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
527 HWPDOFreeFormFunc(int type
, HWPDrawingObject
* hdo
,
528 int cmd
, void *argp
, int argv
)
534 hdo
->u
.freeform
.pt
= 0;
535 if (ReadSizeField(4) < 4)
536 return OBJRET_FILE_ERROR
;
537 hdo
->u
.freeform
.npt
= hmem
->read4b();
539 return OBJRET_FILE_ERROR
;
540 if (!SkipUnusedField())
541 return OBJRET_FILE_ERROR
;
543 int size
= hdo
->u
.freeform
.npt
* sizeof(ZZPoint
);
545 if (ReadSizeField(size
) < size
)
546 return OBJRET_FILE_ERROR
;
547 if (hdo
->u
.freeform
.npt
)
550 ::comphelper::newArray_null
<ZZPoint
>(hdo
->u
.freeform
.npt
);
551 if (hdo
->u
.freeform
.pt
== NULL
)
553 hdo
->u
.freeform
.npt
= 0;
554 return OBJRET_FILE_ERROR
;
556 for (int ii
= 0; ii
< hdo
->u
.freeform
.npt
; ii
++)
558 hdo
->u
.freeform
.pt
[ii
].x
= hmem
->read4b();
559 hdo
->u
.freeform
.pt
[ii
].y
= hmem
->read4b();
562 delete[]hdo
->u
.freeform
.pt
;
563 hdo
->u
.freeform
.npt
= 0;
564 return OBJRET_FILE_ERROR
;
568 if (!SkipUnusedField())
569 return OBJRET_FILE_ERROR
;
570 return OBJRET_FILE_OK
;
573 if (hdo
->u
.freeform
.pt
)
574 delete[]hdo
->u
.freeform
.pt
;
577 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
585 static void FreeParaList(HWPPara
* para
)
588 FreeParaList(para
->Next());
593 static HWPPara
*LoadParaList()
598 HWPFile
*hwpf
= GetCurrentDoc();
599 HIODev
*hio
= hwpf
->SetIODevice(hmem
);
601 std::list
< HWPPara
* > plist
;
603 hwpf
->ReadParaList(plist
);
604 hwpf
->SetIODevice(hio
);
606 return plist
.size()? plist
.front() : 0;
611 HWPDOTextBoxFunc(int type
, HWPDrawingObject
* hdo
,
612 int cmd
, void *argp
, int argv
)
617 if (ReadSizeField(0) < 0 || !SkipUnusedField())
618 return OBJRET_FILE_ERROR
;
619 if (ReadSizeField(0) < 0)
620 return OBJRET_FILE_ERROR
;
621 hdo
->u
.textbox
.h
= LoadParaList();
622 return hdo
->u
.textbox
.h
? OBJRET_FILE_OK
: OBJRET_FILE_ERROR
;
624 if (hdo
->u
.textbox
.h
)
626 FreeParaList(hdo
->u
.textbox
.h
);
627 hdo
->u
.textbox
.h
= NULL
;
631 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
639 HWPDOContainerFunc(int type
, HWPDrawingObject
* hdo
,
640 int cmd
, void *argp
, int argv
)
642 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
646 HWPDrawingObject::HWPDrawingObject()
648 memset(this, 0, sizeof(HWPDrawingObject
));
653 HWPDrawingObject::~HWPDrawingObject()
661 HWPDOFunc(this, OBJFUNC_FREE
, NULL
, 0);
665 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */