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>
39
40using namespace com::sun::star;
41
43{
45 {
46 // Either the rotation or shear angle exists.
48 tools::Long nWdt0=aSR0.Right()-aSR0.Left();
49 tools::Long nHgt0=aSR0.Bottom()-aSR0.Top();
50 tools::Long nWdt1=rRect.Right()-rRect.Left();
51 tools::Long nHgt1=rRect.Bottom()-rRect.Top();
52 SdrTextObj::NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
53 SdrTextObj::NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
54 }
55 else
56 {
57 // No rotation or shear.
58
59 maRect = rRect;
61
63
66 }
67}
68
70{
71 return maRect;
72}
73
75{
76 maRect = rRect;
78
80
82}
83
85{
86 return maGeo.nRotationAngle;
87}
88
89Degree100 SdrTextObj::GetShearAngle(bool /*bVertical*/) const
90{
91 return maGeo.nShearAngle;
92}
93
94void SdrTextObj::NbcMove(const Size& rSize)
95{
96 maRect.Move(rSize);
97 moveOutRectangle(rSize.Width(), rSize.Height());
98 maSnapRect.Move(rSize);
100}
101
102void SdrTextObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
103{
104 bool bNotSheared=maGeo.nShearAngle==0_deg100;
105 bool bRotate90=bNotSheared && maGeo.nRotationAngle.get() % 9000 ==0;
106 bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
107 bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
108 if (bXMirr || bYMirr) {
109 Point aRef1(GetSnapRect().Center());
110 if (bXMirr) {
111 Point aRef2(aRef1);
112 aRef2.AdjustY( 1 );
113 NbcMirrorGluePoints(aRef1,aRef2);
114 }
115 if (bYMirr) {
116 Point aRef2(aRef1);
117 aRef2.AdjustX( 1 );
118 NbcMirrorGluePoints(aRef1,aRef2);
119 }
120 }
121
122 if (maGeo.nRotationAngle==0_deg100 && maGeo.nShearAngle==0_deg100) {
123 ResizeRect(maRect,rRef,xFact,yFact);
124 if (bYMirr) {
127 maGeo.nRotationAngle=18000_deg100;
129 }
130 }
131 else
132 {
134
135 for(sal_uInt16 a(0); a < aPol.GetSize(); a++)
136 {
137 ResizePoint(aPol[a], rRef, xFact, yFact);
138 }
139
140 if(bXMirr != bYMirr)
141 {
142 // turn polygon and move it a little
143 tools::Polygon aPol0(aPol);
144
145 aPol[0] = aPol0[1];
146 aPol[1] = aPol0[0];
147 aPol[2] = aPol0[3];
148 aPol[3] = aPol0[2];
149 aPol[4] = aPol0[1];
150 }
151
152 Poly2Rect(aPol, maRect, maGeo);
153 }
154
155 if (bRotate90) {
156 bool bRota90=maGeo.nRotationAngle.get() % 9000 ==0;
157 if (!bRota90) { // there's seems to be a rounding error occurring: correct it
159 if (a<4500_deg100) a=0_deg100;
160 else if (a<13500_deg100) a=9000_deg100;
161 else if (a<22500_deg100) a=18000_deg100;
162 else if (a<31500_deg100) a=27000_deg100;
163 else a=0_deg100;
166 }
167 if (bNotSheared!=(maGeo.nShearAngle==0_deg100)) { // correct a rounding error occurring with Shear
168 maGeo.nShearAngle=0_deg100;
170 }
171 }
172
174
176
177 if(mbTextFrame && !getSdrModelFromSdrObject().IsPasteResize())
178 {
180 }
181
184}
185
186void SdrTextObj::NbcRotate(const Point& rRef, Degree100 nAngle, double sn, double cs)
187{
191 Point aP(maRect.TopLeft());
192 RotatePoint(aP,rRef,sn,cs);
193 maRect.SetLeft(aP.X() );
194 maRect.SetTop(aP.Y() );
195 maRect.SetRight(maRect.Left()+dx );
196 maRect.SetBottom(maRect.Top()+dy );
197 if (maGeo.nRotationAngle==0_deg100) {
201 } else {
204 }
206 NbcRotateGluePoints(rRef,nAngle,sn,cs);
208}
209
210void SdrTextObj::NbcShear(const Point& rRef, Degree100 /*nAngle*/, double tn, bool bVShear)
211{
213
214 // when this is a SdrPathObj, aRect may be uninitialized
216
217 sal_uInt16 nPointCount=aPol.GetSize();
218 for (sal_uInt16 i=0; i<nPointCount; i++) {
219 ShearPoint(aPol[i],rRef,tn,bVShear);
220 }
221 Poly2Rect(aPol,maRect,maGeo);
223 if (mbTextFrame) {
225 }
228 NbcShearGluePoints(rRef,tn,bVShear);
230}
231
232void SdrTextObj::NbcMirror(const Point& rRef1, const Point& rRef2)
233{
235 bool bNotSheared=maGeo.nShearAngle==0_deg100;
236 bool bRotate90 = false;
237 if (bNotSheared &&
238 (rRef1.X()==rRef2.X() || rRef1.Y()==rRef2.Y() ||
239 std::abs(rRef1.X()-rRef2.X())==std::abs(rRef1.Y()-rRef2.Y()))) {
240 bRotate90=maGeo.nRotationAngle.get() % 9000 ==0;
241 }
243 sal_uInt16 i;
244 sal_uInt16 nPointCount=aPol.GetSize();
245 for (i=0; i<nPointCount; i++) {
246 MirrorPoint(aPol[i],rRef1,rRef2);
247 }
248 // turn polygon and move it a little
249 tools::Polygon aPol0(aPol);
250 aPol[0]=aPol0[1];
251 aPol[1]=aPol0[0];
252 aPol[2]=aPol0[3];
253 aPol[3]=aPol0[2];
254 aPol[4]=aPol0[1];
255 Poly2Rect(aPol,maRect,maGeo);
256
257 if (bRotate90) {
258 bool bRota90=maGeo.nRotationAngle.get() % 9000 ==0;
259 if (bRotate90 && !bRota90) { // there's seems to be a rounding error occurring: correct it
261 if (a<4500_deg100) a=0_deg100;
262 else if (a<13500_deg100) a=9000_deg100;
263 else if (a<22500_deg100) a=18000_deg100;
264 else if (a<31500_deg100) a=27000_deg100;
265 else a=0_deg100;
268 }
269 }
270 if (bNotSheared!=(maGeo.nShearAngle==0_deg100)) { // correct a rounding error occurring with Shear
271 maGeo.nShearAngle=0_deg100;
273 }
274
276 if (mbTextFrame) {
278 }
281 NbcMirrorGluePoints(rRef1,rRef2);
283}
284
285
287{
289
291 {
292 // suppress HelpTexts from PresObj's
293 return nullptr;
294 }
295
296 // create an extractor with neutral ViewInformation
297 const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
298 drawinglayer::processor2d::TextAsPolygonExtractor2D aExtractor(aViewInformation2D);
299
300 // extract text as polygons
302
303 // get results
305 const sal_uInt32 nResultCount(rResult.size());
306
307 if(nResultCount)
308 {
309 // prepare own target
311 SdrObjList* pObjectList = pGroup->GetSubList();
312
313 // process results
314 for(sal_uInt32 a(0); a < nResultCount; a++)
315 {
316 const drawinglayer::processor2d::TextAsPolygonDataNode& rCandidate = rResult[a];
317 basegfx::B2DPolyPolygon aPolyPolygon(rCandidate.getB2DPolyPolygon());
318
319 if(aPolyPolygon.count())
320 {
321 // take care of wanted polygon type
322 if(bToPoly)
323 {
324 if(aPolyPolygon.areControlPointsUsed())
325 {
326 aPolyPolygon = basegfx::utils::adaptiveSubdivideByAngle(aPolyPolygon);
327 }
328 }
329 else
330 {
331 if(!aPolyPolygon.areControlPointsUsed())
332 {
333 aPolyPolygon = basegfx::utils::expandToCurve(aPolyPolygon);
334 }
335 }
336
337 // create ItemSet with object attributes
338 SfxItemSet aAttributeSet(GetObjectItemSet());
340
341 // always clear objectshadow; this is included in the extraction
342 aAttributeSet.Put(makeSdrShadowItem(false));
343
344 if(rCandidate.getIsFilled())
345 {
346 // set needed items
347 aAttributeSet.Put(XFillColorItem(OUString(), Color(rCandidate.getBColor())));
348 aAttributeSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
349 aAttributeSet.Put(XFillStyleItem(drawing::FillStyle_SOLID));
350
351 // create filled SdrPathObj
352 pPathObj = new SdrPathObj(
355 aPolyPolygon);
356 }
357 else
358 {
359 // set needed items
360 aAttributeSet.Put(XLineColorItem(OUString(), Color(rCandidate.getBColor())));
361 aAttributeSet.Put(XLineStyleItem(drawing::LineStyle_SOLID));
362 aAttributeSet.Put(XLineWidthItem(0));
363 aAttributeSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
364
365 // create line SdrPathObj
366 pPathObj = new SdrPathObj(
369 std::move(aPolyPolygon));
370 }
371
372 // copy basic information from original
373 pPathObj->ImpSetAnchorPos(GetAnchorPos());
374 pPathObj->NbcSetLayer(GetLayer());
375 pPathObj->NbcSetStyleSheet(GetStyleSheet(), true);
376
377 // apply prepared ItemSet and add to target
378 pPathObj->SetMergedItemSet(aAttributeSet);
379 pObjectList->InsertObject(pPathObj.get());
380 }
381 }
382
383 // postprocess; if no result and/or only one object, simplify
384 if(!pObjectList->GetObjCount())
385 {
386 pGroup.clear();
387 }
388 else if(1 == pObjectList->GetObjCount())
389 {
390 pRetval = pObjectList->RemoveObject(0);
391 pGroup.clear();
392 }
393 else
394 {
395 pRetval = pGroup;
396 }
397 }
398
399 return pRetval;
400}
401
402
404{
405 if(bAddText)
406 {
408 }
409
410 return nullptr;
411}
412
414{
415 return !IsOutlText();
416}
417
418rtl::Reference<SdrPathObj> SdrTextObj::ImpConvertMakeObj(const basegfx::B2DPolyPolygon& rPolyPolygon, bool bClosed, bool bBezier) const
419{
421 basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPolygon);
422
423 // #i37011#
424 if(!bBezier)
425 {
426 aB2DPolyPolygon = basegfx::utils::adaptiveSubdivideByAngle(aB2DPolyPolygon);
427 ePathKind = bClosed ? SdrObjKind::Polygon : SdrObjKind::PolyLine;
428 }
429
432 ePathKind,
433 std::move(aB2DPolyPolygon)));
434
435 if(bBezier)
436 {
437 // create bezier curves
438 pPathObj->SetPathPoly(basegfx::utils::expandToCurve(pPathObj->GetPathPoly()));
439 }
440
441 pPathObj->ImpSetAnchorPos(m_aAnchor);
442 pPathObj->NbcSetLayer(GetLayer());
444 pPathObj->ClearMergedItem();
445 pPathObj->SetMergedItemSet(GetObjectItemSet());
446 pPathObj->GetProperties().BroadcastItemChange(aC);
447 pPathObj->NbcSetStyleSheet(GetStyleSheet(), true);
448
449 return pPathObj;
450}
451
453{
455 {
456 return pObj;
457 }
458
460
461 if(!pText)
462 {
463 return pObj;
464 }
465
466 if(!pObj)
467 {
468 return pText;
469 }
470
471 if(pText->IsGroupObject())
472 {
473 // is already group object, add partial shape in front
474 SdrObjList* pOL=pText->GetSubList();
475 pOL->InsertObject(pObj.get(),0);
476
477 return pText;
478 }
479 else
480 {
481 // not yet a group, create one and add partial and new shapes
483 SdrObjList* pOL=pGrp->GetSubList();
484 pOL->InsertObject(pObj.get());
485 pOL->InsertObject(pText.get());
486
487 return pGrp;
488 }
489}
490
491/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 GetNumerator() const
sal_Int32 GetDenominator() const
double mfCosRotationAngle
Definition: svdtrans.hxx:207
Degree100 nShearAngle
Definition: svdtrans.hxx:204
double mfSinRotationAngle
Definition: svdtrans.hxx:206
void RecalcTan()
Definition: svdtrans.cxx:456
void RecalcSinCos()
Definition: svdtrans.cxx:444
Degree100 nRotationAngle
Definition: svdtrans.hxx:203
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:332
size_t GetObjCount() const
Definition: svdpage.cxx:816
virtual rtl::Reference< SdrObject > RemoveObject(size_t nObjNum)
Definition: svdpage.cxx:410
const Point & GetAnchorPos() const
Definition: svdobj.cxx:1656
void moveOutRectangle(sal_Int32 nXDelta, sal_Int32 nYDelta)
Definition: svdobj.cxx:3198
Point m_aAnchor
Definition: svdobj.hxx:902
void NbcMirrorGluePoints(const Point &rRef1, const Point &rRef2)
Definition: svdobj.cxx:2351
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:289
void NbcShearGluePoints(const Point &rRef, double tn, bool bVShear)
Definition: svdobj.cxx:2361
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2247
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:2341
void SetGlueReallyAbsolute(bool bOn)
Definition: svdobj.cxx:2331
virtual void SetBoundAndSnapRectsDirty(bool bNotMyself=false, bool bRecursive=true)
Definition: svdobj.cxx:509
const SfxItemSet & GetObjectItemSet() const
Definition: svdobj.cxx:1972
GeoStat maGeo
Definition: svdotext.hxx:171
virtual void AdaptTextMinSize()
Definition: svdotext.cxx:501
virtual void NbcMirror(const Point &rRef1, const Point &rRef2) override
Definition: svdotxtr.cxx:232
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
Definition: svdotxtr.cxx:42
virtual void NbcShear(const Point &rRef, Degree100 nAngle, double tn, bool bVShear) override
Definition: svdotxtr.cxx:210
virtual void NbcMove(const Size &rSiz) override
The methods Move, Resize, Rotate, Mirror, Shear, SetSnapRect and SetLogicRect call the corresponding ...
Definition: svdotxtr.cxx:94
virtual Degree100 GetRotateAngle() const override
Definition: svdotxtr.cxx:84
tools::Rectangle maRect
Definition: svdotext.hxx:168
void ImpCheckShear()
Definition: svdotext.cxx:414
rtl::Reference< SdrPathObj > ImpConvertMakeObj(const basegfx::B2DPolyPolygon &rPolyPolygon, bool bClosed, bool bBezier) const
Definition: svdotxtr.cxx:418
bool ImpCanConvTextToCurve() const
Definition: svdotxtr.cxx:413
virtual bool NbcAdjustTextFrameWidthAndHeight(bool bHgt=true, bool bWdt=true)
Definition: svdotxat.cxx:241
virtual const tools::Rectangle & GetLogicRect() const override
Definition: svdotxtr.cxx:69
static void ImpJustifyRect(tools::Rectangle &rRect)
Definition: svdotext.cxx:405
bool IsOutlText() const
Definition: svdotext.hxx:333
SVX_DLLPRIVATE rtl::Reference< SdrObject > ImpConvertContainedTextToSdrPathObjs(bool bToPoly) const
Definition: svdotxtr.cxx:286
virtual Degree100 GetShearAngle(bool bVertical=false) const override
Definition: svdotxtr.cxx:89
rtl::Reference< SdrObject > ImpConvertAddText(rtl::Reference< SdrObject > pObj, bool bBezier) const
Definition: svdotxtr.cxx:452
virtual rtl::Reference< SdrObject > DoConvertToPolyObj(bool bBezier, bool bAddText) const override
Definition: svdotxtr.cxx:403
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdotxtr.cxx:102
bool mbTextFrame
Definition: svdotext.hxx:217
virtual void NbcSetLogicRect(const tools::Rectangle &rRect) override
Definition: svdotxtr.cxx:74
virtual void NbcRotate(const Point &rRef, Degree100 nAngle, double sn, double cs) override
Definition: svdotxtr.cxx:186
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 void SetLeft(tools::Long v)
constexpr void SetTop(tools::Long v)
constexpr tools::Long Top() const
constexpr Point TopLeft() const
constexpr void SetRight(tools::Long v)
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
constexpr tools::Long Right() const
constexpr void SetBottom(tools::Long v)
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
constexpr bool IsEmpty() const
uno_Any a
B2DPolygon expandToCurve(const B2DPolygon &rCandidate)
B2DPolygon adaptiveSubdivideByAngle(const B2DPolygon &rCandidate, double fAngleBound)
::std::vector< TextAsPolygonDataNode > TextAsPolygonDataNodeVector
int i
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 Poly2Rect(const tools::Polygon &rPol, tools::Rectangle &rRect, GeoStat &rGeo)
Definition: svdtrans.cxx:480
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