Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <svx/svdtrans.hxx>
31 : : #include <math.h>
32 : : #include <svx/xpoly.hxx>
33 : :
34 : : #include <vcl/virdev.hxx>
35 : : #include <tools/bigint.hxx>
36 : : #include <tools/debug.hxx>
37 : : #include <unotools/syslocale.hxx>
38 : :
39 : 0 : void MoveXPoly(XPolygon& rPoly, const Size& S)
40 : : {
41 : 0 : rPoly.Move(S.Width(),S.Height());
42 : 0 : }
43 : :
44 : 82679 : void ResizeRect(Rectangle& rRect, const Point& rRef, const Fraction& rxFact, const Fraction& ryFact, bool bNoJustify)
45 : : {
46 [ + - ]: 82679 : Fraction xFact(rxFact);
47 [ + - ]: 82679 : Fraction yFact(ryFact);
48 : :
49 : : {
50 [ - + ]: 82679 : if (xFact.GetDenominator()==0) {
51 : 0 : long nWdt=rRect.Right()-rRect.Left();
52 [ # # ]: 0 : if (xFact.GetNumerator()>=0) { // catch divisions by zero
53 [ # # ][ # # ]: 0 : xFact=Fraction(xFact.GetNumerator(),1);
54 [ # # ]: 0 : if (nWdt==0) rRect.Right()++;
55 : : } else {
56 [ # # ][ # # ]: 0 : xFact=Fraction(xFact.GetNumerator(),-1);
57 [ # # ]: 0 : if (nWdt==0) rRect.Left()--;
58 : : }
59 : : }
60 : 82679 : rRect.Left() =rRef.X()+Round(((double)(rRect.Left() -rRef.X())*xFact.GetNumerator())/xFact.GetDenominator());
61 : 82679 : rRect.Right() =rRef.X()+Round(((double)(rRect.Right() -rRef.X())*xFact.GetNumerator())/xFact.GetDenominator());
62 : : }
63 : : {
64 [ - + ]: 82679 : if (yFact.GetDenominator()==0) {
65 : 0 : long nHgt=rRect.Bottom()-rRect.Top();
66 [ # # ]: 0 : if (yFact.GetNumerator()>=0) { // catch divisions by zero
67 [ # # ][ # # ]: 0 : yFact=Fraction(yFact.GetNumerator(),1);
68 [ # # ]: 0 : if (nHgt==0) rRect.Bottom()++;
69 : : } else {
70 [ # # ][ # # ]: 0 : yFact=Fraction(yFact.GetNumerator(),-1);
71 [ # # ]: 0 : if (nHgt==0) rRect.Top()--;
72 : : }
73 : :
74 [ # # ][ # # ]: 0 : yFact=Fraction(yFact.GetNumerator(),1); // catch divisions by zero
75 : : }
76 : 82679 : rRect.Top() =rRef.Y()+Round(((double)(rRect.Top() -rRef.Y())*yFact.GetNumerator())/yFact.GetDenominator());
77 : 82679 : rRect.Bottom()=rRef.Y()+Round(((double)(rRect.Bottom()-rRef.Y())*yFact.GetNumerator())/yFact.GetDenominator());
78 : : }
79 [ + - ][ + - ]: 82679 : if (!bNoJustify) rRect.Justify();
80 : 82679 : }
81 : :
82 : :
83 : 0 : void ResizePoly(Polygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
84 : : {
85 : 0 : sal_uInt16 nAnz=rPoly.GetSize();
86 [ # # ]: 0 : for (sal_uInt16 i=0; i<nAnz; i++) {
87 [ # # ][ # # ]: 0 : ResizePoint(rPoly[i],rRef,xFact,yFact);
[ # # ]
88 : : }
89 : 0 : }
90 : :
91 : 0 : void ResizeXPoly(XPolygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
92 : : {
93 : 0 : sal_uInt16 nAnz=rPoly.GetPointCount();
94 [ # # ]: 0 : for (sal_uInt16 i=0; i<nAnz; i++) {
95 [ # # ][ # # ]: 0 : ResizePoint(rPoly[i],rRef,xFact,yFact);
[ # # ]
96 : : }
97 : 0 : }
98 : :
99 : 19083 : void RotatePoly(Polygon& rPoly, const Point& rRef, double sn, double cs)
100 : : {
101 : 19083 : sal_uInt16 nAnz=rPoly.GetSize();
102 [ + + ]: 114483 : for (sal_uInt16 i=0; i<nAnz; i++) {
103 : 95400 : RotatePoint(rPoly[i],rRef,sn,cs);
104 : : }
105 : 19083 : }
106 : :
107 : 0 : void RotateXPoly(XPolygon& rPoly, const Point& rRef, double sn, double cs)
108 : : {
109 : 0 : sal_uInt16 nAnz=rPoly.GetPointCount();
110 [ # # ]: 0 : for (sal_uInt16 i=0; i<nAnz; i++) {
111 : 0 : RotatePoint(rPoly[i],rRef,sn,cs);
112 : : }
113 : 0 : }
114 : :
115 : 0 : void RotateXPoly(XPolyPolygon& rPoly, const Point& rRef, double sn, double cs)
116 : : {
117 : 0 : sal_uInt16 nAnz=rPoly.Count();
118 [ # # ]: 0 : for (sal_uInt16 i=0; i<nAnz; i++) {
119 : 0 : RotateXPoly(rPoly[i],rRef,sn,cs);
120 : : }
121 : 0 : }
122 : :
123 : 155 : void MirrorPoint(Point& rPnt, const Point& rRef1, const Point& rRef2)
124 : : {
125 : 155 : long mx=rRef2.X()-rRef1.X();
126 : 155 : long my=rRef2.Y()-rRef1.Y();
127 [ + - ]: 155 : if (mx==0) { // vertical axis
128 : 155 : long dx=rRef1.X()-rPnt.X();
129 : 155 : rPnt.X()+=2*dx;
130 [ # # ]: 0 : } else if (my==0) { // horizontal axis
131 : 0 : long dy=rRef1.Y()-rPnt.Y();
132 : 0 : rPnt.Y()+=2*dy;
133 [ # # ]: 0 : } else if (mx==my) { // diagonal axis '\'
134 : 0 : long dx1=rPnt.X()-rRef1.X();
135 : 0 : long dy1=rPnt.Y()-rRef1.Y();
136 : 0 : rPnt.X()=rRef1.X()+dy1;
137 : 0 : rPnt.Y()=rRef1.Y()+dx1;
138 [ # # ]: 0 : } else if (mx==-my) { // diagonal axis '/'
139 : 0 : long dx1=rPnt.X()-rRef1.X();
140 : 0 : long dy1=rPnt.Y()-rRef1.Y();
141 : 0 : rPnt.X()=rRef1.X()-dy1;
142 : 0 : rPnt.Y()=rRef1.Y()-dx1;
143 : : } else { // arbitrary axis
144 : : // TODO: Optimize this! Raise perpendicular on the mirroring axis..?
145 [ # # ]: 0 : long nRefWink=GetAngle(rRef2-rRef1);
146 : 0 : rPnt-=rRef1;
147 : 0 : long nPntWink=GetAngle(rPnt);
148 : 0 : long nWink=2*(nRefWink-nPntWink);
149 : 0 : double a=nWink*nPi180;
150 : 0 : double nSin=sin(a);
151 : 0 : double nCos=cos(a);
152 : 0 : RotatePoint(rPnt,Point(),nSin,nCos);
153 : 0 : rPnt+=rRef1;
154 : : }
155 : 155 : }
156 : :
157 : 0 : void MirrorPoly(Polygon& rPoly, const Point& rRef1, const Point& rRef2)
158 : : {
159 : 0 : sal_uInt16 nAnz=rPoly.GetSize();
160 [ # # ]: 0 : for (sal_uInt16 i=0; i<nAnz; i++) {
161 : 0 : MirrorPoint(rPoly[i],rRef1,rRef2);
162 : : }
163 : 0 : }
164 : :
165 : 0 : void MirrorXPoly(XPolygon& rPoly, const Point& rRef1, const Point& rRef2)
166 : : {
167 : 0 : sal_uInt16 nAnz=rPoly.GetPointCount();
168 [ # # ]: 0 : for (sal_uInt16 i=0; i<nAnz; i++) {
169 : 0 : MirrorPoint(rPoly[i],rRef1,rRef2);
170 : : }
171 : 0 : }
172 : :
173 : 0 : void ShearPoly(Polygon& rPoly, const Point& rRef, double tn, bool bVShear)
174 : : {
175 : 0 : sal_uInt16 nAnz=rPoly.GetSize();
176 [ # # ]: 0 : for (sal_uInt16 i=0; i<nAnz; i++) {
177 : 0 : ShearPoint(rPoly[i],rRef,tn,bVShear);
178 : : }
179 : 0 : }
180 : :
181 : 0 : void ShearXPoly(XPolygon& rPoly, const Point& rRef, double tn, bool bVShear)
182 : : {
183 : 0 : sal_uInt16 nAnz=rPoly.GetPointCount();
184 [ # # ]: 0 : for (sal_uInt16 i=0; i<nAnz; i++) {
185 : 0 : ShearPoint(rPoly[i],rRef,tn,bVShear);
186 : : }
187 : 0 : }
188 : :
189 : 0 : double CrookRotateXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
190 : : const Point& rRad, double& rSin, double& rCos, bool bVert)
191 : : {
192 : 0 : bool bC1=pC1!=NULL;
193 : 0 : bool bC2=pC2!=NULL;
194 : 0 : long x0=rPnt.X();
195 : 0 : long y0=rPnt.Y();
196 : 0 : long cx=rCenter.X();
197 : 0 : long cy=rCenter.Y();
198 : 0 : double nWink=GetCrookAngle(rPnt,rCenter,rRad,bVert);
199 : 0 : double sn=sin(nWink);
200 : 0 : double cs=cos(nWink);
201 : 0 : RotatePoint(rPnt,rCenter,sn,cs);
202 [ # # ]: 0 : if (bC1) {
203 [ # # ]: 0 : if (bVert) {
204 : : // move into the direction of the center, as a basic position for the rotation
205 : 0 : pC1->Y()-=y0;
206 : : // resize, account for the distance from the center
207 : 0 : pC1->Y()=Round(((double)pC1->Y()) /rRad.X()*(cx-pC1->X()));
208 : 0 : pC1->Y()+=cy;
209 : : } else {
210 : : // move into the direction of the center, as a basic position for the rotation
211 : 0 : pC1->X()-=x0;
212 : : // resize, account for the distance from the center
213 : 0 : long nPntRad=cy-pC1->Y();
214 : 0 : double nFact=(double)nPntRad/(double)rRad.Y();
215 : 0 : pC1->X()=Round((double)pC1->X()*nFact);
216 : 0 : pC1->X()+=cx;
217 : : }
218 : 0 : RotatePoint(*pC1,rCenter,sn,cs);
219 : : }
220 [ # # ]: 0 : if (bC2) {
221 [ # # ]: 0 : if (bVert) {
222 : : // move into the direction of the center, as a basic position for the rotation
223 : 0 : pC2->Y()-=y0;
224 : : // resize, account for the distance from the center
225 : 0 : pC2->Y()=Round(((double)pC2->Y()) /rRad.X()*(rCenter.X()-pC2->X()));
226 : 0 : pC2->Y()+=cy;
227 : : } else {
228 : : // move into the direction of the center, as a basic position for the rotation
229 : 0 : pC2->X()-=x0;
230 : : // resize, account for the distance from the center
231 : 0 : long nPntRad=rCenter.Y()-pC2->Y();
232 : 0 : double nFact=(double)nPntRad/(double)rRad.Y();
233 : 0 : pC2->X()=Round((double)pC2->X()*nFact);
234 : 0 : pC2->X()+=cx;
235 : : }
236 : 0 : RotatePoint(*pC2,rCenter,sn,cs);
237 : : }
238 : 0 : rSin=sn;
239 : 0 : rCos=cs;
240 : 0 : return nWink;
241 : : }
242 : :
243 : 0 : double CrookSlantXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
244 : : const Point& rRad, double& rSin, double& rCos, bool bVert)
245 : : {
246 : 0 : bool bC1=pC1!=NULL;
247 : 0 : bool bC2=pC2!=NULL;
248 : 0 : long x0=rPnt.X();
249 : 0 : long y0=rPnt.Y();
250 : 0 : long dx1=0,dy1=0;
251 : 0 : long dxC1=0,dyC1=0;
252 : 0 : long dxC2=0,dyC2=0;
253 [ # # ]: 0 : if (bVert) {
254 : 0 : long nStart=rCenter.X()-rRad.X();
255 : 0 : dx1=rPnt.X()-nStart;
256 : 0 : rPnt.X()=nStart;
257 [ # # ]: 0 : if (bC1) {
258 : 0 : dxC1=pC1->X()-nStart;
259 : 0 : pC1->X()=nStart;
260 : : }
261 [ # # ]: 0 : if (bC2) {
262 : 0 : dxC2=pC2->X()-nStart;
263 : 0 : pC2->X()=nStart;
264 : : }
265 : : } else {
266 : 0 : long nStart=rCenter.Y()-rRad.Y();
267 : 0 : dy1=rPnt.Y()-nStart;
268 : 0 : rPnt.Y()=nStart;
269 [ # # ]: 0 : if (bC1) {
270 : 0 : dyC1=pC1->Y()-nStart;
271 : 0 : pC1->Y()=nStart;
272 : : }
273 [ # # ]: 0 : if (bC2) {
274 : 0 : dyC2=pC2->Y()-nStart;
275 : 0 : pC2->Y()=nStart;
276 : : }
277 : : }
278 : 0 : double nWink=GetCrookAngle(rPnt,rCenter,rRad,bVert);
279 : 0 : double sn=sin(nWink);
280 : 0 : double cs=cos(nWink);
281 : 0 : RotatePoint(rPnt,rCenter,sn,cs);
282 [ # # ][ # # ]: 0 : if (bC1) { if (bVert) pC1->Y()-=y0-rCenter.Y(); else pC1->X()-=x0-rCenter.X(); RotatePoint(*pC1,rCenter,sn,cs); }
283 [ # # ][ # # ]: 0 : if (bC2) { if (bVert) pC2->Y()-=y0-rCenter.Y(); else pC2->X()-=x0-rCenter.X(); RotatePoint(*pC2,rCenter,sn,cs); }
284 [ # # ]: 0 : if (bVert) {
285 : 0 : rPnt.X()+=dx1;
286 [ # # ]: 0 : if (bC1) pC1->X()+=dxC1;
287 [ # # ]: 0 : if (bC2) pC2->X()+=dxC2;
288 : : } else {
289 : 0 : rPnt.Y()+=dy1;
290 [ # # ]: 0 : if (bC1) pC1->Y()+=dyC1;
291 [ # # ]: 0 : if (bC2) pC2->Y()+=dyC2;
292 : : }
293 : 0 : rSin=sn;
294 : 0 : rCos=cs;
295 : 0 : return nWink;
296 : : }
297 : :
298 : 0 : double CrookStretchXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
299 : : const Point& rRad, double& rSin, double& rCos, bool bVert,
300 : : const Rectangle rRefRect)
301 : : {
302 : 0 : long y0=rPnt.Y();
303 : 0 : CrookSlantXPoint(rPnt,pC1,pC2,rCenter,rRad,rSin,rCos,bVert);
304 [ # # ]: 0 : if (bVert) {
305 : : } else {
306 : 0 : long nTop=rRefRect.Top();
307 : 0 : long nBtm=rRefRect.Bottom();
308 : 0 : long nHgt=nBtm-nTop;
309 : 0 : long dy=rPnt.Y()-y0;
310 : 0 : double a=((double)(y0-nTop))/nHgt;
311 : 0 : a*=dy;
312 : 0 : rPnt.Y()=y0+Round(a);
313 : 0 : } return 0.0;
314 : : }
315 : :
316 : : ////////////////////////////////////////////////////////////////////////////////////////////////////
317 : :
318 : 0 : void CrookRotatePoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert)
319 : : {
320 : : double nSin,nCos;
321 [ # # ]: 0 : sal_uInt16 nPointAnz=rPoly.GetPointCount();
322 : 0 : sal_uInt16 i=0;
323 [ # # ]: 0 : while (i<nPointAnz) {
324 [ # # ]: 0 : Point* pPnt=&rPoly[i];
325 : 0 : Point* pC1=NULL;
326 : 0 : Point* pC2=NULL;
327 [ # # ][ # # ]: 0 : if (i+1<nPointAnz && rPoly.IsControl(i)) { // control point to the left
[ # # ][ # # ]
328 : 0 : pC1=pPnt;
329 : 0 : i++;
330 [ # # ]: 0 : pPnt=&rPoly[i];
331 : : }
332 : 0 : i++;
333 [ # # ][ # # ]: 0 : if (i<nPointAnz && rPoly.IsControl(i)) { // control point to the right
[ # # ][ # # ]
334 [ # # ]: 0 : pC2=&rPoly[i];
335 : 0 : i++;
336 : : }
337 : 0 : CrookRotateXPoint(*pPnt,pC1,pC2,rCenter,rRad,nSin,nCos,bVert);
338 : : }
339 : 0 : }
340 : :
341 : 0 : void CrookSlantPoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert)
342 : : {
343 : : double nSin,nCos;
344 [ # # ]: 0 : sal_uInt16 nPointAnz=rPoly.GetPointCount();
345 : 0 : sal_uInt16 i=0;
346 [ # # ]: 0 : while (i<nPointAnz) {
347 [ # # ]: 0 : Point* pPnt=&rPoly[i];
348 : 0 : Point* pC1=NULL;
349 : 0 : Point* pC2=NULL;
350 [ # # ][ # # ]: 0 : if (i+1<nPointAnz && rPoly.IsControl(i)) { // control point to the left
[ # # ][ # # ]
351 : 0 : pC1=pPnt;
352 : 0 : i++;
353 [ # # ]: 0 : pPnt=&rPoly[i];
354 : : }
355 : 0 : i++;
356 [ # # ][ # # ]: 0 : if (i<nPointAnz && rPoly.IsControl(i)) { // control point to the right
[ # # ][ # # ]
357 [ # # ]: 0 : pC2=&rPoly[i];
358 : 0 : i++;
359 : : }
360 : 0 : CrookSlantXPoint(*pPnt,pC1,pC2,rCenter,rRad,nSin,nCos,bVert);
361 : : }
362 : 0 : }
363 : :
364 : 0 : void CrookStretchPoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert, const Rectangle rRefRect)
365 : : {
366 : : double nSin,nCos;
367 [ # # ]: 0 : sal_uInt16 nPointAnz=rPoly.GetPointCount();
368 : 0 : sal_uInt16 i=0;
369 [ # # ]: 0 : while (i<nPointAnz) {
370 [ # # ]: 0 : Point* pPnt=&rPoly[i];
371 : 0 : Point* pC1=NULL;
372 : 0 : Point* pC2=NULL;
373 [ # # ][ # # ]: 0 : if (i+1<nPointAnz && rPoly.IsControl(i)) { // control point to the left
[ # # ][ # # ]
374 : 0 : pC1=pPnt;
375 : 0 : i++;
376 [ # # ]: 0 : pPnt=&rPoly[i];
377 : : }
378 : 0 : i++;
379 [ # # ][ # # ]: 0 : if (i<nPointAnz && rPoly.IsControl(i)) { // control point to the right
[ # # ][ # # ]
380 [ # # ]: 0 : pC2=&rPoly[i];
381 : 0 : i++;
382 : : }
383 : 0 : CrookStretchXPoint(*pPnt,pC1,pC2,rCenter,rRad,nSin,nCos,bVert,rRefRect);
384 : : }
385 : 0 : }
386 : :
387 : : ////////////////////////////////////////////////////////////////////////////////////////////////////
388 : :
389 : 0 : void CrookRotatePoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert)
390 : : {
391 : 0 : sal_uInt16 nPolyAnz=rPoly.Count();
392 [ # # ]: 0 : for (sal_uInt16 nPolyNum=0; nPolyNum<nPolyAnz; nPolyNum++) {
393 : 0 : CrookRotatePoly(rPoly[nPolyNum],rCenter,rRad,bVert);
394 : : }
395 : 0 : }
396 : :
397 : 0 : void CrookSlantPoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert)
398 : : {
399 : 0 : sal_uInt16 nPolyAnz=rPoly.Count();
400 [ # # ]: 0 : for (sal_uInt16 nPolyNum=0; nPolyNum<nPolyAnz; nPolyNum++) {
401 : 0 : CrookSlantPoly(rPoly[nPolyNum],rCenter,rRad,bVert);
402 : : }
403 : 0 : }
404 : :
405 : 0 : void CrookStretchPoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert, const Rectangle rRefRect)
406 : : {
407 : 0 : sal_uInt16 nPolyAnz=rPoly.Count();
408 [ # # ]: 0 : for (sal_uInt16 nPolyNum=0; nPolyNum<nPolyAnz; nPolyNum++) {
409 : 0 : CrookStretchPoly(rPoly[nPolyNum],rCenter,rRad,bVert,rRefRect);
410 : : }
411 : 0 : }
412 : :
413 : : ////////////////////////////////////////////////////////////////////////////////////////////////////
414 : :
415 : 41429 : long GetAngle(const Point& rPnt)
416 : : {
417 : 41429 : long a=0;
418 [ + + ]: 41429 : if (rPnt.Y()==0) {
419 [ + + ]: 37998 : if (rPnt.X()<0) a=-18000;
420 [ + + ]: 3431 : } else if (rPnt.X()==0) {
421 [ + + ]: 2080 : if (rPnt.Y()>0) a=-9000;
422 : 1083 : else a=9000;
423 : : } else {
424 : 1351 : a=Round((atan2((double)-rPnt.Y(),(double)rPnt.X())/nPi180));
425 : : }
426 : 41429 : return a;
427 : : }
428 : :
429 : 18568 : long NormAngle180(long a)
430 : : {
431 [ - + ]: 18568 : while (a<18000) a+=36000;
432 [ + + ]: 37136 : while (a>=18000) a-=36000;
433 : 18568 : return a;
434 : : }
435 : :
436 : 20273 : long NormAngle360(long a)
437 : : {
438 [ + + ]: 21130 : while (a<0) a+=36000;
439 [ - + ]: 20273 : while (a>=36000) a-=36000;
440 : 20273 : return a;
441 : : }
442 : :
443 : 0 : sal_uInt16 GetAngleSector(long nWink)
444 : : {
445 [ # # ]: 0 : while (nWink<0) nWink+=36000;
446 [ # # ]: 0 : while (nWink>=36000) nWink-=36000;
447 [ # # ]: 0 : if (nWink< 9000) return 0;
448 [ # # ]: 0 : if (nWink<18000) return 1;
449 [ # # ]: 0 : if (nWink<27000) return 2;
450 : 0 : return 3;
451 : : }
452 : :
453 : 0 : long GetLen(const Point& rPnt)
454 : : {
455 : 0 : long x=Abs(rPnt.X());
456 : 0 : long y=Abs(rPnt.Y());
457 [ # # ]: 0 : if (x+y<0x8000) { // because 7FFF * 7FFF * 2 = 7FFE0002
458 : 0 : x*=x;
459 : 0 : y*=y;
460 : 0 : x+=y;
461 : 0 : x=Round(sqrt((double)x));
462 : 0 : return x;
463 : : } else {
464 : 0 : double nx=x;
465 : 0 : double ny=y;
466 : 0 : nx*=nx;
467 : 0 : ny*=ny;
468 : 0 : nx+=ny;
469 : 0 : nx=sqrt(nx);
470 [ # # ]: 0 : if (nx>0x7FFFFFFF) {
471 : 0 : return 0x7FFFFFFF; // we can't go any further, for fear of an overrun!
472 : : } else {
473 : 0 : return Round(nx);
474 : : }
475 : : }
476 : : }
477 : :
478 : : ////////////////////////////////////////////////////////////////////////////////////////////////////
479 : :
480 : 70972 : void GeoStat::RecalcSinCos()
481 : : {
482 [ + + ]: 70972 : if (nDrehWink==0) {
483 : 50286 : nSin=0.0;
484 : 50286 : nCos=1.0;
485 : : } else {
486 : 20686 : double a=nDrehWink*nPi180;
487 : 20686 : nSin=sin(a);
488 : 20686 : nCos=cos(a);
489 : : }
490 : 70972 : }
491 : :
492 : 70115 : void GeoStat::RecalcTan()
493 : : {
494 [ + + ]: 70115 : if (nShearWink==0) {
495 : 52424 : nTan=0.0;
496 : : } else {
497 : 17691 : double a=nShearWink*nPi180;
498 : 17691 : nTan=tan(a);
499 : : }
500 : 70115 : }
501 : :
502 : : ////////////////////////////////////////////////////////////////////////////////////////////////////
503 : :
504 : 18568 : Polygon Rect2Poly(const Rectangle& rRect, const GeoStat& rGeo)
505 : : {
506 : 18568 : Polygon aPol(5);
507 [ + - ]: 18568 : aPol[0]=rRect.TopLeft();
508 [ + - ][ + - ]: 18568 : aPol[1]=rRect.TopRight();
509 [ + - ][ + - ]: 18568 : aPol[2]=rRect.BottomRight();
510 [ + - ][ + - ]: 18568 : aPol[3]=rRect.BottomLeft();
511 [ + - ]: 18568 : aPol[4]=rRect.TopLeft();
512 [ # # ][ - + ]: 18568 : if (rGeo.nShearWink!=0) ShearPoly(aPol,rRect.TopLeft(),rGeo.nTan);
513 [ + + ][ + - ]: 18568 : if (rGeo.nDrehWink!=0) RotatePoly(aPol,rRect.TopLeft(),rGeo.nSin,rGeo.nCos);
514 : 18568 : return aPol;
515 : : }
516 : :
517 : 18568 : void Poly2Rect(const Polygon& rPol, Rectangle& rRect, GeoStat& rGeo)
518 : : {
519 [ + - ][ + - ]: 18568 : rGeo.nDrehWink=GetAngle(rPol[1]-rPol[0]);
[ + - ]
520 [ + - ]: 18568 : rGeo.nDrehWink=NormAngle360(rGeo.nDrehWink);
521 : : // rotation successful
522 : 18568 : rGeo.RecalcSinCos();
523 : :
524 [ + - ][ + - ]: 18568 : Point aPt1(rPol[1]-rPol[0]);
525 [ + + ]: 18568 : if (rGeo.nDrehWink!=0) RotatePoint(aPt1,Point(0,0),-rGeo.nSin,rGeo.nCos); // -Sin to reverse rotation
526 : 18568 : long nWdt=aPt1.X();
527 : :
528 [ + - ]: 18568 : Point aPt0(rPol[0]);
529 [ + - ][ + - ]: 18568 : Point aPt3(rPol[3]-rPol[0]);
530 [ + + ]: 18568 : if (rGeo.nDrehWink!=0) RotatePoint(aPt3,Point(0,0),-rGeo.nSin,rGeo.nCos); // -Sin to reverse rotation
531 : 18568 : long nHgt=aPt3.Y();
532 : :
533 : :
534 [ + - ]: 18568 : long nShW=GetAngle(aPt3);
535 : 18568 : nShW-=27000; // ShearWink is measured against a vertical line
536 : 18568 : nShW=-nShW; // Negieren, denn '+' ist Rechtskursivierung
537 : :
538 : 18568 : bool bMirr=aPt3.Y()<0;
539 [ - + ]: 18568 : if (bMirr) { // "exchange of points" when mirroring
540 : 0 : nHgt=-nHgt;
541 : 0 : nShW+=18000;
542 [ # # ]: 0 : aPt0=rPol[3];
543 : : }
544 : 18568 : nShW=NormAngle180(nShW);
545 [ - + ][ + - ]: 18568 : if (nShW<-9000 || nShW>9000) {
546 : 0 : nShW=NormAngle180(nShW+18000);
547 : : }
548 [ + + ]: 18568 : if (nShW<-SDRMAXSHEAR) nShW=-SDRMAXSHEAR; // limit ShearWinkel (shear angle) to +/- 89.00 deg
549 [ + + ]: 18568 : if (nShW>SDRMAXSHEAR) nShW=SDRMAXSHEAR;
550 : 18568 : rGeo.nShearWink=nShW;
551 : 18568 : rGeo.RecalcTan();
552 : 18568 : Point aRU(aPt0);
553 : 18568 : aRU.X()+=nWdt;
554 : 18568 : aRU.Y()+=nHgt;
555 [ + - ]: 18568 : rRect=Rectangle(aPt0,aRU);
556 : 18568 : }
557 : :
558 : : ////////////////////////////////////////////////////////////////////////////////////////////////////
559 : :
560 : 0 : void OrthoDistance8(const Point& rPt0, Point& rPt, bool bBigOrtho)
561 : : {
562 : 0 : long dx=rPt.X()-rPt0.X();
563 : 0 : long dy=rPt.Y()-rPt0.Y();
564 : 0 : long dxa=Abs(dx);
565 : 0 : long dya=Abs(dy);
566 [ # # ][ # # ]: 0 : if (dx==0 || dy==0 || dxa==dya) return;
[ # # ]
567 [ # # ]: 0 : if (dxa>=dya*2) { rPt.Y()=rPt0.Y(); return; }
568 [ # # ]: 0 : if (dya>=dxa*2) { rPt.X()=rPt0.X(); return; }
569 [ # # ]: 0 : if ((dxa<dya) != bBigOrtho) {
570 [ # # ]: 0 : rPt.Y()=rPt0.Y()+(dxa* (dy>=0 ? 1 : -1) );
571 : : } else {
572 [ # # ]: 0 : rPt.X()=rPt0.X()+(dya* (dx>=0 ? 1 : -1) );
573 : : }
574 : : }
575 : :
576 : 0 : void OrthoDistance4(const Point& rPt0, Point& rPt, bool bBigOrtho)
577 : : {
578 : 0 : long dx=rPt.X()-rPt0.X();
579 : 0 : long dy=rPt.Y()-rPt0.Y();
580 : 0 : long dxa=Abs(dx);
581 : 0 : long dya=Abs(dy);
582 [ # # ]: 0 : if ((dxa<dya) != bBigOrtho) {
583 [ # # ]: 0 : rPt.Y()=rPt0.Y()+(dxa* (dy>=0 ? 1 : -1) );
584 : : } else {
585 [ # # ]: 0 : rPt.X()=rPt0.X()+(dya* (dx>=0 ? 1 : -1) );
586 : : }
587 : 0 : }
588 : :
589 : : ////////////////////////////////////////////////////////////////////////////////////////////////////
590 : :
591 : 3110 : long BigMulDiv(long nVal, long nMul, long nDiv)
592 : : {
593 [ + - ]: 3110 : BigInt aVal(nVal);
594 [ + - ][ + - ]: 3110 : aVal*=nMul;
595 [ + - ][ + + ]: 3110 : if (aVal.IsNeg()!=(nDiv<0)) {
596 [ + - ][ + - ]: 38 : aVal-=nDiv/2; // to round correctly
597 : : } else {
598 [ + - ][ + - ]: 3072 : aVal+=nDiv/2; // to round correctly
599 : : }
600 [ + - ]: 3110 : if(nDiv)
601 : : {
602 [ + - ][ + - ]: 3110 : aVal/=nDiv;
603 [ + - ]: 3110 : return long(aVal);
604 : : }
605 : 3110 : return 0x7fffffff;
606 : : }
607 : :
608 : 0 : void Kuerzen(Fraction& rF, unsigned nDigits)
609 : : {
610 : 0 : sal_Int32 nMul=rF.GetNumerator();
611 : 0 : sal_Int32 nDiv=rF.GetDenominator();
612 : 0 : bool bNeg = false;
613 [ # # ]: 0 : if (nMul<0) { nMul=-nMul; bNeg=!bNeg; }
614 [ # # ]: 0 : if (nDiv<0) { nDiv=-nDiv; bNeg=!bNeg; }
615 [ # # ][ # # ]: 0 : if (nMul==0 || nDiv==0) return;
616 : : sal_uInt32 a;
617 : 0 : a=sal_uInt32(nMul); unsigned nMulZ=0; // count leading zeros
618 [ # # ]: 0 : while (a<0x00800000) { nMulZ+=8; a<<=8; }
619 [ # # ]: 0 : while (a<0x80000000) { nMulZ++; a<<=1; }
620 : 0 : a=sal_uInt32(nDiv); unsigned nDivZ=0; // count leading zeros
621 [ # # ]: 0 : while (a<0x00800000) { nDivZ+=8; a<<=8; }
622 [ # # ]: 0 : while (a<0x80000000) { nDivZ++; a<<=1; }
623 : : // count the number of digits
624 : 0 : int nMulDigits=32-nMulZ;
625 : 0 : int nDivDigits=32-nDivZ;
626 : : // count how many decimal places can be removed
627 [ # # ]: 0 : int nMulWeg=nMulDigits-nDigits; if (nMulWeg<0) nMulWeg=0;
628 [ # # ]: 0 : int nDivWeg=nDivDigits-nDigits; if (nDivWeg<0) nDivWeg=0;
629 : 0 : int nWeg=Min(nMulWeg,nDivWeg);
630 : 0 : nMul>>=nWeg;
631 : 0 : nDiv>>=nWeg;
632 [ # # ][ # # ]: 0 : if (nMul==0 || nDiv==0) {
633 : : DBG_WARNING("Math error after canceling decimal places.");
634 : 0 : return;
635 : : }
636 [ # # ]: 0 : if (bNeg) nMul=-nMul;
637 [ # # ]: 0 : rF=Fraction(nMul,nDiv);
638 : : }
639 : :
640 : : ////////////////////////////////////////////////////////////////////////////////////////////////////
641 : : // How many eU units fit into a mm, respectively an inch?
642 : : // Or: How many mm, respectively inches, are there in an eU (and then give me the inverse)
643 : :
644 : 628 : FrPair GetInchOrMM(MapUnit eU)
645 : : {
646 [ - - - + : 628 : switch (eU) {
+ + + - -
- - - - ]
647 : 0 : case MAP_1000TH_INCH: return FrPair(1000,1);
648 : 0 : case MAP_100TH_INCH : return FrPair( 100,1);
649 : 0 : case MAP_10TH_INCH : return FrPair( 10,1);
650 : 133 : case MAP_INCH : return FrPair( 1,1);
651 : 133 : case MAP_POINT : return FrPair( 72,1);
652 : 132 : case MAP_TWIP : return FrPair(1440,1);
653 : 230 : case MAP_100TH_MM : return FrPair( 100,1);
654 : 0 : case MAP_10TH_MM : return FrPair( 10,1);
655 : 0 : case MAP_MM : return FrPair( 1,1);
656 : 0 : case MAP_CM : return FrPair( 1,10);
657 : : case MAP_PIXEL : {
658 [ # # ]: 0 : VirtualDevice aVD;
659 [ # # ][ # # ]: 0 : aVD.SetMapMode(MapMode(MAP_100TH_MM));
[ # # ]
660 [ # # ]: 0 : Point aP(aVD.PixelToLogic(Point(64,64))); // 64 pixels for more accuracy
661 [ # # ][ # # ]: 0 : return FrPair(6400,aP.X(),6400,aP.Y());
662 : : }
663 : : case MAP_APPFONT: case MAP_SYSFONT: {
664 [ # # ]: 0 : VirtualDevice aVD;
665 [ # # ][ # # ]: 0 : aVD.SetMapMode(MapMode(eU));
[ # # ]
666 [ # # ]: 0 : Point aP(aVD.LogicToPixel(Point(32,32))); // 32 units for more accuracy
667 [ # # ][ # # ]: 0 : aVD.SetMapMode(MapMode(MAP_100TH_MM));
[ # # ]
668 [ # # ]: 0 : aP=aVD.PixelToLogic(aP);
669 [ # # ][ # # ]: 0 : return FrPair(3200,aP.X(),3200,aP.Y());
670 : : }
671 : 0 : default: break;
672 : : }
673 [ # # ]: 628 : return Fraction(1,1);
674 : : }
675 : :
676 : 0 : FrPair GetInchOrMM(FieldUnit eU)
677 : : {
678 [ # # # # : 0 : switch (eU) {
# # # # #
# # # ]
679 : 0 : case FUNIT_INCH : return FrPair( 1,1);
680 : 0 : case FUNIT_POINT : return FrPair( 72,1);
681 : 0 : case FUNIT_TWIP : return FrPair(1440,1);
682 : 0 : case FUNIT_100TH_MM : return FrPair( 100,1);
683 : 0 : case FUNIT_MM : return FrPair( 1,1);
684 : 0 : case FUNIT_CM : return FrPair( 1,10);
685 : 0 : case FUNIT_M : return FrPair( 1,1000);
686 : 0 : case FUNIT_KM : return FrPair( 1,1000000);
687 : 0 : case FUNIT_PICA : return FrPair( 6,1);
688 : 0 : case FUNIT_FOOT : return FrPair( 1,12);
689 : 0 : case FUNIT_MILE : return FrPair( 1,63360);
690 : 0 : default: break;
691 : : }
692 [ # # ]: 0 : return Fraction(1,1);
693 : : }
694 : :
695 : : // Calculate the factor that we need to convert units from eS to eD.
696 : : // e. g. GetMapFactor(UNIT_MM,UNIT_100TH_MM) => 100.
697 : :
698 : 405 : FrPair GetMapFactor(MapUnit eS, MapUnit eD)
699 : : {
700 [ + + ][ + - ]: 405 : if (eS==eD) return FrPair(1,1,1,1);
701 [ + - ]: 314 : FrPair aS(GetInchOrMM(eS));
702 [ + - ]: 314 : FrPair aD(GetInchOrMM(eD));
703 : 314 : bool bSInch=IsInch(eS);
704 : 314 : bool bDInch=IsInch(eD);
705 [ + - ][ + - ]: 314 : FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
[ + - ]
706 [ + + ][ + + ]: 314 : if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
[ + - ][ + - ]
[ + - ][ + - ]
707 [ + + ][ + - ]: 314 : if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
[ + - ][ + - ]
[ + - ][ + - ]
708 [ + - ]: 405 : return aRet;
709 : : };
710 : :
711 : 0 : FrPair GetMapFactor(FieldUnit eS, FieldUnit eD)
712 : : {
713 [ # # ][ # # ]: 0 : if (eS==eD) return FrPair(1,1,1,1);
714 [ # # ]: 0 : FrPair aS(GetInchOrMM(eS));
715 [ # # ]: 0 : FrPair aD(GetInchOrMM(eD));
716 : 0 : bool bSInch=IsInch(eS);
717 : 0 : bool bDInch=IsInch(eD);
718 [ # # ][ # # ]: 0 : FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
[ # # ]
719 [ # # ][ # # ]: 0 : if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
[ # # ][ # # ]
[ # # ][ # # ]
720 [ # # ][ # # ]: 0 : if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
[ # # ][ # # ]
[ # # ][ # # ]
721 [ # # ]: 0 : return aRet;
722 : : };
723 : :
724 : : ////////////////////////////////////////////////////////////////////////////////////////////////////
725 : :
726 : : // 1 mile = 8 furlong = 63.360" = 1.609.344,0mm
727 : : // 1 furlong = 10 chains = 7.920" = 201.168,0mm
728 : : // 1 chain = 4 poles = 792" = 20.116,8mm
729 : : // 1 pole = 5 1/2 yd = 198" = 5.029,2mm
730 : : // 1 yd = 3 ft = 36" = 914,4mm
731 : : // 1 ft = 12 " = 1" = 304,8mm
732 : :
733 : 0 : void GetMeterOrInch(MapUnit eMU, short& rnKomma, long& rnMul, long& rnDiv, bool& rbMetr, bool& rbInch)
734 : : {
735 : 0 : rnMul=1; rnDiv=1;
736 : 0 : short nKomma=0;
737 : 0 : bool bMetr = false, bInch = false;
738 [ # # # # : 0 : switch (eMU) {
# # # # #
# # # # #
# ]
739 : : // Metrisch
740 : 0 : case MAP_100TH_MM : bMetr = true; nKomma=5; break;
741 : 0 : case MAP_10TH_MM : bMetr = true; nKomma=4; break;
742 : 0 : case MAP_MM : bMetr = true; nKomma=3; break;
743 : 0 : case MAP_CM : bMetr = true; nKomma=2; break;
744 : : // Inch
745 : 0 : case MAP_1000TH_INCH: bInch = true; nKomma=3; break;
746 : 0 : case MAP_100TH_INCH : bInch = true; nKomma=2; break;
747 : 0 : case MAP_10TH_INCH : bInch = true; nKomma=1; break;
748 : 0 : case MAP_INCH : bInch = true; nKomma=0; break;
749 : 0 : case MAP_POINT : bInch = true; rnDiv=72; break; // 1Pt = 1/72"
750 : 0 : case MAP_TWIP : bInch = true; rnDiv=144; nKomma=1; break; // 1Twip = 1/1440"
751 : : // Sonstiges
752 : 0 : case MAP_PIXEL : break;
753 : 0 : case MAP_SYSFONT : break;
754 : 0 : case MAP_APPFONT : break;
755 : 0 : case MAP_RELATIVE : break;
756 : 0 : default: break;
757 : : } // switch
758 : 0 : rnKomma=nKomma;
759 : 0 : rbMetr=bMetr;
760 : 0 : rbInch=bInch;
761 : 0 : }
762 : :
763 : 0 : void GetMeterOrInch(FieldUnit eFU, short& rnKomma, long& rnMul, long& rnDiv, bool& rbMetr, bool& rbInch)
764 : : {
765 : 0 : rnMul=1; rnDiv=1;
766 : 0 : short nKomma=0;
767 : 0 : bool bMetr = false, bInch = false;
768 [ # # # # : 0 : switch (eFU) {
# # # # #
# # # # #
# # # ]
769 : 0 : case FUNIT_NONE : break;
770 : : // metrically
771 : 0 : case FUNIT_100TH_MM : bMetr = true; nKomma=5; break;
772 : 0 : case FUNIT_MM : bMetr = true; nKomma=3; break;
773 : 0 : case FUNIT_CM : bMetr = true; nKomma=2; break;
774 : 0 : case FUNIT_M : bMetr = true; nKomma=0; break;
775 : 0 : case FUNIT_KM : bMetr = true; nKomma=-3; break;
776 : : // Inch
777 : 0 : case FUNIT_TWIP : bInch = true; rnDiv=144; nKomma=1; break; // 1Twip = 1/1440"
778 : 0 : case FUNIT_POINT : bInch = true; rnDiv=72; break; // 1Pt = 1/72"
779 : 0 : case FUNIT_PICA : bInch = true; rnDiv=6; break; // 1Pica = 1/6" ?
780 : 0 : case FUNIT_INCH : bInch = true; break; // 1" = 1"
781 : 0 : case FUNIT_FOOT : bInch = true; rnMul=12; break; // 1Ft = 12"
782 : 0 : case FUNIT_MILE : bInch = true; rnMul=6336; nKomma=-1; break; // 1mile = 63360"
783 : : // others
784 : 0 : case FUNIT_CUSTOM : break;
785 : 0 : case FUNIT_PERCENT : nKomma=2; break;
786 : : // TODO: Add code to handle the following (added to remove warning)
787 : 0 : case FUNIT_CHAR : break;
788 : 0 : case FUNIT_LINE : break;
789 : : } // switch
790 : 0 : rnKomma=nKomma;
791 : 0 : rbMetr=bMetr;
792 : 0 : rbInch=bInch;
793 : 0 : }
794 : :
795 : 0 : void SdrFormatter::Undirty()
796 : : {
797 [ # # ][ # # ]: 0 : if (aScale.GetNumerator()==0 || aScale.GetDenominator()==0) aScale=Fraction(1,1);
[ # # ][ # # ]
[ # # ]
798 : : bool bSrcMetr,bSrcInch,bDstMetr,bDstInch;
799 : : long nMul1,nDiv1,nMul2,nDiv2;
800 : : short nKomma1,nKomma2;
801 : : // first: normalize to m or in
802 [ # # ]: 0 : if (!bSrcFU) {
803 : 0 : GetMeterOrInch(eSrcMU,nKomma1,nMul1,nDiv1,bSrcMetr,bSrcInch);
804 : : } else {
805 : 0 : GetMeterOrInch(eSrcFU,nKomma1,nMul1,nDiv1,bSrcMetr,bSrcInch);
806 : : }
807 [ # # ]: 0 : if (!bDstFU) {
808 : 0 : GetMeterOrInch(eDstMU,nKomma2,nMul2,nDiv2,bDstMetr,bDstInch);
809 : : } else {
810 : 0 : GetMeterOrInch(eDstFU,nKomma2,nMul2,nDiv2,bDstMetr,bDstInch);
811 : : }
812 : 0 : nMul1*=nDiv2;
813 : 0 : nDiv1*=nMul2;
814 : 0 : nKomma1=nKomma1-nKomma2;
815 : :
816 [ # # ][ # # ]: 0 : if (bSrcInch && bDstMetr) {
817 : 0 : nKomma1+=4;
818 : 0 : nMul1*=254;
819 : : }
820 [ # # ][ # # ]: 0 : if (bSrcMetr && bDstInch) {
821 : 0 : nKomma1-=4;
822 : 0 : nDiv1*=254;
823 : : }
824 : :
825 : : // temporary fraction for canceling
826 [ # # ]: 0 : Fraction aTempFract(nMul1,nDiv1);
827 : 0 : nMul1=aTempFract.GetNumerator();
828 : 0 : nDiv1=aTempFract.GetDenominator();
829 : :
830 : 0 : nMul_=nMul1;
831 : 0 : nDiv_=nDiv1;
832 : 0 : nKomma_=nKomma1;
833 : 0 : bDirty=sal_False;
834 : 0 : }
835 : :
836 : :
837 : 0 : void SdrFormatter::TakeStr(long nVal, XubString& rStr) const
838 : : {
839 : 0 : sal_Unicode aNullCode('0');
840 : :
841 [ # # ]: 0 : if(!nVal)
842 : : {
843 [ # # ][ # # ]: 0 : rStr = UniString();
[ # # ]
844 [ # # ]: 0 : rStr += aNullCode;
845 : 0 : return;
846 : : }
847 : :
848 : : // we may lose some decimal places here, because of MulDiv instead of Real
849 : 0 : sal_Bool bNeg(nVal < 0);
850 [ # # ]: 0 : SvtSysLocale aSysLoc;
851 [ # # ]: 0 : const LocaleDataWrapper& rLoc = aSysLoc.GetLocaleData();
852 : :
853 [ # # ]: 0 : ForceUndirty();
854 : :
855 : 0 : sal_Int16 nK(nKomma_);
856 [ # # ]: 0 : XubString aStr;
857 : :
858 [ # # ]: 0 : if(bNeg)
859 : 0 : nVal = -nVal;
860 : :
861 [ # # ]: 0 : while(nK <= -3)
862 : : {
863 : 0 : nVal *= 1000;
864 : 0 : nK += 3;
865 : : }
866 : :
867 [ # # ]: 0 : while(nK <= -1)
868 : : {
869 : 0 : nVal *= 10;
870 : 0 : nK++;
871 : : }
872 : :
873 [ # # ]: 0 : if(nMul_ != nDiv_)
874 [ # # ]: 0 : nVal = BigMulDiv(nVal, nMul_, nDiv_);
875 : :
876 [ # # ][ # # ]: 0 : aStr = UniString::CreateFromInt32(nVal);
[ # # ]
877 : :
878 [ # # ][ # # ]: 0 : if(nK > 0 && aStr.Len() <= nK )
[ # # ]
879 : : {
880 : : // decimal separator necessary
881 : 0 : sal_Int16 nAnz(nK - aStr.Len());
882 : :
883 [ # # ][ # # ]: 0 : if(nAnz >= 0 && rLoc.isNumLeadingZero())
[ # # ]
884 : 0 : nAnz++;
885 : :
886 [ # # ]: 0 : for(xub_StrLen i=0; i<nAnz; i++)
887 [ # # ]: 0 : aStr.Insert(aNullCode, 0);
888 : :
889 : : // remove superfluous decimal points
890 : 0 : xub_StrLen nNumDigits(rLoc.getNumDigits());
891 : 0 : xub_StrLen nWeg(nK - nNumDigits);
892 : :
893 [ # # ]: 0 : if(nWeg > 0)
894 : : {
895 : : // TODO: we should round here
896 [ # # ]: 0 : aStr.Erase(aStr.Len() - nWeg);
897 : 0 : nK = nNumDigits;
898 : : }
899 : : }
900 : :
901 : : // remember everything before the decimal separator for later
902 : 0 : xub_StrLen nVorKomma(aStr.Len() - nK);
903 : :
904 [ # # ]: 0 : if(nK > 0)
905 : : {
906 : : // insert KommaChar (decimal separator)
907 : : // remove trailing zeros
908 [ # # ][ # # ]: 0 : while(nK > 0 && aStr.GetChar(aStr.Len() - 1) == aNullCode)
[ # # ]
909 : : {
910 [ # # ]: 0 : aStr.Erase(aStr.Len() - 1);
911 : 0 : nK--;
912 : : }
913 : :
914 [ # # ]: 0 : if(nK > 0)
915 : : {
916 : : // do we still have decimal places?
917 [ # # ]: 0 : sal_Unicode cDec(rLoc.getNumDecimalSep()[0]);
918 [ # # ]: 0 : aStr.Insert(cDec, nVorKomma);
919 : : }
920 : : }
921 : :
922 : : // add in thousands separator (if necessary)
923 [ # # ]: 0 : if( nVorKomma > 3 )
924 : : {
925 [ # # ][ # # ]: 0 : String aThoSep( rLoc.getNumThousandSep() );
926 [ # # ]: 0 : if ( aThoSep.Len() > 0 )
927 : : {
928 : 0 : sal_Unicode cTho( aThoSep.GetChar(0) );
929 : 0 : sal_Int32 i(nVorKomma - 3);
930 : :
931 [ # # ]: 0 : while(i > 0)
932 : : {
933 [ # # ]: 0 : rStr.Insert(cTho, (xub_StrLen)i);
934 : 0 : i -= 3;
935 : : }
936 [ # # ]: 0 : }
937 : : }
938 : :
939 [ # # ]: 0 : if(!aStr.Len())
940 [ # # ]: 0 : aStr += aNullCode;
941 : :
942 [ # # ][ # # ]: 0 : if(bNeg && (aStr.Len() > 1 || aStr.GetChar(0) != aNullCode))
[ # # ][ # # ]
943 : : {
944 [ # # ]: 0 : rStr.Insert(sal_Unicode('-'), 0);
945 : : }
946 : :
947 [ # # ][ # # ]: 0 : rStr = aStr;
[ # # ]
948 : : }
949 : :
950 : 0 : void SdrFormatter::TakeUnitStr(MapUnit eUnit, XubString& rStr)
951 : : {
952 [ # # # # : 0 : switch(eUnit)
# # # # #
# # # # #
# ]
953 : : {
954 : : // metrically
955 : : case MAP_100TH_MM :
956 : : {
957 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("/100mm"));
958 : 0 : break;
959 : : }
960 : : case MAP_10TH_MM :
961 : : {
962 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("/10mm"));
963 : 0 : break;
964 : : }
965 : : case MAP_MM :
966 : : {
967 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("mm"));
968 : 0 : break;
969 : : }
970 : : case MAP_CM :
971 : : {
972 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("cm"));
973 : 0 : break;
974 : : }
975 : :
976 : : // Inch
977 : : case MAP_1000TH_INCH:
978 : : {
979 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("/1000\""));
980 : 0 : break;
981 : : }
982 : : case MAP_100TH_INCH :
983 : : {
984 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("/100\""));
985 : 0 : break;
986 : : }
987 : : case MAP_10TH_INCH :
988 : : {
989 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("/10\""));
990 : 0 : break;
991 : : }
992 : : case MAP_INCH :
993 : : {
994 [ # # ]: 0 : rStr = UniString();
995 : 0 : rStr += sal_Unicode('"');
996 : 0 : break;
997 : : }
998 : : case MAP_POINT :
999 : : {
1000 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("pt"));
1001 : 0 : break;
1002 : : }
1003 : : case MAP_TWIP :
1004 : : {
1005 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("twip"));
1006 : 0 : break;
1007 : : }
1008 : :
1009 : : // others
1010 : : case MAP_PIXEL :
1011 : : {
1012 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("pixel"));
1013 : 0 : break;
1014 : : }
1015 : : case MAP_SYSFONT :
1016 : : {
1017 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("sysfont"));
1018 : 0 : break;
1019 : : }
1020 : : case MAP_APPFONT :
1021 : : {
1022 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("appfont"));
1023 : 0 : break;
1024 : : }
1025 : : case MAP_RELATIVE :
1026 : : {
1027 [ # # ]: 0 : rStr = UniString();
1028 : 0 : rStr += sal_Unicode('%');
1029 : 0 : break;
1030 : : }
1031 : 0 : default: break;
1032 : : }
1033 : 0 : }
1034 : :
1035 : 0 : void SdrFormatter::TakeUnitStr(FieldUnit eUnit, XubString& rStr)
1036 : : {
1037 [ # # # # : 0 : switch(eUnit)
# # # # #
# # # # ]
1038 : : {
1039 : : default :
1040 : : case FUNIT_NONE :
1041 : : case FUNIT_CUSTOM :
1042 : : {
1043 [ # # ]: 0 : rStr = UniString();
1044 : 0 : break;
1045 : : }
1046 : :
1047 : : // metrically
1048 : : case FUNIT_100TH_MM:
1049 : : {
1050 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("/100mm"));
1051 : 0 : break;
1052 : : }
1053 : : case FUNIT_MM :
1054 : : {
1055 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("mm"));
1056 : 0 : break;
1057 : : }
1058 : : case FUNIT_CM :
1059 : : {
1060 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("cm"));
1061 : 0 : break;
1062 : : }
1063 : : case FUNIT_M :
1064 : : {
1065 [ # # ]: 0 : rStr = UniString();
1066 : 0 : rStr += sal_Unicode('m');
1067 : 0 : break;
1068 : : }
1069 : : case FUNIT_KM :
1070 : : {
1071 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("km"));
1072 : 0 : break;
1073 : : }
1074 : :
1075 : : // Inch
1076 : : case FUNIT_TWIP :
1077 : : {
1078 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("twip"));
1079 : 0 : break;
1080 : : }
1081 : : case FUNIT_POINT :
1082 : : {
1083 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("pt"));
1084 : 0 : break;
1085 : : }
1086 : : case FUNIT_PICA :
1087 : : {
1088 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("pica"));
1089 : 0 : break;
1090 : : }
1091 : : case FUNIT_INCH :
1092 : : {
1093 [ # # ]: 0 : rStr = UniString();
1094 : 0 : rStr += sal_Unicode('"');
1095 : 0 : break;
1096 : : }
1097 : : case FUNIT_FOOT :
1098 : : {
1099 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("ft"));
1100 : 0 : break;
1101 : : }
1102 : : case FUNIT_MILE :
1103 : : {
1104 [ # # ]: 0 : rStr = UniString(RTL_CONSTASCII_USTRINGPARAM("mile(s)"));
1105 : 0 : break;
1106 : : }
1107 : :
1108 : : // others
1109 : : case FUNIT_PERCENT:
1110 : : {
1111 [ # # ]: 0 : rStr = UniString();
1112 : 0 : rStr += sal_Unicode('%');
1113 : 0 : break;
1114 : : }
1115 : : }
1116 : 0 : }
1117 : :
1118 : : ////////////////////////////////////////////////////////////////////////////////////////////////////
1119 : :
1120 : :
1121 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|