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 .
20 #ifndef INCLUDED_HWPFILTER_SOURCE_DRAWING_H
21 #define INCLUDED_HWPFILTER_SOURCE_DRAWING_H
23 #include "precompile.h"
27 #include <osl/diagnose.h>
29 #include <comphelper/newarray.hxx>
47 BEGIN_GRADATION
= 0, LINEAR
, RADIAL
, CONICAL
, SQUARE
,
48 END_GRADATION
, BITMAP_PATTERN
51 #define OBJRET_FILE_OK 0
52 #define OBJRET_FILE_ERROR (-1)
53 #define OBJRET_FILE_NO_PRIVATE_BLOCK (-2)
54 #define OBJRET_FILE_NO_PRIVATE_BLOCK_2 (-3)
56 typedef int (*HWPDOFuncType
) (int, HWPDrawingObject
*, int, void *, int);
58 #define HWPDOFunc(hdo, cmd, argp, argv) \
59 (HWPDOFuncTbl[(hdo)->type]((hdo)->type, (hdo), (cmd), (argp), (argv)))
61 static int HWPDOLineFunc(int, HWPDrawingObject
*, int, void *, int);
62 static int HWPDORectFunc(int, HWPDrawingObject
*, int, void *, int);
63 static int HWPDOEllipseFunc(int, HWPDrawingObject
*, int, void *, int);
64 static int HWPDOArcFunc(int, HWPDrawingObject
*, int, void *, int);
65 static int HWPDOFreeFormFunc(int, HWPDrawingObject
*, int, void *, int);
66 static int HWPDOTextBoxFunc(int, HWPDrawingObject
*, int, void *, int);
67 static int HWPDOEllipse2Func(int, HWPDrawingObject
*, int, void *, int);
68 static int HWPDOArc2Func(int, HWPDrawingObject
*, int, void *, int);
69 static int HWPDOContainerFunc(int, HWPDrawingObject
*, int, void *, int);
70 static HWPPara
*LoadParaList();
72 HWPDOFuncType HWPDOFuncTbl
[] =
87 static HIODev
*hmem
= nullptr;
91 static void SetHdoParallRgn(HWPDrawingObject
* hdo
, int width
, int height
)
93 hdo
->property
.parall
.pt
[0].x
= 0;
94 hdo
->property
.parall
.pt
[0].y
= 0;
95 hdo
->property
.parall
.pt
[1].x
= width
;
96 hdo
->property
.parall
.pt
[1].y
= 0;
97 hdo
->property
.parall
.pt
[2].x
= width
;
98 hdo
->property
.parall
.pt
[2].y
= height
;
101 static bool SkipPrivateBlock(int type
)
105 if (type
== OBJRET_FILE_NO_PRIVATE_BLOCK
)
107 if (!hmem
->read4b(n
))
109 if (hmem
->state() || hmem
->skipBlock(n
) != static_cast<size_t>(n
))
112 if (!hmem
->read4b(n
))
116 return hmem
->skipBlock(n
) == static_cast<size_t>(n
);
119 static int SizeExpected
;
122 static int ReadSizeField(int size
)
125 if (!hmem
->read4b(SizeRead
))
132 static bool SkipUnusedField(void)
134 return (SizeExpected
>= SizeRead
) &&
135 hmem
->skipBlock(SizeRead
- SizeExpected
) != 0;
139 #define HDOFILE_HEADER_SIZE (2*4+16) // 16=sizeof(ZZRect)
140 #define HDOFILE_COMMON_SIZE (7*4+16+44)
142 #define HDOFILE_HAS_NEXT 0x01
143 #define HDOFILE_HAS_CHILD 0x02
145 static bool LoadCommonHeader(HWPDrawingObject
* hdo
, unsigned short * link_info
)
147 uint size
, common_size
;
151 if (!hmem
->read4b(size
))
155 if (size
< HDOFILE_COMMON_SIZE
)
158 common_size
= HDOFILE_COMMON_SIZE
;
159 unsigned short tmp16
;
160 if (!hmem
->read2b(tmp16
))
163 if (!hmem
->read2b(tmp16
))
166 if (!hmem
->read4b(hdo
->offset
.x
))
168 if (!hmem
->read4b(hdo
->offset
.y
))
170 if (!hmem
->read4b(hdo
->extent
.w
))
172 if (!hmem
->read4b(hdo
->extent
.h
))
174 if (!hmem
->read4b(hdo
->offset2
.x
))
176 if (!hmem
->read4b(hdo
->offset2
.y
))
182 if (!hmem
->read4b(hdo
->vrect
.x
))
184 if (!hmem
->read4b(hdo
->vrect
.y
))
186 if (!hmem
->read4b(hdo
->vrect
.w
))
188 if (!hmem
->read4b(hdo
->vrect
.h
))
191 // read bare property 44 bytes
192 if (!hmem
->read4b(hdo
->property
.line_pstyle
))
194 if (!hmem
->read4b(hdo
->property
.line_hstyle
))
196 if (!hmem
->read4b(hdo
->property
.line_tstyle
))
198 if (!hmem
->read4b(hdo
->property
.line_color
))
201 if (!hmem
->read4b(tmp32
))
203 hdo
->property
.line_width
= static_cast<hunit
>(tmp32
);
204 if (!hmem
->read4b(hdo
->property
.fill_color
))
206 if (!hmem
->read4b(hdo
->property
.pattern_type
))
208 if (!hmem
->read4b(hdo
->property
.pattern_color
))
210 if (!hmem
->read4b(tmp32
))
212 hdo
->property
.hmargin
= static_cast<hunit
>(tmp32
);
213 if (!hmem
->read4b(tmp32
))
215 hdo
->property
.vmargin
= static_cast<hunit
>(tmp32
);
216 if (!hmem
->read4b(hdo
->property
.flag
))
218 // read rotation property 32 bytes
219 if ((size
>= common_size
+ 32)
220 && (hdo
->property
.flag
& HWPDO_FLAG_ROTATION
))
222 if (!hmem
->read4b(hdo
->property
.rot_originx
))
224 if (!hmem
->read4b(hdo
->property
.rot_originy
))
226 for (int ii
= 0; ii
< 3; ++ii
)
228 if (!hmem
->read4b(hdo
->property
.parall
.pt
[ii
].x
))
230 if (!hmem
->read4b(hdo
->property
.parall
.pt
[ii
].y
))
236 SetHdoParallRgn(hdo
, hdo
->extent
.w
, hdo
->extent
.h
);
238 // read gradient property 28 bytes
239 if ((size
>= common_size
+ 28) &&
240 (hdo
->property
.flag
& HWPDO_FLAG_GRADATION
))
242 if (!hmem
->read4b(hdo
->property
.fromcolor
))
244 if (!hmem
->read4b(hdo
->property
.tocolor
))
246 if (!hmem
->read4b(hdo
->property
.gstyle
))
248 if (!hmem
->read4b(hdo
->property
.angle
))
250 if (!hmem
->read4b(hdo
->property
.center_x
))
252 if (!hmem
->read4b(hdo
->property
.center_y
))
254 if (!hmem
->read4b(hdo
->property
.nstep
))
259 // read bitmap property 278 bytes
260 if ((size
>= common_size
+ 278) && \
261 (hdo
->property
.flag
& HWPDO_FLAG_BITMAP
))
263 if (!hmem
->read4b(hdo
->property
.offset1
.x
))
265 if (!hmem
->read4b(hdo
->property
.offset1
.y
))
267 if (!hmem
->read4b(hdo
->property
.offset2
.x
))
269 if (!hmem
->read4b(hdo
->property
.offset2
.y
))
271 if (!hmem
->readBlock(hdo
->property
.szPatternFile
, 261))
273 if (!hmem
->read1b(hdo
->property
.pictype
))
277 if( ( size
>= common_size
+ 3 ) && ( hdo
->property
.flag
& HWPDO_FLAG_WATERMARK
) )
278 //if( ( size >= common_size ) && ( hdo->property.flag >> 20 & 0x01 ) )
280 if (size
- common_size
>= 5)
283 if (!hmem
->read1b(tmp8
))
285 hdo
->property
.luminance
= tmp8
;
286 if (!hmem
->read1b(tmp8
))
288 hdo
->property
.contrast
= tmp8
;
289 if (!hmem
->read1b(tmp8
))
291 hdo
->property
.greyscale
= tmp8
;
297 hdo
->property
.luminance
= 0;
298 hdo
->property
.contrast
= 0;
299 hdo
->property
.greyscale
= 0;
301 hdo
->property
.pPara
= nullptr;
303 if( ( size
> common_size
) && (hdo
->property
.flag
& HWPDO_FLAG_AS_TEXTBOX
) )
306 hdo
->property
.pPara
= LoadParaList();
307 if( hdo
->property
.pPara
)
313 if (size
<= common_size
)
315 return hmem
->skipBlock(size
- common_size
) != 0;
318 static std::unique_ptr
<HWPDrawingObject
> LoadDrawingObject(HWPFile
& hwpf
)
320 HWPDrawingObject
*prev
= nullptr;
321 std::unique_ptr
<HWPDrawingObject
> hdo
, head
;
323 unsigned short link_info
;
327 hdo
.reset(new HWPDrawingObject
);
328 if (!LoadCommonHeader(hdo
.get(), &link_info
))
332 if (hdo
->type
< 0 || hdo
->type
>= HWPDO_NITEMS
)
334 hdo
->type
= HWPDO_RECT
;
335 if (!SkipPrivateBlock(OBJRET_FILE_NO_PRIVATE_BLOCK
))
342 switch (int res
= HWPDOFunc(hdo
.get(), OBJFUNC_LOAD
, nullptr, 0))
344 case OBJRET_FILE_ERROR
:
348 case OBJRET_FILE_NO_PRIVATE_BLOCK
:
349 case OBJRET_FILE_NO_PRIVATE_BLOCK_2
:
350 if (!SkipPrivateBlock(res
))
355 if (link_info
& HDOFILE_HAS_CHILD
)
357 hdo
->child
= LoadDrawingObject(hwpf
);
358 if (hdo
->child
== nullptr)
365 head
= std::move(hdo
);
370 prev
->next
= std::move(hdo
);
371 prev
= prev
->next
.get();
374 while (link_info
& HDOFILE_HAS_NEXT
);
379 // drawing object can be list.
380 // hdo = current item, head = list;
382 if (hdo
->type
< 0 || hdo
->type
>= HWPDO_NITEMS
)
384 hdo
->type
= HWPDO_RECT
;
386 if (hdo
->property
.pPara
)
388 HWPPara
* pPara
= hdo
->property
.pPara
;
391 HWPPara
* pNextPara
= pPara
->Next();
392 hwpf
.move_to_failed(std::unique_ptr
<HWPPara
>(pPara
));
395 hdo
->property
.pPara
= nullptr;
397 HWPDOFunc(hdo
.get(), OBJFUNC_FREE
, nullptr, 0);
402 prev
->next
= nullptr;
410 static bool LoadDrawingObjectBlock(Picture
* pic
, HWPFile
& hwpf
)
413 if (!hmem
->read4b(size
))
416 if (hmem
->state() || size
< HDOFILE_HEADER_SIZE
)
419 if (!hmem
->read4b(pic
->picinfo
.picdraw
.zorder
))
421 if (!hmem
->read4b(pic
->picinfo
.picdraw
.mbrcnt
))
423 if (!hmem
->read4b(pic
->picinfo
.picdraw
.vrect
.x
))
425 if (!hmem
->read4b(pic
->picinfo
.picdraw
.vrect
.y
))
427 if (!hmem
->read4b(pic
->picinfo
.picdraw
.vrect
.w
))
429 if (!hmem
->read4b(pic
->picinfo
.picdraw
.vrect
.h
))
432 if (size
> HDOFILE_HEADER_SIZE
&&
433 !hmem
->skipBlock(size
- HDOFILE_HEADER_SIZE
))
436 pic
->picinfo
.picdraw
.hdo
= LoadDrawingObject(hwpf
).release();
437 if (pic
->picinfo
.picdraw
.hdo
== nullptr)
442 // object manipulation function
444 HWPDODefaultFunc(int cmd
)
446 if (cmd
== OBJFUNC_LOAD
)
447 return OBJRET_FILE_NO_PRIVATE_BLOCK
;
448 return OBJRET_FILE_OK
;
452 HWPDOLineFunc(int /*type*/, HWPDrawingObject
* hdo
, int cmd
, void * /*argp*/, int /*argv*/)
454 int ret
= OBJRET_FILE_OK
;
458 if (ReadSizeField(4) < 4)
459 return OBJRET_FILE_ERROR
;
460 if (!hmem
->read4b(hdo
->u
.line_arc
.flip
))
461 return OBJRET_FILE_ERROR
;
463 return OBJRET_FILE_ERROR
;
464 if (!SkipUnusedField())
465 return OBJRET_FILE_ERROR
;
466 ret
= OBJRET_FILE_NO_PRIVATE_BLOCK_2
;
469 ret
= HWPDODefaultFunc(cmd
);
479 HWPDORectFunc(int /*type*/, HWPDrawingObject
* /*hdo*/, int cmd
, void * /*argp*/, int /*argv*/)
481 return HWPDODefaultFunc(cmd
);
488 HWPDOEllipseFunc(int /*type*/, HWPDrawingObject
* /*hdo*/,
489 int cmd
, void * /*argp*/, int /*argv*/)
491 return HWPDODefaultFunc(cmd
);
495 HWPDOEllipse2Func(int /*type*/, HWPDrawingObject
* hdo
,
496 int cmd
, void * /*argp*/, int /*argv*/)
501 if (ReadSizeField(16) < 16)
502 return OBJRET_FILE_ERROR
;
503 if (!hmem
->read4b(hdo
->u
.arc
.radial
[0].x
))
504 return OBJRET_FILE_ERROR
;
505 if (!hmem
->read4b(hdo
->u
.arc
.radial
[0].y
))
506 return OBJRET_FILE_ERROR
;
507 if (!hmem
->read4b(hdo
->u
.arc
.radial
[1].x
))
508 return OBJRET_FILE_ERROR
;
509 if (!hmem
->read4b(hdo
->u
.arc
.radial
[1].y
))
510 return OBJRET_FILE_ERROR
;
511 if (ReadSizeField(0) < 0)
512 return OBJRET_FILE_ERROR
;
515 return HWPDODefaultFunc(cmd
);
517 return OBJRET_FILE_OK
;
524 HWPDOArcFunc(int /*type*/, HWPDrawingObject
* hdo
, int cmd
, void * /*argp*/, int /*argv*/)
529 if (ReadSizeField(4) < 4)
530 return OBJRET_FILE_ERROR
;
531 if (!hmem
->read4b(hdo
->u
.line_arc
.flip
))
532 return OBJRET_FILE_ERROR
;
534 return OBJRET_FILE_ERROR
;
535 if (!SkipUnusedField())
536 return OBJRET_FILE_ERROR
;
539 return HWPDODefaultFunc(cmd
);
541 return OBJRET_FILE_OK
;
546 HWPDOArc2Func(int /*type*/, HWPDrawingObject
* /*hdo*/, int cmd
, void * /*argp*/, int /*argv*/)
548 int ret
= OBJRET_FILE_OK
;
552 ret
= OBJRET_FILE_NO_PRIVATE_BLOCK
;
555 ret
= HWPDODefaultFunc(cmd
);
563 HWPDOFreeFormFunc(int /*type*/, HWPDrawingObject
* hdo
,
564 int cmd
, void * /*argp*/, int /*argv*/)
570 hdo
->u
.freeform
.pt
= nullptr;
571 if (ReadSizeField(4) < 4)
572 return OBJRET_FILE_ERROR
;
573 if (!hmem
->read4b(hdo
->u
.freeform
.npt
))
574 return OBJRET_FILE_ERROR
;
576 return OBJRET_FILE_ERROR
;
577 if (!SkipUnusedField())
578 return OBJRET_FILE_ERROR
;
580 int size
= hdo
->u
.freeform
.npt
* sizeof(ZZPoint
);
582 if (ReadSizeField(size
) < size
)
583 return OBJRET_FILE_ERROR
;
584 if (hdo
->u
.freeform
.npt
)
587 ::comphelper::newArray_null
<ZZPoint
>(hdo
->u
.freeform
.npt
);
588 if (hdo
->u
.freeform
.pt
== nullptr)
590 hdo
->u
.freeform
.npt
= 0;
591 return OBJRET_FILE_ERROR
;
593 for (int ii
= 0; ii
< hdo
->u
.freeform
.npt
; ++ii
)
595 bool bFailure
= false;
596 if (!hmem
->read4b(hdo
->u
.freeform
.pt
[ii
].x
))
598 if (!hmem
->read4b(hdo
->u
.freeform
.pt
[ii
].y
))
604 delete[]hdo
->u
.freeform
.pt
;
605 hdo
->u
.freeform
.npt
= 0;
606 return OBJRET_FILE_ERROR
;
610 if (!SkipUnusedField())
611 return OBJRET_FILE_ERROR
;
612 return OBJRET_FILE_OK
;
615 if (hdo
->u
.freeform
.pt
)
616 delete[]hdo
->u
.freeform
.pt
;
619 return HWPDODefaultFunc(cmd
);
621 return OBJRET_FILE_OK
;
627 static void FreeParaList(HWPPara
* para
)
630 FreeParaList(para
->Next());
635 static HWPPara
*LoadParaList()
640 HWPFile
*hwpf
= GetCurrentDoc();
641 std::unique_ptr
<HIODev
> hio
= hwpf
->SetIODevice(std::unique_ptr
<HIODev
>(hmem
));
643 std::vector
< HWPPara
* > plist
;
645 hwpf
->ReadParaList(plist
);
646 std::unique_ptr
<HIODev
> orighmem
= hwpf
->SetIODevice(std::move(hio
));
647 hmem
= orighmem
.release();
649 return plist
.size()? plist
.front() : nullptr;
654 HWPDOTextBoxFunc(int /*type*/, HWPDrawingObject
* hdo
,
655 int cmd
, void * /*argp*/, int /*argv*/)
660 if (ReadSizeField(0) < 0 || !SkipUnusedField())
661 return OBJRET_FILE_ERROR
;
662 if (ReadSizeField(0) < 0)
663 return OBJRET_FILE_ERROR
;
664 hdo
->u
.textbox
.h
= LoadParaList();
665 return hdo
->u
.textbox
.h
? OBJRET_FILE_OK
: OBJRET_FILE_ERROR
;
667 if (hdo
->u
.textbox
.h
)
669 FreeParaList(hdo
->u
.textbox
.h
);
670 hdo
->u
.textbox
.h
= nullptr;
674 return HWPDODefaultFunc(cmd
);
676 return OBJRET_FILE_OK
;
682 HWPDOContainerFunc(int /*type*/, HWPDrawingObject
* /*hdo*/,
683 int cmd
, void * /*argp*/, int /*argv*/)
685 return HWPDODefaultFunc(cmd
);
689 HWPDrawingObject::HWPDrawingObject():
690 type(0), offset
{0, 0}, offset2
{0, 0}, extent
{0, 0}, vrect
{0, 0, 0, 0}
692 memset(&property
, 0, sizeof property
);
693 memset(&u
, 0, sizeof u
);
698 HWPDrawingObject::~HWPDrawingObject()
701 FreeParaList(property
.pPara
);
703 HWPDOFunc(this, OBJFUNC_FREE
, nullptr, 0);
707 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */