1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
32 #include "precompile.h"
37 #include <osl/diagnose.h>
39 #include <comphelper/newarray.hxx>
57 BEGIN_GRADATION
= 0, LINEAR
, RADIAL
, CONICAL
, SQUARE
,
58 END_GRADATION
, BITMAP_PATTERN
61 #define OBJRET_FILE_OK 0
62 #define OBJRET_FILE_ERROR (-1)
63 #define OBJRET_FILE_NO_PRIVATE_BLOCK (-2)
64 #define OBJRET_FILE_NO_PRIVATE_BLOCK_2 (-3)
66 typedef int (*HWPDOFuncType
) (int, HWPDrawingObject
*, int, void *, int);
68 #define HWPDOFunc(hdo, cmd, argp, argv) \
69 (HWPDOFuncTbl[(hdo)->type]((hdo)->type, (hdo), (cmd), (argp), (argv)))
70 #define HWPDOFunc2(type, cmd, argp, argv) \
71 (HWPDOFuncTbl[(type)]((type), NULL, (cmd), (argp), (argv)))
73 static int HWPDOLineFunc(int, HWPDrawingObject
*, int, void *, int);
74 static int HWPDORectFunc(int, HWPDrawingObject
*, int, void *, int);
75 static int HWPDOEllipseFunc(int, HWPDrawingObject
*, int, void *, int);
76 static int HWPDOArcFunc(int, HWPDrawingObject
*, int, void *, int);
77 static int HWPDOFreeFormFunc(int, HWPDrawingObject
*, int, void *, int);
78 static int HWPDOTextBoxFunc(int, HWPDrawingObject
*, int, void *, int);
79 static int HWPDOEllipse2Func(int, HWPDrawingObject
*, int, void *, int);
80 static int HWPDOArc2Func(int, HWPDrawingObject
*, int, void *, int);
81 static int HWPDOContainerFunc(int, HWPDrawingObject
*, int, void *, int);
82 static HWPPara
*LoadParaList();
84 HWPDOFuncType HWPDOFuncTbl
[] =
99 static HMemIODev
*hmem
= 0;
101 static int count
= 0;
103 inline bool HAVE_FCOLOR(HWPDrawingObject
* hdo
)
105 return hdo
->property
.fill_color
!= HWPDO_COLOR_NONE
;
109 inline bool HAVE_PATTERN(HWPDrawingObject
* hdo
)
111 return (hdo
->property
.pattern_type
& HWPDO_PAT_TYPE_BITS
)
112 != HWPDO_PAT_SOLID
&& hdo
->property
.pattern_color
!= HWPDO_COLOR_NONE
;
116 inline bool HAVE_GRADATION(HWPDrawingObject
* hdo
)
118 return hdo
->property
.gstyle
> BEGIN_GRADATION
&&
119 hdo
->property
.gstyle
< END_GRADATION
&&
120 hdo
->property
.fromcolor
!= HWPDO_COLOR_NONE
&&
121 hdo
->property
.tocolor
!= HWPDO_COLOR_NONE
;
125 inline bool HAVE_BITMAP_PATTERN(HWPDrawingObject
* hdo
)
127 return hdo
->property
.gstyle
== BITMAP_PATTERN
&&
128 hdo
->property
.szPatternFile
[0];
132 inline bool HAS_PAT(HWPDrawingObject
* hdo
)
134 return HAVE_FCOLOR(hdo
) || HAVE_PATTERN(hdo
) ||
135 HAVE_GRADATION(hdo
) || HAVE_BITMAP_PATTERN(hdo
);
139 static void SetHdoParallRgn(HWPDrawingObject
* hdo
, int width
, int height
)
141 hdo
->property
.parall
.pt
[0].x
= 0;
142 hdo
->property
.parall
.pt
[0].y
= 0;
143 hdo
->property
.parall
.pt
[1].x
= width
;
144 hdo
->property
.parall
.pt
[1].y
= 0;
145 hdo
->property
.parall
.pt
[2].x
= width
;
146 hdo
->property
.parall
.pt
[2].y
= height
;
150 static bool SkipPrivateBlock(int type
)
154 if (type
== OBJRET_FILE_NO_PRIVATE_BLOCK
)
157 if (hmem
->state() || hmem
->skipBlock(n
) != n
)
163 return hmem
->skipBlock(n
) == n
;
167 static int SizeExpected
;
170 static int ReadSizeField(int size
)
173 SizeRead
= hmem
->read4b();
180 static bool SkipUnusedField(void)
182 return (SizeExpected
< SizeRead
) ?
183 hmem
->skipBlock(SizeRead
- SizeExpected
) != 0 : true;
187 #define HDOFILE_HEADER_SIZE (2*4+16) // 16=sizeof(ZZRect)
188 #define HDOFILE_COMMON_SIZE (7*4+16+44)
190 #define HDOFILE_HAS_NEXT 0x01
191 #define HDOFILE_HAS_CHILD 0x02
193 static bool LoadCommonHeader(HWPDrawingObject
* hdo
, WORD
* link_info
)
195 uint size
, common_size
;
199 size
= hmem
->read4b();
204 if (size
< HDOFILE_COMMON_SIZE
)
209 common_size
= HDOFILE_COMMON_SIZE
;
210 hdo
->type
= hmem
->read2b();
211 *link_info
= sal::static_int_cast
<WORD
>(hmem
->read2b());
212 hdo
->offset
.x
= hmem
->read4b();
213 hdo
->offset
.y
= hmem
->read4b();
214 hdo
->extent
.w
= hmem
->read4b();
215 hdo
->extent
.h
= hmem
->read4b();
216 hdo
->offset2
.x
= hmem
->read4b();
217 hdo
->offset2
.y
= hmem
->read4b();
222 hdo
->vrect
.x
= hmem
->read4b();
223 hdo
->vrect
.y
= hmem
->read4b();
224 hdo
->vrect
.w
= hmem
->read4b();
225 hdo
->vrect
.h
= hmem
->read4b();
227 // read bare property 44 bytes
228 hdo
->property
.line_pstyle
= hmem
->read4b();
229 hdo
->property
.line_hstyle
= hmem
->read4b();
230 hdo
->property
.line_tstyle
= hmem
->read4b();
231 hdo
->property
.line_color
= hmem
->read4b();
232 hdo
->property
.line_width
= (hunit
) hmem
->read4b();
233 hdo
->property
.fill_color
= hmem
->read4b();
234 hdo
->property
.pattern_type
= hmem
->read4b();
235 hdo
->property
.pattern_color
= hmem
->read4b();
236 hdo
->property
.hmargin
= (hunit
) hmem
->read4b();
237 hdo
->property
.vmargin
= (hunit
) hmem
->read4b();
238 hdo
->property
.flag
= hmem
->read4b();
239 // read ratation property 32 bytes
240 if ((size
>= common_size
+ 32)
241 && (hdo
->property
.flag
& HWPDO_FLAG_ROTATION
))
243 hdo
->property
.rot_originx
= hmem
->read4b();
244 hdo
->property
.rot_originy
= hmem
->read4b();
245 for (int ii
= 0; ii
< 3; ii
++)
247 hdo
->property
.parall
.pt
[ii
].x
= hmem
->read4b();
248 hdo
->property
.parall
.pt
[ii
].y
= hmem
->read4b();
253 SetHdoParallRgn(hdo
, hdo
->extent
.w
, hdo
->extent
.h
);
255 // read gradient property 28 bytes
256 if ((size
>= common_size
+ 28) &&
257 (hdo
->property
.flag
& HWPDO_FLAG_GRADATION
))
259 hdo
->property
.fromcolor
= hmem
->read4b();
260 hdo
->property
.tocolor
= hmem
->read4b();
261 hdo
->property
.gstyle
= hmem
->read4b();
262 hdo
->property
.angle
= hmem
->read4b();
263 hdo
->property
.center_x
= hmem
->read4b();
264 hdo
->property
.center_y
= hmem
->read4b();
265 hdo
->property
.nstep
= hmem
->read4b();
269 // read bitmap property 278 bytes
270 if ((size
>= common_size
+ 278) && \
271 (hdo
->property
.flag
& HWPDO_FLAG_BITMAP
))
273 hdo
->property
.offset1
.x
= hmem
->read4b();
274 hdo
->property
.offset1
.y
= hmem
->read4b();
275 hdo
->property
.offset2
.x
= hmem
->read4b();
276 hdo
->property
.offset2
.y
= hmem
->read4b();
277 if (!hmem
->readBlock(hdo
->property
.szPatternFile
, 261))
279 hdo
->property
.pictype
= sal::static_int_cast
<char>(hmem
->read1b());
282 if( ( size
>= common_size
+ 3 ) && ( hdo
->property
.flag
& HWPDO_FLAG_WATERMARK
) )
283 //if( ( size >= common_size ) && ( hdo->property.flag >> 20 & 0x01 ) )
285 if( size
- common_size
>= 5 )
286 hmem
->skipBlock( 2 );
287 hdo
->property
.luminance
= hmem
->read1b();
288 hdo
->property
.contrast
= hmem
->read1b();
289 hdo
->property
.greyscale
= hmem
->read1b();
293 hdo
->property
.luminance
= 0;
294 hdo
->property
.contrast
= 0;
295 hdo
->property
.greyscale
= 0;
297 hdo
->property
.pPara
= 0L;
299 if( ( size
> common_size
) && (hdo
->property
.flag
& HWPDO_FLAG_AS_TEXTBOX
) )
302 hdo
->property
.pPara
= LoadParaList();
303 if( hdo
->property
.pPara
)
309 if( size
<= common_size
)
311 return hmem
->skipBlock(size
- common_size
) != 0;
315 static HWPDrawingObject
*LoadDrawingObject(void)
317 HWPDrawingObject
*hdo
, *head
, *prev
;
325 if ((hdo
= new HWPDrawingObject
) == NULL
)
329 if (!LoadCommonHeader(hdo
, &link_info
))
333 if (hdo
->type
< 0 || hdo
->type
>= HWPDO_NITEMS
)
335 hdo
->type
= HWPDO_RECT
;
336 if (!SkipPrivateBlock(OBJRET_FILE_NO_PRIVATE_BLOCK
))
343 switch (res
= HWPDOFunc(hdo
, OBJFUNC_LOAD
, NULL
, 0))
345 case OBJRET_FILE_ERROR
:
349 case OBJRET_FILE_NO_PRIVATE_BLOCK
:
350 case OBJRET_FILE_NO_PRIVATE_BLOCK_2
:
351 if (!SkipPrivateBlock(res
))
356 if (link_info
& HDOFILE_HAS_CHILD
)
358 hdo
->child
= LoadDrawingObject();
359 if (hdo
->child
== NULL
)
370 while (link_info
& HDOFILE_HAS_NEXT
);
374 // drawing object can be list.
375 // hdo = current item, head = list;
379 HWPDOFunc(hdo
, OBJFUNC_FREE
, NULL
, 0);
392 static bool LoadDrawingObjectBlock(Picture
* pic
)
394 int size
= hmem
->read4b();
396 if (hmem
->state() || size
< HDOFILE_HEADER_SIZE
)
399 pic
->picinfo
.picdraw
.zorder
= hmem
->read4b();
400 pic
->picinfo
.picdraw
.mbrcnt
= hmem
->read4b();
401 pic
->picinfo
.picdraw
.vrect
.x
= hmem
->read4b();
402 pic
->picinfo
.picdraw
.vrect
.y
= hmem
->read4b();
403 pic
->picinfo
.picdraw
.vrect
.w
= hmem
->read4b();
404 pic
->picinfo
.picdraw
.vrect
.h
= hmem
->read4b();
406 if (size
> HDOFILE_HEADER_SIZE
&&
407 !hmem
->skipBlock(size
- HDOFILE_HEADER_SIZE
))
410 pic
->picinfo
.picdraw
.hdo
= LoadDrawingObject();
411 if (pic
->picinfo
.picdraw
.hdo
== 0)
417 // object manipulation function
420 HWPDODefaultFunc(int , HWPDrawingObject
* , int cmd
, void *, int)
422 if (cmd
== OBJFUNC_LOAD
)
423 return OBJRET_FILE_NO_PRIVATE_BLOCK
;
429 HWPDOLineFunc(int type
, HWPDrawingObject
* hdo
, int cmd
, void *argp
, int argv
)
435 if (ReadSizeField(4) < 4)
436 return OBJRET_FILE_ERROR
;
437 hdo
->u
.line_arc
.flip
= hmem
->read4b();
439 return OBJRET_FILE_ERROR
;
440 if (!SkipUnusedField())
441 return OBJRET_FILE_ERROR
;
442 ret
= OBJRET_FILE_NO_PRIVATE_BLOCK_2
;
445 ret
= HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
455 HWPDORectFunc(int type
, HWPDrawingObject
* hdo
, int cmd
, void *argp
, int argv
)
457 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
464 HWPDOEllipseFunc(int type
, HWPDrawingObject
* hdo
,
465 int cmd
, void *argp
, int argv
)
467 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
470 #define WTMM(x) ((double)(x) / 1800. * 25.4)
472 HWPDOEllipse2Func(int type
, HWPDrawingObject
* hdo
,
473 int cmd
, void *argp
, int argv
)
478 if (ReadSizeField(16) < 16)
479 return OBJRET_FILE_ERROR
;
480 hdo
->u
.arc
.radial
[0].x
= hmem
->read4b();
481 hdo
->u
.arc
.radial
[0].y
= hmem
->read4b();
482 hdo
->u
.arc
.radial
[1].x
= hmem
->read4b();
483 hdo
->u
.arc
.radial
[1].y
= hmem
->read4b();
485 if (ReadSizeField(0) < 0)
486 return OBJRET_FILE_ERROR
;
489 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
498 HWPDOArcFunc(int type
, HWPDrawingObject
* hdo
, int cmd
, void *argp
, int argv
)
503 if (ReadSizeField(4) < 4)
504 return OBJRET_FILE_ERROR
;
505 hdo
->u
.line_arc
.flip
= hmem
->read4b();
507 return OBJRET_FILE_ERROR
;
508 if (!SkipUnusedField())
509 return OBJRET_FILE_ERROR
;
512 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
519 HWPDOArc2Func(int type
, HWPDrawingObject
* hdo
, int cmd
, void *argp
, int argv
)
525 ret
= OBJRET_FILE_NO_PRIVATE_BLOCK
;
528 ret
= HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
536 HWPDOFreeFormFunc(int type
, HWPDrawingObject
* hdo
,
537 int cmd
, void *argp
, int argv
)
543 hdo
->u
.freeform
.pt
= 0;
544 if (ReadSizeField(4) < 4)
545 return OBJRET_FILE_ERROR
;
546 hdo
->u
.freeform
.npt
= hmem
->read4b();
548 return OBJRET_FILE_ERROR
;
549 if (!SkipUnusedField())
550 return OBJRET_FILE_ERROR
;
552 int size
= hdo
->u
.freeform
.npt
* sizeof(ZZPoint
);
554 if (ReadSizeField(size
) < size
)
555 return OBJRET_FILE_ERROR
;
556 if (hdo
->u
.freeform
.npt
)
559 ::comphelper::newArray_null
<ZZPoint
>(hdo
->u
.freeform
.npt
);
560 if (hdo
->u
.freeform
.pt
== NULL
)
562 hdo
->u
.freeform
.npt
= 0;
563 return OBJRET_FILE_ERROR
;
565 for (int ii
= 0; ii
< hdo
->u
.freeform
.npt
; ii
++)
567 hdo
->u
.freeform
.pt
[ii
].x
= hmem
->read4b();
568 hdo
->u
.freeform
.pt
[ii
].y
= hmem
->read4b();
571 delete[]hdo
->u
.freeform
.pt
;
572 hdo
->u
.freeform
.npt
= 0;
573 return OBJRET_FILE_ERROR
;
577 if (!SkipUnusedField())
578 return OBJRET_FILE_ERROR
;
579 return OBJRET_FILE_OK
;
582 if (hdo
->u
.freeform
.pt
)
583 delete[]hdo
->u
.freeform
.pt
;
586 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
594 static void FreeParaList(HWPPara
* para
)
597 FreeParaList(para
->Next());
602 static HWPPara
*LoadParaList()
607 HWPFile
*hwpf
= GetCurrentDoc();
608 HIODev
*hio
= hwpf
->SetIODevice(hmem
);
610 std::list
< HWPPara
* > plist
;
612 hwpf
->ReadParaList(plist
);
613 hwpf
->SetIODevice(hio
);
615 return plist
.size()? plist
.front() : 0;
620 HWPDOTextBoxFunc(int type
, HWPDrawingObject
* hdo
,
621 int cmd
, void *argp
, int argv
)
626 if (ReadSizeField(0) < 0 || !SkipUnusedField())
627 return OBJRET_FILE_ERROR
;
628 if (ReadSizeField(0) < 0)
629 return OBJRET_FILE_ERROR
;
630 hdo
->u
.textbox
.h
= LoadParaList();
631 return hdo
->u
.textbox
.h
? OBJRET_FILE_OK
: OBJRET_FILE_ERROR
;
633 if (hdo
->u
.textbox
.h
)
635 FreeParaList(hdo
->u
.textbox
.h
);
636 hdo
->u
.textbox
.h
= NULL
;
640 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
648 HWPDOContainerFunc(int type
, HWPDrawingObject
* hdo
,
649 int cmd
, void *argp
, int argv
)
651 return HWPDODefaultFunc(type
, hdo
, cmd
, argp
, argv
);
655 HWPDrawingObject::HWPDrawingObject()
657 memset(this, 0, sizeof(HWPDrawingObject
));
662 HWPDrawingObject::~HWPDrawingObject()
665 if (hdo
->property
.pictype
== PICTYP_EMBED
)
666 RemoveEmbeddedPic(hdo
->property
.szPatternFile
);
667 hdo
->property
.szPatternFile
[0] = 0;
675 HWPDOFunc(this, OBJFUNC_FREE
, NULL
, 0);
679 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */