diff options
Diffstat (limited to 'drawinglayer/source/tools/emfpregion.cxx')
-rw-r--r-- | drawinglayer/source/tools/emfpregion.cxx | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/drawinglayer/source/tools/emfpregion.cxx b/drawinglayer/source/tools/emfpregion.cxx new file mode 100644 index 000000000..9fcced337 --- /dev/null +++ b/drawinglayer/source/tools/emfpregion.cxx @@ -0,0 +1,134 @@ +/* -*- 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 . + */ + +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/range/b2drectangle.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <sal/log.hxx> +#include "emfpregion.hxx" +#include "emfppath.hxx" + +namespace emfplushelper +{ + EMFPRegion::EMFPRegion() + { + } + + EMFPRegion::~EMFPRegion() + { + } + + ::basegfx::B2DPolyPolygon EMFPRegion::ReadRegionNode(SvStream& s, EmfPlusHelperData& rR) + { + // Regions are specified as a binary tree of region nodes, and each node must either be a terminal node + // (RegionNodeDataTypeRect, RegionNodeDataTypePath, RegionNodeDataTypeEmpty, RegionNodeDataTypeInfinite) + // or specify one or two child nodes + // (RegionNodeDataTypeAnd, RegionNodeDataTypeOr, RegionNodeDataTypeXor, + // RegionNodeDataTypeExclude, RegionNodeDataTypeComplement). + sal_uInt32 dataType; + ::basegfx::B2DPolyPolygon polygon; + s.ReadUInt32(dataType); + SAL_INFO("drawinglayer.emf", "EMF+\t Region node data type 0x" << std::hex << dataType << std::dec); + + switch (dataType) + { + case RegionNodeDataTypeAnd: // CombineModeIntersect + case RegionNodeDataTypeOr: // CombineModeUnion + case RegionNodeDataTypeXor: // CombineModeXOR + case RegionNodeDataTypeExclude: // CombineModeExclude + case RegionNodeDataTypeComplement: // CombineModeComplement + { + ::basegfx::B2DPolyPolygon leftPolygon = ReadRegionNode(s, rR); + ::basegfx::B2DPolyPolygon rightPolygon = ReadRegionNode(s, rR); + polygon = EmfPlusHelperData::combineClip(leftPolygon, dataType, rightPolygon); + break; + } + case RegionNodeDataTypeRect: + { + float dx, dy, dw, dh; + s.ReadFloat(dx).ReadFloat(dy).ReadFloat(dw).ReadFloat(dh); + SAL_INFO("drawinglayer.emf", "EMF+\t\t RegionNodeDataTypeRect x:" << dx << ", y:" << dy << + ", width:" << dw << ", height:" << dh); + + const ::basegfx::B2DPoint mappedStartPoint(rR.Map(dx, dy)); + const ::basegfx::B2DPoint mappedEndPoint(rR.Map(dx + dw, dy + dh)); + polygon = ::basegfx::B2DPolyPolygon( + ::basegfx::utils::createPolygonFromRect( + ::basegfx::B2DRectangle( + mappedStartPoint.getX(), + mappedStartPoint.getY(), + mappedEndPoint.getX(), + mappedEndPoint.getY()))); + break; + } + case RegionNodeDataTypePath: + { + sal_Int32 pathLength; + s.ReadInt32(pathLength); + SAL_INFO("drawinglayer.emf", "EMF+\t\t RegionNodeDataTypePath, Path Length: " << pathLength << " bytes"); + + sal_uInt32 header, pathFlags; + sal_Int32 points; + + s.ReadUInt32(header).ReadInt32(points).ReadUInt32(pathFlags); + SAL_INFO("drawinglayer.emf", "EMF+\t\t header: 0x" << std::hex << header << + " points: " << std::dec << points << " additional flags: 0x" << std::hex << pathFlags << std::dec); + + EMFPPath path(points); + path.Read(s, pathFlags); + polygon = path.GetPolygon(rR); + break; + } + case RegionNodeDataTypeEmpty: + { + SAL_INFO("drawinglayer.emf", "EMF+\t\t RegionNodeDataTypeEmpty"); + SAL_WARN("drawinglayer.emf", "EMF+\t\t TODO we need to set empty polygon here"); + polygon = ::basegfx::B2DPolyPolygon(); + + break; + } + case RegionNodeDataTypeInfinite: + { + SAL_INFO("drawinglayer.emf", "EMF+\t\t RegionNodeDataTypeInfinite"); + polygon = ::basegfx::B2DPolyPolygon(); + break; + } + default: + { + SAL_WARN("drawinglayer.emf", "EMF+\t\t Unhandled region type: 0x" << std::hex << dataType << std::dec); + polygon = ::basegfx::B2DPolyPolygon(); + } + } + return polygon; + } + + void EMFPRegion::ReadRegion(SvStream& s, EmfPlusHelperData& rR) + { + sal_uInt32 header, count; + s.ReadUInt32(header).ReadUInt32(count); + // An array should be RegionNodeCount+1 of EmfPlusRegionNode objects. + SAL_INFO("drawinglayer.emf", "EMF+\t version: 0x" << std::hex << header << std::dec << ", region node count: " << count); + + regionPolyPolygon = ReadRegionNode(s, rR); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |