LibreOffice Module svx (master) 1
svdotxtr.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
21#include <svx/svdotext.hxx>
22#include <svx/svdtrans.hxx>
23#include <svx/svdogrp.hxx>
24#include <svx/svdopath.hxx>
25#include <svx/svdpage.hxx>
26#include <svx/svdmodel.hxx>
30#include <svl/itemset.hxx>
33#include <svx/xfillit0.hxx>
34#include <svx/xflclit.hxx>
35#include <svx/xlineit0.hxx>
36#include <svx/xlnclit.hxx>
37#include <svx/xlnwtit.hxx>
38#include <svx/sdshitm.hxx>
40
41using namespace com::sun::star;
42
44{
46 {
47 // Either the rotation or shear angle exists.
49 tools::Long nWdt0=aSR0.Right()-aSR0.Left();
50 tools::Long nHgt0=aSR0.Bottom()-aSR0.Top();
51 tools::Long nWdt1=rRect.Right()-rRect.Left();
52 tools::Long nHgt1=rRect.Bottom()-rRect.Top();
53 SdrTextObj::NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
54 SdrTextObj::NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
55 }
56 else
57 {
58 // No rotation or shear.
59
60 setRectangle(rRect);
62
64
67 }
68}
69
71{
72 return getRectangle();
73}
74
76{
77 setRectangle(rRect);
79
81
83}
84
86{
88}
89
90Degree100 SdrTextObj::GetShearAngle(bool /*bVertical*/) const
91{
92 return maGeo.m_nShearAngle;
93}
94
95void SdrTextObj::NbcMove(const Size& rSize)
96{
97 moveRectangle(rSize.Width(), rSize.Height());
98 moveOutRectangle(rSize.Width(), rSize.Height());
99 maSnapRect.Move(rSize);
101}
102
103void SdrTextObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
104{
105 bool bNotSheared=maGeo.m_nShearAngle==0_deg100;
106 bool bRotate90=bNotSheared && maGeo.m_nRotationAngle.get() % 9000 ==0;
107 bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
108 bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
109 if (bXMirr || bYMirr) {
110 Point aRef1(GetSnapRect().Center());
111 if (bXMirr) {
112 Point aRef2(aRef1);
113 aRef2.AdjustY( 1 );
114 NbcMirrorGluePoints(aRef1,aRef2);
115 }
116 if (bYMirr) {
117 Point aRef2(aRef1);
118 aRef2.AdjustX( 1 );
119 NbcMirrorGluePoints(aRef1,aRef2);
120 }
121 }
122
123 if (maGeo.m_nRotationAngle==0_deg100 && maGeo.m_nShearAngle==0_deg100) {
124 auto aRectangle = getRectangle();
125 ResizeRect(aRectangle, rRef, xFact, yFact);
126 setRectangle(aRectangle);
127 if (bYMirr)
128 {
130 moveRectangle(aRectangle.Right() - aRectangle.Left(), aRectangle.Bottom() - aRectangle.Top());
131 maGeo.m_nRotationAngle=18000_deg100;
133 }
134 }
135 else
136 {
138
139 for(sal_uInt16 a(0); a < aPol.GetSize(); a++)
140 {
141 ResizePoint(aPol[a], rRef, xFact, yFact);
142 }
143
144 if(bXMirr != bYMirr)
145 {
146 // turn polygon and move it a little
147 tools::Polygon aPol0(aPol);
148
149 aPol[0] = aPol0[1];
150 aPol[1] = aPol0[0];
151 aPol[2] = aPol0[3];
152 aPol[3] = aPol0[2];
153 aPol[4] = aPol0[1];
154 }
156 setRectangle(aRectangle);
157 }
158
159 if (bRotate90) {
160 bool bRota90=maGeo.m_nRotationAngle.get() % 9000 ==0;
161 if (!bRota90) { // there's seems to be a rounding error occurring: correct it
163 if (a<4500_deg100) a=0_deg100;
164 else if (a<13500_deg100) a=9000_deg100;
165 else if (a<22500_deg100) a=18000_deg100;
166 else if (a<31500_deg100) a=27000_deg100;
167 else a=0_deg100;
170 }
171 if (bNotSheared!=(maGeo.m_nShearAngle==0_deg100)) { // correct a rounding error occurring with Shear
172 maGeo.m_nShearAngle=0_deg100;
174 }
175 }
176
178
180
181 if(mbTextFrame && !getSdrModelFromSdrObject().IsPasteResize())
182 {
184 }
185
188}
189
190void SdrTextObj::NbcRotate(const Point& rRef, Degree100 nAngle, double sn, double cs)
191{
195 Point aPoint1(getRectangle().TopLeft());
196 RotatePoint(aPoint1, rRef, sn, cs);
197 Point aPoint2(aPoint1.X() + dx, aPoint1.Y() + dy);
198 tools::Rectangle aRectangle(aPoint1, aPoint2);
199 setRectangle(aRectangle);
200
201 if (maGeo.m_nRotationAngle==0_deg100) {
205 } else {
208 }
210 NbcRotateGluePoints(rRef,nAngle,sn,cs);
212}
213
214void SdrTextObj::NbcShear(const Point& rRef, Degree100 /*nAngle*/, double tn, bool bVShear)
215{
217
218 // when this is a SdrPathObj, aRect may be uninitialized
220
221 sal_uInt16 nPointCount=aPol.GetSize();
222 for (sal_uInt16 i=0; i<nPointCount; i++) {
223 ShearPoint(aPol[i],rRef,tn,bVShear);
224 }
226 setRectangle(aRectangle);
228
229 if (mbTextFrame) {
231 }
234 NbcShearGluePoints(rRef,tn,bVShear);
236}
237
238void SdrTextObj::NbcMirror(const Point& rRef1, const Point& rRef2)
239{
241 bool bNotSheared=maGeo.m_nShearAngle==0_deg100;
242 bool bRotate90 = false;
243 if (bNotSheared &&
244 (rRef1.X()==rRef2.X() || rRef1.Y()==rRef2.Y() ||
245 std::abs(rRef1.X()-rRef2.X())==std::abs(rRef1.Y()-rRef2.Y()))) {
246 bRotate90=maGeo.m_nRotationAngle.get() % 9000 ==0;
247 }
249 sal_uInt16 i;
250 sal_uInt16 nPointCount=aPol.GetSize();
251 for (i=0; i<nPointCount; i++) {
252 MirrorPoint(aPol[i],rRef1,rRef2);
253 }
254 // turn polygon and move it a little
255 tools::Polygon aPol0(aPol);
256 aPol[0]=aPol0[1];
257 aPol[1]=aPol0[0];
258 aPol[2]=aPol0[3];
259 aPol[3]=aPol0[2];
260 aPol[4]=aPol0[1];
262 setRectangle(aRectangle);
263
264 if (bRotate90) {
265 bool bRota90=maGeo.m_nRotationAngle.get() % 9000 ==0;
266 if (bRotate90 && !bRota90) { // there's seems to be a rounding error occurring: correct it
268 if (a<4500_deg100) a=0_deg100;
269 else if (a<13500_deg100) a=9000_deg100;
270 else if (a<22500_deg100) a=18000_deg100;
271 else if (a<31500_deg100) a=27000_deg100;
272 else a=0_deg100;
275 }
276 }
277 if (bNotSheared!=(maGeo.m_nShearAngle==0_deg100)) { // correct a rounding error occurring with Shear
278 maGeo.m_nShearAngle=0_deg100;
280 }
281
283 if (mbTextFrame) {
285 }
288 NbcMirrorGluePoints(rRef1,rRef2);
290}
291
292
294{
296
298 {
299 // suppress HelpTexts from PresObj's
300 return nullptr;
301 }
302
303 // create an extractor with neutral ViewInformation
304 const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
305 drawinglayer::processor2d::TextAsPolygonExtractor2D aExtractor(aViewInformation2D);
306
307 // extract text as polygons
309
310 // get results
312 const sal_uInt32 nResultCount(rResult.size());
313
314 if(nResultCount)
315 {
316 // prepare own target
318 SdrObjList* pObjectList = pGroup->GetSubList();
319
320 // process results
321 for(sal_uInt32 a(0); a < nResultCount; a++)
322 {
323 const drawinglayer::processor2d::TextAsPolygonDataNode& rCandidate = rResult[a];
324 basegfx::B2DPolyPolygon aPolyPolygon(rCandidate.getB2DPolyPolygon());
325
326 if(aPolyPolygon.count())
327 {
328 // take care of wanted polygon type
329 if(bToPoly)
330 {
331 if(aPolyPolygon.areControlPointsUsed())
332 {
333 aPolyPolygon = basegfx::utils::adaptiveSubdivideByAngle(aPolyPolygon);
334 }
335 }
336 else
337 {
338 if(!aPolyPolygon.areControlPointsUsed())
339 {
340 aPolyPolygon = basegfx::utils::expandToCurve(aPolyPolygon);
341 }
342 }
343
344 // create ItemSet with object attributes
345 SfxItemSet aAttributeSet(GetObjectItemSet());
347
348 // always clear objectshadow; this is included in the extraction
349 aAttributeSet.Put(makeSdrShadowItem(false));
350
351 if(rCandidate.getIsFilled())
352 {
353 // set needed items
354 aAttributeSet.Put(XFillColorItem(OUString(), Color(rCandidate.getBColor())));
355 aAttributeSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
356 aAttributeSet.Put(XFillStyleItem(drawing::FillStyle_SOLID));
357
358 // create filled SdrPathObj
359 pPathObj = new SdrPathObj(
362 aPolyPolygon);
363 }
364 else
365 {
366 // set needed items
367 aAttributeSet.Put(XLineColorItem(OUString(), Color(rCandidate.getBColor())));
368 aAttributeSet.Put(XLineStyleItem(drawing::LineStyle_SOLID));
369 aAttributeSet.Put(XLineWidthItem(0));
370 aAttributeSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
371
372 // create line SdrPathObj
373 pPathObj = new SdrPathObj(
376 std::move(aPolyPolygon));
377 }
378
379 // copy basic information from original
380 pPathObj->ImpSetAnchorPos(GetAnchorPos());
381 pPathObj->NbcSetLayer(GetLayer());
382 pPathObj->NbcSetStyleSheet(GetStyleSheet(), true);
383
384 // apply prepared ItemSet and add to target
385 pPathObj->SetMergedItemSet(aAttributeSet);
386 pObjectList->InsertObject(pPathObj.get());
387 }
388 }
389
390 // postprocess; if no result and/or only one object, simplify
391 if(!pObjectList->GetObjCount())
392 {
393 pGroup.clear();
394 }
395 else if(1 == pObjectList->GetObjCount())
396 {
397 pRetval = pObjectList->RemoveObject(0);
398 pGroup.clear();
399 }
400 else
401 {
402 pRetval = pGroup;
403 }
404 }
405
406 return pRetval;
407}
408
409
411{
412 if(bAddText)
413 {
415 }
416
417 return nullptr;
418}
419
421{
423}
424
425rtl::Reference<SdrPathObj> SdrTextObj::ImpConvertMakeObj(const basegfx::B2DPolyPolygon& rPolyPolygon, bool bClosed, bool bBezier) const
426{
428 basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPolygon);
429
430 // #i37011#
431 if(!bBezier)
432 {
433 aB2DPolyPolygon = basegfx::utils::adaptiveSubdivideByAngle(aB2DPolyPolygon);
434 ePathKind = bClosed ? SdrObjKind::Polygon : SdrObjKind::PolyLine;
435 }
436
439 ePathKind,
440 std::move(aB2DPolyPolygon)));
441
442 if(bBezier)
443 {
444 // create bezier curves
445 pPathObj->SetPathPoly(basegfx::utils::expandToCurve(pPathObj->GetPathPoly()));
446 }
447
448 pPathObj->ImpSetAnchorPos(m_aAnchor);
449 pPathObj->NbcSetLayer(GetLayer());
451 pPathObj->ClearMergedItem();
452 pPathObj->SetMergedItemSet(GetObjectItemSet());
453 pPathObj->GetProperties().BroadcastItemChange(aC);
454 pPathObj->NbcSetStyleSheet(GetStyleSheet(), true);
455
456 return pPathObj;
457}
458
460{
462 {
463 return pObj;
464 }
465
467
468 if(!pText)
469 {
470 return pObj;
471 }
472
473 if(!pObj)
474 {
475 return pText;
476 }
477
478 if(pText->IsGroupObject())
479 {
480 // is already group object, add partial shape in front
481 SdrObjList* pOL=pText->GetSubList();
482 pOL->InsertObject(pObj.get(),0);
483
484 return pText;
485 }
486 else
487 {
488 // not yet a group, create one and add partial and new shapes
490 SdrObjList* pOL=pGrp->GetSubList();
491 pOL->InsertObject(pObj.get());
492 pOL->InsertObject(pText.get());
493
494 return pGrp;
495 }
496}
497
498/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 GetNumerator() const
sal_Int32 GetDenominator() const
double mfCosRotationAngle
Definition: svdtrans.hxx:207
double mfSinRotationAngle
Definition: svdtrans.hxx:206
void RecalcTan()
Definition: svdtrans.cxx:456
void RecalcSinCos()
Definition: svdtrans.cxx:444
Degree100 m_nShearAngle
Definition: svdtrans.hxx:204
Degree100 m_nRotationAngle
Definition: svdtrans.hxx:203
constexpr tools::Long Y() const
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
virtual const tools::Rectangle & GetSnapRect() const override
Definition: svdoattr.cxx:49
tools::Rectangle maSnapRect
Definition: svdoattr.hxx:41
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE)
Definition: svdpage.cxx:295
size_t GetObjCount() const
Definition: svdpage.cxx:779
virtual rtl::Reference< SdrObject > RemoveObject(size_t nObjNum)
Definition: svdpage.cxx:373
const Point & GetAnchorPos() const
Definition: svdobj.cxx:1653
void moveOutRectangle(sal_Int32 nXDelta, sal_Int32 nYDelta)
Definition: svdobj.cxx:3193
Point m_aAnchor
Definition: svdobj.hxx:896
void NbcMirrorGluePoints(const Point &rRef1, const Point &rRef2)
Definition: svdobj.cxx:2348
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:289
void NbcShearGluePoints(const Point &rRef, double tn, bool bVShear)
Definition: svdobj.cxx:2358
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2244
sdr::contact::ViewContact & GetViewContact() const
Definition: svdobj.cxx:261
virtual SdrLayerID GetLayer() const
Definition: svdobj.cxx:645
void NbcRotateGluePoints(const Point &rRef, Degree100 nAngle, double sn, double cs)
Definition: svdobj.cxx:2338
void SetGlueReallyAbsolute(bool bOn)
Definition: svdobj.cxx:2328
virtual void SetBoundAndSnapRectsDirty(bool bNotMyself=false, bool bRecursive=true)
Definition: svdobj.cxx:509
const SfxItemSet & GetObjectItemSet() const
Definition: svdobj.cxx:1969
GeoStat maGeo
Definition: svdotext.hxx:196
virtual void AdaptTextMinSize()
Definition: svdotext.cxx:507
tools::Rectangle const & getRectangle() const
Definition: svdotext.hxx:170
virtual void NbcMirror(const Point &rRef1, const Point &rRef2) override
Definition: svdotxtr.cxx:238
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
Definition: svdotxtr.cxx:43
virtual void NbcShear(const Point &rRef, Degree100 nAngle, double tn, bool bVShear) override
Definition: svdotxtr.cxx:214
virtual void NbcMove(const Size &rSiz) override
The methods Move, Resize, Rotate, Mirror, Shear, SetSnapRect and SetLogicRect call the corresponding ...
Definition: svdotxtr.cxx:95
virtual Degree100 GetRotateAngle() const override
Definition: svdotxtr.cxx:85
void moveRectangle(sal_Int32 nXDelta, sal_Int32 nYDelta)
Definition: svdotext.hxx:185
void ImpCheckShear()
Definition: svdotext.cxx:420
tools::Rectangle maRectangle
Definition: svdotext.hxx:168
rtl::Reference< SdrPathObj > ImpConvertMakeObj(const basegfx::B2DPolyPolygon &rPolyPolygon, bool bClosed, bool bBezier) const
Definition: svdotxtr.cxx:425
bool ImpCanConvTextToCurve() const
Definition: svdotxtr.cxx:420
virtual bool NbcAdjustTextFrameWidthAndHeight(bool bHgt=true, bool bWdt=true)
Definition: svdotxat.cxx:241
virtual const tools::Rectangle & GetLogicRect() const override
Definition: svdotxtr.cxx:70
static void ImpJustifyRect(tools::Rectangle &rRect)
Definition: svdotext.cxx:411
bool IsOutlText() const
Definition: svdotext.hxx:360
SVX_DLLPRIVATE rtl::Reference< SdrObject > ImpConvertContainedTextToSdrPathObjs(bool bToPoly) const
Definition: svdotxtr.cxx:293
virtual Degree100 GetShearAngle(bool bVertical=false) const override
Definition: svdotxtr.cxx:90
rtl::Reference< SdrObject > ImpConvertAddText(rtl::Reference< SdrObject > pObj, bool bBezier) const
Definition: svdotxtr.cxx:459
virtual rtl::Reference< SdrObject > DoConvertToPolyObj(bool bBezier, bool bAddText) const override
Definition: svdotxtr.cxx:410
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdotxtr.cxx:103
void setRectangle(tools::Rectangle const &rRectangle)
Definition: svdotext.hxx:175
bool mbTextFrame
Definition: svdotext.hxx:242
virtual void NbcSetLogicRect(const tools::Rectangle &rRect) override
Definition: svdotxtr.cxx:75
virtual void NbcRotate(const Point &rRef, Degree100 nAngle, double sn, double cs) override
Definition: svdotxtr.cxx:190
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
constexpr tools::Long Height() const
constexpr tools::Long Width() const
bool areControlPointsUsed() const
sal_uInt32 count() const
const TextAsPolygonDataNodeVector & getTarget() const
void getViewIndependentPrimitive2DContainer(drawinglayer::primitive2d::Primitive2DDecompositionVisitor &rVisitor) const
sal_uInt16 GetSize() const
constexpr tools::Long Top() const
constexpr Point TopLeft() const
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
constexpr tools::Long Right() const
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
static bool IsFuzzing()
uno_Any a
B2DPolygon expandToCurve(const B2DPolygon &rCandidate)
B2DPolygon adaptiveSubdivideByAngle(const B2DPolygon &rCandidate, double fAngleBound)
::std::vector< TextAsPolygonDataNode > TextAsPolygonDataNodeVector
int i
tools::Rectangle polygonToRectangle(const tools::Polygon &rPolygon, GeoStat &rGeo)
Definition: svdtrans.cxx:482
long Long
SdrOnOffItem makeSdrShadowItem(bool bShadow)
Definition: sdshitm.hxx:25
const basegfx::BColor & getBColor() const
const basegfx::B2DPolyPolygon & getB2DPolyPolygon() const
UNDERLYING_TYPE get() const
SdrObjKind
Definition: svdobjkind.hxx:25
@ PathFill
open Bezier-curve
@ Polygon
circle cut
@ PathLine
PolyLine.
@ PolyLine
polygon, PolyPolygon
void ResizeRect(tools::Rectangle &rRect, const Point &rRef, const Fraction &rxFact, const Fraction &ryFact)
Definition: svdtrans.cxx:38
tools::Polygon Rect2Poly(const tools::Rectangle &rRect, const GeoStat &rGeo)
Definition: svdtrans.cxx:467
void MirrorPoint(Point &rPnt, const Point &rRef1, const Point &rRef2)
Definition: svdtrans.cxx:105
Degree100 NormAngle36000(Degree100 a)
Normalize angle to -180.00..179.99.
Definition: svdtrans.cxx:408
void ShearPoint(Point &rPnt, const Point &rRef, double tn, bool bVShear=false)
Definition: svdtrans.hxx:109
void RotatePoint(Point &rPnt, const Point &rRef, double sn, double cs)
Definition: svdtrans.hxx:101
void ResizePoint(Point &rPnt, const Point &rRef, const Fraction &xFract, const Fraction &yFract)
Definition: svdtrans.hxx:93
Center