summaryrefslogtreecommitdiffstats
path: root/hwpfilter/source/drawing.h
diff options
context:
space:
mode:
Diffstat (limited to 'hwpfilter/source/drawing.h')
-rw-r--r--hwpfilter/source/drawing.h708
1 files changed, 708 insertions, 0 deletions
diff --git a/hwpfilter/source/drawing.h b/hwpfilter/source/drawing.h
new file mode 100644
index 000000000..e3f2a512e
--- /dev/null
+++ b/hwpfilter/source/drawing.h
@@ -0,0 +1,708 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_HWPFILTER_SOURCE_DRAWING_H
+#define INCLUDED_HWPFILTER_SOURCE_DRAWING_H
+
+#include "precompile.h"
+
+#include <math.h>
+
+#include <osl/diagnose.h>
+
+#include <comphelper/newarray.hxx>
+
+#include "hwplib.h"
+#include "hwpfile.h"
+#include "hiodev.h"
+#include "hbox.h"
+#include "drawdef.h"
+
+enum
+{
+ OBJFUNC_LOAD,
+ OBJFUNC_FREE,
+ OBJFUNC_DISPLAY,
+ OBJFUNC_NITEM
+};
+
+enum
+{
+ BEGIN_GRADATION = 0, LINEAR, RADIAL, CONICAL, SQUARE,
+ END_GRADATION, BITMAP_PATTERN
+};
+
+#define OBJRET_FILE_OK 0
+#define OBJRET_FILE_ERROR (-1)
+#define OBJRET_FILE_NO_PRIVATE_BLOCK (-2)
+#define OBJRET_FILE_NO_PRIVATE_BLOCK_2 (-3)
+
+typedef int (*HWPDOFuncType) (int, HWPDrawingObject *, int, void *, int);
+
+#define HWPDOFunc(hdo, cmd, argp, argv) \
+ (HWPDOFuncTbl[(hdo)->type]((hdo)->type, (hdo), (cmd), (argp), (argv)))
+
+static int HWPDOLineFunc(int, HWPDrawingObject *, int, void *, int);
+static int HWPDORectFunc(int, HWPDrawingObject *, int, void *, int);
+static int HWPDOEllipseFunc(int, HWPDrawingObject *, int, void *, int);
+static int HWPDOArcFunc(int, HWPDrawingObject *, int, void *, int);
+static int HWPDOFreeFormFunc(int, HWPDrawingObject *, int, void *, int);
+static int HWPDOTextBoxFunc(int, HWPDrawingObject *, int, void *, int);
+static int HWPDOEllipse2Func(int, HWPDrawingObject *, int, void *, int);
+static int HWPDOArc2Func(int, HWPDrawingObject *, int, void *, int);
+static int HWPDOContainerFunc(int, HWPDrawingObject *, int, void *, int);
+static HWPPara *LoadParaList();
+
+HWPDOFuncType HWPDOFuncTbl[] =
+{
+ HWPDOContainerFunc,
+ HWPDOLineFunc,
+ HWPDORectFunc,
+ HWPDOEllipseFunc,
+ HWPDOArcFunc,
+ HWPDOFreeFormFunc,
+ HWPDOTextBoxFunc,
+ HWPDOFreeFormFunc,
+ HWPDOEllipse2Func,
+ HWPDOArc2Func,
+ HWPDOFreeFormFunc,
+};
+
+static HIODev *hmem = nullptr;
+
+static int count = 0;
+
+static void SetHdoParallRgn(HWPDrawingObject * hdo, int width, int height)
+{
+ hdo->property.parall.pt[0].x = 0;
+ hdo->property.parall.pt[0].y = 0;
+ hdo->property.parall.pt[1].x = width;
+ hdo->property.parall.pt[1].y = 0;
+ hdo->property.parall.pt[2].x = width;
+ hdo->property.parall.pt[2].y = height;
+}
+
+static bool SkipPrivateBlock(int type)
+{
+ int n;
+
+ if (type == OBJRET_FILE_NO_PRIVATE_BLOCK)
+ {
+ if (!hmem->read4b(n))
+ return false;
+ if (hmem->state() || hmem->skipBlock(n) != static_cast<size_t>(n))
+ return false;
+ }
+ if (!hmem->read4b(n))
+ return false;
+ if (hmem->state())
+ return false;
+ return hmem->skipBlock(n) == static_cast<size_t>(n);
+}
+
+static int SizeExpected;
+static int SizeRead;
+
+static int ReadSizeField(int size)
+{
+ SizeExpected = size;
+ if (!hmem->read4b(SizeRead))
+ return -1;
+ if (hmem->state())
+ return -1;
+ return SizeRead;
+}
+
+static bool SkipUnusedField(void)
+{
+ return (SizeExpected >= SizeRead) &&
+ hmem->skipBlock(SizeRead - SizeExpected) != 0;
+}
+
+
+#define HDOFILE_HEADER_SIZE (2*4+16) // 16=sizeof(ZZRect)
+#define HDOFILE_COMMON_SIZE (7*4+16+44)
+
+#define HDOFILE_HAS_NEXT 0x01
+#define HDOFILE_HAS_CHILD 0x02
+
+static bool LoadCommonHeader(HWPDrawingObject * hdo, unsigned short * link_info)
+{
+ uint size, common_size;
+
+ if (!hmem)
+ return false;
+ if (!hmem->read4b(size))
+ return false;
+ if (hmem->state())
+ return false;
+ if (size < HDOFILE_COMMON_SIZE)
+ return false;
+
+ common_size = HDOFILE_COMMON_SIZE;
+ unsigned short tmp16;
+ if (!hmem->read2b(tmp16))
+ return false;
+ hdo->type = tmp16;
+ if (!hmem->read2b(tmp16))
+ return false;
+ *link_info = tmp16;
+ if (!hmem->read4b(hdo->offset.x))
+ return false;
+ if (!hmem->read4b(hdo->offset.y))
+ return false;
+ if (!hmem->read4b(hdo->extent.w))
+ return false;
+ if (!hmem->read4b(hdo->extent.h))
+ return false;
+ if (!hmem->read4b(hdo->offset2.x))
+ return false;
+ if (!hmem->read4b(hdo->offset2.y))
+ return false;
+
+ if (hmem->state())
+ return false;
+
+ if (!hmem->read4b(hdo->vrect.x))
+ return false;
+ if (!hmem->read4b(hdo->vrect.y))
+ return false;
+ if (!hmem->read4b(hdo->vrect.w))
+ return false;
+ if (!hmem->read4b(hdo->vrect.h))
+ return false;
+
+// read bare property 44 bytes
+ if (!hmem->read4b(hdo->property.line_pstyle))
+ return false;
+ if (!hmem->read4b(hdo->property.line_hstyle))
+ return false;
+ if (!hmem->read4b(hdo->property.line_tstyle))
+ return false;
+ if (!hmem->read4b(hdo->property.line_color))
+ return false;
+ unsigned int tmp32;
+ if (!hmem->read4b(tmp32))
+ return false;
+ hdo->property.line_width = static_cast<hunit>(tmp32);
+ if (!hmem->read4b(hdo->property.fill_color))
+ return false;
+ if (!hmem->read4b(hdo->property.pattern_type))
+ return false;
+ if (!hmem->read4b(hdo->property.pattern_color))
+ return false;
+ if (!hmem->read4b(tmp32))
+ return false;
+ hdo->property.hmargin = static_cast<hunit>(tmp32);
+ if (!hmem->read4b(tmp32))
+ return false;
+ hdo->property.vmargin = static_cast<hunit>(tmp32);
+ if (!hmem->read4b(hdo->property.flag))
+ return false;
+// read rotation property 32 bytes
+ if ((size >= common_size + 32)
+ && (hdo->property.flag & HWPDO_FLAG_ROTATION))
+ {
+ if (!hmem->read4b(hdo->property.rot_originx))
+ return false;
+ if (!hmem->read4b(hdo->property.rot_originy))
+ return false;
+ for (int ii = 0; ii < 3; ++ii)
+ {
+ if (!hmem->read4b(hdo->property.parall.pt[ii].x))
+ return false;
+ if (!hmem->read4b(hdo->property.parall.pt[ii].y))
+ return false;
+ }
+ common_size += 32;
+ }
+ else
+ SetHdoParallRgn(hdo, hdo->extent.w, hdo->extent.h);
+
+// read gradient property 28 bytes
+ if ((size >= common_size + 28) &&
+ (hdo->property.flag & HWPDO_FLAG_GRADATION))
+ {
+ if (!hmem->read4b(hdo->property.fromcolor))
+ return false;
+ if (!hmem->read4b(hdo->property.tocolor))
+ return false;
+ if (!hmem->read4b(hdo->property.gstyle))
+ return false;
+ if (!hmem->read4b(hdo->property.angle))
+ return false;
+ if (!hmem->read4b(hdo->property.center_x))
+ return false;
+ if (!hmem->read4b(hdo->property.center_y))
+ return false;
+ if (!hmem->read4b(hdo->property.nstep))
+ return false;
+ common_size += 28;
+ }
+
+// read bitmap property 278 bytes
+ if ((size >= common_size + 278) && \
+ (hdo->property.flag & HWPDO_FLAG_BITMAP))
+ {
+ if (!hmem->read4b(hdo->property.offset1.x))
+ return false;
+ if (!hmem->read4b(hdo->property.offset1.y))
+ return false;
+ if (!hmem->read4b(hdo->property.offset2.x))
+ return false;
+ if (!hmem->read4b(hdo->property.offset2.y))
+ return false;
+ if (!hmem->readBlock(hdo->property.szPatternFile, 261))
+ return false;
+ if (!hmem->read1b(hdo->property.pictype))
+ return false;
+ common_size += 278;
+ }
+ if( ( size >= common_size + 3 ) && ( hdo->property.flag & HWPDO_FLAG_WATERMARK ) )
+ //if( ( size >= common_size ) && ( hdo->property.flag >> 20 & 0x01 ) )
+ {
+ if (size - common_size >= 5)
+ hmem->skipBlock(2);
+ unsigned char tmp8;
+ if (!hmem->read1b(tmp8))
+ return false;
+ hdo->property.luminance = tmp8;
+ if (!hmem->read1b(tmp8))
+ return false;
+ hdo->property.contrast = tmp8;
+ if (!hmem->read1b(tmp8))
+ return false;
+ hdo->property.greyscale = tmp8;
+
+ common_size += 5;
+ }
+ else
+ {
+ hdo->property.luminance = 0;
+ hdo->property.contrast = 0;
+ hdo->property.greyscale = 0;
+ }
+ hdo->property.pPara = nullptr;
+
+ if( ( size > common_size ) && (hdo->property.flag & HWPDO_FLAG_AS_TEXTBOX) )
+ {
+ hmem->skipBlock(8);
+ hdo->property.pPara = LoadParaList();
+ if( hdo->property.pPara )
+ return true;
+ else
+ return false;
+ }
+
+ if (size <= common_size)
+ return true;
+ return hmem->skipBlock(size - common_size ) != 0;
+}
+
+static std::unique_ptr<HWPDrawingObject> LoadDrawingObject(HWPFile& hwpf)
+{
+ HWPDrawingObject *prev = nullptr;
+ std::unique_ptr<HWPDrawingObject> hdo, head;
+
+ unsigned short link_info;
+
+ do
+ {
+ hdo.reset(new HWPDrawingObject);
+ if (!LoadCommonHeader(hdo.get(), &link_info))
+ {
+ goto error;
+ }
+ if (hdo->type < 0 || hdo->type >= HWPDO_NITEMS)
+ {
+ hdo->type = HWPDO_RECT;
+ if (!SkipPrivateBlock(OBJRET_FILE_NO_PRIVATE_BLOCK))
+ {
+ goto error;
+ }
+ }
+ else
+ {
+ switch (int res = HWPDOFunc(hdo.get(), OBJFUNC_LOAD, nullptr, 0))
+ {
+ case OBJRET_FILE_ERROR:
+ goto error;
+ case OBJRET_FILE_OK:
+ break;
+ case OBJRET_FILE_NO_PRIVATE_BLOCK:
+ case OBJRET_FILE_NO_PRIVATE_BLOCK_2:
+ if (!SkipPrivateBlock(res))
+ goto error;
+ break;
+ }
+ }
+ if (link_info & HDOFILE_HAS_CHILD)
+ {
+ hdo->child = LoadDrawingObject(hwpf);
+ if (hdo->child == nullptr)
+ {
+ goto error;
+ }
+ }
+ if (prev == nullptr)
+ {
+ head = std::move(hdo);
+ prev = head.get();
+ }
+ else
+ {
+ prev->next = std::move(hdo);
+ prev = prev->next.get();
+ }
+ }
+ while (link_info & HDOFILE_HAS_NEXT);
+
+ return head;
+
+error:
+// drawing object can be list.
+// hdo = current item, head = list;
+
+ if (hdo->type < 0 || hdo->type >= HWPDO_NITEMS)
+ {
+ hdo->type = HWPDO_RECT;
+ }
+ if (hdo->property.pPara)
+ {
+ HWPPara* pPara = hdo->property.pPara;
+ while (pPara)
+ {
+ HWPPara* pNextPara = pPara->Next();
+ hwpf.move_to_failed(std::unique_ptr<HWPPara>(pPara));
+ pPara = pNextPara;
+ }
+ hdo->property.pPara = nullptr;
+ }
+ HWPDOFunc(hdo.get(), OBJFUNC_FREE, nullptr, 0);
+ hdo.reset();
+
+ if( prev )
+ {
+ prev->next = nullptr;
+ return head;
+ }
+ else
+ return nullptr;
+}
+
+
+static bool LoadDrawingObjectBlock(Picture * pic, HWPFile& hwpf)
+{
+ int size;
+ if (!hmem->read4b(size))
+ return false;
+
+ if (hmem->state() || size < HDOFILE_HEADER_SIZE)
+ return false;
+
+ if (!hmem->read4b(pic->picinfo.picdraw.zorder))
+ return false;
+ if (!hmem->read4b(pic->picinfo.picdraw.mbrcnt))
+ return false;
+ if (!hmem->read4b(pic->picinfo.picdraw.vrect.x))
+ return false;
+ if (!hmem->read4b(pic->picinfo.picdraw.vrect.y))
+ return false;
+ if (!hmem->read4b(pic->picinfo.picdraw.vrect.w))
+ return false;
+ if (!hmem->read4b(pic->picinfo.picdraw.vrect.h))
+ return false;
+
+ if (size > HDOFILE_HEADER_SIZE &&
+ !hmem->skipBlock(size - HDOFILE_HEADER_SIZE))
+ return false;
+
+ pic->picinfo.picdraw.hdo = LoadDrawingObject(hwpf).release();
+ if (pic->picinfo.picdraw.hdo == nullptr)
+ return false;
+ return true;
+}
+
+// object manipulation function
+static int
+HWPDODefaultFunc(int cmd)
+{
+ if (cmd == OBJFUNC_LOAD)
+ return OBJRET_FILE_NO_PRIVATE_BLOCK;
+ return OBJRET_FILE_OK;
+}
+
+static int
+HWPDOLineFunc(int /*type*/, HWPDrawingObject * hdo, int cmd, void * /*argp*/, int /*argv*/)
+{
+ int ret = OBJRET_FILE_OK;
+ switch (cmd)
+ {
+ case OBJFUNC_LOAD:
+ if (ReadSizeField(4) < 4)
+ return OBJRET_FILE_ERROR;
+ if (!hmem->read4b(hdo->u.line_arc.flip))
+ return OBJRET_FILE_ERROR;
+ if (hmem->state())
+ return OBJRET_FILE_ERROR;
+ if (!SkipUnusedField())
+ return OBJRET_FILE_ERROR;
+ ret = OBJRET_FILE_NO_PRIVATE_BLOCK_2;
+ break;
+ default:
+ ret = HWPDODefaultFunc(cmd);
+ break;
+ }
+ return ret;
+}
+
+
+// rectangle
+
+static int
+HWPDORectFunc(int /*type*/, HWPDrawingObject * /*hdo*/, int cmd, void * /*argp*/, int /*argv*/)
+{
+ return HWPDODefaultFunc(cmd);
+}
+
+
+// ellipse
+
+static int
+HWPDOEllipseFunc(int /*type*/, HWPDrawingObject * /*hdo*/,
+int cmd, void * /*argp*/, int /*argv*/)
+{
+ return HWPDODefaultFunc(cmd);
+}
+
+#define WTMM(x) ((double)(x) / 1800. * 25.4)
+static int
+HWPDOEllipse2Func(int /*type*/, HWPDrawingObject * hdo,
+int cmd, void * /*argp*/, int /*argv*/)
+{
+ switch (cmd)
+ {
+ case OBJFUNC_LOAD:
+ if (ReadSizeField(16) < 16)
+ return OBJRET_FILE_ERROR;
+ if (!hmem->read4b(hdo->u.arc.radial[0].x))
+ return OBJRET_FILE_ERROR;
+ if (!hmem->read4b(hdo->u.arc.radial[0].y))
+ return OBJRET_FILE_ERROR;
+ if (!hmem->read4b(hdo->u.arc.radial[1].x))
+ return OBJRET_FILE_ERROR;
+ if (!hmem->read4b(hdo->u.arc.radial[1].y))
+ return OBJRET_FILE_ERROR;
+ if (ReadSizeField(0) < 0)
+ return OBJRET_FILE_ERROR;
+ break;
+ default:
+ return HWPDODefaultFunc(cmd);
+ }
+ return OBJRET_FILE_OK;
+}
+
+
+// arc
+
+static int
+HWPDOArcFunc(int /*type*/, HWPDrawingObject * hdo, int cmd, void * /*argp*/, int /*argv*/)
+{
+ switch (cmd)
+ {
+ case OBJFUNC_LOAD:
+ if (ReadSizeField(4) < 4)
+ return OBJRET_FILE_ERROR;
+ if (!hmem->read4b(hdo->u.line_arc.flip))
+ return OBJRET_FILE_ERROR;
+ if (hmem->state())
+ return OBJRET_FILE_ERROR;
+ if (!SkipUnusedField())
+ return OBJRET_FILE_ERROR;
+ break;
+ default:
+ return HWPDODefaultFunc(cmd);
+ }
+ return OBJRET_FILE_OK;
+}
+
+
+static int
+HWPDOArc2Func(int /*type*/, HWPDrawingObject * /*hdo*/, int cmd, void * /*argp*/, int /*argv*/)
+{
+ int ret = OBJRET_FILE_OK;
+ switch (cmd)
+ {
+ case OBJFUNC_LOAD:
+ ret = OBJRET_FILE_NO_PRIVATE_BLOCK;
+ break;
+ default:
+ ret = HWPDODefaultFunc(cmd);
+ break;
+ }
+ return ret;
+}
+
+
+static int
+HWPDOFreeFormFunc(int /*type*/, HWPDrawingObject * hdo,
+int cmd, void * /*argp*/, int /*argv*/)
+{
+ switch (cmd)
+ {
+ case OBJFUNC_LOAD:
+ {
+ hdo->u.freeform.pt = nullptr;
+ if (ReadSizeField(4) < 4)
+ return OBJRET_FILE_ERROR;
+ if (!hmem->read4b(hdo->u.freeform.npt))
+ return OBJRET_FILE_ERROR;
+ if (hmem->state())
+ return OBJRET_FILE_ERROR;
+ if (!SkipUnusedField())
+ return OBJRET_FILE_ERROR;
+
+ int size = hdo->u.freeform.npt * sizeof(ZZPoint);
+
+ if (ReadSizeField(size) < size)
+ return OBJRET_FILE_ERROR;
+ if (hdo->u.freeform.npt)
+ {
+ hdo->u.freeform.pt =
+ ::comphelper::newArray_null<ZZPoint>(hdo->u.freeform.npt);
+ if (hdo->u.freeform.pt == nullptr)
+ {
+ hdo->u.freeform.npt = 0;
+ return OBJRET_FILE_ERROR;
+ }
+ for (int ii = 0; ii < hdo->u.freeform.npt; ++ii)
+ {
+ bool bFailure = false;
+ if (!hmem->read4b(hdo->u.freeform.pt[ii].x))
+ bFailure = true;
+ if (!hmem->read4b(hdo->u.freeform.pt[ii].y))
+ bFailure = true;
+ if (hmem->state())
+ bFailure = true;
+ if (bFailure)
+ {
+ delete[]hdo->u.freeform.pt;
+ hdo->u.freeform.npt = 0;
+ return OBJRET_FILE_ERROR;
+ }
+ }
+ }
+ if (!SkipUnusedField())
+ return OBJRET_FILE_ERROR;
+ return OBJRET_FILE_OK;
+ }
+ case OBJFUNC_FREE:
+ if (hdo->u.freeform.pt)
+ delete[]hdo->u.freeform.pt;
+ break;
+ default:
+ return HWPDODefaultFunc(cmd);
+ }
+ return OBJRET_FILE_OK;
+}
+
+
+// text box
+
+static void FreeParaList(HWPPara * para)
+{
+ if (para->Next())
+ FreeParaList(para->Next());
+ delete para;
+}
+
+
+static HWPPara *LoadParaList()
+{
+ if (!hmem)
+ return nullptr;
+
+ HWPFile *hwpf = GetCurrentDoc();
+ std::unique_ptr<HIODev> hio = hwpf->SetIODevice(std::unique_ptr<HIODev>(hmem));
+
+ std::vector< HWPPara* > plist;
+
+ hwpf->ReadParaList(plist);
+ std::unique_ptr<HIODev> orighmem = hwpf->SetIODevice(std::move(hio));
+ hmem = orighmem.release();
+
+ return plist.size()? plist.front() : nullptr;
+}
+
+
+static int
+HWPDOTextBoxFunc(int /*type*/, HWPDrawingObject * hdo,
+int cmd, void * /*argp*/, int /*argv*/)
+{
+ switch (cmd)
+ {
+ case OBJFUNC_LOAD:
+ if (ReadSizeField(0) < 0 || !SkipUnusedField())
+ return OBJRET_FILE_ERROR;
+ if (ReadSizeField(0) < 0)
+ return OBJRET_FILE_ERROR;
+ hdo->u.textbox.h = LoadParaList();
+ return hdo->u.textbox.h ? OBJRET_FILE_OK : OBJRET_FILE_ERROR;
+ case OBJFUNC_FREE:
+ if (hdo->u.textbox.h)
+ {
+ FreeParaList(hdo->u.textbox.h);
+ hdo->u.textbox.h = nullptr;
+ }
+ break;
+ default:
+ return HWPDODefaultFunc(cmd);
+ }
+ return OBJRET_FILE_OK;
+}
+
+
+
+static int
+HWPDOContainerFunc(int /*type*/, HWPDrawingObject * /*hdo*/,
+int cmd, void * /*argp*/, int /*argv*/)
+{
+ return HWPDODefaultFunc(cmd);
+}
+
+
+HWPDrawingObject::HWPDrawingObject():
+ type(0), offset{0, 0}, offset2{0, 0}, extent{0, 0}, vrect{0, 0, 0, 0}
+{
+ memset(&property, 0, sizeof property);
+ memset(&u, 0, sizeof u);
+ index = ++count;
+}
+
+
+HWPDrawingObject::~HWPDrawingObject()
+{
+ if (property.pPara)
+ FreeParaList(property.pPara);
+
+ HWPDOFunc(this, OBJFUNC_FREE, nullptr, 0);
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */