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"
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)))
62 static int HWPDOLineFunc(int, HWPDrawingObject
*, int, void *, int);
63 static int HWPDORectFunc(int, HWPDrawingObject
*, int, void *, int);
64 static int HWPDOEllipseFunc(int, HWPDrawingObject
*, int, void *, int);
65 static int HWPDOArcFunc(int, HWPDrawingObject
*, int, void *, int);
66 static int HWPDOFreeFormFunc(int, HWPDrawingObject
*, int, void *, int);
67 static int HWPDOTextBoxFunc(int, HWPDrawingObject
*, int, void *, int);
68 static int HWPDOEllipse2Func(int, HWPDrawingObject
*, int, void *, int);
69 static int HWPDOArc2Func(int, HWPDrawingObject
*, int, void *, int);
70 static int HWPDOContainerFunc(int, HWPDrawingObject
*, int, void *, int);
71 static HWPPara
*LoadParaList();
73 HWPDOFuncType HWPDOFuncTbl
[] =
88 static HIODev
*hmem
= nullptr;
92 static void SetHdoParallRgn(HWPDrawingObject
* hdo
, int width
, int height
)
94 hdo
->property
.parall
.pt
[0].x
= 0;
95 hdo
->property
.parall
.pt
[0].y
= 0;
96 hdo
->property
.parall
.pt
[1].x
= width
;
97 hdo
->property
.parall
.pt
[1].y
= 0;
98 hdo
->property
.parall
.pt
[2].x
= width
;
99 hdo
->property
.parall
.pt
[2].y
= height
;
102 static bool SkipPrivateBlock(int type
)
106 if (type
== OBJRET_FILE_NO_PRIVATE_BLOCK
)
108 if (!hmem
->read4b(n
))
110 if (hmem
->state() || hmem
->skipBlock(n
) != static_cast<size_t>(n
))
113 if (!hmem
->read4b(n
))
117 return hmem
->skipBlock(n
) == static_cast<size_t>(n
);
120 static int SizeExpected
;
123 static int ReadSizeField(int size
)
126 if (!hmem
->read4b(SizeRead
))
133 static bool SkipUnusedField(void)
135 return (SizeExpected
>= SizeRead
) &&
136 hmem
->skipBlock(SizeRead
- SizeExpected
) != 0;
140 #define HDOFILE_HEADER_SIZE (2*4+16) // 16=sizeof(ZZRect)
141 #define HDOFILE_COMMON_SIZE (7*4+16+44)
143 #define HDOFILE_HAS_NEXT 0x01
144 #define HDOFILE_HAS_CHILD 0x02
146 static bool LoadCommonHeader(HWPDrawingObject
* hdo
, unsigned short * link_info
)
148 uint size
, common_size
;
152 if (!hmem
->read4b(size
))
156 if (size
< HDOFILE_COMMON_SIZE
)
159 common_size
= HDOFILE_COMMON_SIZE
;
160 unsigned short tmp16
;
161 if (!hmem
->read2b(tmp16
))
164 if (!hmem
->read2b(tmp16
))
167 if (!hmem
->read4b(hdo
->offset
.x
))
169 if (!hmem
->read4b(hdo
->offset
.y
))
171 if (!hmem
->read4b(hdo
->extent
.w
))
173 if (!hmem
->read4b(hdo
->extent
.h
))
175 if (!hmem
->read4b(hdo
->offset2
.x
))
177 if (!hmem
->read4b(hdo
->offset2
.y
))
183 if (!hmem
->read4b(hdo
->vrect
.x
))
185 if (!hmem
->read4b(hdo
->vrect
.y
))
187 if (!hmem
->read4b(hdo
->vrect
.w
))
189 if (!hmem
->read4b(hdo
->vrect
.h
))
192 // read bare property 44 bytes
193 if (!hmem
->read4b(hdo
->property
.line_pstyle
))
195 if (!hmem
->read4b(hdo
->property
.line_hstyle
))
197 if (!hmem
->read4b(hdo
->property
.line_tstyle
))
199 if (!hmem
->read4b(hdo
->property
.line_color
))
202 if (!hmem
->read4b(tmp32
))
204 hdo
->property
.line_width
= static_cast<hunit
>(tmp32
);
205 if (!hmem
->read4b(hdo
->property
.fill_color
))
207 if (!hmem
->read4b(hdo
->property
.pattern_type
))
209 if (!hmem
->read4b(hdo
->property
.pattern_color
))
211 if (!hmem
->read4b(tmp32
))
213 hdo
->property
.hmargin
= static_cast<hunit
>(tmp32
);
214 if (!hmem
->read4b(tmp32
))
216 hdo
->property
.vmargin
= static_cast<hunit
>(tmp32
);
217 if (!hmem
->read4b(hdo
->property
.flag
))
219 // read rotation property 32 bytes
220 if ((size
>= common_size
+ 32)
221 && (hdo
->property
.flag
& HWPDO_FLAG_ROTATION
))
223 if (!hmem
->read4b(hdo
->property
.rot_originx
))
225 if (!hmem
->read4b(hdo
->property
.rot_originy
))
227 for (int ii
= 0; ii
< 3; ++ii
)
229 if (!hmem
->read4b(hdo
->property
.parall
.pt
[ii
].x
))
231 if (!hmem
->read4b(hdo
->property
.parall
.pt
[ii
].y
))
237 SetHdoParallRgn(hdo
, hdo
->extent
.w
, hdo
->extent
.h
);
239 // read gradient property 28 bytes
240 if ((size
>= common_size
+ 28) &&
241 (hdo
->property
.flag
& HWPDO_FLAG_GRADATION
))
243 if (!hmem
->read4b(hdo
->property
.fromcolor
))
245 if (!hmem
->read4b(hdo
->property
.tocolor
))
247 if (!hmem
->read4b(hdo
->property
.gstyle
))
249 if (!hmem
->read4b(hdo
->property
.angle
))
251 if (!hmem
->read4b(hdo
->property
.center_x
))
253 if (!hmem
->read4b(hdo
->property
.center_y
))
255 if (!hmem
->read4b(hdo
->property
.nstep
))
260 // read bitmap property 278 bytes
261 if ((size
>= common_size
+ 278) && \
262 (hdo
->property
.flag
& HWPDO_FLAG_BITMAP
))
264 if (!hmem
->read4b(hdo
->property
.offset1
.x
))
266 if (!hmem
->read4b(hdo
->property
.offset1
.y
))
268 if (!hmem
->read4b(hdo
->property
.offset2
.x
))
270 if (!hmem
->read4b(hdo
->property
.offset2
.y
))
272 if (!hmem
->readBlock(hdo
->property
.szPatternFile
, 261))
274 if (!hmem
->read1b(hdo
->property
.pictype
))
278 if( ( size
>= common_size
+ 3 ) && ( hdo
->property
.flag
& HWPDO_FLAG_WATERMARK
) )
279 //if( ( size >= common_size ) && ( hdo->property.flag >> 20 & 0x01 ) )
281 if (size
- common_size
>= 5)
284 if (!hmem
->read1b(tmp8
))
286 hdo
->property
.luminance
= tmp8
;
287 if (!hmem
->read1b(tmp8
))
289 hdo
->property
.contrast
= tmp8
;
290 if (!hmem
->read1b(tmp8
))
292 hdo
->property
.greyscale
= tmp8
;
298 hdo
->property
.luminance
= 0;
299 hdo
->property
.contrast
= 0;
300 hdo
->property
.greyscale
= 0;
302 hdo
->property
.pPara
= nullptr;
304 if( ( size
> common_size
) && (hdo
->property
.flag
& HWPDO_FLAG_AS_TEXTBOX
) )
307 hdo
->property
.pPara
= LoadParaList();
308 if( hdo
->property
.pPara
)
314 if (size
<= common_size
)
316 return hmem
->skipBlock(size
- common_size
) != 0;
319 static std::unique_ptr
<HWPDrawingObject
> LoadDrawingObject(void)
321 HWPDrawingObject
*prev
= nullptr;
322 std::unique_ptr
<HWPDrawingObject
> hdo
, head
;
324 unsigned short link_info
;
328 hdo
.reset(new HWPDrawingObject
);
329 if (!LoadCommonHeader(hdo
.get(), &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 (int res
= HWPDOFunc(hdo
.get(), OBJFUNC_LOAD
, nullptr, 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
== nullptr)
366 head
= std::move(hdo
);
371 prev
->next
= std::move(hdo
);
372 prev
= prev
->next
.get();
375 while (link_info
& HDOFILE_HAS_NEXT
);
380 // drawing object can be list.
381 // hdo = current item, head = list;
383 if (hdo
->type
< 0 || hdo
->type
>= HWPDO_NITEMS
)
385 hdo
->type
= HWPDO_RECT
;
387 HWPDOFunc(hdo
.get(), OBJFUNC_FREE
, nullptr, 0);
392 prev
->next
= nullptr;
400 static bool LoadDrawingObjectBlock(Picture
* pic
)
403 if (!hmem
->read4b(size
))
406 if (hmem
->state() || size
< HDOFILE_HEADER_SIZE
)
409 if (!hmem
->read4b(pic
->picinfo
.picdraw
.zorder
))
411 if (!hmem
->read4b(pic
->picinfo
.picdraw
.mbrcnt
))
413 if (!hmem
->read4b(pic
->picinfo
.picdraw
.vrect
.x
))
415 if (!hmem
->read4b(pic
->picinfo
.picdraw
.vrect
.y
))
417 if (!hmem
->read4b(pic
->picinfo
.picdraw
.vrect
.w
))
419 if (!hmem
->read4b(pic
->picinfo
.picdraw
.vrect
.h
))
422 if (size
> HDOFILE_HEADER_SIZE
&&
423 !hmem
->skipBlock(size
- HDOFILE_HEADER_SIZE
))
426 pic
->picinfo
.picdraw
.hdo
= LoadDrawingObject().release();
427 if (pic
->picinfo
.picdraw
.hdo
== nullptr)
432 // object manipulation function
434 HWPDODefaultFunc(int cmd
)
436 if (cmd
== OBJFUNC_LOAD
)
437 return OBJRET_FILE_NO_PRIVATE_BLOCK
;
438 return OBJRET_FILE_OK
;
442 HWPDOLineFunc(int /*type*/, HWPDrawingObject
* hdo
, int cmd
, void * /*argp*/, int /*argv*/)
444 int ret
= OBJRET_FILE_OK
;
448 if (ReadSizeField(4) < 4)
449 return OBJRET_FILE_ERROR
;
450 if (!hmem
->read4b(hdo
->u
.line_arc
.flip
))
451 return OBJRET_FILE_ERROR
;
453 return OBJRET_FILE_ERROR
;
454 if (!SkipUnusedField())
455 return OBJRET_FILE_ERROR
;
456 ret
= OBJRET_FILE_NO_PRIVATE_BLOCK_2
;
459 ret
= HWPDODefaultFunc(cmd
);
469 HWPDORectFunc(int /*type*/, HWPDrawingObject
* /*hdo*/, int cmd
, void * /*argp*/, int /*argv*/)
471 return HWPDODefaultFunc(cmd
);
478 HWPDOEllipseFunc(int /*type*/, HWPDrawingObject
* /*hdo*/,
479 int cmd
, void * /*argp*/, int /*argv*/)
481 return HWPDODefaultFunc(cmd
);
484 #define WTMM(x) ((double)(x) / 1800. * 25.4)
486 HWPDOEllipse2Func(int /*type*/, HWPDrawingObject
* hdo
,
487 int cmd
, void * /*argp*/, int /*argv*/)
492 if (ReadSizeField(16) < 16)
493 return OBJRET_FILE_ERROR
;
494 if (!hmem
->read4b(hdo
->u
.arc
.radial
[0].x
))
495 return OBJRET_FILE_ERROR
;
496 if (!hmem
->read4b(hdo
->u
.arc
.radial
[0].y
))
497 return OBJRET_FILE_ERROR
;
498 if (!hmem
->read4b(hdo
->u
.arc
.radial
[1].x
))
499 return OBJRET_FILE_ERROR
;
500 if (!hmem
->read4b(hdo
->u
.arc
.radial
[1].y
))
501 return OBJRET_FILE_ERROR
;
502 if (ReadSizeField(0) < 0)
503 return OBJRET_FILE_ERROR
;
506 return HWPDODefaultFunc(cmd
);
508 return OBJRET_FILE_OK
;
515 HWPDOArcFunc(int /*type*/, HWPDrawingObject
* hdo
, int cmd
, void * /*argp*/, int /*argv*/)
520 if (ReadSizeField(4) < 4)
521 return OBJRET_FILE_ERROR
;
522 if (!hmem
->read4b(hdo
->u
.line_arc
.flip
))
523 return OBJRET_FILE_ERROR
;
525 return OBJRET_FILE_ERROR
;
526 if (!SkipUnusedField())
527 return OBJRET_FILE_ERROR
;
530 return HWPDODefaultFunc(cmd
);
532 return OBJRET_FILE_OK
;
537 HWPDOArc2Func(int /*type*/, HWPDrawingObject
* /*hdo*/, int cmd
, void * /*argp*/, int /*argv*/)
539 int ret
= OBJRET_FILE_OK
;
543 ret
= OBJRET_FILE_NO_PRIVATE_BLOCK
;
546 ret
= HWPDODefaultFunc(cmd
);
554 HWPDOFreeFormFunc(int /*type*/, HWPDrawingObject
* hdo
,
555 int cmd
, void * /*argp*/, int /*argv*/)
561 hdo
->u
.freeform
.pt
= nullptr;
562 if (ReadSizeField(4) < 4)
563 return OBJRET_FILE_ERROR
;
564 if (!hmem
->read4b(hdo
->u
.freeform
.npt
))
565 return OBJRET_FILE_ERROR
;
567 return OBJRET_FILE_ERROR
;
568 if (!SkipUnusedField())
569 return OBJRET_FILE_ERROR
;
571 int size
= hdo
->u
.freeform
.npt
* sizeof(ZZPoint
);
573 if (ReadSizeField(size
) < size
)
574 return OBJRET_FILE_ERROR
;
575 if (hdo
->u
.freeform
.npt
)
578 ::comphelper::newArray_null
<ZZPoint
>(hdo
->u
.freeform
.npt
);
579 if (hdo
->u
.freeform
.pt
== nullptr)
581 hdo
->u
.freeform
.npt
= 0;
582 return OBJRET_FILE_ERROR
;
584 for (int ii
= 0; ii
< hdo
->u
.freeform
.npt
; ++ii
)
586 bool bFailure
= false;
587 if (!hmem
->read4b(hdo
->u
.freeform
.pt
[ii
].x
))
589 if (!hmem
->read4b(hdo
->u
.freeform
.pt
[ii
].y
))
595 delete[]hdo
->u
.freeform
.pt
;
596 hdo
->u
.freeform
.npt
= 0;
597 return OBJRET_FILE_ERROR
;
601 if (!SkipUnusedField())
602 return OBJRET_FILE_ERROR
;
603 return OBJRET_FILE_OK
;
606 if (hdo
->u
.freeform
.pt
)
607 delete[]hdo
->u
.freeform
.pt
;
610 return HWPDODefaultFunc(cmd
);
612 return OBJRET_FILE_OK
;
618 static void FreeParaList(HWPPara
* para
)
621 FreeParaList(para
->Next());
626 static HWPPara
*LoadParaList()
631 HWPFile
*hwpf
= GetCurrentDoc();
632 std::unique_ptr
<HIODev
> hio
= hwpf
->SetIODevice(std::unique_ptr
<HIODev
>(hmem
));
634 std::vector
< HWPPara
* > plist
;
636 hwpf
->ReadParaList(plist
);
637 std::unique_ptr
<HIODev
> orighmem
= hwpf
->SetIODevice(std::move(hio
));
638 hmem
= orighmem
.release();
640 return plist
.size()? plist
.front() : nullptr;
645 HWPDOTextBoxFunc(int /*type*/, HWPDrawingObject
* hdo
,
646 int cmd
, void * /*argp*/, int /*argv*/)
651 if (ReadSizeField(0) < 0 || !SkipUnusedField())
652 return OBJRET_FILE_ERROR
;
653 if (ReadSizeField(0) < 0)
654 return OBJRET_FILE_ERROR
;
655 hdo
->u
.textbox
.h
= LoadParaList();
656 return hdo
->u
.textbox
.h
? OBJRET_FILE_OK
: OBJRET_FILE_ERROR
;
658 if (hdo
->u
.textbox
.h
)
660 FreeParaList(hdo
->u
.textbox
.h
);
661 hdo
->u
.textbox
.h
= nullptr;
665 return HWPDODefaultFunc(cmd
);
667 return OBJRET_FILE_OK
;
673 HWPDOContainerFunc(int /*type*/, HWPDrawingObject
* /*hdo*/,
674 int cmd
, void * /*argp*/, int /*argv*/)
676 return HWPDODefaultFunc(cmd
);
680 HWPDrawingObject::HWPDrawingObject():
681 type(0), offset
{0, 0}, offset2
{0, 0}, extent
{0, 0}, vrect
{0, 0, 0, 0}
683 memset(&property
, 0, sizeof property
);
684 memset(&u
, 0, sizeof u
);
689 HWPDrawingObject::~HWPDrawingObject()
692 FreeParaList(property
.pPara
);
694 HWPDOFunc(this, OBJFUNC_FREE
, nullptr, 0);
698 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */