1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 #include <com/sun/star/drawing/PointSequence.hpp>
21 #include <com/sun/star/text/GraphicCrop.hpp>
22 #include <comphelper/sequence.hxx>
23 #include <tools/UnitConversion.hxx>
25 #include <ooxml/resourceids.hxx>
27 #include "WrapPolygonHandler.hxx"
30 #include <sal/log.hxx>
32 namespace writerfilter
{
34 using namespace com::sun::star
;
38 WrapPolygon::WrapPolygon()
42 WrapPolygon::~WrapPolygon()
46 void WrapPolygon::addPoint(const awt::Point
& rPoint
)
48 mPoints
.push_back(rPoint
);
51 WrapPolygon::Points_t::const_iterator
WrapPolygon::begin() const
53 return mPoints
.begin();
56 WrapPolygon::Points_t::const_iterator
WrapPolygon::end() const
61 WrapPolygon::Pointer_t
WrapPolygon::move(const awt::Point
& rPoint
) const
63 WrapPolygon::Pointer_t
pResult(new WrapPolygon
);
65 Points_t::const_iterator aIt
= begin();
66 Points_t::const_iterator aItEnd
= end();
70 awt::Point
aPoint(aIt
->X
+ rPoint
.X
, aIt
->Y
+ rPoint
.Y
);
71 pResult
->addPoint(aPoint
);
78 WrapPolygon::Pointer_t
WrapPolygon::scale(const Fraction
& rFractionX
, const Fraction
& rFractionY
) const
80 WrapPolygon::Pointer_t
pResult(new WrapPolygon
);
82 Points_t::const_iterator aIt
= begin();
83 Points_t::const_iterator aItEnd
= end();
87 awt::Point
aPoint((Fraction(tools::Long(aIt
->X
)) * rFractionX
).operator long(), (Fraction(tools::Long(aIt
->Y
)) * rFractionY
).operator long());
88 pResult
->addPoint(aPoint
);
95 WrapPolygon::Pointer_t
WrapPolygon::correctWordWrapPolygon(const awt::Size
& rSrcSize
) const
97 WrapPolygon::Pointer_t pResult
;
99 const tools::Long nWrap100Percent
= 21600;
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
);
106 Fraction aScaleX
= nWrap100Percent
/ (nWrap100Percent
+ aMove
);
107 Fraction aScaleY
= nWrap100Percent
/ (nWrap100Percent
- aMove
);
108 pResult
= pResult
->scale(aScaleX
, aScaleY
);
110 Fraction
aScaleSrcX(rSrcSize
.Width
, nWrap100Percent
);
111 Fraction
aScaleSrcY(rSrcSize
.Height
, nWrap100Percent
);
112 pResult
= pResult
->scale(aScaleSrcX
, aScaleSrcY
);
117 WrapPolygon::Pointer_t
WrapPolygon::correctWordWrapPolygonPixel(const awt::Size
& rSrcSize
) const
119 WrapPolygon::Pointer_t pResult
;
122 * https://msdn.microsoft.com/en-us/library/ee342530.aspx
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.
131 const tools::Long nWrap100Percent
= 21600;
133 Fraction
aScaleX(rSrcSize
.Width
, nWrap100Percent
);
134 Fraction
aScaleY(rSrcSize
.Height
, nWrap100Percent
);
135 pResult
= scale(aScaleX
, aScaleY
);
140 WrapPolygon::Pointer_t
WrapPolygon::correctCrop(const awt::Size
& rGraphicSize
,
141 const text::GraphicCrop
& rGraphicCrop
) const
143 WrapPolygon::Pointer_t pResult
;
145 Fraction
aScaleX(rGraphicSize
.Width
- rGraphicCrop
.Left
- rGraphicCrop
.Right
,
147 Fraction
aScaleY(rGraphicSize
.Height
- rGraphicCrop
.Top
- rGraphicCrop
.Bottom
,
148 rGraphicSize
.Height
);
149 pResult
= scale(aScaleX
, aScaleY
);
151 awt::Point
aMove(rGraphicCrop
.Left
, rGraphicCrop
.Top
);
152 pResult
= pResult
->move(aMove
);
157 drawing::PointSequenceSequence
WrapPolygon::getPointSequenceSequence() const
159 return { comphelper::containerToSequence(mPoints
) };
162 WrapPolygonHandler::WrapPolygonHandler()
163 : LoggedProperties("WrapPolygonHandler")
164 , mpPolygon(new WrapPolygon
)
170 WrapPolygonHandler::~WrapPolygonHandler()
174 void WrapPolygonHandler::lcl_attribute(Id Name
, Value
& val
)
176 sal_Int32 nIntValue
= val
.getInt();
180 case NS_ooxml::LN_CT_Point2D_x
:
183 case NS_ooxml::LN_CT_Point2D_y
:
187 SAL_WARN("writerfilter", "WrapPolygonHandler::lcl_attribute: unhandled token: " << Name
);
192 void WrapPolygonHandler::lcl_sprm(Sprm
& _sprm
)
194 switch (_sprm
.getId())
196 case NS_ooxml::LN_CT_WrapPath_lineTo
:
197 case NS_ooxml::LN_CT_WrapPath_start
:
199 resolveSprmProps(*this, _sprm
);
201 awt::Point
aPoint(mnX
, mnY
);
202 mpPolygon
->addPoint(aPoint
);
206 SAL_WARN("writerfilter", "WrapPolygonHandler::lcl_sprm: unhandled token: " << _sprm
.getId());
214 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */