xref: /AOO41X/main/svx/source/svdraw/svdotxtr.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_svx.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <svx/svdotext.hxx>
32*cdf0e10cSrcweir #include "svx/svditext.hxx"
33*cdf0e10cSrcweir #include <svx/svdtrans.hxx>
34*cdf0e10cSrcweir #include <svx/svdogrp.hxx>
35*cdf0e10cSrcweir #include <svx/svdopath.hxx>
36*cdf0e10cSrcweir #include <svx/svdoutl.hxx>
37*cdf0e10cSrcweir #include <svx/svdpage.hxx>   // fuer Convert
38*cdf0e10cSrcweir #include <svx/svdmodel.hxx>  // fuer Convert
39*cdf0e10cSrcweir #include <editeng/outliner.hxx>
40*cdf0e10cSrcweir #include <svx/sdr/properties/itemsettools.hxx>
41*cdf0e10cSrcweir #include <svx/sdr/properties/properties.hxx>
42*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx>
43*cdf0e10cSrcweir #include <svl/itemset.hxx>
44*cdf0e10cSrcweir #include <svx/svditer.hxx>
45*cdf0e10cSrcweir #include <drawinglayer/processor2d/textaspolygonextractor2d.hxx>
46*cdf0e10cSrcweir #include <svx/sdr/contact/viewcontact.hxx>
47*cdf0e10cSrcweir #include <svx/xflclit.hxx>
48*cdf0e10cSrcweir #include <svx/xlnclit.hxx>
49*cdf0e10cSrcweir #include <svx/xlnwtit.hxx>
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
52*cdf0e10cSrcweir //
53*cdf0e10cSrcweir //  @@@@@@ @@@@@ @@   @@ @@@@@@  @@@@  @@@@@  @@@@@@
54*cdf0e10cSrcweir //    @@   @@    @@@ @@@   @@   @@  @@ @@  @@     @@
55*cdf0e10cSrcweir //    @@   @@     @@@@@    @@   @@  @@ @@  @@     @@
56*cdf0e10cSrcweir //    @@   @@@@    @@@     @@   @@  @@ @@@@@      @@
57*cdf0e10cSrcweir //    @@   @@     @@@@@    @@   @@  @@ @@  @@     @@
58*cdf0e10cSrcweir //    @@   @@    @@@ @@@   @@   @@  @@ @@  @@ @@  @@
59*cdf0e10cSrcweir //    @@   @@@@@ @@   @@   @@    @@@@  @@@@@   @@@@
60*cdf0e10cSrcweir //
61*cdf0e10cSrcweir //  Transformationen
62*cdf0e10cSrcweir //
63*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir void SdrTextObj::NbcSetSnapRect(const Rectangle& rRect)
66*cdf0e10cSrcweir {
67*cdf0e10cSrcweir 	if (aGeo.nDrehWink!=0 || aGeo.nShearWink!=0) {
68*cdf0e10cSrcweir 		Rectangle aSR0(GetSnapRect());
69*cdf0e10cSrcweir 		long nWdt0=aSR0.Right()-aSR0.Left();
70*cdf0e10cSrcweir 		long nHgt0=aSR0.Bottom()-aSR0.Top();
71*cdf0e10cSrcweir 		long nWdt1=rRect.Right()-rRect.Left();
72*cdf0e10cSrcweir 		long nHgt1=rRect.Bottom()-rRect.Top();
73*cdf0e10cSrcweir 		SdrTextObj::NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
74*cdf0e10cSrcweir 		SdrTextObj::NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
75*cdf0e10cSrcweir 	} else {
76*cdf0e10cSrcweir 		long nHDist=GetTextLeftDistance()+GetTextRightDistance();
77*cdf0e10cSrcweir 		long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
78*cdf0e10cSrcweir 		long nTWdt0=aRect.GetWidth ()-1-nHDist; if (nTWdt0<0) nTWdt0=0;
79*cdf0e10cSrcweir 		long nTHgt0=aRect.GetHeight()-1-nVDist; if (nTHgt0<0) nTHgt0=0;
80*cdf0e10cSrcweir 		long nTWdt1=rRect.GetWidth ()-1-nHDist; if (nTWdt1<0) nTWdt1=0;
81*cdf0e10cSrcweir 		long nTHgt1=rRect.GetHeight()-1-nVDist; if (nTHgt1<0) nTHgt1=0;
82*cdf0e10cSrcweir 		aRect=rRect;
83*cdf0e10cSrcweir 		ImpJustifyRect(aRect);
84*cdf0e10cSrcweir 		if (bTextFrame && (pModel==NULL || !pModel->IsPasteResize())) { // #51139#
85*cdf0e10cSrcweir 			if (nTWdt0!=nTWdt1 && IsAutoGrowWidth() ) NbcSetMinTextFrameWidth(nTWdt1);
86*cdf0e10cSrcweir 			if (nTHgt0!=nTHgt1 && IsAutoGrowHeight()) NbcSetMinTextFrameHeight(nTHgt1);
87*cdf0e10cSrcweir 			if (GetFitToSize()==SDRTEXTFIT_RESIZEATTR) {
88*cdf0e10cSrcweir 				NbcResizeTextAttributes(Fraction(nTWdt1,nTWdt0),Fraction(nTHgt1,nTHgt0));
89*cdf0e10cSrcweir 			}
90*cdf0e10cSrcweir 			NbcAdjustTextFrameWidthAndHeight();
91*cdf0e10cSrcweir 		}
92*cdf0e10cSrcweir 		ImpCheckShear();
93*cdf0e10cSrcweir 		SetRectsDirty();
94*cdf0e10cSrcweir 	}
95*cdf0e10cSrcweir }
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir const Rectangle& SdrTextObj::GetLogicRect() const
98*cdf0e10cSrcweir {
99*cdf0e10cSrcweir 	return aRect;
100*cdf0e10cSrcweir }
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir void SdrTextObj::NbcSetLogicRect(const Rectangle& rRect)
103*cdf0e10cSrcweir {
104*cdf0e10cSrcweir 	long nHDist=GetTextLeftDistance()+GetTextRightDistance();
105*cdf0e10cSrcweir 	long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
106*cdf0e10cSrcweir 	long nTWdt0=aRect.GetWidth ()-1-nHDist; if (nTWdt0<0) nTWdt0=0;
107*cdf0e10cSrcweir 	long nTHgt0=aRect.GetHeight()-1-nVDist; if (nTHgt0<0) nTHgt0=0;
108*cdf0e10cSrcweir 	long nTWdt1=rRect.GetWidth ()-1-nHDist; if (nTWdt1<0) nTWdt1=0;
109*cdf0e10cSrcweir 	long nTHgt1=rRect.GetHeight()-1-nVDist; if (nTHgt1<0) nTHgt1=0;
110*cdf0e10cSrcweir 	aRect=rRect;
111*cdf0e10cSrcweir 	ImpJustifyRect(aRect);
112*cdf0e10cSrcweir 	if (bTextFrame) {
113*cdf0e10cSrcweir 		if (nTWdt0!=nTWdt1 && IsAutoGrowWidth() ) NbcSetMinTextFrameWidth(nTWdt1);
114*cdf0e10cSrcweir 		if (nTHgt0!=nTHgt1 && IsAutoGrowHeight()) NbcSetMinTextFrameHeight(nTHgt1);
115*cdf0e10cSrcweir 		if (GetFitToSize()==SDRTEXTFIT_RESIZEATTR) {
116*cdf0e10cSrcweir 			NbcResizeTextAttributes(Fraction(nTWdt1,nTWdt0),Fraction(nTHgt1,nTHgt0));
117*cdf0e10cSrcweir 		}
118*cdf0e10cSrcweir 		NbcAdjustTextFrameWidthAndHeight();
119*cdf0e10cSrcweir 	}
120*cdf0e10cSrcweir 	SetRectsDirty();
121*cdf0e10cSrcweir }
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir long SdrTextObj::GetRotateAngle() const
124*cdf0e10cSrcweir {
125*cdf0e10cSrcweir 	return aGeo.nDrehWink;
126*cdf0e10cSrcweir }
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir long SdrTextObj::GetShearAngle(FASTBOOL /*bVertical*/) const
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir 	return aGeo.nShearWink;
131*cdf0e10cSrcweir }
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir void SdrTextObj::NbcMove(const Size& rSiz)
134*cdf0e10cSrcweir {
135*cdf0e10cSrcweir 	MoveRect(aRect,rSiz);
136*cdf0e10cSrcweir 	MoveRect(aOutRect,rSiz);
137*cdf0e10cSrcweir 	MoveRect(maSnapRect,rSiz);
138*cdf0e10cSrcweir 	SetRectsDirty(sal_True);
139*cdf0e10cSrcweir }
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir void SdrTextObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
142*cdf0e10cSrcweir {
143*cdf0e10cSrcweir 	FASTBOOL bNoShearMerk=aGeo.nShearWink==0;
144*cdf0e10cSrcweir 	FASTBOOL bRota90Merk=bNoShearMerk && aGeo.nDrehWink % 9000 ==0;
145*cdf0e10cSrcweir 	long nHDist=GetTextLeftDistance()+GetTextRightDistance();
146*cdf0e10cSrcweir 	long nVDist=GetTextUpperDistance()+GetTextLowerDistance();
147*cdf0e10cSrcweir 	long nTWdt0=aRect.GetWidth ()-1-nHDist; if (nTWdt0<0) nTWdt0=0;
148*cdf0e10cSrcweir 	long nTHgt0=aRect.GetHeight()-1-nVDist; if (nTHgt0<0) nTHgt0=0;
149*cdf0e10cSrcweir 	FASTBOOL bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
150*cdf0e10cSrcweir 	FASTBOOL bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
151*cdf0e10cSrcweir 	if (bXMirr || bYMirr) {
152*cdf0e10cSrcweir 		Point aRef1(GetSnapRect().Center());
153*cdf0e10cSrcweir 		if (bXMirr) {
154*cdf0e10cSrcweir 			Point aRef2(aRef1);
155*cdf0e10cSrcweir 			aRef2.Y()++;
156*cdf0e10cSrcweir 			NbcMirrorGluePoints(aRef1,aRef2);
157*cdf0e10cSrcweir 		}
158*cdf0e10cSrcweir 		if (bYMirr) {
159*cdf0e10cSrcweir 			Point aRef2(aRef1);
160*cdf0e10cSrcweir 			aRef2.X()++;
161*cdf0e10cSrcweir 			NbcMirrorGluePoints(aRef1,aRef2);
162*cdf0e10cSrcweir 		}
163*cdf0e10cSrcweir 	}
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir 	if (aGeo.nDrehWink==0 && aGeo.nShearWink==0) {
166*cdf0e10cSrcweir 		ResizeRect(aRect,rRef,xFact,yFact);
167*cdf0e10cSrcweir 		if (bYMirr) {
168*cdf0e10cSrcweir 			aRect.Justify();
169*cdf0e10cSrcweir 			aRect.Move(aRect.Right()-aRect.Left(),aRect.Bottom()-aRect.Top());
170*cdf0e10cSrcweir 			aGeo.nDrehWink=18000;
171*cdf0e10cSrcweir 			aGeo.RecalcSinCos();
172*cdf0e10cSrcweir 		}
173*cdf0e10cSrcweir 	}
174*cdf0e10cSrcweir 	else
175*cdf0e10cSrcweir 	{
176*cdf0e10cSrcweir 		// #100663# aRect is NOT initialized for lines (polgon objects with two
177*cdf0e10cSrcweir 		// exceptionally handled points). Thus, after this call the text rotaion is
178*cdf0e10cSrcweir 		// gone. This error must be present since day one of this old drawing layer.
179*cdf0e10cSrcweir 		// It's astonishing that noone discovered it earlier.
180*cdf0e10cSrcweir 		// Polygon aPol(Rect2Poly(aRect,aGeo));
181*cdf0e10cSrcweir 		// Polygon aPol(Rect2Poly(GetSnapRect(), aGeo));
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir 		// #101412# go back to old method, side effects are impossible
184*cdf0e10cSrcweir 		// to calculate.
185*cdf0e10cSrcweir 		Polygon aPol(Rect2Poly(aRect,aGeo));
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir 		for(sal_uInt16 a(0); a < aPol.GetSize(); a++)
188*cdf0e10cSrcweir 		{
189*cdf0e10cSrcweir 			 ResizePoint(aPol[a], rRef, xFact, yFact);
190*cdf0e10cSrcweir 		}
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir 		if(bXMirr != bYMirr)
193*cdf0e10cSrcweir 		{
194*cdf0e10cSrcweir 			// Polygon wenden und etwas schieben
195*cdf0e10cSrcweir 			Polygon aPol0(aPol);
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir 			aPol[0] = aPol0[1];
198*cdf0e10cSrcweir 			aPol[1] = aPol0[0];
199*cdf0e10cSrcweir 			aPol[2] = aPol0[3];
200*cdf0e10cSrcweir 			aPol[3] = aPol0[2];
201*cdf0e10cSrcweir 			aPol[4] = aPol0[1];
202*cdf0e10cSrcweir 		}
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir 		Poly2Rect(aPol, aRect, aGeo);
205*cdf0e10cSrcweir 	}
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir 	if (bRota90Merk) {
208*cdf0e10cSrcweir 		FASTBOOL bRota90=aGeo.nDrehWink % 9000 ==0;
209*cdf0e10cSrcweir 		if (!bRota90) { // Scheinbar Rundungsfehler: Korregieren
210*cdf0e10cSrcweir 			long a=NormAngle360(aGeo.nDrehWink);
211*cdf0e10cSrcweir 			if (a<4500) a=0;
212*cdf0e10cSrcweir 			else if (a<13500) a=9000;
213*cdf0e10cSrcweir 			else if (a<22500) a=18000;
214*cdf0e10cSrcweir 			else if (a<31500) a=27000;
215*cdf0e10cSrcweir 			else a=0;
216*cdf0e10cSrcweir 			aGeo.nDrehWink=a;
217*cdf0e10cSrcweir 			aGeo.RecalcSinCos();
218*cdf0e10cSrcweir 		}
219*cdf0e10cSrcweir 		if (bNoShearMerk!=(aGeo.nShearWink==0)) { // Shear ggf. korregieren wg. Rundungsfehler
220*cdf0e10cSrcweir 			aGeo.nShearWink=0;
221*cdf0e10cSrcweir 			aGeo.RecalcTan();
222*cdf0e10cSrcweir 		}
223*cdf0e10cSrcweir 	}
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir 	ImpJustifyRect(aRect);
226*cdf0e10cSrcweir 	long nTWdt1=aRect.GetWidth ()-1-nHDist; if (nTWdt1<0) nTWdt1=0;
227*cdf0e10cSrcweir 	long nTHgt1=aRect.GetHeight()-1-nVDist; if (nTHgt1<0) nTHgt1=0;
228*cdf0e10cSrcweir 	if (bTextFrame && (pModel==NULL || !pModel->IsPasteResize())) { // #51139#
229*cdf0e10cSrcweir 		if (nTWdt0!=nTWdt1 && IsAutoGrowWidth() ) NbcSetMinTextFrameWidth(nTWdt1);
230*cdf0e10cSrcweir 		if (nTHgt0!=nTHgt1 && IsAutoGrowHeight()) NbcSetMinTextFrameHeight(nTHgt1);
231*cdf0e10cSrcweir 		if (GetFitToSize()==SDRTEXTFIT_RESIZEATTR) {
232*cdf0e10cSrcweir 			NbcResizeTextAttributes(Fraction(nTWdt1,nTWdt0),Fraction(nTHgt1,nTHgt0));
233*cdf0e10cSrcweir 		}
234*cdf0e10cSrcweir 		NbcAdjustTextFrameWidthAndHeight();
235*cdf0e10cSrcweir 	}
236*cdf0e10cSrcweir 	ImpCheckShear();
237*cdf0e10cSrcweir 	SetRectsDirty();
238*cdf0e10cSrcweir }
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir void SdrTextObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
241*cdf0e10cSrcweir {
242*cdf0e10cSrcweir 	SetGlueReallyAbsolute(sal_True);
243*cdf0e10cSrcweir 	long dx=aRect.Right()-aRect.Left();
244*cdf0e10cSrcweir 	long dy=aRect.Bottom()-aRect.Top();
245*cdf0e10cSrcweir 	Point aP(aRect.TopLeft());
246*cdf0e10cSrcweir 	RotatePoint(aP,rRef,sn,cs);
247*cdf0e10cSrcweir 	aRect.Left()=aP.X();
248*cdf0e10cSrcweir 	aRect.Top()=aP.Y();
249*cdf0e10cSrcweir 	aRect.Right()=aRect.Left()+dx;
250*cdf0e10cSrcweir 	aRect.Bottom()=aRect.Top()+dy;
251*cdf0e10cSrcweir 	if (aGeo.nDrehWink==0) {
252*cdf0e10cSrcweir 		aGeo.nDrehWink=NormAngle360(nWink);
253*cdf0e10cSrcweir 		aGeo.nSin=sn;
254*cdf0e10cSrcweir 		aGeo.nCos=cs;
255*cdf0e10cSrcweir 	} else {
256*cdf0e10cSrcweir 		aGeo.nDrehWink=NormAngle360(aGeo.nDrehWink+nWink);
257*cdf0e10cSrcweir 		aGeo.RecalcSinCos();
258*cdf0e10cSrcweir 	}
259*cdf0e10cSrcweir 	SetRectsDirty();
260*cdf0e10cSrcweir 	NbcRotateGluePoints(rRef,nWink,sn,cs);
261*cdf0e10cSrcweir 	SetGlueReallyAbsolute(sal_False);
262*cdf0e10cSrcweir }
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir void SdrTextObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
265*cdf0e10cSrcweir {
266*cdf0e10cSrcweir 	SetGlueReallyAbsolute(sal_True);
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir 	// #75889# when this is a SdrPathObj aRect maybe not initialized
269*cdf0e10cSrcweir 	Polygon aPol(Rect2Poly(aRect.IsEmpty() ? GetSnapRect() : aRect, aGeo));
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir 	sal_uInt16 nPointCount=aPol.GetSize();
272*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nPointCount; i++) {
273*cdf0e10cSrcweir 		 ShearPoint(aPol[i],rRef,tn,bVShear);
274*cdf0e10cSrcweir 	}
275*cdf0e10cSrcweir 	Poly2Rect(aPol,aRect,aGeo);
276*cdf0e10cSrcweir 	ImpJustifyRect(aRect);
277*cdf0e10cSrcweir 	if (bTextFrame) {
278*cdf0e10cSrcweir 		NbcAdjustTextFrameWidthAndHeight();
279*cdf0e10cSrcweir 	}
280*cdf0e10cSrcweir 	ImpCheckShear();
281*cdf0e10cSrcweir 	SetRectsDirty();
282*cdf0e10cSrcweir 	NbcShearGluePoints(rRef,nWink,tn,bVShear);
283*cdf0e10cSrcweir 	SetGlueReallyAbsolute(sal_False);
284*cdf0e10cSrcweir }
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir void SdrTextObj::NbcMirror(const Point& rRef1, const Point& rRef2)
287*cdf0e10cSrcweir {
288*cdf0e10cSrcweir 	SetGlueReallyAbsolute(sal_True);
289*cdf0e10cSrcweir 	FASTBOOL bNoShearMerk=aGeo.nShearWink==0;
290*cdf0e10cSrcweir 	FASTBOOL bRota90Merk=sal_False;
291*cdf0e10cSrcweir 	if (bNoShearMerk &&
292*cdf0e10cSrcweir 		(rRef1.X()==rRef2.X() || rRef1.Y()==rRef2.Y() ||
293*cdf0e10cSrcweir 		 Abs(rRef1.X()-rRef2.X())==Abs(rRef1.Y()-rRef2.Y()))) {
294*cdf0e10cSrcweir 		bRota90Merk=aGeo.nDrehWink % 9000 ==0;
295*cdf0e10cSrcweir 	}
296*cdf0e10cSrcweir 	Polygon aPol(Rect2Poly(aRect,aGeo));
297*cdf0e10cSrcweir 	sal_uInt16 i;
298*cdf0e10cSrcweir 	sal_uInt16 nPntAnz=aPol.GetSize();
299*cdf0e10cSrcweir 	for (i=0; i<nPntAnz; i++) {
300*cdf0e10cSrcweir 		 MirrorPoint(aPol[i],rRef1,rRef2);
301*cdf0e10cSrcweir 	}
302*cdf0e10cSrcweir 	// Polygon wenden und etwas schieben
303*cdf0e10cSrcweir 	Polygon aPol0(aPol);
304*cdf0e10cSrcweir 	aPol[0]=aPol0[1];
305*cdf0e10cSrcweir 	aPol[1]=aPol0[0];
306*cdf0e10cSrcweir 	aPol[2]=aPol0[3];
307*cdf0e10cSrcweir 	aPol[3]=aPol0[2];
308*cdf0e10cSrcweir 	aPol[4]=aPol0[1];
309*cdf0e10cSrcweir 	Poly2Rect(aPol,aRect,aGeo);
310*cdf0e10cSrcweir 
311*cdf0e10cSrcweir 	if (bRota90Merk) {
312*cdf0e10cSrcweir 		FASTBOOL bRota90=aGeo.nDrehWink % 9000 ==0;
313*cdf0e10cSrcweir 		if (bRota90Merk && !bRota90) { // Scheinbar Rundungsfehler: Korregieren
314*cdf0e10cSrcweir 			long a=NormAngle360(aGeo.nDrehWink);
315*cdf0e10cSrcweir 			if (a<4500) a=0;
316*cdf0e10cSrcweir 			else if (a<13500) a=9000;
317*cdf0e10cSrcweir 			else if (a<22500) a=18000;
318*cdf0e10cSrcweir 			else if (a<31500) a=27000;
319*cdf0e10cSrcweir 			else a=0;
320*cdf0e10cSrcweir 			aGeo.nDrehWink=a;
321*cdf0e10cSrcweir 			aGeo.RecalcSinCos();
322*cdf0e10cSrcweir 		}
323*cdf0e10cSrcweir 	}
324*cdf0e10cSrcweir 	if (bNoShearMerk!=(aGeo.nShearWink==0)) { // Shear ggf. korregieren wg. Rundungsfehler
325*cdf0e10cSrcweir 		aGeo.nShearWink=0;
326*cdf0e10cSrcweir 		aGeo.RecalcTan();
327*cdf0e10cSrcweir 	}
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir 	ImpJustifyRect(aRect);
330*cdf0e10cSrcweir 	if (bTextFrame) {
331*cdf0e10cSrcweir 		NbcAdjustTextFrameWidthAndHeight();
332*cdf0e10cSrcweir 	}
333*cdf0e10cSrcweir 	ImpCheckShear();
334*cdf0e10cSrcweir 	SetRectsDirty();
335*cdf0e10cSrcweir 	NbcMirrorGluePoints(rRef1,rRef2);
336*cdf0e10cSrcweir 	SetGlueReallyAbsolute(sal_False);
337*cdf0e10cSrcweir }
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir SdrObject* SdrTextObj::ImpConvertContainedTextToSdrPathObjs(bool bToPoly) const
342*cdf0e10cSrcweir {
343*cdf0e10cSrcweir 	SdrObject* pRetval = 0;
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir 	if(!ImpCanConvTextToCurve())
346*cdf0e10cSrcweir 	{
347*cdf0e10cSrcweir 		// suppress HelpTexts from PresObj's
348*cdf0e10cSrcweir 		return 0;
349*cdf0e10cSrcweir 	}
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir 	// get primitives
352*cdf0e10cSrcweir 	const drawinglayer::primitive2d::Primitive2DSequence xSequence(GetViewContact().getViewIndependentPrimitive2DSequence());
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir 	if(xSequence.hasElements())
355*cdf0e10cSrcweir 	{
356*cdf0e10cSrcweir 		// create an extractor with neutral ViewInformation
357*cdf0e10cSrcweir 		const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
358*cdf0e10cSrcweir 		drawinglayer::processor2d::TextAsPolygonExtractor2D aExtractor(aViewInformation2D);
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir 		// extract text as polygons
361*cdf0e10cSrcweir 		aExtractor.process(xSequence);
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir 		// get results
364*cdf0e10cSrcweir 		const drawinglayer::processor2d::TextAsPolygonDataNodeVector& rResult = aExtractor.getTarget();
365*cdf0e10cSrcweir 		const sal_uInt32 nResultCount(rResult.size());
366*cdf0e10cSrcweir 
367*cdf0e10cSrcweir 		if(nResultCount)
368*cdf0e10cSrcweir 		{
369*cdf0e10cSrcweir 			// prepare own target
370*cdf0e10cSrcweir 			SdrObjGroup* pGroup = new SdrObjGroup();
371*cdf0e10cSrcweir 			SdrObjList* pObjectList = pGroup->GetSubList();
372*cdf0e10cSrcweir 
373*cdf0e10cSrcweir 			// process results
374*cdf0e10cSrcweir 			for(sal_uInt32 a(0); a < nResultCount; a++)
375*cdf0e10cSrcweir 			{
376*cdf0e10cSrcweir 				const drawinglayer::processor2d::TextAsPolygonDataNode& rCandidate = rResult[a];
377*cdf0e10cSrcweir 				basegfx::B2DPolyPolygon aPolyPolygon(rCandidate.getB2DPolyPolygon());
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir 				if(aPolyPolygon.count())
380*cdf0e10cSrcweir 				{
381*cdf0e10cSrcweir 					// take care of wanted polygon type
382*cdf0e10cSrcweir 					if(bToPoly)
383*cdf0e10cSrcweir 					{
384*cdf0e10cSrcweir 						if(aPolyPolygon.areControlPointsUsed())
385*cdf0e10cSrcweir 						{
386*cdf0e10cSrcweir 							aPolyPolygon = basegfx::tools::adaptiveSubdivideByAngle(aPolyPolygon);
387*cdf0e10cSrcweir 						}
388*cdf0e10cSrcweir 					}
389*cdf0e10cSrcweir 					else
390*cdf0e10cSrcweir 					{
391*cdf0e10cSrcweir 						if(!aPolyPolygon.areControlPointsUsed())
392*cdf0e10cSrcweir 						{
393*cdf0e10cSrcweir 							aPolyPolygon = basegfx::tools::expandToCurve(aPolyPolygon);
394*cdf0e10cSrcweir 						}
395*cdf0e10cSrcweir 					}
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir 					// create ItemSet with object attributes
398*cdf0e10cSrcweir 					SfxItemSet aAttributeSet(GetObjectItemSet());
399*cdf0e10cSrcweir 					SdrPathObj* pPathObj = 0;
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir 					// always clear objectshadow; this is included in the extraction
402*cdf0e10cSrcweir 					aAttributeSet.Put(SdrShadowItem(false));
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir 					if(rCandidate.getIsFilled())
405*cdf0e10cSrcweir 					{
406*cdf0e10cSrcweir 						// set needed items
407*cdf0e10cSrcweir 						aAttributeSet.Put(XFillColorItem(String(), Color(rCandidate.getBColor())));
408*cdf0e10cSrcweir 						aAttributeSet.Put(XLineStyleItem(XLINE_NONE));
409*cdf0e10cSrcweir 						aAttributeSet.Put(XFillStyleItem(XFILL_SOLID));
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir 						// create filled SdrPathObj
412*cdf0e10cSrcweir 						pPathObj = new SdrPathObj(OBJ_PATHFILL, aPolyPolygon);
413*cdf0e10cSrcweir 					}
414*cdf0e10cSrcweir 					else
415*cdf0e10cSrcweir 					{
416*cdf0e10cSrcweir 						// set needed items
417*cdf0e10cSrcweir 						aAttributeSet.Put(XLineColorItem(String(), Color(rCandidate.getBColor())));
418*cdf0e10cSrcweir 						aAttributeSet.Put(XLineStyleItem(XLINE_SOLID));
419*cdf0e10cSrcweir 						aAttributeSet.Put(XLineWidthItem(0));
420*cdf0e10cSrcweir 						aAttributeSet.Put(XFillStyleItem(XFILL_NONE));
421*cdf0e10cSrcweir 
422*cdf0e10cSrcweir 						// create line SdrPathObj
423*cdf0e10cSrcweir 						pPathObj = new SdrPathObj(OBJ_PATHLINE, aPolyPolygon);
424*cdf0e10cSrcweir 					}
425*cdf0e10cSrcweir 
426*cdf0e10cSrcweir 					// copy basic information from original
427*cdf0e10cSrcweir 					pPathObj->ImpSetAnchorPos(GetAnchorPos());
428*cdf0e10cSrcweir 					pPathObj->NbcSetLayer(GetLayer());
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir 					if(GetModel())
431*cdf0e10cSrcweir 					{
432*cdf0e10cSrcweir 						pPathObj->SetModel(GetModel());
433*cdf0e10cSrcweir 						pPathObj->NbcSetStyleSheet(GetStyleSheet(), true);
434*cdf0e10cSrcweir 					}
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir 					// apply prepared ItemSet and add to target
437*cdf0e10cSrcweir 					pPathObj->SetMergedItemSet(aAttributeSet);
438*cdf0e10cSrcweir 					pObjectList->InsertObject(pPathObj);
439*cdf0e10cSrcweir 				}
440*cdf0e10cSrcweir 			}
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir 			// postprocess; if no result and/or only one object, simplify
443*cdf0e10cSrcweir 			if(!pObjectList->GetObjCount())
444*cdf0e10cSrcweir 			{
445*cdf0e10cSrcweir 				delete pGroup;
446*cdf0e10cSrcweir 			}
447*cdf0e10cSrcweir 			else if(1 == pObjectList->GetObjCount())
448*cdf0e10cSrcweir 			{
449*cdf0e10cSrcweir 				pRetval = pObjectList->RemoveObject(0);
450*cdf0e10cSrcweir 				delete pGroup;
451*cdf0e10cSrcweir 			}
452*cdf0e10cSrcweir 			else
453*cdf0e10cSrcweir 			{
454*cdf0e10cSrcweir 				pRetval = pGroup;
455*cdf0e10cSrcweir 			}
456*cdf0e10cSrcweir 		}
457*cdf0e10cSrcweir 	}
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir 	return pRetval;
460*cdf0e10cSrcweir }
461*cdf0e10cSrcweir 
462*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir SdrObject* SdrTextObj::DoConvertToPolyObj(sal_Bool bBezier) const
465*cdf0e10cSrcweir {
466*cdf0e10cSrcweir 	return ImpConvertContainedTextToSdrPathObjs(!bBezier);
467*cdf0e10cSrcweir }
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir bool SdrTextObj::ImpCanConvTextToCurve() const
470*cdf0e10cSrcweir {
471*cdf0e10cSrcweir 	return !IsOutlText();
472*cdf0e10cSrcweir }
473*cdf0e10cSrcweir 
474*cdf0e10cSrcweir SdrObject* SdrTextObj::ImpConvertMakeObj(const basegfx::B2DPolyPolygon& rPolyPolygon, sal_Bool bClosed, sal_Bool bBezier, sal_Bool bNoSetAttr) const
475*cdf0e10cSrcweir {
476*cdf0e10cSrcweir 	SdrObjKind ePathKind = bClosed ? OBJ_PATHFILL : OBJ_PATHLINE;
477*cdf0e10cSrcweir 	basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPolygon);
478*cdf0e10cSrcweir 
479*cdf0e10cSrcweir 	// #i37011#
480*cdf0e10cSrcweir 	if(!bBezier)
481*cdf0e10cSrcweir 	{
482*cdf0e10cSrcweir 		aB2DPolyPolygon = basegfx::tools::adaptiveSubdivideByAngle(aB2DPolyPolygon);
483*cdf0e10cSrcweir 		ePathKind = bClosed ? OBJ_POLY : OBJ_PLIN;
484*cdf0e10cSrcweir 	}
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir 	SdrPathObj* pPathObj = new SdrPathObj(ePathKind, aB2DPolyPolygon);
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir 	if(bBezier)
489*cdf0e10cSrcweir 	{
490*cdf0e10cSrcweir 		// create bezier curves
491*cdf0e10cSrcweir 		pPathObj->SetPathPoly(basegfx::tools::expandToCurve(pPathObj->GetPathPoly()));
492*cdf0e10cSrcweir 	}
493*cdf0e10cSrcweir 
494*cdf0e10cSrcweir 	if(pPathObj)
495*cdf0e10cSrcweir 	{
496*cdf0e10cSrcweir 		pPathObj->ImpSetAnchorPos(aAnchor);
497*cdf0e10cSrcweir 		pPathObj->NbcSetLayer(SdrLayerID(GetLayer()));
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir 		if(pModel)
500*cdf0e10cSrcweir 		{
501*cdf0e10cSrcweir 			pPathObj->SetModel(pModel);
502*cdf0e10cSrcweir 
503*cdf0e10cSrcweir 			if(!bNoSetAttr)
504*cdf0e10cSrcweir 			{
505*cdf0e10cSrcweir 				sdr::properties::ItemChangeBroadcaster aC(*pPathObj);
506*cdf0e10cSrcweir 
507*cdf0e10cSrcweir 				pPathObj->ClearMergedItem();
508*cdf0e10cSrcweir 				pPathObj->SetMergedItemSet(GetObjectItemSet());
509*cdf0e10cSrcweir 				pPathObj->GetProperties().BroadcastItemChange(aC);
510*cdf0e10cSrcweir 				pPathObj->NbcSetStyleSheet(GetStyleSheet(), sal_True);
511*cdf0e10cSrcweir 			}
512*cdf0e10cSrcweir 		}
513*cdf0e10cSrcweir 	}
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir 	return pPathObj;
516*cdf0e10cSrcweir }
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir SdrObject* SdrTextObj::ImpConvertAddText(SdrObject* pObj, FASTBOOL bBezier) const
519*cdf0e10cSrcweir {
520*cdf0e10cSrcweir 	if(!ImpCanConvTextToCurve())
521*cdf0e10cSrcweir     {
522*cdf0e10cSrcweir         return pObj;
523*cdf0e10cSrcweir     }
524*cdf0e10cSrcweir 
525*cdf0e10cSrcweir 	SdrObject* pText = ImpConvertContainedTextToSdrPathObjs(!bBezier);
526*cdf0e10cSrcweir 
527*cdf0e10cSrcweir     if(!pText)
528*cdf0e10cSrcweir     {
529*cdf0e10cSrcweir         return pObj;
530*cdf0e10cSrcweir     }
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir 	if(!pObj)
533*cdf0e10cSrcweir     {
534*cdf0e10cSrcweir         return pText;
535*cdf0e10cSrcweir     }
536*cdf0e10cSrcweir 
537*cdf0e10cSrcweir 	if(pText->IsGroupObject())
538*cdf0e10cSrcweir     {
539*cdf0e10cSrcweir         // is already group object, add partial shape in front
540*cdf0e10cSrcweir 		SdrObjList* pOL=pText->GetSubList();
541*cdf0e10cSrcweir 		pOL->InsertObject(pObj,0);
542*cdf0e10cSrcweir 
543*cdf0e10cSrcweir         return pText;
544*cdf0e10cSrcweir 	}
545*cdf0e10cSrcweir     else
546*cdf0e10cSrcweir     {
547*cdf0e10cSrcweir         // not yet a group, create one and add partial and new shapes
548*cdf0e10cSrcweir 		SdrObjGroup* pGrp=new SdrObjGroup;
549*cdf0e10cSrcweir 		SdrObjList* pOL=pGrp->GetSubList();
550*cdf0e10cSrcweir 		pOL->InsertObject(pObj);
551*cdf0e10cSrcweir 		pOL->InsertObject(pText);
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir         return pGrp;
554*cdf0e10cSrcweir 	}
555*cdf0e10cSrcweir }
556*cdf0e10cSrcweir 
557*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
558*cdf0e10cSrcweir // eof
559