LibreOffice Module writerfilter (master) 1
WrapPolygonHandler.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <com/sun/star/drawing/PointSequence.hpp>
21#include <com/sun/star/text/GraphicCrop.hpp>
24
25#include <ooxml/resourceids.hxx>
26
28#include "util.hxx"
29
30#include <sal/log.hxx>
31
32namespace writerfilter {
33
34using namespace com::sun::star;
35
36namespace dmapper {
37
39{
40}
41
43{
44}
45
46void WrapPolygon::addPoint(const awt::Point & rPoint)
47{
48 mPoints.push_back(rPoint);
49}
50
51WrapPolygon::Points_t::const_iterator WrapPolygon::begin() const
52{
53 return mPoints.begin();
54}
55
56WrapPolygon::Points_t::const_iterator WrapPolygon::end() const
57{
58 return mPoints.end();
59}
60
61WrapPolygon::Pointer_t WrapPolygon::move(const awt::Point & rPoint) const
62{
64
65 Points_t::const_iterator aIt = begin();
66 Points_t::const_iterator aItEnd = end();
67
68 while (aIt != aItEnd)
69 {
70 awt::Point aPoint(aIt->X + rPoint.X, aIt->Y + rPoint.Y);
71 pResult->addPoint(aPoint);
72 ++aIt;
73 }
74
75 return pResult;
76}
77
78WrapPolygon::Pointer_t WrapPolygon::scale(const Fraction & rFractionX, const Fraction & rFractionY) const
79{
81
82 Points_t::const_iterator aIt = begin();
83 Points_t::const_iterator aItEnd = end();
84
85 while (aIt != aItEnd)
86 {
87 awt::Point aPoint((Fraction(tools::Long(aIt->X)) * rFractionX).operator long(), (Fraction(tools::Long(aIt->Y)) * rFractionY).operator long());
88 pResult->addPoint(aPoint);
89 ++aIt;
90 }
91
92 return pResult;
93}
94
96{
98
99 const tools::Long nWrap100Percent = 21600;
100
101 Fraction aMove(nWrap100Percent, rSrcSize.Width);
102 aMove = aMove * Fraction(convertTwipToMm100(15), 1);
103 awt::Point aMovePoint(aMove.operator long(), 0);
104 pResult = move(aMovePoint);
105
106 Fraction aScaleX = nWrap100Percent / (nWrap100Percent + aMove);
107 Fraction aScaleY = nWrap100Percent / (nWrap100Percent - aMove);
108 pResult = pResult->scale(aScaleX, aScaleY);
109
110 Fraction aScaleSrcX(rSrcSize.Width, nWrap100Percent);
111 Fraction aScaleSrcY(rSrcSize.Height, nWrap100Percent);
112 pResult = pResult->scale(aScaleSrcX, aScaleSrcY);
113
114 return pResult;
115}
116
118{
120
121 /*
122 * https://msdn.microsoft.com/en-us/library/ee342530.aspx
123 *
124 * Image wrapping polygons in Microsoft Word use a fixed coordinate space
125 * that is 21600 units x 21600 units. Coordinate (0,0) is the upper left
126 * corner of the image and coordinate (21600,21600) is the lower right
127 * corner of the image. Microsoft Word scales the size of the wrapping
128 * polygon units to fit the size of the image. The 21600 value is a legacy
129 * artifact from the drawing layer of early versions of Microsoft Office.
130 */
131 const tools::Long nWrap100Percent = 21600;
132
133 Fraction aScaleX(rSrcSize.Width, nWrap100Percent);
134 Fraction aScaleY(rSrcSize.Height, nWrap100Percent);
135 pResult = scale(aScaleX, aScaleY);
136
137 return pResult;
138}
139
141 const text::GraphicCrop& rGraphicCrop) const
142{
144
145 Fraction aScaleX(rGraphicSize.Width - rGraphicCrop.Left - rGraphicCrop.Right,
146 rGraphicSize.Width);
147 Fraction aScaleY(rGraphicSize.Height - rGraphicCrop.Top - rGraphicCrop.Bottom,
148 rGraphicSize.Height);
149 pResult = scale(aScaleX, aScaleY);
150
151 awt::Point aMove(rGraphicCrop.Left, rGraphicCrop.Top);
152 pResult = pResult->move(aMove);
153
154 return pResult;
155}
156
157drawing::PointSequenceSequence WrapPolygon::getPointSequenceSequence() const
158{
160}
161
163 : LoggedProperties("WrapPolygonHandler")
164 , mpPolygon(new WrapPolygon)
165 , mnX(0)
166 , mnY(0)
167{
168}
169
171{
172}
173
175{
176 sal_Int32 nIntValue = val.getInt();
177
178 switch(Name)
179 {
180 case NS_ooxml::LN_CT_Point2D_x:
181 mnX = nIntValue;
182 break;
183 case NS_ooxml::LN_CT_Point2D_y:
184 mnY = nIntValue;
185 break;
186 default:
187 SAL_WARN("writerfilter", "WrapPolygonHandler::lcl_attribute: unhandled token: " << Name);
188 break;
189 }
190}
191
193{
194 switch (_sprm.getId())
195 {
196 case NS_ooxml::LN_CT_WrapPath_lineTo:
197 case NS_ooxml::LN_CT_WrapPath_start:
198 {
199 resolveSprmProps(*this, _sprm);
200
201 awt::Point aPoint(mnX, mnY);
202 mpPolygon->addPoint(aPoint);
203 }
204 break;
205 default:
206 SAL_WARN("writerfilter", "WrapPolygonHandler::lcl_sprm: unhandled token: " << _sprm.getId());
207 break;
208 }
209}
210
211
212}}
213
214/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr auto convertTwipToMm100(N n)
An SPRM: Section, Paragraph and Run Modifier.
virtual sal_uInt32 getId() const =0
Returns id of the SPRM.
virtual int getInt() const =0
Returns integer representation of the value.
virtual void lcl_sprm(Sprm &sprm) override
virtual void lcl_attribute(Id Name, Value &val) override
Handles <wp:wrapPolygon> from DOCX and the pWrapPolygonVertices shape property from RTF.
WrapPolygon::Pointer_t correctCrop(const css::awt::Size &rGraphicSize, const css::text::GraphicCrop &rGraphicCrop) const
Points_t::const_iterator end() const
WrapPolygon::Pointer_t correctWordWrapPolygonPixel(const css::awt::Size &rSrcSize) const
WrapPolygon::Pointer_t correctWordWrapPolygon(const css::awt::Size &rSrcSize) const
WrapPolygon::Pointer_t scale(const Fraction &rFractionX, const Fraction &rFractionY) const
Points_t::const_iterator begin() const
void addPoint(const css::awt::Point &rPoint)
css::drawing::PointSequenceSequence getPointSequenceSequence() const
WrapPolygon::Pointer_t move(const css::awt::Point &rMove) const
#define SAL_WARN(area, stream)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
long Long
void resolveSprmProps(Properties &rHandler, Sprm &rSprm)
Definition: util.cxx:62
const int nWrap100Percent
sal_uInt32 Id
OUString Name