tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / hwpfilter / source / drawing.h
blobe549896a5eed604404320a33bc13d230d0898bd7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
25 #include <math.h>
27 #include <osl/diagnose.h>
29 #include <comphelper/newarray.hxx>
31 #include "hwplib.h"
32 #include "hwpfile.h"
33 #include "hiodev.h"
34 #include "hbox.h"
35 #include "drawdef.h"
37 enum
39 OBJFUNC_LOAD,
40 OBJFUNC_FREE,
41 OBJFUNC_DISPLAY,
42 OBJFUNC_NITEM
45 enum
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[] =
74 HWPDOContainerFunc,
75 HWPDOLineFunc,
76 HWPDORectFunc,
77 HWPDOEllipseFunc,
78 HWPDOArcFunc,
79 HWPDOFreeFormFunc,
80 HWPDOTextBoxFunc,
81 HWPDOFreeFormFunc,
82 HWPDOEllipse2Func,
83 HWPDOArc2Func,
84 HWPDOFreeFormFunc,
87 static HIODev *hmem = nullptr;
89 static int count = 0;
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)
103 int n;
105 if (type == OBJRET_FILE_NO_PRIVATE_BLOCK)
107 if (!hmem->read4b(n))
108 return false;
109 if (hmem->state() || hmem->skipBlock(n) != static_cast<size_t>(n))
110 return false;
112 if (!hmem->read4b(n))
113 return false;
114 if (hmem->state())
115 return false;
116 return hmem->skipBlock(n) == static_cast<size_t>(n);
119 static int SizeExpected;
120 static int SizeRead;
122 static int ReadSizeField(int size)
124 SizeExpected = size;
125 if (!hmem->read4b(SizeRead))
126 return -1;
127 if (hmem->state())
128 return -1;
129 return 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;
149 if (!hmem)
150 return false;
151 if (!hmem->read4b(size))
152 return false;
153 if (hmem->state())
154 return false;
155 if (size < HDOFILE_COMMON_SIZE)
156 return false;
158 common_size = HDOFILE_COMMON_SIZE;
159 unsigned short tmp16;
160 if (!hmem->read2b(tmp16))
161 return false;
162 hdo->type = tmp16;
163 if (!hmem->read2b(tmp16))
164 return false;
165 *link_info = tmp16;
166 if (!hmem->read4b(hdo->offset.x))
167 return false;
168 if (!hmem->read4b(hdo->offset.y))
169 return false;
170 if (!hmem->read4b(hdo->extent.w))
171 return false;
172 if (!hmem->read4b(hdo->extent.h))
173 return false;
174 if (!hmem->read4b(hdo->offset2.x))
175 return false;
176 if (!hmem->read4b(hdo->offset2.y))
177 return false;
179 if (hmem->state())
180 return false;
182 if (!hmem->read4b(hdo->vrect.x))
183 return false;
184 if (!hmem->read4b(hdo->vrect.y))
185 return false;
186 if (!hmem->read4b(hdo->vrect.w))
187 return false;
188 if (!hmem->read4b(hdo->vrect.h))
189 return false;
191 // read bare property 44 bytes
192 if (!hmem->read4b(hdo->property.line_pstyle))
193 return false;
194 if (!hmem->read4b(hdo->property.line_hstyle))
195 return false;
196 if (!hmem->read4b(hdo->property.line_tstyle))
197 return false;
198 if (!hmem->read4b(hdo->property.line_color))
199 return false;
200 unsigned int tmp32;
201 if (!hmem->read4b(tmp32))
202 return false;
203 hdo->property.line_width = static_cast<hunit>(tmp32);
204 if (!hmem->read4b(hdo->property.fill_color))
205 return false;
206 if (!hmem->read4b(hdo->property.pattern_type))
207 return false;
208 if (!hmem->read4b(hdo->property.pattern_color))
209 return false;
210 if (!hmem->read4b(tmp32))
211 return false;
212 hdo->property.hmargin = static_cast<hunit>(tmp32);
213 if (!hmem->read4b(tmp32))
214 return false;
215 hdo->property.vmargin = static_cast<hunit>(tmp32);
216 if (!hmem->read4b(hdo->property.flag))
217 return false;
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))
223 return false;
224 if (!hmem->read4b(hdo->property.rot_originy))
225 return false;
226 for (int ii = 0; ii < 3; ++ii)
228 if (!hmem->read4b(hdo->property.parall.pt[ii].x))
229 return false;
230 if (!hmem->read4b(hdo->property.parall.pt[ii].y))
231 return false;
233 common_size += 32;
235 else
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))
243 return false;
244 if (!hmem->read4b(hdo->property.tocolor))
245 return false;
246 if (!hmem->read4b(hdo->property.gstyle))
247 return false;
248 if (!hmem->read4b(hdo->property.angle))
249 return false;
250 if (!hmem->read4b(hdo->property.center_x))
251 return false;
252 if (!hmem->read4b(hdo->property.center_y))
253 return false;
254 if (!hmem->read4b(hdo->property.nstep))
255 return false;
256 common_size += 28;
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))
264 return false;
265 if (!hmem->read4b(hdo->property.offset1.y))
266 return false;
267 if (!hmem->read4b(hdo->property.offset2.x))
268 return false;
269 if (!hmem->read4b(hdo->property.offset2.y))
270 return false;
271 if (!hmem->readBlock(hdo->property.szPatternFile, 261))
272 return false;
273 if (!hmem->read1b(hdo->property.pictype))
274 return false;
275 common_size += 278;
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)
281 hmem->skipBlock(2);
282 unsigned char tmp8;
283 if (!hmem->read1b(tmp8))
284 return false;
285 hdo->property.luminance = tmp8;
286 if (!hmem->read1b(tmp8))
287 return false;
288 hdo->property.contrast = tmp8;
289 if (!hmem->read1b(tmp8))
290 return false;
291 hdo->property.greyscale = tmp8;
293 common_size += 5;
295 else
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) )
305 hmem->skipBlock(8);
306 hdo->property.pPara = LoadParaList();
307 if( hdo->property.pPara )
308 return true;
309 else
310 return false;
313 if (size <= common_size)
314 return true;
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))
330 goto error;
332 if (hdo->type < 0 || hdo->type >= HWPDO_NITEMS)
334 hdo->type = HWPDO_RECT;
335 if (!SkipPrivateBlock(OBJRET_FILE_NO_PRIVATE_BLOCK))
337 goto error;
340 else
342 switch (int res = HWPDOFunc(hdo.get(), OBJFUNC_LOAD, nullptr, 0))
344 case OBJRET_FILE_ERROR:
345 goto error;
346 case OBJRET_FILE_OK:
347 break;
348 case OBJRET_FILE_NO_PRIVATE_BLOCK:
349 case OBJRET_FILE_NO_PRIVATE_BLOCK_2:
350 if (!SkipPrivateBlock(res))
351 goto error;
352 break;
355 if (link_info & HDOFILE_HAS_CHILD)
357 hdo->child = LoadDrawingObject(hwpf);
358 if (hdo->child == nullptr)
360 goto error;
363 if (prev == nullptr)
365 head = std::move(hdo);
366 prev = head.get();
368 else
370 prev->next = std::move(hdo);
371 prev = prev->next.get();
374 while (link_info & HDOFILE_HAS_NEXT);
376 return head;
378 error:
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;
389 while (pPara)
391 HWPPara* pNextPara = pPara->Next();
392 hwpf.move_to_failed(std::unique_ptr<HWPPara>(pPara));
393 pPara = pNextPara;
395 hdo->property.pPara = nullptr;
397 HWPDOFunc(hdo.get(), OBJFUNC_FREE, nullptr, 0);
398 hdo.reset();
400 if( prev )
402 prev->next = nullptr;
403 return head;
405 else
406 return nullptr;
410 static bool LoadDrawingObjectBlock(Picture * pic, HWPFile& hwpf)
412 int size;
413 if (!hmem->read4b(size))
414 return false;
416 if (hmem->state() || size < HDOFILE_HEADER_SIZE)
417 return false;
419 if (!hmem->read4b(pic->picinfo.picdraw.zorder))
420 return false;
421 if (!hmem->read4b(pic->picinfo.picdraw.mbrcnt))
422 return false;
423 if (!hmem->read4b(pic->picinfo.picdraw.vrect.x))
424 return false;
425 if (!hmem->read4b(pic->picinfo.picdraw.vrect.y))
426 return false;
427 if (!hmem->read4b(pic->picinfo.picdraw.vrect.w))
428 return false;
429 if (!hmem->read4b(pic->picinfo.picdraw.vrect.h))
430 return false;
432 if (size > HDOFILE_HEADER_SIZE &&
433 !hmem->skipBlock(size - HDOFILE_HEADER_SIZE))
434 return false;
436 pic->picinfo.picdraw.hdo = LoadDrawingObject(hwpf).release();
437 if (pic->picinfo.picdraw.hdo == nullptr)
438 return false;
439 return true;
442 // object manipulation function
443 static int
444 HWPDODefaultFunc(int cmd)
446 if (cmd == OBJFUNC_LOAD)
447 return OBJRET_FILE_NO_PRIVATE_BLOCK;
448 return OBJRET_FILE_OK;
451 static int
452 HWPDOLineFunc(int /*type*/, HWPDrawingObject * hdo, int cmd, void * /*argp*/, int /*argv*/)
454 int ret = OBJRET_FILE_OK;
455 switch (cmd)
457 case OBJFUNC_LOAD:
458 if (ReadSizeField(4) < 4)
459 return OBJRET_FILE_ERROR;
460 if (!hmem->read4b(hdo->u.line_arc.flip))
461 return OBJRET_FILE_ERROR;
462 if (hmem->state())
463 return OBJRET_FILE_ERROR;
464 if (!SkipUnusedField())
465 return OBJRET_FILE_ERROR;
466 ret = OBJRET_FILE_NO_PRIVATE_BLOCK_2;
467 break;
468 default:
469 ret = HWPDODefaultFunc(cmd);
470 break;
472 return ret;
476 // rectangle
478 static int
479 HWPDORectFunc(int /*type*/, HWPDrawingObject * /*hdo*/, int cmd, void * /*argp*/, int /*argv*/)
481 return HWPDODefaultFunc(cmd);
485 // ellipse
487 static int
488 HWPDOEllipseFunc(int /*type*/, HWPDrawingObject * /*hdo*/,
489 int cmd, void * /*argp*/, int /*argv*/)
491 return HWPDODefaultFunc(cmd);
494 static int
495 HWPDOEllipse2Func(int /*type*/, HWPDrawingObject * hdo,
496 int cmd, void * /*argp*/, int /*argv*/)
498 switch (cmd)
500 case OBJFUNC_LOAD:
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;
513 break;
514 default:
515 return HWPDODefaultFunc(cmd);
517 return OBJRET_FILE_OK;
521 // arc
523 static int
524 HWPDOArcFunc(int /*type*/, HWPDrawingObject * hdo, int cmd, void * /*argp*/, int /*argv*/)
526 switch (cmd)
528 case OBJFUNC_LOAD:
529 if (ReadSizeField(4) < 4)
530 return OBJRET_FILE_ERROR;
531 if (!hmem->read4b(hdo->u.line_arc.flip))
532 return OBJRET_FILE_ERROR;
533 if (hmem->state())
534 return OBJRET_FILE_ERROR;
535 if (!SkipUnusedField())
536 return OBJRET_FILE_ERROR;
537 break;
538 default:
539 return HWPDODefaultFunc(cmd);
541 return OBJRET_FILE_OK;
545 static int
546 HWPDOArc2Func(int /*type*/, HWPDrawingObject * /*hdo*/, int cmd, void * /*argp*/, int /*argv*/)
548 int ret = OBJRET_FILE_OK;
549 switch (cmd)
551 case OBJFUNC_LOAD:
552 ret = OBJRET_FILE_NO_PRIVATE_BLOCK;
553 break;
554 default:
555 ret = HWPDODefaultFunc(cmd);
556 break;
558 return ret;
562 static int
563 HWPDOFreeFormFunc(int /*type*/, HWPDrawingObject * hdo,
564 int cmd, void * /*argp*/, int /*argv*/)
566 switch (cmd)
568 case OBJFUNC_LOAD:
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;
575 if (hmem->state())
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)
586 hdo->u.freeform.pt =
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))
597 bFailure = true;
598 if (!hmem->read4b(hdo->u.freeform.pt[ii].y))
599 bFailure = true;
600 if (hmem->state())
601 bFailure = true;
602 if (bFailure)
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;
614 case OBJFUNC_FREE:
615 if (hdo->u.freeform.pt)
616 delete[]hdo->u.freeform.pt;
617 break;
618 default:
619 return HWPDODefaultFunc(cmd);
621 return OBJRET_FILE_OK;
625 // text box
627 static void FreeParaList(HWPPara * para)
629 if (para->Next())
630 FreeParaList(para->Next());
631 delete para;
635 static HWPPara *LoadParaList()
637 if (!hmem)
638 return nullptr;
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;
653 static int
654 HWPDOTextBoxFunc(int /*type*/, HWPDrawingObject * hdo,
655 int cmd, void * /*argp*/, int /*argv*/)
657 switch (cmd)
659 case OBJFUNC_LOAD:
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;
666 case OBJFUNC_FREE:
667 if (hdo->u.textbox.h)
669 FreeParaList(hdo->u.textbox.h);
670 hdo->u.textbox.h = nullptr;
672 break;
673 default:
674 return HWPDODefaultFunc(cmd);
676 return OBJRET_FILE_OK;
681 static int
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);
694 index = ++count;
698 HWPDrawingObject::~HWPDrawingObject()
700 if (property.pPara)
701 FreeParaList(property.pPara);
703 HWPDOFunc(this, OBJFUNC_FREE, nullptr, 0);
705 #endif
707 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */