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