xref: /aoo41x/main/svx/source/svdraw/svdomeas.cxx (revision cdf0e10c)
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/svdomeas.hxx>
32*cdf0e10cSrcweir #include <math.h>
33*cdf0e10cSrcweir #include "svx/svditext.hxx" //
34*cdf0e10cSrcweir #include <svx/xpoly.hxx>
35*cdf0e10cSrcweir #include <svx/svdtrans.hxx>
36*cdf0e10cSrcweir #include <svx/svdhdl.hxx>
37*cdf0e10cSrcweir #include <svx/svdoutl.hxx>
38*cdf0e10cSrcweir #include <svx/svddrag.hxx>
39*cdf0e10cSrcweir #include <svx/svdpool.hxx>
40*cdf0e10cSrcweir #include <svx/svdattrx.hxx>
41*cdf0e10cSrcweir #include <svx/svdmodel.hxx>
42*cdf0e10cSrcweir #include <svx/svdview.hxx>
43*cdf0e10cSrcweir #include "svx/svdglob.hxx"   // StringCache
44*cdf0e10cSrcweir #include "svx/svdstr.hrc"    // Objektname
45*cdf0e10cSrcweir #include <svl/style.hxx>
46*cdf0e10cSrcweir #include <svl/smplhint.hxx>
47*cdf0e10cSrcweir #include <editeng/eeitem.hxx>
48*cdf0e10cSrcweir #include <svx/xlnstit.hxx>
49*cdf0e10cSrcweir #include <svx/xlnstwit.hxx>
50*cdf0e10cSrcweir #include <svx/xlnedit.hxx>
51*cdf0e10cSrcweir #include <svx/xlnwtit.hxx>
52*cdf0e10cSrcweir #include <svx/xlnedwit.hxx>
53*cdf0e10cSrcweir #include <svx/xlnstcit.hxx>
54*cdf0e10cSrcweir #include <svx/xlnedcit.hxx>
55*cdf0e10cSrcweir #include <editeng/outlobj.hxx>
56*cdf0e10cSrcweir #include <editeng/outliner.hxx>
57*cdf0e10cSrcweir #include <editeng/editobj.hxx>
58*cdf0e10cSrcweir #include <editeng/measfld.hxx>
59*cdf0e10cSrcweir #include <editeng/flditem.hxx>
60*cdf0e10cSrcweir #include <svx/svdogrp.hxx>
61*cdf0e10cSrcweir #include <svx/svdopath.hxx>
62*cdf0e10cSrcweir #include <svx/svdpage.hxx>
63*cdf0e10cSrcweir #include <unotools/syslocale.hxx>
64*cdf0e10cSrcweir #include "svdoimp.hxx"
65*cdf0e10cSrcweir #include <svx/sdr/properties/measureproperties.hxx>
66*cdf0e10cSrcweir #include <svx/sdr/contact/viewcontactofsdrmeasureobj.hxx>
67*cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx>
68*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
69*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx>
70*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
71*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx>
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir SdrMeasureObjGeoData::SdrMeasureObjGeoData() {}
76*cdf0e10cSrcweir SdrMeasureObjGeoData::~SdrMeasureObjGeoData() {}
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir void SdrMeasureObj::TakeRepresentation( XubString& rStr, SdrMeasureFieldKind eMeasureFieldKind ) const
79*cdf0e10cSrcweir {
80*cdf0e10cSrcweir 	rStr.Erase();
81*cdf0e10cSrcweir 	Fraction aMeasureScale(1, 1);
82*cdf0e10cSrcweir 	sal_Bool bTextRota90(sal_False);
83*cdf0e10cSrcweir 	sal_Bool bShowUnit(sal_False);
84*cdf0e10cSrcweir 	FieldUnit eMeasureUnit(FUNIT_NONE);
85*cdf0e10cSrcweir 	FieldUnit eModUIUnit(FUNIT_NONE);
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir 	const SfxItemSet& rSet = GetMergedItemSet();
88*cdf0e10cSrcweir 	bTextRota90 = ((SdrMeasureTextRota90Item&)rSet.Get(SDRATTR_MEASURETEXTROTA90)).GetValue();
89*cdf0e10cSrcweir 	eMeasureUnit = ((SdrMeasureUnitItem&)rSet.Get(SDRATTR_MEASUREUNIT)).GetValue();
90*cdf0e10cSrcweir 	aMeasureScale = ((SdrMeasureScaleItem&)rSet.Get(SDRATTR_MEASURESCALE)).GetValue();
91*cdf0e10cSrcweir 	bShowUnit = ((SdrMeasureShowUnitItem&)rSet.Get(SDRATTR_MEASURESHOWUNIT)).GetValue();
92*cdf0e10cSrcweir 	sal_Int16 nNumDigits = ((SdrMeasureDecimalPlacesItem&)rSet.Get(SDRATTR_MEASUREDECIMALPLACES)).GetValue();
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir 	//SdrModel* pModel = rObj.pModel;
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir 	switch(eMeasureFieldKind)
97*cdf0e10cSrcweir 	{
98*cdf0e10cSrcweir 		case SDRMEASUREFIELD_VALUE:
99*cdf0e10cSrcweir 		{
100*cdf0e10cSrcweir 			if(pModel)
101*cdf0e10cSrcweir 			{
102*cdf0e10cSrcweir 				eModUIUnit = pModel->GetUIUnit();
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir 				if(eMeasureUnit == FUNIT_NONE)
105*cdf0e10cSrcweir 					eMeasureUnit = eModUIUnit;
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir 				sal_Int32 nLen(GetLen(aPt2 - aPt1));
108*cdf0e10cSrcweir 				Fraction aFact(1,1);
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir 				if(eMeasureUnit != eModUIUnit)
111*cdf0e10cSrcweir 				{
112*cdf0e10cSrcweir 					// Zur Umrechnung der Einheiten
113*cdf0e10cSrcweir 					aFact *= GetMapFactor(eModUIUnit, eMeasureUnit).X();
114*cdf0e10cSrcweir 				}
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir 				if(aMeasureScale.GetNumerator() != aMeasureScale.GetDenominator())
117*cdf0e10cSrcweir 				{
118*cdf0e10cSrcweir 					aFact *= aMeasureScale;
119*cdf0e10cSrcweir 				}
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir 				if(aFact.GetNumerator() != aFact.GetDenominator())
122*cdf0e10cSrcweir 				{
123*cdf0e10cSrcweir 					// Scaling ueber BigInt, um Ueberlaeufe zu vermeiden
124*cdf0e10cSrcweir 					nLen = BigMulDiv(nLen, aFact.GetNumerator(), aFact.GetDenominator());
125*cdf0e10cSrcweir 				}
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir 				pModel->TakeMetricStr(nLen, rStr, sal_True, nNumDigits);
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir 				if(!aFact.IsValid())
130*cdf0e10cSrcweir 				{
131*cdf0e10cSrcweir 					rStr = String();
132*cdf0e10cSrcweir 					rStr += sal_Unicode('?');
133*cdf0e10cSrcweir 				}
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir                 sal_Unicode cDec(SvtSysLocale().GetLocaleData().getNumDecimalSep().GetChar(0));
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir 				if(rStr.Search(cDec) != STRING_NOTFOUND)
138*cdf0e10cSrcweir 				{
139*cdf0e10cSrcweir 					xub_StrLen nLen2(rStr.Len() - 1);
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir 					while(rStr.GetChar(nLen2) == sal_Unicode('0'))
142*cdf0e10cSrcweir 					{
143*cdf0e10cSrcweir 						rStr.Erase(nLen2);
144*cdf0e10cSrcweir 						nLen2--;
145*cdf0e10cSrcweir 					}
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir 					if(rStr.GetChar(nLen2) == cDec)
148*cdf0e10cSrcweir 					{
149*cdf0e10cSrcweir 						rStr.Erase(nLen2);
150*cdf0e10cSrcweir 						nLen2--;
151*cdf0e10cSrcweir 					}
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir 					if(!rStr.Len())
154*cdf0e10cSrcweir 						rStr += sal_Unicode('0');
155*cdf0e10cSrcweir 				}
156*cdf0e10cSrcweir 			}
157*cdf0e10cSrcweir 			else
158*cdf0e10cSrcweir 			{
159*cdf0e10cSrcweir 				// falls kein Model da ... (z.B. Preview im Dialog)
160*cdf0e10cSrcweir 				rStr = String();
161*cdf0e10cSrcweir 				rStr.AppendAscii("4711");
162*cdf0e10cSrcweir 			}
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir 			break;
165*cdf0e10cSrcweir 		}
166*cdf0e10cSrcweir 		case SDRMEASUREFIELD_UNIT:
167*cdf0e10cSrcweir 		{
168*cdf0e10cSrcweir 			if(bShowUnit)
169*cdf0e10cSrcweir 			{
170*cdf0e10cSrcweir 				if(pModel)
171*cdf0e10cSrcweir 				{
172*cdf0e10cSrcweir 					eModUIUnit = pModel->GetUIUnit();
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir 					if(eMeasureUnit == FUNIT_NONE)
175*cdf0e10cSrcweir 						eMeasureUnit = eModUIUnit;
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir 					if(bShowUnit)
178*cdf0e10cSrcweir 						pModel->TakeUnitStr(eMeasureUnit, rStr);
179*cdf0e10cSrcweir 				}
180*cdf0e10cSrcweir 			}
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir 			break;
183*cdf0e10cSrcweir 		}
184*cdf0e10cSrcweir 		case SDRMEASUREFIELD_ROTA90BLANCS:
185*cdf0e10cSrcweir 		{
186*cdf0e10cSrcweir 			if(bTextRota90)
187*cdf0e10cSrcweir 			{
188*cdf0e10cSrcweir 				rStr = String();
189*cdf0e10cSrcweir 				rStr += sal_Unicode(' ');
190*cdf0e10cSrcweir 			}
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir 			break;
193*cdf0e10cSrcweir 		}
194*cdf0e10cSrcweir 	}
195*cdf0e10cSrcweir }
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
198*cdf0e10cSrcweir // BaseProperties section
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir sdr::properties::BaseProperties* SdrMeasureObj::CreateObjectSpecificProperties()
201*cdf0e10cSrcweir {
202*cdf0e10cSrcweir 	return new sdr::properties::MeasureProperties(*this);
203*cdf0e10cSrcweir }
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
206*cdf0e10cSrcweir // DrawContact section
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir sdr::contact::ViewContact* SdrMeasureObj::CreateObjectSpecificViewContact()
209*cdf0e10cSrcweir {
210*cdf0e10cSrcweir 	return new sdr::contact::ViewContactOfSdrMeasureObj(*this);
211*cdf0e10cSrcweir }
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir TYPEINIT1(SdrMeasureObj,SdrTextObj);
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir SdrMeasureObj::SdrMeasureObj():
218*cdf0e10cSrcweir 	bTextDirty(sal_False)
219*cdf0e10cSrcweir {
220*cdf0e10cSrcweir 	// #i25616#
221*cdf0e10cSrcweir 	mbSupportTextIndentingOnLineWidthChange = sal_False;
222*cdf0e10cSrcweir }
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir SdrMeasureObj::SdrMeasureObj(const Point& rPt1, const Point& rPt2):
225*cdf0e10cSrcweir 	aPt1(rPt1),
226*cdf0e10cSrcweir 	aPt2(rPt2),
227*cdf0e10cSrcweir 	bTextDirty(sal_False)
228*cdf0e10cSrcweir {
229*cdf0e10cSrcweir 	// #i25616#
230*cdf0e10cSrcweir 	mbSupportTextIndentingOnLineWidthChange = sal_False;
231*cdf0e10cSrcweir }
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir SdrMeasureObj::~SdrMeasureObj()
234*cdf0e10cSrcweir {
235*cdf0e10cSrcweir }
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir void SdrMeasureObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
238*cdf0e10cSrcweir {
239*cdf0e10cSrcweir 	rInfo.bSelectAllowed    =sal_True;
240*cdf0e10cSrcweir 	rInfo.bMoveAllowed      =sal_True;
241*cdf0e10cSrcweir 	rInfo.bResizeFreeAllowed=sal_True;
242*cdf0e10cSrcweir 	rInfo.bResizePropAllowed=sal_True;
243*cdf0e10cSrcweir 	rInfo.bRotateFreeAllowed=sal_True;
244*cdf0e10cSrcweir 	rInfo.bRotate90Allowed  =sal_True;
245*cdf0e10cSrcweir 	rInfo.bMirrorFreeAllowed=sal_True;
246*cdf0e10cSrcweir 	rInfo.bMirror45Allowed  =sal_True;
247*cdf0e10cSrcweir 	rInfo.bMirror90Allowed  =sal_True;
248*cdf0e10cSrcweir 	rInfo.bTransparenceAllowed = sal_False;
249*cdf0e10cSrcweir 	rInfo.bGradientAllowed = sal_False;
250*cdf0e10cSrcweir 	rInfo.bShearAllowed     =sal_True;
251*cdf0e10cSrcweir 	rInfo.bEdgeRadiusAllowed=sal_False;
252*cdf0e10cSrcweir 	rInfo.bNoOrthoDesired   =sal_True;
253*cdf0e10cSrcweir 	rInfo.bNoContortion     =sal_False;
254*cdf0e10cSrcweir 	rInfo.bCanConvToPath    =sal_False;
255*cdf0e10cSrcweir 	rInfo.bCanConvToPoly    =sal_True;
256*cdf0e10cSrcweir 	rInfo.bCanConvToPathLineToArea=sal_False;
257*cdf0e10cSrcweir 	rInfo.bCanConvToPolyLineToArea=sal_False;
258*cdf0e10cSrcweir 	rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
259*cdf0e10cSrcweir }
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir sal_uInt16 SdrMeasureObj::GetObjIdentifier() const
262*cdf0e10cSrcweir {
263*cdf0e10cSrcweir 	return (sal_uInt16)OBJ_MEASURE;
264*cdf0e10cSrcweir }
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir struct ImpMeasureRec : public SdrDragStatUserData
267*cdf0e10cSrcweir {
268*cdf0e10cSrcweir 	Point						aPt1;
269*cdf0e10cSrcweir 	Point						aPt2;
270*cdf0e10cSrcweir 	SdrMeasureKind				eKind;
271*cdf0e10cSrcweir 	SdrMeasureTextHPos			eWantTextHPos;
272*cdf0e10cSrcweir 	SdrMeasureTextVPos			eWantTextVPos;
273*cdf0e10cSrcweir 	long						nLineDist;
274*cdf0e10cSrcweir 	long						nHelplineOverhang;
275*cdf0e10cSrcweir 	long						nHelplineDist;
276*cdf0e10cSrcweir 	long						nHelpline1Len;
277*cdf0e10cSrcweir 	long						nHelpline2Len;
278*cdf0e10cSrcweir 	FASTBOOL					bBelowRefEdge;
279*cdf0e10cSrcweir 	FASTBOOL					bTextRota90;
280*cdf0e10cSrcweir 	FASTBOOL					bTextUpsideDown;
281*cdf0e10cSrcweir 	long						nMeasureOverhang;
282*cdf0e10cSrcweir 	FieldUnit					eMeasureUnit;
283*cdf0e10cSrcweir 	Fraction					aMeasureScale;
284*cdf0e10cSrcweir 	FASTBOOL					bShowUnit;
285*cdf0e10cSrcweir 	String						aFormatString;
286*cdf0e10cSrcweir 	FASTBOOL					bTextAutoAngle;
287*cdf0e10cSrcweir 	long						nTextAutoAngleView;
288*cdf0e10cSrcweir 	FASTBOOL					bTextIsFixedAngle;
289*cdf0e10cSrcweir 	long						nTextFixedAngle;
290*cdf0e10cSrcweir };
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir struct ImpLineRec
293*cdf0e10cSrcweir {
294*cdf0e10cSrcweir 	Point						aP1;
295*cdf0e10cSrcweir 	Point						aP2;
296*cdf0e10cSrcweir };
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir struct ImpMeasurePoly
299*cdf0e10cSrcweir {
300*cdf0e10cSrcweir 	ImpLineRec					aMainline1; // die mit dem 1. Pfeil
301*cdf0e10cSrcweir 	ImpLineRec					aMainline2; // die mit dem 2. Pfeil
302*cdf0e10cSrcweir 	ImpLineRec					aMainline3; // die dazwischen
303*cdf0e10cSrcweir 	ImpLineRec					aHelpline1;
304*cdf0e10cSrcweir 	ImpLineRec					aHelpline2;
305*cdf0e10cSrcweir 	Rectangle					aTextRect;
306*cdf0e10cSrcweir 	Size						aTextSize;
307*cdf0e10cSrcweir 	long						nLineLen;
308*cdf0e10cSrcweir 	long						nLineWink;
309*cdf0e10cSrcweir 	long						nTextWink;
310*cdf0e10cSrcweir 	long						nHlpWink;
311*cdf0e10cSrcweir 	double						nLineSin;
312*cdf0e10cSrcweir 	double						nLineCos;
313*cdf0e10cSrcweir 	double						nHlpSin;
314*cdf0e10cSrcweir 	double						nHlpCos;
315*cdf0e10cSrcweir 	sal_uInt16						nMainlineAnz;
316*cdf0e10cSrcweir 	SdrMeasureTextHPos			eUsedTextHPos;
317*cdf0e10cSrcweir 	SdrMeasureTextVPos			eUsedTextVPos;
318*cdf0e10cSrcweir 	long						nLineWdt2;  // Halbe Strichstaerke
319*cdf0e10cSrcweir 	long						nArrow1Len; // Laenge des 1. Pfeils. Bei Center nur die Haelfte
320*cdf0e10cSrcweir 	long						nArrow2Len; // Laenge des 2. Pfeils. Bei Center nur die Haelfte
321*cdf0e10cSrcweir 	long						nArrow1Wdt; // Breite des 1. Pfeils
322*cdf0e10cSrcweir 	long						nArrow2Wdt; // Breite des 2. Pfeils
323*cdf0e10cSrcweir 	long						nShortLineLen; // Linienlaenge, wenn PfeileAussen
324*cdf0e10cSrcweir 	FASTBOOL					bArrow1Center; // Pfeil 1 zentriert?
325*cdf0e10cSrcweir 	FASTBOOL					bArrow2Center; // Pfeil 2 zentriert?
326*cdf0e10cSrcweir 	FASTBOOL					bAutoUpsideDown; // UpsideDown durch Automatik
327*cdf0e10cSrcweir 	FASTBOOL					bPfeileAussen;
328*cdf0e10cSrcweir 	FASTBOOL					bBreakedLine;
329*cdf0e10cSrcweir };
330*cdf0e10cSrcweir 
331*cdf0e10cSrcweir void SdrMeasureObj::ImpTakeAttr(ImpMeasureRec& rRec) const
332*cdf0e10cSrcweir {
333*cdf0e10cSrcweir 	rRec.aPt1 = aPt1;
334*cdf0e10cSrcweir 	rRec.aPt2 = aPt2;
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir 	const SfxItemSet& rSet = GetObjectItemSet();
337*cdf0e10cSrcweir 	rRec.eKind            =((SdrMeasureKindItem&            )rSet.Get(SDRATTR_MEASUREKIND            )).GetValue();
338*cdf0e10cSrcweir 	rRec.eWantTextHPos    =((SdrMeasureTextHPosItem&        )rSet.Get(SDRATTR_MEASURETEXTHPOS        )).GetValue();
339*cdf0e10cSrcweir 	rRec.eWantTextVPos    =((SdrMeasureTextVPosItem&        )rSet.Get(SDRATTR_MEASURETEXTVPOS        )).GetValue();
340*cdf0e10cSrcweir 	rRec.nLineDist        =((SdrMeasureLineDistItem&        )rSet.Get(SDRATTR_MEASURELINEDIST        )).GetValue();
341*cdf0e10cSrcweir 	rRec.nHelplineOverhang=((SdrMeasureHelplineOverhangItem&)rSet.Get(SDRATTR_MEASUREHELPLINEOVERHANG)).GetValue();
342*cdf0e10cSrcweir 	rRec.nHelplineDist    =((SdrMeasureHelplineDistItem&    )rSet.Get(SDRATTR_MEASUREHELPLINEDIST    )).GetValue();
343*cdf0e10cSrcweir 	rRec.nHelpline1Len    =((SdrMeasureHelpline1LenItem&    )rSet.Get(SDRATTR_MEASUREHELPLINE1LEN    )).GetValue();
344*cdf0e10cSrcweir 	rRec.nHelpline2Len    =((SdrMeasureHelpline2LenItem&    )rSet.Get(SDRATTR_MEASUREHELPLINE2LEN    )).GetValue();
345*cdf0e10cSrcweir 	rRec.bBelowRefEdge    =((SdrMeasureBelowRefEdgeItem&    )rSet.Get(SDRATTR_MEASUREBELOWREFEDGE    )).GetValue();
346*cdf0e10cSrcweir 	rRec.bTextRota90      =((SdrMeasureTextRota90Item&      )rSet.Get(SDRATTR_MEASURETEXTROTA90      )).GetValue();
347*cdf0e10cSrcweir 	rRec.bTextUpsideDown  =((SdrMeasureTextUpsideDownItem&  )rSet.Get(SDRATTR_MEASURETEXTUPSIDEDOWN  )).GetValue();
348*cdf0e10cSrcweir 	rRec.nMeasureOverhang =((SdrMeasureOverhangItem&        )rSet.Get(SDRATTR_MEASUREOVERHANG        )).GetValue();
349*cdf0e10cSrcweir 	rRec.eMeasureUnit     =((SdrMeasureUnitItem&            )rSet.Get(SDRATTR_MEASUREUNIT            )).GetValue();
350*cdf0e10cSrcweir 	rRec.aMeasureScale    =((SdrMeasureScaleItem&           )rSet.Get(SDRATTR_MEASURESCALE           )).GetValue();
351*cdf0e10cSrcweir 	rRec.bShowUnit        =((SdrMeasureShowUnitItem&        )rSet.Get(SDRATTR_MEASURESHOWUNIT        )).GetValue();
352*cdf0e10cSrcweir 	rRec.aFormatString    =((SdrMeasureFormatStringItem&    )rSet.Get(SDRATTR_MEASUREFORMATSTRING    )).GetValue();
353*cdf0e10cSrcweir 	rRec.bTextAutoAngle    =((SdrMeasureTextAutoAngleItem&    )rSet.Get(SDRATTR_MEASURETEXTAUTOANGLE    )).GetValue();
354*cdf0e10cSrcweir 	rRec.nTextAutoAngleView=((SdrMeasureTextAutoAngleViewItem&)rSet.Get(SDRATTR_MEASURETEXTAUTOANGLEVIEW)).GetValue();
355*cdf0e10cSrcweir 	rRec.bTextIsFixedAngle =((SdrMeasureTextIsFixedAngleItem& )rSet.Get(SDRATTR_MEASURETEXTISFIXEDANGLE )).GetValue();
356*cdf0e10cSrcweir 	rRec.nTextFixedAngle   =((SdrMeasureTextFixedAngleItem&   )rSet.Get(SDRATTR_MEASURETEXTFIXEDANGLE   )).GetValue();
357*cdf0e10cSrcweir }
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir long impGetLineStartEndDistance(const basegfx::B2DPolyPolygon& rPolyPolygon, long nNewWidth, bool bCenter)
360*cdf0e10cSrcweir {
361*cdf0e10cSrcweir 	const basegfx::B2DRange aPolygonRange(rPolyPolygon.getB2DRange());
362*cdf0e10cSrcweir 	const double fOldWidth(aPolygonRange.getWidth() > 1.0 ? aPolygonRange.getWidth() : 1.0);
363*cdf0e10cSrcweir 	const double fScale((double)nNewWidth / fOldWidth);
364*cdf0e10cSrcweir 	long nHeight(basegfx::fround(aPolygonRange.getHeight() * fScale));
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir 	if(bCenter)
367*cdf0e10cSrcweir 	{
368*cdf0e10cSrcweir 		nHeight /= 2L;
369*cdf0e10cSrcweir 	}
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir 	return nHeight;
372*cdf0e10cSrcweir }
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir void SdrMeasureObj::ImpCalcGeometrics(const ImpMeasureRec& rRec, ImpMeasurePoly& rPol) const
375*cdf0e10cSrcweir {
376*cdf0e10cSrcweir 	Point aP1(rRec.aPt1);
377*cdf0e10cSrcweir 	Point aP2(rRec.aPt2);
378*cdf0e10cSrcweir 	Point aDelt(aP2); aDelt-=aP1;
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir 	rPol.aTextSize=GetTextSize();
381*cdf0e10cSrcweir 	rPol.nLineLen=GetLen(aDelt);
382*cdf0e10cSrcweir 
383*cdf0e10cSrcweir 	rPol.nLineWdt2=0;
384*cdf0e10cSrcweir 	long nArrow1Len=0; bool bArrow1Center=false;
385*cdf0e10cSrcweir 	long nArrow2Len=0; bool bArrow2Center=false;
386*cdf0e10cSrcweir 	long nArrow1Wdt=0;
387*cdf0e10cSrcweir 	long nArrow2Wdt=0;
388*cdf0e10cSrcweir 	rPol.nArrow1Wdt=0;
389*cdf0e10cSrcweir 	rPol.nArrow2Wdt=0;
390*cdf0e10cSrcweir 	long nArrowNeed=0;
391*cdf0e10cSrcweir 	long nShortLen=0;
392*cdf0e10cSrcweir 	FASTBOOL bPfeileAussen=sal_False;
393*cdf0e10cSrcweir 
394*cdf0e10cSrcweir 	const SfxItemSet& rSet = GetObjectItemSet();
395*cdf0e10cSrcweir 	sal_Int32 nLineWdt = ((XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue(); // Strichstaerke
396*cdf0e10cSrcweir 	rPol.nLineWdt2 = (nLineWdt + 1) / 2;
397*cdf0e10cSrcweir 
398*cdf0e10cSrcweir 	nArrow1Wdt = ((const XLineStartWidthItem&)(rSet.Get(XATTR_LINESTARTWIDTH))).GetValue();
399*cdf0e10cSrcweir 	if(nArrow1Wdt < 0)
400*cdf0e10cSrcweir 		nArrow1Wdt = -nLineWdt * nArrow1Wdt / 100; // <0 = relativ
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir 	nArrow2Wdt = ((const XLineEndWidthItem&)(rSet.Get(XATTR_LINEENDWIDTH))).GetValue();
403*cdf0e10cSrcweir 	if(nArrow2Wdt < 0)
404*cdf0e10cSrcweir 		nArrow2Wdt = -nLineWdt * nArrow2Wdt / 100; // <0 = relativ
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir 	basegfx::B2DPolyPolygon aPol1(((const XLineStartItem&)(rSet.Get(XATTR_LINESTART))).GetLineStartValue());
407*cdf0e10cSrcweir 	basegfx::B2DPolyPolygon aPol2(((const XLineEndItem&)(rSet.Get(XATTR_LINEEND))).GetLineEndValue());
408*cdf0e10cSrcweir 	bArrow1Center = ((const XLineStartCenterItem&)(rSet.Get(XATTR_LINESTARTCENTER))).GetValue();
409*cdf0e10cSrcweir 	bArrow2Center = ((const XLineEndCenterItem&)(rSet.Get(XATTR_LINEENDCENTER))).GetValue();
410*cdf0e10cSrcweir 	nArrow1Len = impGetLineStartEndDistance(aPol1, nArrow1Wdt, bArrow1Center) - 1;
411*cdf0e10cSrcweir 	nArrow2Len = impGetLineStartEndDistance(aPol2, nArrow2Wdt, bArrow2Center) - 1;
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir 	// nArrowLen ist bei bCenter bereits halbiert
414*cdf0e10cSrcweir 	// Bei 2 Pfeilen a 4mm ist unter 10mm Schluss.
415*cdf0e10cSrcweir 	nArrowNeed=nArrow1Len+nArrow2Len+(nArrow1Wdt+nArrow2Wdt)/2;
416*cdf0e10cSrcweir 	if (rPol.nLineLen<nArrowNeed) bPfeileAussen=sal_True;
417*cdf0e10cSrcweir 	nShortLen=(nArrow1Len+nArrow1Wdt + nArrow2Len+nArrow2Wdt) /2;
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir 	rPol.eUsedTextHPos=rRec.eWantTextHPos;
420*cdf0e10cSrcweir 	rPol.eUsedTextVPos=rRec.eWantTextVPos;
421*cdf0e10cSrcweir 	if (rPol.eUsedTextVPos==SDRMEASURE_TEXTVAUTO) rPol.eUsedTextVPos=SDRMEASURE_ABOVE;
422*cdf0e10cSrcweir 	FASTBOOL bBrkLine=rPol.eUsedTextVPos==SDRMEASURETEXT_BREAKEDLINE;
423*cdf0e10cSrcweir 	if (rPol.eUsedTextVPos==SDRMEASURETEXT_VERTICALCENTERED)
424*cdf0e10cSrcweir 	{
425*cdf0e10cSrcweir 		OutlinerParaObject* pOutlinerParaObject = SdrTextObj::GetOutlinerParaObject();
426*cdf0e10cSrcweir 		if (pOutlinerParaObject!=NULL && pOutlinerParaObject->GetTextObject().GetParagraphCount()==1)
427*cdf0e10cSrcweir 		{
428*cdf0e10cSrcweir 			bBrkLine=sal_True; // Unterbrochene Linie, wenn nur 1 Absatz.
429*cdf0e10cSrcweir 		}
430*cdf0e10cSrcweir 	}
431*cdf0e10cSrcweir 	rPol.bBreakedLine=bBrkLine;
432*cdf0e10cSrcweir 	if (rPol.eUsedTextHPos==SDRMEASURE_TEXTHAUTO) { // bei zu breitem Text diesen eventuell nach aussen schieben
433*cdf0e10cSrcweir 		FASTBOOL bOutside=sal_False;
434*cdf0e10cSrcweir 		long nNeedSiz=!rRec.bTextRota90 ? rPol.aTextSize.Width() : rPol.aTextSize.Height();
435*cdf0e10cSrcweir 		if (nNeedSiz>rPol.nLineLen) bOutside=sal_True; // Text passt nicht in die Mitte
436*cdf0e10cSrcweir 		if (bBrkLine) {
437*cdf0e10cSrcweir 			if (nNeedSiz+nArrowNeed>rPol.nLineLen) bPfeileAussen=sal_True; // Text passt in die Mitte, wenn die Pfeile nach aussen kommen
438*cdf0e10cSrcweir 		} else {
439*cdf0e10cSrcweir 			long nSmallNeed=nArrow1Len+nArrow2Len+(nArrow1Wdt+nArrow2Wdt)/2/4;
440*cdf0e10cSrcweir 			if (nNeedSiz+nSmallNeed>rPol.nLineLen) bPfeileAussen=sal_True; // Text passt in die Mitte, wenn die Pfeile nach aussen kommen
441*cdf0e10cSrcweir 		}
442*cdf0e10cSrcweir 		rPol.eUsedTextHPos=bOutside ? SDRMEASURE_TEXTLEFTOUTSIDE : SDRMEASURE_TEXTINSIDE;
443*cdf0e10cSrcweir 	}
444*cdf0e10cSrcweir 	if (rPol.eUsedTextHPos!=SDRMEASURE_TEXTINSIDE) bPfeileAussen=sal_True;
445*cdf0e10cSrcweir 	rPol.nArrow1Wdt=nArrow1Wdt;
446*cdf0e10cSrcweir 	rPol.nArrow2Wdt=nArrow2Wdt;
447*cdf0e10cSrcweir 	rPol.nShortLineLen=nShortLen;
448*cdf0e10cSrcweir 	rPol.bPfeileAussen=bPfeileAussen;
449*cdf0e10cSrcweir 	rPol.nArrow1Len=nArrow1Len;
450*cdf0e10cSrcweir 	rPol.bArrow1Center=bArrow1Center;
451*cdf0e10cSrcweir 	rPol.nArrow2Len=nArrow2Len;
452*cdf0e10cSrcweir 	rPol.bArrow2Center=bArrow2Center;
453*cdf0e10cSrcweir 
454*cdf0e10cSrcweir 	rPol.nLineWink=GetAngle(aDelt);
455*cdf0e10cSrcweir 	double a=rPol.nLineWink*nPi180;
456*cdf0e10cSrcweir 	double nLineSin=sin(a);
457*cdf0e10cSrcweir 	double nLineCos=cos(a);
458*cdf0e10cSrcweir 	rPol.nLineSin=nLineSin;
459*cdf0e10cSrcweir 	rPol.nLineCos=nLineCos;
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir 	rPol.nTextWink=rPol.nLineWink;
462*cdf0e10cSrcweir 	if (rRec.bTextRota90) rPol.nTextWink+=9000;
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir 	rPol.bAutoUpsideDown=sal_False;
465*cdf0e10cSrcweir 	if (rRec.bTextAutoAngle) {
466*cdf0e10cSrcweir 		long nTmpWink=NormAngle360(rPol.nTextWink-rRec.nTextAutoAngleView);
467*cdf0e10cSrcweir 		if (nTmpWink>=18000) {
468*cdf0e10cSrcweir 			rPol.nTextWink+=18000;
469*cdf0e10cSrcweir 			rPol.bAutoUpsideDown=sal_True;
470*cdf0e10cSrcweir 		}
471*cdf0e10cSrcweir 	}
472*cdf0e10cSrcweir 
473*cdf0e10cSrcweir 	if (rRec.bTextUpsideDown) rPol.nTextWink+=18000;
474*cdf0e10cSrcweir 	rPol.nTextWink=NormAngle360(rPol.nTextWink);
475*cdf0e10cSrcweir 	rPol.nHlpWink=rPol.nLineWink+9000;
476*cdf0e10cSrcweir 	if (rRec.bBelowRefEdge) rPol.nHlpWink+=18000;
477*cdf0e10cSrcweir 	rPol.nHlpWink=NormAngle360(rPol.nHlpWink);
478*cdf0e10cSrcweir 	double nHlpSin=nLineCos;
479*cdf0e10cSrcweir 	double nHlpCos=-nLineSin;
480*cdf0e10cSrcweir 	if (rRec.bBelowRefEdge) {
481*cdf0e10cSrcweir 		nHlpSin=-nHlpSin;
482*cdf0e10cSrcweir 		nHlpCos=-nHlpCos;
483*cdf0e10cSrcweir 	}
484*cdf0e10cSrcweir 	rPol.nHlpSin=nHlpSin;
485*cdf0e10cSrcweir 	rPol.nHlpCos=nHlpCos;
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir 	long nLineDist=rRec.nLineDist;
488*cdf0e10cSrcweir 	long nOverhang=rRec.nHelplineOverhang;
489*cdf0e10cSrcweir 	long nHelplineDist=rRec.nHelplineDist;
490*cdf0e10cSrcweir 
491*cdf0e10cSrcweir 	long dx= Round(nLineDist*nHlpCos);
492*cdf0e10cSrcweir 	long dy=-Round(nLineDist*nHlpSin);
493*cdf0e10cSrcweir 	long dxh1a= Round((nHelplineDist-rRec.nHelpline1Len)*nHlpCos);
494*cdf0e10cSrcweir 	long dyh1a=-Round((nHelplineDist-rRec.nHelpline1Len)*nHlpSin);
495*cdf0e10cSrcweir 	long dxh1b= Round((nHelplineDist-rRec.nHelpline2Len)*nHlpCos);
496*cdf0e10cSrcweir 	long dyh1b=-Round((nHelplineDist-rRec.nHelpline2Len)*nHlpSin);
497*cdf0e10cSrcweir 	long dxh2= Round((nLineDist+nOverhang)*nHlpCos);
498*cdf0e10cSrcweir 	long dyh2=-Round((nLineDist+nOverhang)*nHlpSin);
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir 	// Masshilfslinie 1
501*cdf0e10cSrcweir 	rPol.aHelpline1.aP1=Point(aP1.X()+dxh1a,aP1.Y()+dyh1a);
502*cdf0e10cSrcweir 	rPol.aHelpline1.aP2=Point(aP1.X()+dxh2,aP1.Y()+dyh2);
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir 	// Masshilfslinie 2
505*cdf0e10cSrcweir 	rPol.aHelpline2.aP1=Point(aP2.X()+dxh1b,aP2.Y()+dyh1b);
506*cdf0e10cSrcweir 	rPol.aHelpline2.aP2=Point(aP2.X()+dxh2,aP2.Y()+dyh2);
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir 	// Masslinie(n)
509*cdf0e10cSrcweir 	Point aMainlinePt1(aP1.X()+dx,aP1.Y()+dy);
510*cdf0e10cSrcweir 	Point aMainlinePt2(aP2.X()+dx,aP2.Y()+dy);
511*cdf0e10cSrcweir 	if (!bPfeileAussen) {
512*cdf0e10cSrcweir 		rPol.aMainline1.aP1=aMainlinePt1;
513*cdf0e10cSrcweir 		rPol.aMainline1.aP2=aMainlinePt2;
514*cdf0e10cSrcweir 		rPol.aMainline2=rPol.aMainline1;
515*cdf0e10cSrcweir 		rPol.aMainline3=rPol.aMainline1;
516*cdf0e10cSrcweir 		rPol.nMainlineAnz=1;
517*cdf0e10cSrcweir 		if (bBrkLine) {
518*cdf0e10cSrcweir 			long nNeedSiz=!rRec.bTextRota90 ? rPol.aTextSize.Width() : rPol.aTextSize.Height();
519*cdf0e10cSrcweir 			long nHalfLen=(rPol.nLineLen-nNeedSiz-nArrow1Wdt/4-nArrow2Wdt/4) /2;
520*cdf0e10cSrcweir 			rPol.nMainlineAnz=2;
521*cdf0e10cSrcweir 			rPol.aMainline1.aP2=aMainlinePt1;
522*cdf0e10cSrcweir 			rPol.aMainline1.aP2.X()+=nHalfLen;
523*cdf0e10cSrcweir 			RotatePoint(rPol.aMainline1.aP2,rPol.aMainline1.aP1,nLineSin,nLineCos);
524*cdf0e10cSrcweir 			rPol.aMainline2.aP1=aMainlinePt2;
525*cdf0e10cSrcweir 			rPol.aMainline2.aP1.X()-=nHalfLen;
526*cdf0e10cSrcweir 			RotatePoint(rPol.aMainline2.aP1,rPol.aMainline2.aP2,nLineSin,nLineCos);
527*cdf0e10cSrcweir 		}
528*cdf0e10cSrcweir 	} else {
529*cdf0e10cSrcweir 		long nLen1=nShortLen; // Pfeilbreite als Linienlaenge ausserhalb des Pfeils
530*cdf0e10cSrcweir 		long nLen2=nShortLen;
531*cdf0e10cSrcweir 		long nTextWdt=rRec.bTextRota90 ? rPol.aTextSize.Height() : rPol.aTextSize.Width();
532*cdf0e10cSrcweir 		if (!bBrkLine) {
533*cdf0e10cSrcweir 			if (rPol.eUsedTextHPos==SDRMEASURE_TEXTLEFTOUTSIDE) nLen1=nArrow1Len+nTextWdt;
534*cdf0e10cSrcweir 			if (rPol.eUsedTextHPos==SDRMEASURE_TEXTRIGHTOUTSIDE) nLen2=nArrow2Len+nTextWdt;
535*cdf0e10cSrcweir 		}
536*cdf0e10cSrcweir 		rPol.aMainline1.aP1=aMainlinePt1;
537*cdf0e10cSrcweir 		rPol.aMainline1.aP2=aMainlinePt1; rPol.aMainline1.aP2.X()-=nLen1; RotatePoint(rPol.aMainline1.aP2,aMainlinePt1,nLineSin,nLineCos);
538*cdf0e10cSrcweir 		rPol.aMainline2.aP1=aMainlinePt2; rPol.aMainline2.aP1.X()+=nLen2; RotatePoint(rPol.aMainline2.aP1,aMainlinePt2,nLineSin,nLineCos);
539*cdf0e10cSrcweir 		rPol.aMainline2.aP2=aMainlinePt2;
540*cdf0e10cSrcweir 		rPol.aMainline3.aP1=aMainlinePt1;
541*cdf0e10cSrcweir 		rPol.aMainline3.aP2=aMainlinePt2;
542*cdf0e10cSrcweir 		rPol.nMainlineAnz=3;
543*cdf0e10cSrcweir 		if (bBrkLine && rPol.eUsedTextHPos==SDRMEASURE_TEXTINSIDE) rPol.nMainlineAnz=2;
544*cdf0e10cSrcweir 	}
545*cdf0e10cSrcweir }
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir basegfx::B2DPolyPolygon SdrMeasureObj::ImpCalcXPoly(const ImpMeasurePoly& rPol) const
548*cdf0e10cSrcweir {
549*cdf0e10cSrcweir 	basegfx::B2DPolyPolygon aRetval;
550*cdf0e10cSrcweir 	basegfx::B2DPolygon aPartPolyA;
551*cdf0e10cSrcweir 	aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline1.aP1.X(), rPol.aMainline1.aP1.Y()));
552*cdf0e10cSrcweir 	aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline1.aP2.X(), rPol.aMainline1.aP2.Y()));
553*cdf0e10cSrcweir 	aRetval.append(aPartPolyA);
554*cdf0e10cSrcweir 
555*cdf0e10cSrcweir 	if(rPol.nMainlineAnz > 1)
556*cdf0e10cSrcweir 	{
557*cdf0e10cSrcweir 		aPartPolyA.clear();
558*cdf0e10cSrcweir 		aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline2.aP1.X(), rPol.aMainline2.aP1.Y()));
559*cdf0e10cSrcweir 		aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline2.aP2.X(), rPol.aMainline2.aP2.Y()));
560*cdf0e10cSrcweir 		aRetval.append(aPartPolyA);
561*cdf0e10cSrcweir 	}
562*cdf0e10cSrcweir 
563*cdf0e10cSrcweir 	if(rPol.nMainlineAnz > 2)
564*cdf0e10cSrcweir 	{
565*cdf0e10cSrcweir 		aPartPolyA.clear();
566*cdf0e10cSrcweir 		aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline3.aP1.X(), rPol.aMainline3.aP1.Y()));
567*cdf0e10cSrcweir 		aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline3.aP2.X(), rPol.aMainline3.aP2.Y()));
568*cdf0e10cSrcweir 		aRetval.append(aPartPolyA);
569*cdf0e10cSrcweir 	}
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir 	aPartPolyA.clear();
572*cdf0e10cSrcweir 	aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline1.aP1.X(), rPol.aHelpline1.aP1.Y()));
573*cdf0e10cSrcweir 	aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline1.aP2.X(), rPol.aHelpline1.aP2.Y()));
574*cdf0e10cSrcweir 	aRetval.append(aPartPolyA);
575*cdf0e10cSrcweir 
576*cdf0e10cSrcweir 	aPartPolyA.clear();
577*cdf0e10cSrcweir 	aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline2.aP1.X(), rPol.aHelpline2.aP1.Y()));
578*cdf0e10cSrcweir 	aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline2.aP2.X(), rPol.aHelpline2.aP2.Y()));
579*cdf0e10cSrcweir 	aRetval.append(aPartPolyA);
580*cdf0e10cSrcweir 
581*cdf0e10cSrcweir 	return aRetval;
582*cdf0e10cSrcweir }
583*cdf0e10cSrcweir 
584*cdf0e10cSrcweir FASTBOOL SdrMeasureObj::CalcFieldValue(const SvxFieldItem& rField, sal_uInt16 nPara, sal_uInt16 nPos,
585*cdf0e10cSrcweir 	FASTBOOL bEdit,
586*cdf0e10cSrcweir 	Color*& rpTxtColor, Color*& rpFldColor, XubString& rRet) const
587*cdf0e10cSrcweir {
588*cdf0e10cSrcweir 	const SvxFieldData* pField=rField.GetField();
589*cdf0e10cSrcweir 	SdrMeasureField* pMeasureField=PTR_CAST(SdrMeasureField,pField);
590*cdf0e10cSrcweir 	if (pMeasureField!=NULL) {
591*cdf0e10cSrcweir 		TakeRepresentation(rRet, pMeasureField->GetMeasureFieldKind());
592*cdf0e10cSrcweir 		if (rpFldColor!=NULL) {
593*cdf0e10cSrcweir 			if (!bEdit)
594*cdf0e10cSrcweir 			{
595*cdf0e10cSrcweir 				delete rpFldColor;
596*cdf0e10cSrcweir 				rpFldColor=NULL;
597*cdf0e10cSrcweir 			}
598*cdf0e10cSrcweir 		}
599*cdf0e10cSrcweir 		return sal_True;
600*cdf0e10cSrcweir 	} else {
601*cdf0e10cSrcweir 		return SdrTextObj::CalcFieldValue(rField,nPara,nPos,bEdit,rpTxtColor,rpFldColor,rRet);
602*cdf0e10cSrcweir 	}
603*cdf0e10cSrcweir }
604*cdf0e10cSrcweir 
605*cdf0e10cSrcweir void SdrMeasureObj::UndirtyText() const
606*cdf0e10cSrcweir {
607*cdf0e10cSrcweir 	if (bTextDirty)
608*cdf0e10cSrcweir 	{
609*cdf0e10cSrcweir 		SdrOutliner& rOutliner=ImpGetDrawOutliner();
610*cdf0e10cSrcweir 		OutlinerParaObject* pOutlinerParaObject = SdrTextObj::GetOutlinerParaObject();
611*cdf0e10cSrcweir 		if(pOutlinerParaObject==NULL)
612*cdf0e10cSrcweir 		{
613*cdf0e10cSrcweir             rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_ROTA90BLANCS), EE_FEATURE_FIELD), ESelection(0,0));
614*cdf0e10cSrcweir             rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_VALUE), EE_FEATURE_FIELD),ESelection(0,1));
615*cdf0e10cSrcweir             rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_UNIT), EE_FEATURE_FIELD),ESelection(0,2));
616*cdf0e10cSrcweir             rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_ROTA90BLANCS), EE_FEATURE_FIELD),ESelection(0,3));
617*cdf0e10cSrcweir 
618*cdf0e10cSrcweir 			if(GetStyleSheet())
619*cdf0e10cSrcweir 				rOutliner.SetStyleSheet(0, GetStyleSheet());
620*cdf0e10cSrcweir 
621*cdf0e10cSrcweir 			rOutliner.SetParaAttribs(0, GetObjectItemSet());
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir 			// casting auf nonconst
624*cdf0e10cSrcweir 			const_cast<SdrMeasureObj*>(this)->NbcSetOutlinerParaObject( rOutliner.CreateParaObject() );
625*cdf0e10cSrcweir 		}
626*cdf0e10cSrcweir 		else
627*cdf0e10cSrcweir 		{
628*cdf0e10cSrcweir 			rOutliner.SetText(*pOutlinerParaObject);
629*cdf0e10cSrcweir 		}
630*cdf0e10cSrcweir 
631*cdf0e10cSrcweir 		rOutliner.SetUpdateMode(sal_True);
632*cdf0e10cSrcweir 		rOutliner.UpdateFields();
633*cdf0e10cSrcweir 		Size aSiz(rOutliner.CalcTextSize());
634*cdf0e10cSrcweir 		rOutliner.Clear();
635*cdf0e10cSrcweir 		// 3x casting auf nonconst
636*cdf0e10cSrcweir 		((SdrMeasureObj*)this)->aTextSize=aSiz;
637*cdf0e10cSrcweir 		((SdrMeasureObj*)this)->bTextSizeDirty=sal_False;
638*cdf0e10cSrcweir 		((SdrMeasureObj*)this)->bTextDirty=sal_False;
639*cdf0e10cSrcweir 	}
640*cdf0e10cSrcweir }
641*cdf0e10cSrcweir 
642*cdf0e10cSrcweir void SdrMeasureObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
643*cdf0e10cSrcweir {
644*cdf0e10cSrcweir 	if (bTextDirty) UndirtyText();
645*cdf0e10cSrcweir 	ImpMeasureRec aRec;
646*cdf0e10cSrcweir 	ImpMeasurePoly aMPol;
647*cdf0e10cSrcweir 	ImpTakeAttr(aRec);
648*cdf0e10cSrcweir 	ImpCalcGeometrics(aRec,aMPol);
649*cdf0e10cSrcweir 
650*cdf0e10cSrcweir 	// TextSize ermitteln inkl. Textrahmenabstaende
651*cdf0e10cSrcweir 	Size aTextSize2(aMPol.aTextSize);
652*cdf0e10cSrcweir 	if (aTextSize2.Width()<1) aTextSize2.Width()=1;
653*cdf0e10cSrcweir 	if (aTextSize2.Height()<1) aTextSize2.Height()=1;
654*cdf0e10cSrcweir 	aTextSize2.Width()+=GetTextLeftDistance()+GetTextRightDistance();
655*cdf0e10cSrcweir 	aTextSize2.Height()+=GetTextUpperDistance()+GetTextLowerDistance();
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir 	Point aPt1b(aMPol.aMainline1.aP1);
658*cdf0e10cSrcweir 	long nLen=aMPol.nLineLen;
659*cdf0e10cSrcweir 	long nLWdt=aMPol.nLineWdt2;
660*cdf0e10cSrcweir 	long nArr1Len=aMPol.nArrow1Len;
661*cdf0e10cSrcweir 	long nArr2Len=aMPol.nArrow2Len;
662*cdf0e10cSrcweir 	if (aMPol.bBreakedLine) {
663*cdf0e10cSrcweir 		// Bei Unterbrochener Linie und Outside muss der Text nicht neben den
664*cdf0e10cSrcweir 		// Pfeil sondern neben die Linie an dem Pfeil plaziert werden
665*cdf0e10cSrcweir 		nArr1Len=aMPol.nShortLineLen+aMPol.nArrow1Wdt/4;
666*cdf0e10cSrcweir 		nArr2Len=aMPol.nShortLineLen+aMPol.nArrow2Wdt/4;
667*cdf0e10cSrcweir 	}
668*cdf0e10cSrcweir 
669*cdf0e10cSrcweir 	Point aTextPos;
670*cdf0e10cSrcweir 	FASTBOOL bRota90=aRec.bTextRota90;
671*cdf0e10cSrcweir 	FASTBOOL bUpsideDown=aRec.bTextUpsideDown!=aMPol.bAutoUpsideDown;
672*cdf0e10cSrcweir 	FASTBOOL bBelowRefEdge=aRec.bBelowRefEdge;
673*cdf0e10cSrcweir 	SdrMeasureTextHPos eMH=aMPol.eUsedTextHPos;
674*cdf0e10cSrcweir 	SdrMeasureTextVPos eMV=aMPol.eUsedTextVPos;
675*cdf0e10cSrcweir 	if (!bRota90) {
676*cdf0e10cSrcweir 		switch (eMH) {
677*cdf0e10cSrcweir 			case SDRMEASURE_TEXTLEFTOUTSIDE: aTextPos.X()=aPt1b.X()-aTextSize2.Width()-nArr1Len-nLWdt; break;
678*cdf0e10cSrcweir 			case SDRMEASURE_TEXTRIGHTOUTSIDE: aTextPos.X()=aPt1b.X()+nLen+nArr2Len+nLWdt; break;
679*cdf0e10cSrcweir 			default: aTextPos.X()=aPt1b.X(); aTextSize2.Width()=nLen;
680*cdf0e10cSrcweir 		}
681*cdf0e10cSrcweir 		switch (eMV) {
682*cdf0e10cSrcweir 			case SDRMEASURETEXT_VERTICALCENTERED:
683*cdf0e10cSrcweir 			case SDRMEASURETEXT_BREAKEDLINE: aTextPos.Y()=aPt1b.Y()-aTextSize2.Height()/2; break;
684*cdf0e10cSrcweir 			case SDRMEASURE_BELOW: {
685*cdf0e10cSrcweir 				if (!bUpsideDown) aTextPos.Y()=aPt1b.Y()+nLWdt;
686*cdf0e10cSrcweir 				else aTextPos.Y()=aPt1b.Y()-aTextSize2.Height()-nLWdt;
687*cdf0e10cSrcweir 			} break;
688*cdf0e10cSrcweir 			default: {
689*cdf0e10cSrcweir 				if (!bUpsideDown) aTextPos.Y()=aPt1b.Y()-aTextSize2.Height()-nLWdt;
690*cdf0e10cSrcweir 				else aTextPos.Y()=aPt1b.Y()+nLWdt;
691*cdf0e10cSrcweir 			}
692*cdf0e10cSrcweir 		}
693*cdf0e10cSrcweir 		if (bUpsideDown) {
694*cdf0e10cSrcweir 			aTextPos.X()+=aTextSize2.Width();
695*cdf0e10cSrcweir 			aTextPos.Y()+=aTextSize2.Height();
696*cdf0e10cSrcweir 		}
697*cdf0e10cSrcweir 	} else { // also wenn bTextRota90==TRUE
698*cdf0e10cSrcweir 		switch (eMH) {
699*cdf0e10cSrcweir 			case SDRMEASURE_TEXTLEFTOUTSIDE: aTextPos.X()=aPt1b.X()-aTextSize2.Height()-nArr1Len; break;
700*cdf0e10cSrcweir 			case SDRMEASURE_TEXTRIGHTOUTSIDE: aTextPos.X()=aPt1b.X()+nLen+nArr2Len; break;
701*cdf0e10cSrcweir 			default: aTextPos.X()=aPt1b.X(); aTextSize2.Height()=nLen;
702*cdf0e10cSrcweir 		}
703*cdf0e10cSrcweir 		switch (eMV) {
704*cdf0e10cSrcweir 			case SDRMEASURETEXT_VERTICALCENTERED:
705*cdf0e10cSrcweir 			case SDRMEASURETEXT_BREAKEDLINE: aTextPos.Y()=aPt1b.Y()+aTextSize2.Width()/2; break;
706*cdf0e10cSrcweir 			case SDRMEASURE_BELOW: {
707*cdf0e10cSrcweir 				if (!bBelowRefEdge) aTextPos.Y()=aPt1b.Y()+aTextSize2.Width()+nLWdt;
708*cdf0e10cSrcweir 				else aTextPos.Y()=aPt1b.Y()-nLWdt;
709*cdf0e10cSrcweir 			} break;
710*cdf0e10cSrcweir 			default: {
711*cdf0e10cSrcweir 				if (!bBelowRefEdge) aTextPos.Y()=aPt1b.Y()-nLWdt;
712*cdf0e10cSrcweir 				else aTextPos.Y()=aPt1b.Y()+aTextSize2.Width()+nLWdt;
713*cdf0e10cSrcweir 			}
714*cdf0e10cSrcweir 		}
715*cdf0e10cSrcweir 		if (bUpsideDown) {
716*cdf0e10cSrcweir 			aTextPos.X()+=aTextSize2.Height();
717*cdf0e10cSrcweir 			aTextPos.Y()-=aTextSize2.Width();
718*cdf0e10cSrcweir 		}
719*cdf0e10cSrcweir 	}
720*cdf0e10cSrcweir 	if (aMPol.nTextWink!=aGeo.nDrehWink) {
721*cdf0e10cSrcweir 		((SdrMeasureObj*)this)->aGeo.nDrehWink=aMPol.nTextWink;
722*cdf0e10cSrcweir 		((SdrMeasureObj*)this)->aGeo.RecalcSinCos();
723*cdf0e10cSrcweir 	}
724*cdf0e10cSrcweir 	RotatePoint(aTextPos,aPt1b,aMPol.nLineSin,aMPol.nLineCos);
725*cdf0e10cSrcweir 	aTextSize2.Width()++; aTextSize2.Height()++; // wg. des komischen Verhaltens beim Rect-Ctor
726*cdf0e10cSrcweir 	rRect=Rectangle(aTextPos,aTextSize2);
727*cdf0e10cSrcweir 	rRect.Justify();
728*cdf0e10cSrcweir 	((SdrMeasureObj*)this)->aRect=rRect;
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir 	if (aMPol.nTextWink!=aGeo.nDrehWink) {
731*cdf0e10cSrcweir 		((SdrMeasureObj*)this)->aGeo.nDrehWink=aMPol.nTextWink;
732*cdf0e10cSrcweir 		((SdrMeasureObj*)this)->aGeo.RecalcSinCos();
733*cdf0e10cSrcweir 	}
734*cdf0e10cSrcweir }
735*cdf0e10cSrcweir 
736*cdf0e10cSrcweir void SdrMeasureObj::operator=(const SdrObject& rObj)
737*cdf0e10cSrcweir {
738*cdf0e10cSrcweir 	SdrTextObj::operator=(rObj);
739*cdf0e10cSrcweir 	aPt1=((SdrMeasureObj&)rObj).aPt1;
740*cdf0e10cSrcweir 	aPt2=((SdrMeasureObj&)rObj).aPt2;
741*cdf0e10cSrcweir 	bTextDirty=((SdrMeasureObj&)rObj).bTextDirty;
742*cdf0e10cSrcweir }
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir void SdrMeasureObj::TakeObjNameSingul(XubString& rName) const
745*cdf0e10cSrcweir {
746*cdf0e10cSrcweir 	rName=ImpGetResStr(STR_ObjNameSingulMEASURE);
747*cdf0e10cSrcweir 
748*cdf0e10cSrcweir 	String aName( GetName() );
749*cdf0e10cSrcweir 	if(aName.Len())
750*cdf0e10cSrcweir 	{
751*cdf0e10cSrcweir 		rName += sal_Unicode(' ');
752*cdf0e10cSrcweir 		rName += sal_Unicode('\'');
753*cdf0e10cSrcweir 		rName += aName;
754*cdf0e10cSrcweir 		rName += sal_Unicode('\'');
755*cdf0e10cSrcweir 	}
756*cdf0e10cSrcweir }
757*cdf0e10cSrcweir 
758*cdf0e10cSrcweir void SdrMeasureObj::TakeObjNamePlural(XubString& rName) const
759*cdf0e10cSrcweir {
760*cdf0e10cSrcweir 	rName=ImpGetResStr(STR_ObjNamePluralMEASURE);
761*cdf0e10cSrcweir }
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir basegfx::B2DPolyPolygon SdrMeasureObj::TakeXorPoly() const
764*cdf0e10cSrcweir {
765*cdf0e10cSrcweir 	ImpMeasureRec aRec;
766*cdf0e10cSrcweir 	ImpMeasurePoly aMPol;
767*cdf0e10cSrcweir 	ImpTakeAttr(aRec);
768*cdf0e10cSrcweir 	ImpCalcGeometrics(aRec,aMPol);
769*cdf0e10cSrcweir 	return ImpCalcXPoly(aMPol);
770*cdf0e10cSrcweir }
771*cdf0e10cSrcweir 
772*cdf0e10cSrcweir sal_uInt32 SdrMeasureObj::GetHdlCount() const
773*cdf0e10cSrcweir {
774*cdf0e10cSrcweir 	return 6L;
775*cdf0e10cSrcweir }
776*cdf0e10cSrcweir 
777*cdf0e10cSrcweir SdrHdl* SdrMeasureObj::GetHdl(sal_uInt32 nHdlNum) const
778*cdf0e10cSrcweir {
779*cdf0e10cSrcweir 	ImpMeasureRec aRec;
780*cdf0e10cSrcweir 	ImpMeasurePoly aMPol;
781*cdf0e10cSrcweir 	ImpTakeAttr(aRec);
782*cdf0e10cSrcweir 	aRec.nHelplineDist=0;
783*cdf0e10cSrcweir 	ImpCalcGeometrics(aRec,aMPol);
784*cdf0e10cSrcweir 	Point aPt;
785*cdf0e10cSrcweir 	//SdrHdlKind eHdl=HDL_POLY;
786*cdf0e10cSrcweir 	switch (nHdlNum) {
787*cdf0e10cSrcweir 		case 0: aPt=aMPol.aHelpline1.aP1; break;
788*cdf0e10cSrcweir 		case 1: aPt=aMPol.aHelpline2.aP1; break;
789*cdf0e10cSrcweir 		case 2: aPt=aPt1;       break;
790*cdf0e10cSrcweir 		case 3: aPt=aPt2;       break;
791*cdf0e10cSrcweir 		case 4: aPt=aMPol.aHelpline1.aP2; break;
792*cdf0e10cSrcweir 		case 5: aPt=aMPol.aHelpline2.aP2; break;
793*cdf0e10cSrcweir 	} // switch
794*cdf0e10cSrcweir 	SdrHdl* pHdl=new ImpMeasureHdl(aPt,HDL_USER);
795*cdf0e10cSrcweir 	pHdl->SetObjHdlNum(nHdlNum);
796*cdf0e10cSrcweir 	pHdl->SetDrehWink(aMPol.nLineWink);
797*cdf0e10cSrcweir 	return pHdl;
798*cdf0e10cSrcweir }
799*cdf0e10cSrcweir 
800*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
801*cdf0e10cSrcweir 
802*cdf0e10cSrcweir bool SdrMeasureObj::hasSpecialDrag() const
803*cdf0e10cSrcweir {
804*cdf0e10cSrcweir 	return true;
805*cdf0e10cSrcweir }
806*cdf0e10cSrcweir 
807*cdf0e10cSrcweir bool SdrMeasureObj::beginSpecialDrag(SdrDragStat& rDrag) const
808*cdf0e10cSrcweir {
809*cdf0e10cSrcweir 	const SdrHdl* pHdl = rDrag.GetHdl();
810*cdf0e10cSrcweir 
811*cdf0e10cSrcweir     if(pHdl)
812*cdf0e10cSrcweir     {
813*cdf0e10cSrcweir 		const sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
814*cdf0e10cSrcweir 
815*cdf0e10cSrcweir         if(nHdlNum != 2 && nHdlNum != 3)
816*cdf0e10cSrcweir         {
817*cdf0e10cSrcweir 			rDrag.SetEndDragChangesAttributes(true);
818*cdf0e10cSrcweir 		}
819*cdf0e10cSrcweir 
820*cdf0e10cSrcweir         return true;
821*cdf0e10cSrcweir 	}
822*cdf0e10cSrcweir 
823*cdf0e10cSrcweir     return false;
824*cdf0e10cSrcweir }
825*cdf0e10cSrcweir 
826*cdf0e10cSrcweir bool SdrMeasureObj::applySpecialDrag(SdrDragStat& rDrag)
827*cdf0e10cSrcweir {
828*cdf0e10cSrcweir     ImpMeasureRec aMeasureRec;
829*cdf0e10cSrcweir 	const SdrHdl* pHdl = rDrag.GetHdl();
830*cdf0e10cSrcweir 	const sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir 	ImpTakeAttr(aMeasureRec);
833*cdf0e10cSrcweir 	ImpEvalDrag(aMeasureRec, rDrag);
834*cdf0e10cSrcweir 
835*cdf0e10cSrcweir 	switch (nHdlNum)
836*cdf0e10cSrcweir     {
837*cdf0e10cSrcweir 		case 2:
838*cdf0e10cSrcweir         {
839*cdf0e10cSrcweir             aPt1 = aMeasureRec.aPt1;
840*cdf0e10cSrcweir             SetTextDirty();
841*cdf0e10cSrcweir             break;
842*cdf0e10cSrcweir         }
843*cdf0e10cSrcweir 		case 3:
844*cdf0e10cSrcweir         {
845*cdf0e10cSrcweir             aPt2 = aMeasureRec.aPt2;
846*cdf0e10cSrcweir             SetTextDirty();
847*cdf0e10cSrcweir             break;
848*cdf0e10cSrcweir         }
849*cdf0e10cSrcweir 		default:
850*cdf0e10cSrcweir 		{
851*cdf0e10cSrcweir             switch(nHdlNum)
852*cdf0e10cSrcweir 			{
853*cdf0e10cSrcweir 				case 0:
854*cdf0e10cSrcweir 				case 1:
855*cdf0e10cSrcweir 				{
856*cdf0e10cSrcweir                     ImpMeasureRec aOrigMeasureRec;
857*cdf0e10cSrcweir 	                ImpTakeAttr(aOrigMeasureRec);
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir                     if(aMeasureRec.nHelpline1Len != aOrigMeasureRec.nHelpline1Len)
860*cdf0e10cSrcweir 					{
861*cdf0e10cSrcweir 						SetObjectItem(SdrMeasureHelpline1LenItem(aMeasureRec.nHelpline1Len));
862*cdf0e10cSrcweir 					}
863*cdf0e10cSrcweir 
864*cdf0e10cSrcweir 					if(aMeasureRec.nHelpline2Len != aOrigMeasureRec.nHelpline2Len)
865*cdf0e10cSrcweir 					{
866*cdf0e10cSrcweir 						SetObjectItem(SdrMeasureHelpline2LenItem(aMeasureRec.nHelpline2Len));
867*cdf0e10cSrcweir 					}
868*cdf0e10cSrcweir 
869*cdf0e10cSrcweir 					break;
870*cdf0e10cSrcweir 				}
871*cdf0e10cSrcweir 
872*cdf0e10cSrcweir 				case 4:
873*cdf0e10cSrcweir 				case 5:
874*cdf0e10cSrcweir 				{
875*cdf0e10cSrcweir                     ImpMeasureRec aOrigMeasureRec;
876*cdf0e10cSrcweir 	                ImpTakeAttr(aOrigMeasureRec);
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir                     if(aMeasureRec.nLineDist != aOrigMeasureRec.nLineDist)
879*cdf0e10cSrcweir 					{
880*cdf0e10cSrcweir 						SetObjectItem(SdrMeasureLineDistItem(aMeasureRec.nLineDist));
881*cdf0e10cSrcweir 					}
882*cdf0e10cSrcweir 
883*cdf0e10cSrcweir 					if(aMeasureRec.bBelowRefEdge != aOrigMeasureRec.bBelowRefEdge)
884*cdf0e10cSrcweir 					{
885*cdf0e10cSrcweir 						SetObjectItem(SdrMeasureBelowRefEdgeItem(aMeasureRec.bBelowRefEdge));
886*cdf0e10cSrcweir 					}
887*cdf0e10cSrcweir 				}
888*cdf0e10cSrcweir 			}
889*cdf0e10cSrcweir 		}
890*cdf0e10cSrcweir 	} // switch
891*cdf0e10cSrcweir 
892*cdf0e10cSrcweir     SetRectsDirty();
893*cdf0e10cSrcweir 	SetChanged();
894*cdf0e10cSrcweir 
895*cdf0e10cSrcweir     return true;
896*cdf0e10cSrcweir }
897*cdf0e10cSrcweir 
898*cdf0e10cSrcweir String SdrMeasureObj::getSpecialDragComment(const SdrDragStat& /*rDrag*/) const
899*cdf0e10cSrcweir {
900*cdf0e10cSrcweir 	XubString aStr;
901*cdf0e10cSrcweir 	return aStr;
902*cdf0e10cSrcweir }
903*cdf0e10cSrcweir 
904*cdf0e10cSrcweir void SdrMeasureObj::ImpEvalDrag(ImpMeasureRec& rRec, const SdrDragStat& rDrag) const
905*cdf0e10cSrcweir {
906*cdf0e10cSrcweir 	long nLineWink=GetAngle(rRec.aPt2-rRec.aPt1);
907*cdf0e10cSrcweir 	double a=nLineWink*nPi180;
908*cdf0e10cSrcweir 	double nSin=sin(a);
909*cdf0e10cSrcweir 	double nCos=cos(a);
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir 	const SdrHdl* pHdl=rDrag.GetHdl();
912*cdf0e10cSrcweir 	sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
913*cdf0e10cSrcweir 	FASTBOOL bOrtho=rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho();
914*cdf0e10cSrcweir 	FASTBOOL bBigOrtho=bOrtho && rDrag.GetView()->IsBigOrtho();
915*cdf0e10cSrcweir 	FASTBOOL bBelow=rRec.bBelowRefEdge;
916*cdf0e10cSrcweir 	Point aPt(rDrag.GetNow());
917*cdf0e10cSrcweir 
918*cdf0e10cSrcweir 	switch (nHdlNum) {
919*cdf0e10cSrcweir 		case 0: {
920*cdf0e10cSrcweir 			RotatePoint(aPt,aPt1,nSin,-nCos);
921*cdf0e10cSrcweir 			rRec.nHelpline1Len=aPt1.Y()-aPt.Y();
922*cdf0e10cSrcweir 			if (bBelow) rRec.nHelpline1Len=-rRec.nHelpline1Len;
923*cdf0e10cSrcweir 			if (bOrtho) rRec.nHelpline2Len=rRec.nHelpline1Len;
924*cdf0e10cSrcweir 		} break;
925*cdf0e10cSrcweir 		case 1: {
926*cdf0e10cSrcweir 			RotatePoint(aPt,aPt2,nSin,-nCos);
927*cdf0e10cSrcweir 			rRec.nHelpline2Len=aPt2.Y()-aPt.Y();
928*cdf0e10cSrcweir 			if (bBelow) rRec.nHelpline2Len=-rRec.nHelpline2Len;
929*cdf0e10cSrcweir 			if (bOrtho) rRec.nHelpline1Len=rRec.nHelpline2Len;
930*cdf0e10cSrcweir 		} break;
931*cdf0e10cSrcweir 		case 2: case 3: {
932*cdf0e10cSrcweir 			FASTBOOL bAnf=nHdlNum==2;
933*cdf0e10cSrcweir 			Point& rMov=bAnf ? rRec.aPt1 : rRec.aPt2;
934*cdf0e10cSrcweir 			Point aMov(rMov);
935*cdf0e10cSrcweir 			Point aFix(bAnf ? rRec.aPt2 : rRec.aPt1);
936*cdf0e10cSrcweir 			if (bOrtho) {
937*cdf0e10cSrcweir 				long ndx0=aMov.X()-aFix.X();
938*cdf0e10cSrcweir 				long ndy0=aMov.Y()-aFix.Y();
939*cdf0e10cSrcweir 				FASTBOOL bHLin=ndy0==0;
940*cdf0e10cSrcweir 				FASTBOOL bVLin=ndx0==0;
941*cdf0e10cSrcweir 				if (!bHLin || !bVLin) { // sonst ist aPt1==aPt2
942*cdf0e10cSrcweir 					long ndx=aPt.X()-aFix.X();
943*cdf0e10cSrcweir 					long ndy=aPt.Y()-aFix.Y();
944*cdf0e10cSrcweir 					double nXFact=0; if (!bVLin) nXFact=(double)ndx/(double)ndx0;
945*cdf0e10cSrcweir 					double nYFact=0; if (!bHLin) nYFact=(double)ndy/(double)ndy0;
946*cdf0e10cSrcweir 					FASTBOOL bHor=bHLin || (!bVLin && (nXFact>nYFact) ==bBigOrtho);
947*cdf0e10cSrcweir 					FASTBOOL bVer=bVLin || (!bHLin && (nXFact<=nYFact)==bBigOrtho);
948*cdf0e10cSrcweir 					if (bHor) ndy=long(ndy0*nXFact);
949*cdf0e10cSrcweir 					if (bVer) ndx=long(ndx0*nYFact);
950*cdf0e10cSrcweir 					aPt=aFix;
951*cdf0e10cSrcweir 					aPt.X()+=ndx;
952*cdf0e10cSrcweir 					aPt.Y()+=ndy;
953*cdf0e10cSrcweir 				} // else Ortho8
954*cdf0e10cSrcweir 			}
955*cdf0e10cSrcweir 			rMov=aPt;
956*cdf0e10cSrcweir 		} break;
957*cdf0e10cSrcweir 		case 4: case 5: {
958*cdf0e10cSrcweir 			long nVal0=rRec.nLineDist;
959*cdf0e10cSrcweir 			RotatePoint(aPt,(nHdlNum==4 ? aPt1 : aPt2),nSin,-nCos);
960*cdf0e10cSrcweir 			rRec.nLineDist=aPt.Y()- (nHdlNum==4 ? aPt1.Y() : aPt2.Y());
961*cdf0e10cSrcweir 			if (bBelow) rRec.nLineDist=-rRec.nLineDist;
962*cdf0e10cSrcweir 			if (rRec.nLineDist<0) {
963*cdf0e10cSrcweir 				rRec.nLineDist=-rRec.nLineDist;
964*cdf0e10cSrcweir 				rRec.bBelowRefEdge=!bBelow;
965*cdf0e10cSrcweir 			}
966*cdf0e10cSrcweir 			rRec.nLineDist-=rRec.nHelplineOverhang;
967*cdf0e10cSrcweir 			if (bOrtho) rRec.nLineDist=nVal0;
968*cdf0e10cSrcweir 		} break;
969*cdf0e10cSrcweir 	} // switch
970*cdf0e10cSrcweir }
971*cdf0e10cSrcweir 
972*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
973*cdf0e10cSrcweir 
974*cdf0e10cSrcweir FASTBOOL SdrMeasureObj::BegCreate(SdrDragStat& rStat)
975*cdf0e10cSrcweir {
976*cdf0e10cSrcweir 	rStat.SetOrtho8Possible();
977*cdf0e10cSrcweir 	aPt1=rStat.GetStart();
978*cdf0e10cSrcweir 	aPt2=rStat.GetNow();
979*cdf0e10cSrcweir 	SetTextDirty();
980*cdf0e10cSrcweir 	return sal_True;
981*cdf0e10cSrcweir }
982*cdf0e10cSrcweir 
983*cdf0e10cSrcweir FASTBOOL SdrMeasureObj::MovCreate(SdrDragStat& rStat)
984*cdf0e10cSrcweir {
985*cdf0e10cSrcweir 	SdrView* pView=rStat.GetView();
986*cdf0e10cSrcweir 	aPt1=rStat.GetStart();
987*cdf0e10cSrcweir 	aPt2=rStat.GetNow();
988*cdf0e10cSrcweir 	if (pView!=NULL && pView->IsCreate1stPointAsCenter()) {
989*cdf0e10cSrcweir 		aPt1+=aPt1;
990*cdf0e10cSrcweir 		aPt1-=rStat.Now();
991*cdf0e10cSrcweir 	}
992*cdf0e10cSrcweir 	SetTextDirty();
993*cdf0e10cSrcweir 	SetBoundRectDirty();
994*cdf0e10cSrcweir 	bSnapRectDirty=sal_True;
995*cdf0e10cSrcweir 	return sal_True;
996*cdf0e10cSrcweir }
997*cdf0e10cSrcweir 
998*cdf0e10cSrcweir FASTBOOL SdrMeasureObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
999*cdf0e10cSrcweir {
1000*cdf0e10cSrcweir 	SetTextDirty();
1001*cdf0e10cSrcweir 	SetRectsDirty();
1002*cdf0e10cSrcweir 	return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
1003*cdf0e10cSrcweir }
1004*cdf0e10cSrcweir 
1005*cdf0e10cSrcweir FASTBOOL SdrMeasureObj::BckCreate(SdrDragStat& /*rStat*/)
1006*cdf0e10cSrcweir {
1007*cdf0e10cSrcweir 	return sal_False;
1008*cdf0e10cSrcweir }
1009*cdf0e10cSrcweir 
1010*cdf0e10cSrcweir void SdrMeasureObj::BrkCreate(SdrDragStat& /*rStat*/)
1011*cdf0e10cSrcweir {
1012*cdf0e10cSrcweir }
1013*cdf0e10cSrcweir 
1014*cdf0e10cSrcweir basegfx::B2DPolyPolygon SdrMeasureObj::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
1015*cdf0e10cSrcweir {
1016*cdf0e10cSrcweir 	ImpMeasureRec aRec;
1017*cdf0e10cSrcweir 	ImpMeasurePoly aMPol;
1018*cdf0e10cSrcweir 
1019*cdf0e10cSrcweir 	ImpTakeAttr(aRec);
1020*cdf0e10cSrcweir 	ImpCalcGeometrics(aRec, aMPol);
1021*cdf0e10cSrcweir 
1022*cdf0e10cSrcweir 	return ImpCalcXPoly(aMPol);
1023*cdf0e10cSrcweir }
1024*cdf0e10cSrcweir 
1025*cdf0e10cSrcweir Pointer SdrMeasureObj::GetCreatePointer() const
1026*cdf0e10cSrcweir {
1027*cdf0e10cSrcweir 	return Pointer(POINTER_CROSS);
1028*cdf0e10cSrcweir }
1029*cdf0e10cSrcweir 
1030*cdf0e10cSrcweir void SdrMeasureObj::NbcMove(const Size& rSiz)
1031*cdf0e10cSrcweir {
1032*cdf0e10cSrcweir 	SdrTextObj::NbcMove(rSiz);
1033*cdf0e10cSrcweir 	MovePoint(aPt1,rSiz);
1034*cdf0e10cSrcweir 	MovePoint(aPt2,rSiz);
1035*cdf0e10cSrcweir }
1036*cdf0e10cSrcweir 
1037*cdf0e10cSrcweir void SdrMeasureObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
1038*cdf0e10cSrcweir {
1039*cdf0e10cSrcweir 	SdrTextObj::NbcResize(rRef,xFact,yFact);
1040*cdf0e10cSrcweir 	ResizePoint(aPt1,rRef,xFact,yFact);
1041*cdf0e10cSrcweir 	ResizePoint(aPt2,rRef,xFact,yFact);
1042*cdf0e10cSrcweir 	SetTextDirty();
1043*cdf0e10cSrcweir }
1044*cdf0e10cSrcweir 
1045*cdf0e10cSrcweir void SdrMeasureObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
1046*cdf0e10cSrcweir {
1047*cdf0e10cSrcweir 	SdrTextObj::NbcRotate(rRef,nWink,sn,cs);
1048*cdf0e10cSrcweir 	long nLen0=GetLen(aPt2-aPt1);
1049*cdf0e10cSrcweir 	RotatePoint(aPt1,rRef,sn,cs);
1050*cdf0e10cSrcweir 	RotatePoint(aPt2,rRef,sn,cs);
1051*cdf0e10cSrcweir 	long nLen1=GetLen(aPt2-aPt1);
1052*cdf0e10cSrcweir 	if (nLen1!=nLen0) { // Aha, Rundungsfehler
1053*cdf0e10cSrcweir 		long dx=aPt2.X()-aPt1.X();
1054*cdf0e10cSrcweir 		long dy=aPt2.Y()-aPt1.Y();
1055*cdf0e10cSrcweir 		dx=BigMulDiv(dx,nLen0,nLen1);
1056*cdf0e10cSrcweir 		dy=BigMulDiv(dy,nLen0,nLen1);
1057*cdf0e10cSrcweir 		if (rRef==aPt2) {
1058*cdf0e10cSrcweir 			aPt1.X()=aPt2.X()-dx;
1059*cdf0e10cSrcweir 			aPt1.Y()=aPt2.Y()-dy;
1060*cdf0e10cSrcweir 		} else {
1061*cdf0e10cSrcweir 			aPt2.X()=aPt1.X()+dx;
1062*cdf0e10cSrcweir 			aPt2.Y()=aPt1.Y()+dy;
1063*cdf0e10cSrcweir 		}
1064*cdf0e10cSrcweir 	}
1065*cdf0e10cSrcweir 	SetRectsDirty();
1066*cdf0e10cSrcweir }
1067*cdf0e10cSrcweir 
1068*cdf0e10cSrcweir void SdrMeasureObj::NbcMirror(const Point& rRef1, const Point& rRef2)
1069*cdf0e10cSrcweir {
1070*cdf0e10cSrcweir 	SdrTextObj::NbcMirror(rRef1,rRef2);
1071*cdf0e10cSrcweir 	MirrorPoint(aPt1,rRef1,rRef2);
1072*cdf0e10cSrcweir 	MirrorPoint(aPt2,rRef1,rRef2);
1073*cdf0e10cSrcweir 	SetRectsDirty();
1074*cdf0e10cSrcweir }
1075*cdf0e10cSrcweir 
1076*cdf0e10cSrcweir void SdrMeasureObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
1077*cdf0e10cSrcweir {
1078*cdf0e10cSrcweir 	SdrTextObj::NbcShear(rRef,nWink,tn,bVShear);
1079*cdf0e10cSrcweir 	ShearPoint(aPt1,rRef,tn,bVShear);
1080*cdf0e10cSrcweir 	ShearPoint(aPt2,rRef,tn,bVShear);
1081*cdf0e10cSrcweir 	SetRectsDirty();
1082*cdf0e10cSrcweir 	SetTextDirty();
1083*cdf0e10cSrcweir }
1084*cdf0e10cSrcweir 
1085*cdf0e10cSrcweir long SdrMeasureObj::GetRotateAngle() const
1086*cdf0e10cSrcweir {
1087*cdf0e10cSrcweir 	return GetAngle(aPt2-aPt1);
1088*cdf0e10cSrcweir }
1089*cdf0e10cSrcweir 
1090*cdf0e10cSrcweir void SdrMeasureObj::RecalcSnapRect()
1091*cdf0e10cSrcweir {
1092*cdf0e10cSrcweir 	// #94520# Added correct implementation here.
1093*cdf0e10cSrcweir 	ImpMeasureRec aRec;
1094*cdf0e10cSrcweir 	ImpMeasurePoly aMPol;
1095*cdf0e10cSrcweir 	XPolyPolygon aXPP;
1096*cdf0e10cSrcweir 
1097*cdf0e10cSrcweir 	ImpTakeAttr(aRec);
1098*cdf0e10cSrcweir 	ImpCalcGeometrics(aRec, aMPol);
1099*cdf0e10cSrcweir 	aXPP = XPolyPolygon(ImpCalcXPoly(aMPol));
1100*cdf0e10cSrcweir 	maSnapRect = aXPP.GetBoundRect();
1101*cdf0e10cSrcweir }
1102*cdf0e10cSrcweir 
1103*cdf0e10cSrcweir sal_uInt32 SdrMeasureObj::GetSnapPointCount() const
1104*cdf0e10cSrcweir {
1105*cdf0e10cSrcweir 	return 2L;
1106*cdf0e10cSrcweir }
1107*cdf0e10cSrcweir 
1108*cdf0e10cSrcweir Point SdrMeasureObj::GetSnapPoint(sal_uInt32 i) const
1109*cdf0e10cSrcweir {
1110*cdf0e10cSrcweir 	if (i==0) return aPt1;
1111*cdf0e10cSrcweir 	else return aPt2;
1112*cdf0e10cSrcweir }
1113*cdf0e10cSrcweir 
1114*cdf0e10cSrcweir sal_Bool SdrMeasureObj::IsPolyObj() const
1115*cdf0e10cSrcweir {
1116*cdf0e10cSrcweir 	return sal_True;
1117*cdf0e10cSrcweir }
1118*cdf0e10cSrcweir 
1119*cdf0e10cSrcweir sal_uInt32 SdrMeasureObj::GetPointCount() const
1120*cdf0e10cSrcweir {
1121*cdf0e10cSrcweir 	return 2L;
1122*cdf0e10cSrcweir }
1123*cdf0e10cSrcweir 
1124*cdf0e10cSrcweir Point SdrMeasureObj::GetPoint(sal_uInt32 i) const
1125*cdf0e10cSrcweir {
1126*cdf0e10cSrcweir 	 return (0L == i) ? aPt1 : aPt2;
1127*cdf0e10cSrcweir }
1128*cdf0e10cSrcweir 
1129*cdf0e10cSrcweir void SdrMeasureObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
1130*cdf0e10cSrcweir {
1131*cdf0e10cSrcweir 	if (0L == i)
1132*cdf0e10cSrcweir 		aPt1=rPnt;
1133*cdf0e10cSrcweir 	if (1L == i)
1134*cdf0e10cSrcweir 		aPt2=rPnt;
1135*cdf0e10cSrcweir 	SetRectsDirty();
1136*cdf0e10cSrcweir 	SetTextDirty();
1137*cdf0e10cSrcweir }
1138*cdf0e10cSrcweir 
1139*cdf0e10cSrcweir SdrObjGeoData* SdrMeasureObj::NewGeoData() const
1140*cdf0e10cSrcweir {
1141*cdf0e10cSrcweir 	return new SdrMeasureObjGeoData;
1142*cdf0e10cSrcweir }
1143*cdf0e10cSrcweir 
1144*cdf0e10cSrcweir void SdrMeasureObj::SaveGeoData(SdrObjGeoData& rGeo) const
1145*cdf0e10cSrcweir {
1146*cdf0e10cSrcweir 	SdrTextObj::SaveGeoData(rGeo);
1147*cdf0e10cSrcweir 	SdrMeasureObjGeoData& rMGeo=(SdrMeasureObjGeoData&)rGeo;
1148*cdf0e10cSrcweir 	rMGeo.aPt1=aPt1;
1149*cdf0e10cSrcweir 	rMGeo.aPt2=aPt2;
1150*cdf0e10cSrcweir }
1151*cdf0e10cSrcweir 
1152*cdf0e10cSrcweir void SdrMeasureObj::RestGeoData(const SdrObjGeoData& rGeo)
1153*cdf0e10cSrcweir {
1154*cdf0e10cSrcweir 	SdrTextObj::RestGeoData(rGeo);
1155*cdf0e10cSrcweir 	SdrMeasureObjGeoData& rMGeo=(SdrMeasureObjGeoData&)rGeo;
1156*cdf0e10cSrcweir 	aPt1=rMGeo.aPt1;
1157*cdf0e10cSrcweir 	aPt2=rMGeo.aPt2;
1158*cdf0e10cSrcweir 	SetTextDirty();
1159*cdf0e10cSrcweir }
1160*cdf0e10cSrcweir 
1161*cdf0e10cSrcweir SdrObject* SdrMeasureObj::DoConvertToPolyObj(sal_Bool bBezier) const
1162*cdf0e10cSrcweir {
1163*cdf0e10cSrcweir 	// get XOR Poly as base
1164*cdf0e10cSrcweir 	XPolyPolygon aTmpPolyPolygon(TakeXorPoly());
1165*cdf0e10cSrcweir 
1166*cdf0e10cSrcweir 	// get local ItemSet and StyleSheet
1167*cdf0e10cSrcweir 	SfxItemSet aSet(GetObjectItemSet());
1168*cdf0e10cSrcweir     SfxStyleSheet* pStyleSheet = GetStyleSheet();
1169*cdf0e10cSrcweir 
1170*cdf0e10cSrcweir     // prepare group
1171*cdf0e10cSrcweir 	SdrObjGroup* pGroup = new SdrObjGroup;
1172*cdf0e10cSrcweir 	pGroup->SetModel(GetModel());
1173*cdf0e10cSrcweir 
1174*cdf0e10cSrcweir 	// prepare parameters
1175*cdf0e10cSrcweir 	basegfx::B2DPolyPolygon aPolyPoly;
1176*cdf0e10cSrcweir 	SdrPathObj* pPath;
1177*cdf0e10cSrcweir 	sal_uInt16 nCount(aTmpPolyPolygon.Count());
1178*cdf0e10cSrcweir 	sal_uInt16 nLoopStart(0);
1179*cdf0e10cSrcweir 
1180*cdf0e10cSrcweir 	if(nCount == 3)
1181*cdf0e10cSrcweir 	{
1182*cdf0e10cSrcweir 		// three lines, first one is the middle one
1183*cdf0e10cSrcweir 		aPolyPoly.clear();
1184*cdf0e10cSrcweir 		aPolyPoly.append(aTmpPolyPolygon[0].getB2DPolygon());
1185*cdf0e10cSrcweir 
1186*cdf0e10cSrcweir 		pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
1187*cdf0e10cSrcweir 		pPath->SetModel(GetModel());
1188*cdf0e10cSrcweir 		pPath->SetMergedItemSet(aSet);
1189*cdf0e10cSrcweir         pPath->SetStyleSheet(pStyleSheet, true);
1190*cdf0e10cSrcweir 		pGroup->GetSubList()->NbcInsertObject(pPath);
1191*cdf0e10cSrcweir 		aSet.Put(XLineStartWidthItem(0L));
1192*cdf0e10cSrcweir 		aSet.Put(XLineEndWidthItem(0L));
1193*cdf0e10cSrcweir 		nLoopStart = 1;
1194*cdf0e10cSrcweir 	}
1195*cdf0e10cSrcweir 	else if(nCount == 4)
1196*cdf0e10cSrcweir 	{
1197*cdf0e10cSrcweir 		// four lines, middle line with gap, so there are two lines used
1198*cdf0e10cSrcweir 		// which have one arrow each
1199*cdf0e10cSrcweir 		//sal_Int32 nStartWidth = ((const XLineStartWidthItem&)(aSet.Get(XATTR_LINESTARTWIDTH))).GetValue();
1200*cdf0e10cSrcweir 		sal_Int32 nEndWidth = ((const XLineEndWidthItem&)(aSet.Get(XATTR_LINEENDWIDTH))).GetValue();
1201*cdf0e10cSrcweir 		aSet.Put(XLineEndWidthItem(0L));
1202*cdf0e10cSrcweir 
1203*cdf0e10cSrcweir 		aPolyPoly.clear();
1204*cdf0e10cSrcweir 		aPolyPoly.append(aTmpPolyPolygon[0].getB2DPolygon());
1205*cdf0e10cSrcweir 		pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
1206*cdf0e10cSrcweir 		pPath->SetModel(GetModel());
1207*cdf0e10cSrcweir 		pPath->SetMergedItemSet(aSet);
1208*cdf0e10cSrcweir         pPath->SetStyleSheet(pStyleSheet, true);
1209*cdf0e10cSrcweir 
1210*cdf0e10cSrcweir 		pGroup->GetSubList()->NbcInsertObject(pPath);
1211*cdf0e10cSrcweir 
1212*cdf0e10cSrcweir 		aSet.Put(XLineEndWidthItem(nEndWidth));
1213*cdf0e10cSrcweir 		aSet.Put(XLineStartWidthItem(0L));
1214*cdf0e10cSrcweir 
1215*cdf0e10cSrcweir 		aPolyPoly.clear();
1216*cdf0e10cSrcweir 		aPolyPoly.append(aTmpPolyPolygon[1].getB2DPolygon());
1217*cdf0e10cSrcweir 		pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
1218*cdf0e10cSrcweir 		pPath->SetModel(GetModel());
1219*cdf0e10cSrcweir 		pPath->SetMergedItemSet(aSet);
1220*cdf0e10cSrcweir         pPath->SetStyleSheet(pStyleSheet, true);
1221*cdf0e10cSrcweir 
1222*cdf0e10cSrcweir 		pGroup->GetSubList()->NbcInsertObject(pPath);
1223*cdf0e10cSrcweir 
1224*cdf0e10cSrcweir 		aSet.Put(XLineEndWidthItem(0L));
1225*cdf0e10cSrcweir 		nLoopStart = 2;
1226*cdf0e10cSrcweir 	}
1227*cdf0e10cSrcweir 	else if(nCount == 5)
1228*cdf0e10cSrcweir 	{
1229*cdf0e10cSrcweir 		// five lines, first two are the outer ones
1230*cdf0e10cSrcweir 		//sal_Int32 nStartWidth = ((const XLineStartWidthItem&)(aSet.Get(XATTR_LINESTARTWIDTH))).GetValue();
1231*cdf0e10cSrcweir 		sal_Int32 nEndWidth = ((const XLineEndWidthItem&)(aSet.Get(XATTR_LINEENDWIDTH))).GetValue();
1232*cdf0e10cSrcweir 
1233*cdf0e10cSrcweir 		aSet.Put(XLineEndWidthItem(0L));
1234*cdf0e10cSrcweir 
1235*cdf0e10cSrcweir 		aPolyPoly.clear();
1236*cdf0e10cSrcweir 		aPolyPoly.append(aTmpPolyPolygon[0].getB2DPolygon());
1237*cdf0e10cSrcweir 		pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
1238*cdf0e10cSrcweir 		pPath->SetModel(GetModel());
1239*cdf0e10cSrcweir 		pPath->SetMergedItemSet(aSet);
1240*cdf0e10cSrcweir         pPath->SetStyleSheet(pStyleSheet, true);
1241*cdf0e10cSrcweir 
1242*cdf0e10cSrcweir 		pGroup->GetSubList()->NbcInsertObject(pPath);
1243*cdf0e10cSrcweir 
1244*cdf0e10cSrcweir 		aSet.Put(XLineEndWidthItem(nEndWidth));
1245*cdf0e10cSrcweir 		aSet.Put(XLineStartWidthItem(0L));
1246*cdf0e10cSrcweir 
1247*cdf0e10cSrcweir 		aPolyPoly.clear();
1248*cdf0e10cSrcweir 		aPolyPoly.append(aTmpPolyPolygon[1].getB2DPolygon());
1249*cdf0e10cSrcweir 		pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
1250*cdf0e10cSrcweir 		pPath->SetModel(GetModel());
1251*cdf0e10cSrcweir 		pPath->SetMergedItemSet(aSet);
1252*cdf0e10cSrcweir         pPath->SetStyleSheet(pStyleSheet, true);
1253*cdf0e10cSrcweir 
1254*cdf0e10cSrcweir 		pGroup->GetSubList()->NbcInsertObject(pPath);
1255*cdf0e10cSrcweir 
1256*cdf0e10cSrcweir 		aSet.Put(XLineEndWidthItem(0L));
1257*cdf0e10cSrcweir 		nLoopStart = 2;
1258*cdf0e10cSrcweir 	}
1259*cdf0e10cSrcweir 
1260*cdf0e10cSrcweir 	for(;nLoopStart<nCount;nLoopStart++)
1261*cdf0e10cSrcweir 	{
1262*cdf0e10cSrcweir 		aPolyPoly.clear();
1263*cdf0e10cSrcweir 		aPolyPoly.append(aTmpPolyPolygon[nLoopStart].getB2DPolygon());
1264*cdf0e10cSrcweir 		pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
1265*cdf0e10cSrcweir 		pPath->SetModel(GetModel());
1266*cdf0e10cSrcweir 		pPath->SetMergedItemSet(aSet);
1267*cdf0e10cSrcweir         pPath->SetStyleSheet(pStyleSheet, true);
1268*cdf0e10cSrcweir 
1269*cdf0e10cSrcweir 		pGroup->GetSubList()->NbcInsertObject(pPath);
1270*cdf0e10cSrcweir 	}
1271*cdf0e10cSrcweir 
1272*cdf0e10cSrcweir 	return ImpConvertAddText(pGroup, bBezier);
1273*cdf0e10cSrcweir }
1274*cdf0e10cSrcweir 
1275*cdf0e10cSrcweir sal_Bool SdrMeasureObj::BegTextEdit(SdrOutliner& rOutl)
1276*cdf0e10cSrcweir {
1277*cdf0e10cSrcweir 	UndirtyText();
1278*cdf0e10cSrcweir 	return SdrTextObj::BegTextEdit(rOutl);
1279*cdf0e10cSrcweir }
1280*cdf0e10cSrcweir 
1281*cdf0e10cSrcweir const Size& SdrMeasureObj::GetTextSize() const
1282*cdf0e10cSrcweir {
1283*cdf0e10cSrcweir 	if (bTextDirty) UndirtyText();
1284*cdf0e10cSrcweir 	return SdrTextObj::GetTextSize();
1285*cdf0e10cSrcweir }
1286*cdf0e10cSrcweir 
1287*cdf0e10cSrcweir OutlinerParaObject* SdrMeasureObj::GetOutlinerParaObject() const
1288*cdf0e10cSrcweir {
1289*cdf0e10cSrcweir 	if(bTextDirty)
1290*cdf0e10cSrcweir 		UndirtyText();
1291*cdf0e10cSrcweir 	return SdrTextObj::GetOutlinerParaObject();
1292*cdf0e10cSrcweir }
1293*cdf0e10cSrcweir 
1294*cdf0e10cSrcweir void SdrMeasureObj::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
1295*cdf0e10cSrcweir {
1296*cdf0e10cSrcweir 	SdrTextObj::NbcSetOutlinerParaObject(pTextObject);
1297*cdf0e10cSrcweir 	if(SdrTextObj::GetOutlinerParaObject())
1298*cdf0e10cSrcweir 		SetTextDirty(); // Text neu berechnen!
1299*cdf0e10cSrcweir }
1300*cdf0e10cSrcweir 
1301*cdf0e10cSrcweir void SdrMeasureObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText,
1302*cdf0e10cSrcweir 	Rectangle* pAnchorRect, sal_Bool bLineWidth ) const
1303*cdf0e10cSrcweir {
1304*cdf0e10cSrcweir 	if (bTextDirty) UndirtyText();
1305*cdf0e10cSrcweir 	SdrTextObj::TakeTextRect( rOutliner, rTextRect, bNoEditText, pAnchorRect, bLineWidth );
1306*cdf0e10cSrcweir }
1307*cdf0e10cSrcweir 
1308*cdf0e10cSrcweir void SdrMeasureObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const
1309*cdf0e10cSrcweir {
1310*cdf0e10cSrcweir 	if (bTextDirty) UndirtyText();
1311*cdf0e10cSrcweir 	SdrTextObj::TakeTextAnchorRect(rAnchorRect);
1312*cdf0e10cSrcweir }
1313*cdf0e10cSrcweir 
1314*cdf0e10cSrcweir void SdrMeasureObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
1315*cdf0e10cSrcweir {
1316*cdf0e10cSrcweir 	if (bTextDirty) UndirtyText();
1317*cdf0e10cSrcweir 	SdrTextObj::TakeTextEditArea(pPaperMin,pPaperMax,pViewInit,pViewMin);
1318*cdf0e10cSrcweir }
1319*cdf0e10cSrcweir 
1320*cdf0e10cSrcweir sal_uInt16 SdrMeasureObj::GetOutlinerViewAnchorMode() const
1321*cdf0e10cSrcweir {
1322*cdf0e10cSrcweir 	if (bTextDirty) UndirtyText();
1323*cdf0e10cSrcweir 	ImpMeasureRec aRec;
1324*cdf0e10cSrcweir 	ImpMeasurePoly aMPol;
1325*cdf0e10cSrcweir 	ImpTakeAttr(aRec);
1326*cdf0e10cSrcweir 	ImpCalcGeometrics(aRec,aMPol);
1327*cdf0e10cSrcweir 
1328*cdf0e10cSrcweir 	SdrTextHorzAdjust eTH=GetTextHorizontalAdjust();
1329*cdf0e10cSrcweir 	SdrTextVertAdjust eTV=GetTextVerticalAdjust();
1330*cdf0e10cSrcweir 	SdrMeasureTextHPos eMH=aMPol.eUsedTextHPos;
1331*cdf0e10cSrcweir 	SdrMeasureTextVPos eMV=aMPol.eUsedTextVPos;
1332*cdf0e10cSrcweir 	FASTBOOL bTextRota90=aRec.bTextRota90;
1333*cdf0e10cSrcweir 	//int bTextUpsideDown=aRec.bTextUpsideDown;
1334*cdf0e10cSrcweir 	FASTBOOL bBelowRefEdge=aRec.bBelowRefEdge;
1335*cdf0e10cSrcweir 
1336*cdf0e10cSrcweir 	// bTextUpsideDown muss hier noch ausgewertet werden!!!!
1337*cdf0e10cSrcweir 	if (!bTextRota90) {
1338*cdf0e10cSrcweir 		if (eMH==SDRMEASURE_TEXTLEFTOUTSIDE) eTH=SDRTEXTHORZADJUST_RIGHT;
1339*cdf0e10cSrcweir 		if (eMH==SDRMEASURE_TEXTRIGHTOUTSIDE) eTH=SDRTEXTHORZADJUST_LEFT;
1340*cdf0e10cSrcweir 		// bei eMH==SDRMEASURE_TEXTINSIDE kann horizontal geankert werden.
1341*cdf0e10cSrcweir 		if (eMV==SDRMEASURE_ABOVE) eTV=SDRTEXTVERTADJUST_BOTTOM;
1342*cdf0e10cSrcweir 		if (eMV==SDRMEASURE_BELOW) eTV=SDRTEXTVERTADJUST_TOP;
1343*cdf0e10cSrcweir 		if (eMV==SDRMEASURETEXT_BREAKEDLINE || eMV==SDRMEASURETEXT_VERTICALCENTERED) eTV=SDRTEXTVERTADJUST_CENTER;
1344*cdf0e10cSrcweir 	} else {
1345*cdf0e10cSrcweir 		if (eMH==SDRMEASURE_TEXTLEFTOUTSIDE) eTV=SDRTEXTVERTADJUST_BOTTOM;
1346*cdf0e10cSrcweir 		if (eMH==SDRMEASURE_TEXTRIGHTOUTSIDE) eTV=SDRTEXTVERTADJUST_TOP;
1347*cdf0e10cSrcweir 		// bei eMH==SDRMEASURE_TEXTINSIDE kann vertikal geankert werden.
1348*cdf0e10cSrcweir 		if (!bBelowRefEdge) {
1349*cdf0e10cSrcweir 			if (eMV==SDRMEASURE_ABOVE) eTH=SDRTEXTHORZADJUST_LEFT;
1350*cdf0e10cSrcweir 			if (eMV==SDRMEASURE_BELOW) eTH=SDRTEXTHORZADJUST_RIGHT;
1351*cdf0e10cSrcweir 		} else {
1352*cdf0e10cSrcweir 			if (eMV==SDRMEASURE_ABOVE) eTH=SDRTEXTHORZADJUST_RIGHT;
1353*cdf0e10cSrcweir 			if (eMV==SDRMEASURE_BELOW) eTH=SDRTEXTHORZADJUST_LEFT;
1354*cdf0e10cSrcweir 		}
1355*cdf0e10cSrcweir 		if (eMV==SDRMEASURETEXT_BREAKEDLINE || eMV==SDRMEASURETEXT_VERTICALCENTERED) eTH=SDRTEXTHORZADJUST_CENTER;
1356*cdf0e10cSrcweir 	}
1357*cdf0e10cSrcweir 
1358*cdf0e10cSrcweir 	EVAnchorMode eRet=ANCHOR_BOTTOM_HCENTER;
1359*cdf0e10cSrcweir 	if (eTH==SDRTEXTHORZADJUST_LEFT) {
1360*cdf0e10cSrcweir 		if (eTV==SDRTEXTVERTADJUST_TOP) eRet=ANCHOR_TOP_LEFT;
1361*cdf0e10cSrcweir 		else if (eTV==SDRTEXTVERTADJUST_BOTTOM) eRet=ANCHOR_BOTTOM_LEFT;
1362*cdf0e10cSrcweir 		else eRet=ANCHOR_VCENTER_LEFT;
1363*cdf0e10cSrcweir 	} else if (eTH==SDRTEXTHORZADJUST_RIGHT) {
1364*cdf0e10cSrcweir 		if (eTV==SDRTEXTVERTADJUST_TOP) eRet=ANCHOR_TOP_RIGHT;
1365*cdf0e10cSrcweir 		else if (eTV==SDRTEXTVERTADJUST_BOTTOM) eRet=ANCHOR_BOTTOM_RIGHT;
1366*cdf0e10cSrcweir 		else eRet=ANCHOR_VCENTER_RIGHT;
1367*cdf0e10cSrcweir 	} else {
1368*cdf0e10cSrcweir 		if (eTV==SDRTEXTVERTADJUST_TOP) eRet=ANCHOR_TOP_HCENTER;
1369*cdf0e10cSrcweir 		else if (eTV==SDRTEXTVERTADJUST_BOTTOM) eRet=ANCHOR_BOTTOM_HCENTER;
1370*cdf0e10cSrcweir 		else eRet=ANCHOR_VCENTER_HCENTER;
1371*cdf0e10cSrcweir 	}
1372*cdf0e10cSrcweir 	return (sal_uInt16)eRet;
1373*cdf0e10cSrcweir }
1374*cdf0e10cSrcweir 
1375*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
1376*cdf0e10cSrcweir // #i97878#
1377*cdf0e10cSrcweir // TRGetBaseGeometry/TRSetBaseGeometry needs to be based on two positions,
1378*cdf0e10cSrcweir // same as line geometry in SdrPathObj. Thus needs to be overloaded and
1379*cdf0e10cSrcweir // implemented since currently it is derived from SdrTextObj which uses
1380*cdf0e10cSrcweir // a functionality based on SnapRect which is not useful here
1381*cdf0e10cSrcweir 
1382*cdf0e10cSrcweir inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
1383*cdf0e10cSrcweir inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
1384*cdf0e10cSrcweir 
1385*cdf0e10cSrcweir sal_Bool SdrMeasureObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
1386*cdf0e10cSrcweir {
1387*cdf0e10cSrcweir     // handle the same as a simple line since the definition is based on two points
1388*cdf0e10cSrcweir     const basegfx::B2DRange aRange(aPt1.X(), aPt1.Y(), aPt2.X(), aPt2.Y());
1389*cdf0e10cSrcweir 	basegfx::B2DTuple aScale(aRange.getRange());
1390*cdf0e10cSrcweir     basegfx::B2DTuple aTranslate(aRange.getMinimum());
1391*cdf0e10cSrcweir 
1392*cdf0e10cSrcweir 	// position maybe relative to anchorpos, convert
1393*cdf0e10cSrcweir 	if( pModel->IsWriter() )
1394*cdf0e10cSrcweir 	{
1395*cdf0e10cSrcweir 		if(GetAnchorPos().X() || GetAnchorPos().Y())
1396*cdf0e10cSrcweir 		{
1397*cdf0e10cSrcweir 			aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1398*cdf0e10cSrcweir 		}
1399*cdf0e10cSrcweir 	}
1400*cdf0e10cSrcweir 
1401*cdf0e10cSrcweir 	// force MapUnit to 100th mm
1402*cdf0e10cSrcweir 	SfxMapUnit eMapUnit = pModel->GetItemPool().GetMetric(0);
1403*cdf0e10cSrcweir 	if(eMapUnit != SFX_MAPUNIT_100TH_MM)
1404*cdf0e10cSrcweir 	{
1405*cdf0e10cSrcweir 		switch(eMapUnit)
1406*cdf0e10cSrcweir 		{
1407*cdf0e10cSrcweir 			case SFX_MAPUNIT_TWIP :
1408*cdf0e10cSrcweir 			{
1409*cdf0e10cSrcweir 				// postion
1410*cdf0e10cSrcweir 				aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
1411*cdf0e10cSrcweir 				aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
1412*cdf0e10cSrcweir 
1413*cdf0e10cSrcweir 				// size
1414*cdf0e10cSrcweir 				aScale.setX(ImplTwipsToMM(aScale.getX()));
1415*cdf0e10cSrcweir 				aScale.setY(ImplTwipsToMM(aScale.getY()));
1416*cdf0e10cSrcweir 
1417*cdf0e10cSrcweir 				break;
1418*cdf0e10cSrcweir 			}
1419*cdf0e10cSrcweir 			default:
1420*cdf0e10cSrcweir 			{
1421*cdf0e10cSrcweir 				DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
1422*cdf0e10cSrcweir 			}
1423*cdf0e10cSrcweir 		}
1424*cdf0e10cSrcweir 	}
1425*cdf0e10cSrcweir 
1426*cdf0e10cSrcweir 	// build return value matrix
1427*cdf0e10cSrcweir 	rMatrix = basegfx::tools::createScaleTranslateB2DHomMatrix(aScale, aTranslate);
1428*cdf0e10cSrcweir 
1429*cdf0e10cSrcweir 	return sal_True;
1430*cdf0e10cSrcweir }
1431*cdf0e10cSrcweir 
1432*cdf0e10cSrcweir void SdrMeasureObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
1433*cdf0e10cSrcweir {
1434*cdf0e10cSrcweir     // use given transformation to derive the two defining points from unit line
1435*cdf0e10cSrcweir     basegfx::B2DPoint aPosA(rMatrix * basegfx::B2DPoint(0.0, 0.0));
1436*cdf0e10cSrcweir     basegfx::B2DPoint aPosB(rMatrix * basegfx::B2DPoint(1.0, 0.0));
1437*cdf0e10cSrcweir 
1438*cdf0e10cSrcweir 	// force metric to pool metric
1439*cdf0e10cSrcweir 	SfxMapUnit eMapUnit = pModel->GetItemPool().GetMetric(0);
1440*cdf0e10cSrcweir 	if(eMapUnit != SFX_MAPUNIT_100TH_MM)
1441*cdf0e10cSrcweir 	{
1442*cdf0e10cSrcweir 		switch(eMapUnit)
1443*cdf0e10cSrcweir 		{
1444*cdf0e10cSrcweir 			case SFX_MAPUNIT_TWIP :
1445*cdf0e10cSrcweir 			{
1446*cdf0e10cSrcweir 				// position
1447*cdf0e10cSrcweir                 aPosA.setX(ImplMMToTwips(aPosA.getX()));
1448*cdf0e10cSrcweir                 aPosA.setY(ImplMMToTwips(aPosA.getY()));
1449*cdf0e10cSrcweir                 aPosB.setX(ImplMMToTwips(aPosB.getX()));
1450*cdf0e10cSrcweir                 aPosB.setY(ImplMMToTwips(aPosB.getY()));
1451*cdf0e10cSrcweir 
1452*cdf0e10cSrcweir 				break;
1453*cdf0e10cSrcweir 			}
1454*cdf0e10cSrcweir 			default:
1455*cdf0e10cSrcweir 			{
1456*cdf0e10cSrcweir 				DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
1457*cdf0e10cSrcweir 			}
1458*cdf0e10cSrcweir 		}
1459*cdf0e10cSrcweir 	}
1460*cdf0e10cSrcweir 
1461*cdf0e10cSrcweir 	if( pModel->IsWriter() )
1462*cdf0e10cSrcweir 	{
1463*cdf0e10cSrcweir 		// if anchor is used, make position relative to it
1464*cdf0e10cSrcweir 		if(GetAnchorPos().X() || GetAnchorPos().Y())
1465*cdf0e10cSrcweir 		{
1466*cdf0e10cSrcweir             const basegfx::B2DVector aAnchorOffset(GetAnchorPos().X(), GetAnchorPos().Y());
1467*cdf0e10cSrcweir 
1468*cdf0e10cSrcweir             aPosA += aAnchorOffset;
1469*cdf0e10cSrcweir             aPosB += aAnchorOffset;
1470*cdf0e10cSrcweir 		}
1471*cdf0e10cSrcweir 	}
1472*cdf0e10cSrcweir 
1473*cdf0e10cSrcweir     // derive new model data
1474*cdf0e10cSrcweir     const Point aNewPt1(basegfx::fround(aPosA.getX()), basegfx::fround(aPosA.getY()));
1475*cdf0e10cSrcweir     const Point aNewPt2(basegfx::fround(aPosB.getX()), basegfx::fround(aPosB.getY()));
1476*cdf0e10cSrcweir 
1477*cdf0e10cSrcweir     if(aNewPt1 != aPt1 || aNewPt2 != aPt2)
1478*cdf0e10cSrcweir     {
1479*cdf0e10cSrcweir         // set model values and broadcast
1480*cdf0e10cSrcweir 		Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
1481*cdf0e10cSrcweir 
1482*cdf0e10cSrcweir         aPt1 = aNewPt1;
1483*cdf0e10cSrcweir         aPt2 = aNewPt2;
1484*cdf0e10cSrcweir 
1485*cdf0e10cSrcweir         SetTextDirty();
1486*cdf0e10cSrcweir         ActionChanged();
1487*cdf0e10cSrcweir 		SetChanged();
1488*cdf0e10cSrcweir 		BroadcastObjectChange();
1489*cdf0e10cSrcweir 		SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
1490*cdf0e10cSrcweir     }
1491*cdf0e10cSrcweir }
1492*cdf0e10cSrcweir 
1493*cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
1494*cdf0e10cSrcweir // eof
1495