Bump for 3.6-28
[LibreOffice.git] / hwpfilter / source / drawing.h
blob3e630c2c4386c2382d9cfb8856c5a2597fa8529c
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 ************************************************************************/
29 #ifndef _DRAWING_H_
30 #define _DRAWING_H_
32 #include "precompile.h"
34 #include <list>
35 #include <math.h>
37 #include <osl/diagnose.h>
39 #include <comphelper/newarray.hxx>
41 #include "hwplib.h"
42 #include "hwpfile.h"
43 #include "hiodev.h"
44 #include "hbox.h"
45 #include "drawdef.h"
47 enum
49 OBJFUNC_LOAD,
50 OBJFUNC_FREE,
51 OBJFUNC_DISPLAY,
52 OBJFUNC_NITEM
55 enum
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[] =
86 HWPDOContainerFunc,
87 HWPDOLineFunc,
88 HWPDORectFunc,
89 HWPDOEllipseFunc,
90 HWPDOArcFunc,
91 HWPDOFreeFormFunc,
92 HWPDOTextBoxFunc,
93 HWPDOFreeFormFunc,
94 HWPDOEllipse2Func,
95 HWPDOArc2Func,
96 HWPDOFreeFormFunc,
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)
152 int n;
154 if (type == OBJRET_FILE_NO_PRIVATE_BLOCK)
156 n = hmem->read4b();
157 if (hmem->state() || hmem->skipBlock(n) != n)
158 return false;
160 n = hmem->read4b();
161 if (hmem->state())
162 return false;
163 return hmem->skipBlock(n) == n;
167 static int SizeExpected;
168 static int SizeRead;
170 static int ReadSizeField(int size)
172 SizeExpected = size;
173 SizeRead = hmem->read4b();
174 if (hmem->state())
175 return -1;
176 return SizeRead;
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;
197 if( !hmem )
198 return FALSE;
199 size = hmem->read4b();
200 if (hmem->state())
202 return FALSE;
204 if (size < HDOFILE_COMMON_SIZE)
206 return FALSE;
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();
219 if (hmem->state())
220 return FALSE;
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();
250 common_size += 32;
252 else
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();
266 common_size += 28;
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))
278 return FALSE;
279 hdo->property.pictype = sal::static_int_cast<char>(hmem->read1b());
280 common_size += 278;
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();
290 common_size += 5;
292 else{
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) )
301 hmem->skipBlock(8);
302 hdo->property.pPara = LoadParaList();
303 if( hdo->property.pPara )
304 return TRUE;
305 else
306 return FALSE;
309 if( size <= common_size )
310 return TRUE;
311 return hmem->skipBlock(size - common_size ) != 0;
315 static HWPDrawingObject *LoadDrawingObject(void)
317 HWPDrawingObject *hdo, *head, *prev;
318 int res;
320 WORD link_info;
322 head = prev = NULL;
325 if ((hdo = new HWPDrawingObject) == NULL)
327 goto error;
329 if (!LoadCommonHeader(hdo, &link_info))
331 goto error;
333 if (hdo->type < 0 || hdo->type >= HWPDO_NITEMS)
335 hdo->type = HWPDO_RECT;
336 if (!SkipPrivateBlock(OBJRET_FILE_NO_PRIVATE_BLOCK))
338 goto error;
341 else
343 switch (res = HWPDOFunc(hdo, OBJFUNC_LOAD, NULL, 0))
345 case OBJRET_FILE_ERROR:
346 goto error;
347 case OBJRET_FILE_OK:
348 break;
349 case OBJRET_FILE_NO_PRIVATE_BLOCK:
350 case OBJRET_FILE_NO_PRIVATE_BLOCK_2:
351 if (!SkipPrivateBlock(res))
352 goto error;
353 break;
356 if (link_info & HDOFILE_HAS_CHILD)
358 hdo->child = LoadDrawingObject();
359 if (hdo->child == NULL)
361 goto error;
364 if (prev == NULL)
365 head = hdo;
366 else
367 prev->next = hdo;
368 prev = hdo;
370 while (link_info & HDOFILE_HAS_NEXT);
372 return head;
373 error:
374 // drawing object can be list.
375 // hdo = current item, head = list;
377 if (hdo != NULL)
379 HWPDOFunc(hdo, OBJFUNC_FREE, NULL, 0);
380 delete hdo;
382 if( prev )
384 prev->next = NULL;
385 return head;
387 else
388 return 0;
392 static bool LoadDrawingObjectBlock(Picture * pic)
394 int size = hmem->read4b();
396 if (hmem->state() || size < HDOFILE_HEADER_SIZE)
397 return false;
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))
408 return false;
410 pic->picinfo.picdraw.hdo = LoadDrawingObject();
411 if (pic->picinfo.picdraw.hdo == 0)
412 return false;
413 return true;
417 // object manipulation function
419 static int
420 HWPDODefaultFunc(int , HWPDrawingObject * , int cmd, void *, int)
422 if (cmd == OBJFUNC_LOAD)
423 return OBJRET_FILE_NO_PRIVATE_BLOCK;
424 return true;
428 static int
429 HWPDOLineFunc(int type, HWPDrawingObject * hdo, int cmd, void *argp, int argv)
431 int ret = true;
432 switch (cmd)
434 case OBJFUNC_LOAD:
435 if (ReadSizeField(4) < 4)
436 return OBJRET_FILE_ERROR;
437 hdo->u.line_arc.flip = hmem->read4b();
438 if (hmem->state())
439 return OBJRET_FILE_ERROR;
440 if (!SkipUnusedField())
441 return OBJRET_FILE_ERROR;
442 ret = OBJRET_FILE_NO_PRIVATE_BLOCK_2;
443 break;
444 default:
445 ret = HWPDODefaultFunc(type, hdo, cmd, argp, argv);
446 break;
448 return ret;
452 // rectangle
454 static int
455 HWPDORectFunc(int type, HWPDrawingObject * hdo, int cmd, void *argp, int argv)
457 return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
461 // ellipse
463 static int
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)
471 static int
472 HWPDOEllipse2Func(int type, HWPDrawingObject * hdo,
473 int cmd, void *argp, int argv)
475 switch (cmd)
477 case OBJFUNC_LOAD:
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;
487 break;
488 default:
489 return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
491 return true;
495 // arc
497 static int
498 HWPDOArcFunc(int type, HWPDrawingObject * hdo, int cmd, void *argp, int argv)
500 switch (cmd)
502 case OBJFUNC_LOAD:
503 if (ReadSizeField(4) < 4)
504 return OBJRET_FILE_ERROR;
505 hdo->u.line_arc.flip = hmem->read4b();
506 if (hmem->state())
507 return OBJRET_FILE_ERROR;
508 if (!SkipUnusedField())
509 return OBJRET_FILE_ERROR;
510 break;
511 default:
512 return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
514 return true;
518 static int
519 HWPDOArc2Func(int type, HWPDrawingObject * hdo, int cmd, void *argp, int argv)
521 int ret = true;
522 switch (cmd)
524 case OBJFUNC_LOAD:
525 ret = OBJRET_FILE_NO_PRIVATE_BLOCK;
526 break;
527 default:
528 ret = HWPDODefaultFunc(type, hdo, cmd, argp, argv);
529 break;
531 return ret;
535 static int
536 HWPDOFreeFormFunc(int type, HWPDrawingObject * hdo,
537 int cmd, void *argp, int argv)
539 switch (cmd)
541 case OBJFUNC_LOAD:
543 hdo->u.freeform.pt = 0;
544 if (ReadSizeField(4) < 4)
545 return OBJRET_FILE_ERROR;
546 hdo->u.freeform.npt = hmem->read4b();
547 if (hmem->state())
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)
558 hdo->u.freeform.pt =
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();
569 if (hmem->state())
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;
581 case OBJFUNC_FREE:
582 if (hdo->u.freeform.pt)
583 delete[]hdo->u.freeform.pt;
584 break;
585 default:
586 return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
588 return true;
592 // text box
594 static void FreeParaList(HWPPara * para)
596 if (para->Next())
597 FreeParaList(para->Next());
598 delete para;
602 static HWPPara *LoadParaList()
604 if (!hmem)
605 return 0;
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;
619 static int
620 HWPDOTextBoxFunc(int type, HWPDrawingObject * hdo,
621 int cmd, void *argp, int argv)
623 switch (cmd)
625 case OBJFUNC_LOAD:
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;
632 case OBJFUNC_FREE:
633 if (hdo->u.textbox.h)
635 FreeParaList(hdo->u.textbox.h);
636 hdo->u.textbox.h = NULL;
638 break;
639 default:
640 return HWPDODefaultFunc(type, hdo, cmd, argp, argv);
642 return true;
647 static int
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));
658 index = ++count;
662 HWPDrawingObject::~HWPDrawingObject()
664 #if 0
665 if (hdo->property.pictype == PICTYP_EMBED)
666 RemoveEmbeddedPic(hdo->property.szPatternFile);
667 hdo->property.szPatternFile[0] = 0;
668 #endif
669 if (child)
670 delete child;
672 if (next)
673 delete next;
675 HWPDOFunc(this, OBJFUNC_FREE, NULL, 0);
677 #endif
679 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */