1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26
27 #include <svx/svdtrans.hxx>
28 #include <math.h>
29 #include <svx/xpoly.hxx>
30
31 #include <vcl/virdev.hxx>
32 #include <tools/bigint.hxx>
33 #include <tools/debug.hxx>
34 #include <unotools/syslocale.hxx>
35
36 ////////////////////////////////////////////////////////////////////////////////////////////////////
37
MoveXPoly(XPolygon & rPoly,const Size & S)38 void MoveXPoly(XPolygon& rPoly, const Size& S)
39 {
40 rPoly.Move(S.Width(),S.Height());
41 }
42
MoveXPoly(XPolyPolygon & rPoly,const Size & S)43 void MoveXPoly(XPolyPolygon& rPoly, const Size& S)
44 {
45 rPoly.Move(S.Width(),S.Height());
46 }
47
48 ////////////////////////////////////////////////////////////////////////////////////////////////////
49
ResizeRect(Rectangle & rRect,const Point & rRef,const Fraction & rxFact,const Fraction & ryFact,FASTBOOL bNoJustify)50 void ResizeRect(Rectangle& rRect, const Point& rRef, const Fraction& rxFact, const Fraction& ryFact, FASTBOOL bNoJustify)
51 {
52 Fraction xFact(rxFact);
53 Fraction yFact(ryFact);
54 //long nHgt=rRect.Bottom()-rRect.Top();
55
56 {
57 if (xFact.GetDenominator()==0) {
58 long nWdt=rRect.Right()-rRect.Left();
59 if (xFact.GetNumerator()>=0) { // DivZero abfangen
60 xFact=Fraction(xFact.GetNumerator(),1);
61 if (nWdt==0) rRect.Right()++;
62 } else {
63 xFact=Fraction(xFact.GetNumerator(),-1);
64 if (nWdt==0) rRect.Left()--;
65 }
66 }
67 rRect.Left() =rRef.X()+Round(((double)(rRect.Left() -rRef.X())*xFact.GetNumerator())/xFact.GetDenominator());
68 rRect.Right() =rRef.X()+Round(((double)(rRect.Right() -rRef.X())*xFact.GetNumerator())/xFact.GetDenominator());
69 }
70 {
71 if (yFact.GetDenominator()==0) {
72 long nHgt=rRect.Bottom()-rRect.Top();
73 if (yFact.GetNumerator()>=0) { // DivZero abfangen
74 yFact=Fraction(yFact.GetNumerator(),1);
75 if (nHgt==0) rRect.Bottom()++;
76 } else {
77 yFact=Fraction(yFact.GetNumerator(),-1);
78 if (nHgt==0) rRect.Top()--;
79 }
80
81 yFact=Fraction(yFact.GetNumerator(),1); // DivZero abfangen
82 }
83 rRect.Top() =rRef.Y()+Round(((double)(rRect.Top() -rRef.Y())*yFact.GetNumerator())/yFact.GetDenominator());
84 rRect.Bottom()=rRef.Y()+Round(((double)(rRect.Bottom()-rRef.Y())*yFact.GetNumerator())/yFact.GetDenominator());
85 }
86 if (!bNoJustify) rRect.Justify();
87 }
88
89
ResizePoly(Polygon & rPoly,const Point & rRef,const Fraction & xFact,const Fraction & yFact)90 void ResizePoly(Polygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
91 {
92 sal_uInt16 nAnz=rPoly.GetSize();
93 for (sal_uInt16 i=0; i<nAnz; i++) {
94 ResizePoint(rPoly[i],rRef,xFact,yFact);
95 }
96 }
97
ResizeXPoly(XPolygon & rPoly,const Point & rRef,const Fraction & xFact,const Fraction & yFact)98 void ResizeXPoly(XPolygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
99 {
100 sal_uInt16 nAnz=rPoly.GetPointCount();
101 for (sal_uInt16 i=0; i<nAnz; i++) {
102 ResizePoint(rPoly[i],rRef,xFact,yFact);
103 }
104 }
105
ResizePoly(PolyPolygon & rPoly,const Point & rRef,const Fraction & xFact,const Fraction & yFact)106 void ResizePoly(PolyPolygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
107 {
108 sal_uInt16 nAnz=rPoly.Count();
109 for (sal_uInt16 i=0; i<nAnz; i++) {
110 ResizePoly(rPoly[i],rRef,xFact,yFact);
111 }
112 }
113
ResizeXPoly(XPolyPolygon & rPoly,const Point & rRef,const Fraction & xFact,const Fraction & yFact)114 void ResizeXPoly(XPolyPolygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
115 {
116 sal_uInt16 nAnz=rPoly.Count();
117 for (sal_uInt16 i=0; i<nAnz; i++) {
118 ResizeXPoly(rPoly[i],rRef,xFact,yFact);
119 }
120 }
121
122 ////////////////////////////////////////////////////////////////////////////////////////////////////
123
RotatePoly(Polygon & rPoly,const Point & rRef,double sn,double cs)124 void RotatePoly(Polygon& rPoly, const Point& rRef, double sn, double cs)
125 {
126 sal_uInt16 nAnz=rPoly.GetSize();
127 for (sal_uInt16 i=0; i<nAnz; i++) {
128 RotatePoint(rPoly[i],rRef,sn,cs);
129 }
130 }
131
RotateXPoly(XPolygon & rPoly,const Point & rRef,double sn,double cs)132 void RotateXPoly(XPolygon& rPoly, const Point& rRef, double sn, double cs)
133 {
134 sal_uInt16 nAnz=rPoly.GetPointCount();
135 for (sal_uInt16 i=0; i<nAnz; i++) {
136 RotatePoint(rPoly[i],rRef,sn,cs);
137 }
138 }
139
RotatePoly(PolyPolygon & rPoly,const Point & rRef,double sn,double cs)140 void RotatePoly(PolyPolygon& rPoly, const Point& rRef, double sn, double cs)
141 {
142 sal_uInt16 nAnz=rPoly.Count();
143 for (sal_uInt16 i=0; i<nAnz; i++) {
144 RotatePoly(rPoly[i],rRef,sn,cs);
145 }
146 }
147
RotateXPoly(XPolyPolygon & rPoly,const Point & rRef,double sn,double cs)148 void RotateXPoly(XPolyPolygon& rPoly, const Point& rRef, double sn, double cs)
149 {
150 sal_uInt16 nAnz=rPoly.Count();
151 for (sal_uInt16 i=0; i<nAnz; i++) {
152 RotateXPoly(rPoly[i],rRef,sn,cs);
153 }
154 }
155
156 ////////////////////////////////////////////////////////////////////////////////////////////////////
157
MirrorRect(Rectangle & rRect,const Point &,const Point &,FASTBOOL bNoJustify)158 void MirrorRect(Rectangle& rRect, const Point& /*rRef1*/, const Point& /*rRef2*/, FASTBOOL bNoJustify)
159 {
160 // !!! fehlende Implementation !!!
161 if (!bNoJustify) rRect.Justify();
162 }
163
MirrorPoint(Point & rPnt,const Point & rRef1,const Point & rRef2)164 void MirrorPoint(Point& rPnt, const Point& rRef1, const Point& rRef2)
165 {
166 long mx=rRef2.X()-rRef1.X();
167 long my=rRef2.Y()-rRef1.Y();
168 if (mx==0) { // Achse senkrecht
169 long dx=rRef1.X()-rPnt.X();
170 rPnt.X()+=2*dx;
171 } else if (my==0) { // Achse waagerecht
172 long dy=rRef1.Y()-rPnt.Y();
173 rPnt.Y()+=2*dy;
174 } else if (mx==my) { // Achse diagonal '\'
175 long dx1=rPnt.X()-rRef1.X();
176 long dy1=rPnt.Y()-rRef1.Y();
177 rPnt.X()=rRef1.X()+dy1;
178 rPnt.Y()=rRef1.Y()+dx1;
179 } else if (mx==-my) { // Achse diagonal '/'
180 long dx1=rPnt.X()-rRef1.X();
181 long dy1=rPnt.Y()-rRef1.Y();
182 rPnt.X()=rRef1.X()-dy1;
183 rPnt.Y()=rRef1.Y()-dx1;
184 } else { // beliebige Achse
185 // mal optimieren !!!
186 // Lot auf der Spiegelachse faellen oder so
187 long nRefWink=GetAngle(rRef2-rRef1);
188 rPnt-=rRef1;
189 long nPntWink=GetAngle(rPnt);
190 long nWink=2*(nRefWink-nPntWink);
191 double a=nWink*nPi180;
192 double nSin=sin(a);
193 double nCos=cos(a);
194 RotatePoint(rPnt,Point(),nSin,nCos);
195 rPnt+=rRef1;
196 }
197 }
198
MirrorPoly(Polygon & rPoly,const Point & rRef1,const Point & rRef2)199 void MirrorPoly(Polygon& rPoly, const Point& rRef1, const Point& rRef2)
200 {
201 sal_uInt16 nAnz=rPoly.GetSize();
202 for (sal_uInt16 i=0; i<nAnz; i++) {
203 MirrorPoint(rPoly[i],rRef1,rRef2);
204 }
205 }
206
MirrorXPoly(XPolygon & rPoly,const Point & rRef1,const Point & rRef2)207 void MirrorXPoly(XPolygon& rPoly, const Point& rRef1, const Point& rRef2)
208 {
209 sal_uInt16 nAnz=rPoly.GetPointCount();
210 for (sal_uInt16 i=0; i<nAnz; i++) {
211 MirrorPoint(rPoly[i],rRef1,rRef2);
212 }
213 }
214
MirrorPoly(PolyPolygon & rPoly,const Point & rRef1,const Point & rRef2)215 void MirrorPoly(PolyPolygon& rPoly, const Point& rRef1, const Point& rRef2)
216 {
217 sal_uInt16 nAnz=rPoly.Count();
218 for (sal_uInt16 i=0; i<nAnz; i++) {
219 MirrorPoly(rPoly[i],rRef1,rRef2);
220 }
221 }
222
MirrorXPoly(XPolyPolygon & rPoly,const Point & rRef1,const Point & rRef2)223 void MirrorXPoly(XPolyPolygon& rPoly, const Point& rRef1, const Point& rRef2)
224 {
225 sal_uInt16 nAnz=rPoly.Count();
226 for (sal_uInt16 i=0; i<nAnz; i++) {
227 MirrorXPoly(rPoly[i],rRef1,rRef2);
228 }
229 }
230
231 ////////////////////////////////////////////////////////////////////////////////////////////////////
232
ShearPoly(Polygon & rPoly,const Point & rRef,double tn,FASTBOOL bVShear)233 void ShearPoly(Polygon& rPoly, const Point& rRef, double tn, FASTBOOL bVShear)
234 {
235 sal_uInt16 nAnz=rPoly.GetSize();
236 for (sal_uInt16 i=0; i<nAnz; i++) {
237 ShearPoint(rPoly[i],rRef,tn,bVShear);
238 }
239 }
240
ShearXPoly(XPolygon & rPoly,const Point & rRef,double tn,FASTBOOL bVShear)241 void ShearXPoly(XPolygon& rPoly, const Point& rRef, double tn, FASTBOOL bVShear)
242 {
243 sal_uInt16 nAnz=rPoly.GetPointCount();
244 for (sal_uInt16 i=0; i<nAnz; i++) {
245 ShearPoint(rPoly[i],rRef,tn,bVShear);
246 }
247 }
248
ShearPoly(PolyPolygon & rPoly,const Point & rRef,double tn,FASTBOOL bVShear)249 void ShearPoly(PolyPolygon& rPoly, const Point& rRef, double tn, FASTBOOL bVShear)
250 {
251 sal_uInt16 nAnz=rPoly.Count();
252 for (sal_uInt16 i=0; i<nAnz; i++) {
253 ShearPoly(rPoly[i],rRef,tn,bVShear);
254 }
255 }
256
ShearXPoly(XPolyPolygon & rPoly,const Point & rRef,double tn,FASTBOOL bVShear)257 void ShearXPoly(XPolyPolygon& rPoly, const Point& rRef, double tn, FASTBOOL bVShear)
258 {
259 sal_uInt16 nAnz=rPoly.Count();
260 for (sal_uInt16 i=0; i<nAnz; i++) {
261 ShearXPoly(rPoly[i],rRef,tn,bVShear);
262 }
263 }
264
265 ////////////////////////////////////////////////////////////////////////////////////////////////////
266 //
267 // @@@@ @@@@@ @@@@ @@@@ @@ @@
268 // @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
269 // @@ @@ @@ @@ @@ @@ @@ @@ @@
270 // @@ @@@@@ @@ @@ @@ @@ @@@@
271 // @@ @@ @@ @@ @@ @@ @@ @@ @@
272 // @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
273 // @@@@ @@ @@ @@@@ @@@@ @@ @@
274 //
275 ////////////////////////////////////////////////////////////////////////////////////////////////////
276
CrookRotateXPoint(Point & rPnt,Point * pC1,Point * pC2,const Point & rCenter,const Point & rRad,double & rSin,double & rCos,FASTBOOL bVert)277 double CrookRotateXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
278 const Point& rRad, double& rSin, double& rCos, FASTBOOL bVert)
279 {
280 FASTBOOL bC1=pC1!=NULL;
281 FASTBOOL bC2=pC2!=NULL;
282 long x0=rPnt.X();
283 long y0=rPnt.Y();
284 long cx=rCenter.X();
285 long cy=rCenter.Y();
286 double nWink=GetCrookAngle(rPnt,rCenter,rRad,bVert);
287 double sn=sin(nWink);
288 double cs=cos(nWink);
289 RotatePoint(rPnt,rCenter,sn,cs);
290 if (bC1) {
291 if (bVert) {
292 // Richtung Zentrum verschieben, als Ausgangsposition fuer Rotate
293 pC1->Y()-=y0;
294 // Resize, entsprechend der Entfernung vom Zentrum
295 pC1->Y()=Round(((double)pC1->Y()) /rRad.X()*(cx-pC1->X()));
296 pC1->Y()+=cy;
297 } else {
298 // Richtung Zentrum verschieben, als Ausgangsposition fuer Rotate
299 pC1->X()-=x0;
300 // Resize, entsprechend der Entfernung vom Zentrum
301 long nPntRad=cy-pC1->Y();
302 double nFact=(double)nPntRad/(double)rRad.Y();
303 pC1->X()=Round((double)pC1->X()*nFact);
304 pC1->X()+=cx;
305 }
306 RotatePoint(*pC1,rCenter,sn,cs);
307 }
308 if (bC2) {
309 if (bVert) {
310 // Richtung Zentrum verschieben, als Ausgangsposition fuer Rotate
311 pC2->Y()-=y0;
312 // Resize, entsprechend der Entfernung vom Zentrum
313 pC2->Y()=Round(((double)pC2->Y()) /rRad.X()*(rCenter.X()-pC2->X()));
314 pC2->Y()+=cy;
315 } else {
316 // Richtung Zentrum verschieben, als Ausgangsposition fuer Rotate
317 pC2->X()-=x0;
318 // Resize, entsprechend der Entfernung vom Zentrum
319 long nPntRad=rCenter.Y()-pC2->Y();
320 double nFact=(double)nPntRad/(double)rRad.Y();
321 pC2->X()=Round((double)pC2->X()*nFact);
322 pC2->X()+=cx;
323 }
324 RotatePoint(*pC2,rCenter,sn,cs);
325 }
326 rSin=sn;
327 rCos=cs;
328 return nWink;
329 }
330
CrookSlantXPoint(Point & rPnt,Point * pC1,Point * pC2,const Point & rCenter,const Point & rRad,double & rSin,double & rCos,FASTBOOL bVert)331 double CrookSlantXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
332 const Point& rRad, double& rSin, double& rCos, FASTBOOL bVert)
333 {
334 FASTBOOL bC1=pC1!=NULL;
335 FASTBOOL bC2=pC2!=NULL;
336 long x0=rPnt.X();
337 long y0=rPnt.Y();
338 long dx1=0,dy1=0;
339 long dxC1=0,dyC1=0;
340 long dxC2=0,dyC2=0;
341 if (bVert) {
342 long nStart=rCenter.X()-rRad.X();
343 dx1=rPnt.X()-nStart;
344 rPnt.X()=nStart;
345 if (bC1) {
346 dxC1=pC1->X()-nStart;
347 pC1->X()=nStart;
348 }
349 if (bC2) {
350 dxC2=pC2->X()-nStart;
351 pC2->X()=nStart;
352 }
353 } else {
354 long nStart=rCenter.Y()-rRad.Y();
355 dy1=rPnt.Y()-nStart;
356 rPnt.Y()=nStart;
357 if (bC1) {
358 dyC1=pC1->Y()-nStart;
359 pC1->Y()=nStart;
360 }
361 if (bC2) {
362 dyC2=pC2->Y()-nStart;
363 pC2->Y()=nStart;
364 }
365 }
366 double nWink=GetCrookAngle(rPnt,rCenter,rRad,bVert);
367 double sn=sin(nWink);
368 double cs=cos(nWink);
369 RotatePoint(rPnt,rCenter,sn,cs);
370 if (bC1) { if (bVert) pC1->Y()-=y0-rCenter.Y(); else pC1->X()-=x0-rCenter.X(); RotatePoint(*pC1,rCenter,sn,cs); }
371 if (bC2) { if (bVert) pC2->Y()-=y0-rCenter.Y(); else pC2->X()-=x0-rCenter.X(); RotatePoint(*pC2,rCenter,sn,cs); }
372 if (bVert) {
373 rPnt.X()+=dx1;
374 if (bC1) pC1->X()+=dxC1;
375 if (bC2) pC2->X()+=dxC2;
376 } else {
377 rPnt.Y()+=dy1;
378 if (bC1) pC1->Y()+=dyC1;
379 if (bC2) pC2->Y()+=dyC2;
380 }
381 rSin=sn;
382 rCos=cs;
383 return nWink;
384 }
385
CrookStretchXPoint(Point & rPnt,Point * pC1,Point * pC2,const Point & rCenter,const Point & rRad,double & rSin,double & rCos,FASTBOOL bVert,const Rectangle rRefRect)386 double CrookStretchXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
387 const Point& rRad, double& rSin, double& rCos, FASTBOOL bVert,
388 const Rectangle rRefRect)
389 {
390 //FASTBOOL bC1=pC1!=NULL;
391 //FASTBOOL bC2=pC2!=NULL;
392 //long x0=rPnt.X();
393 long y0=rPnt.Y();
394 CrookSlantXPoint(rPnt,pC1,pC2,rCenter,rRad,rSin,rCos,bVert);
395 if (bVert) {
396 } else {
397 //long nBase=rCenter.Y()-rRad.Y();
398 long nTop=rRefRect.Top();
399 long nBtm=rRefRect.Bottom();
400 long nHgt=nBtm-nTop;
401 long dy=rPnt.Y()-y0;
402 //FASTBOOL bOben=rRad.Y()<0;
403 double a=((double)(y0-nTop))/nHgt;
404 a*=dy;
405 rPnt.Y()=y0+Round(a);
406 } return 0.0;
407 }
408
409 ////////////////////////////////////////////////////////////////////////////////////////////////////
410
CrookRotatePoly(XPolygon & rPoly,const Point & rCenter,const Point & rRad,FASTBOOL bVert)411 void CrookRotatePoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert)
412 {
413 double nSin,nCos;
414 sal_uInt16 nPointAnz=rPoly.GetPointCount();
415 sal_uInt16 i=0;
416 while (i<nPointAnz) {
417 Point* pPnt=&rPoly[i];
418 Point* pC1=NULL;
419 Point* pC2=NULL;
420 if (i+1<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt links
421 pC1=pPnt;
422 i++;
423 pPnt=&rPoly[i];
424 }
425 i++;
426 if (i<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt rechts
427 pC2=&rPoly[i];
428 i++;
429 }
430 CrookRotateXPoint(*pPnt,pC1,pC2,rCenter,rRad,nSin,nCos,bVert);
431 }
432 }
433
CrookSlantPoly(XPolygon & rPoly,const Point & rCenter,const Point & rRad,FASTBOOL bVert)434 void CrookSlantPoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert)
435 {
436 double nSin,nCos;
437 sal_uInt16 nPointAnz=rPoly.GetPointCount();
438 sal_uInt16 i=0;
439 while (i<nPointAnz) {
440 Point* pPnt=&rPoly[i];
441 Point* pC1=NULL;
442 Point* pC2=NULL;
443 if (i+1<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt links
444 pC1=pPnt;
445 i++;
446 pPnt=&rPoly[i];
447 }
448 i++;
449 if (i<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt rechts
450 pC2=&rPoly[i];
451 i++;
452 }
453 CrookSlantXPoint(*pPnt,pC1,pC2,rCenter,rRad,nSin,nCos,bVert);
454 }
455 }
456
CrookStretchPoly(XPolygon & rPoly,const Point & rCenter,const Point & rRad,FASTBOOL bVert,const Rectangle rRefRect)457 void CrookStretchPoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert, const Rectangle rRefRect)
458 {
459 double nSin,nCos;
460 sal_uInt16 nPointAnz=rPoly.GetPointCount();
461 sal_uInt16 i=0;
462 while (i<nPointAnz) {
463 Point* pPnt=&rPoly[i];
464 Point* pC1=NULL;
465 Point* pC2=NULL;
466 if (i+1<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt links
467 pC1=pPnt;
468 i++;
469 pPnt=&rPoly[i];
470 }
471 i++;
472 if (i<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt rechts
473 pC2=&rPoly[i];
474 i++;
475 }
476 CrookStretchXPoint(*pPnt,pC1,pC2,rCenter,rRad,nSin,nCos,bVert,rRefRect);
477 }
478 }
479
480 ////////////////////////////////////////////////////////////////////////////////////////////////////
481
CrookRotatePoly(XPolyPolygon & rPoly,const Point & rCenter,const Point & rRad,FASTBOOL bVert)482 void CrookRotatePoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert)
483 {
484 sal_uInt16 nPolyAnz=rPoly.Count();
485 for (sal_uInt16 nPolyNum=0; nPolyNum<nPolyAnz; nPolyNum++) {
486 CrookRotatePoly(rPoly[nPolyNum],rCenter,rRad,bVert);
487 }
488 }
489
CrookSlantPoly(XPolyPolygon & rPoly,const Point & rCenter,const Point & rRad,FASTBOOL bVert)490 void CrookSlantPoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert)
491 {
492 sal_uInt16 nPolyAnz=rPoly.Count();
493 for (sal_uInt16 nPolyNum=0; nPolyNum<nPolyAnz; nPolyNum++) {
494 CrookSlantPoly(rPoly[nPolyNum],rCenter,rRad,bVert);
495 }
496 }
497
CrookStretchPoly(XPolyPolygon & rPoly,const Point & rCenter,const Point & rRad,FASTBOOL bVert,const Rectangle rRefRect)498 void CrookStretchPoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert, const Rectangle rRefRect)
499 {
500 sal_uInt16 nPolyAnz=rPoly.Count();
501 for (sal_uInt16 nPolyNum=0; nPolyNum<nPolyAnz; nPolyNum++) {
502 CrookStretchPoly(rPoly[nPolyNum],rCenter,rRad,bVert,rRefRect);
503 }
504 }
505
506 ////////////////////////////////////////////////////////////////////////////////////////////////////
507
GetAngle(const Point & rPnt)508 long GetAngle(const Point& rPnt)
509 {
510 long a=0;
511 if (rPnt.Y()==0) {
512 if (rPnt.X()<0) a=-18000;
513 } else if (rPnt.X()==0) {
514 if (rPnt.Y()>0) a=-9000;
515 else a=9000;
516 } else {
517 a=Round((atan2((double)-rPnt.Y(),(double)rPnt.X())/nPi180));
518 }
519 return a;
520 }
521
NormAngle180(long a)522 long NormAngle180(long a)
523 {
524 while (a<18000) a+=36000;
525 while (a>=18000) a-=36000;
526 return a;
527 }
528
NormAngle360(long a)529 long NormAngle360(long a)
530 {
531 while (a<0) a+=36000;
532 while (a>=36000) a-=36000;
533 return a;
534 }
535
GetAngleSector(long nWink)536 sal_uInt16 GetAngleSector(long nWink)
537 {
538 while (nWink<0) nWink+=36000;
539 while (nWink>=36000) nWink-=36000;
540 if (nWink< 9000) return 0;
541 if (nWink<18000) return 1;
542 if (nWink<27000) return 2;
543 return 3;
544 }
545
GetLen(const Point & rPnt)546 long GetLen(const Point& rPnt)
547 {
548 long x=Abs(rPnt.X());
549 long y=Abs(rPnt.Y());
550 if (x+y<0x8000) { // weil 7FFF * 7FFF * 2 = 7FFE0002
551 x*=x;
552 y*=y;
553 x+=y;
554 x=Round(sqrt((double)x));
555 return x;
556 } else {
557 double nx=x;
558 double ny=y;
559 nx*=nx;
560 ny*=ny;
561 nx+=ny;
562 nx=sqrt(nx);
563 if (nx>0x7FFFFFFF) {
564 return 0x7FFFFFFF; // Ueberlauf, mehr is nich!
565 } else {
566 return Round(nx);
567 }
568 }
569 }
570
571 ////////////////////////////////////////////////////////////////////////////////////////////////////
572
RecalcSinCos()573 void GeoStat::RecalcSinCos()
574 {
575 if (nDrehWink==0) {
576 nSin=0.0;
577 nCos=1.0;
578 } else {
579 double a=nDrehWink*nPi180;
580 nSin=sin(a);
581 nCos=cos(a);
582 }
583 }
584
RecalcTan()585 void GeoStat::RecalcTan()
586 {
587 if (nShearWink==0) {
588 nTan=0.0;
589 } else {
590 double a=nShearWink*nPi180;
591 nTan=tan(a);
592 }
593 }
594
595 ////////////////////////////////////////////////////////////////////////////////////////////////////
596
Rect2Poly(const Rectangle & rRect,const GeoStat & rGeo)597 Polygon Rect2Poly(const Rectangle& rRect, const GeoStat& rGeo)
598 {
599 Polygon aPol(5);
600 aPol[0]=rRect.TopLeft();
601 aPol[1]=rRect.TopRight();
602 aPol[2]=rRect.BottomRight();
603 aPol[3]=rRect.BottomLeft();
604 aPol[4]=rRect.TopLeft();
605 if (rGeo.nShearWink!=0) ShearPoly(aPol,rRect.TopLeft(),rGeo.nTan);
606 if (rGeo.nDrehWink!=0) RotatePoly(aPol,rRect.TopLeft(),rGeo.nSin,rGeo.nCos);
607 return aPol;
608 }
609
Poly2Rect(const Polygon & rPol,Rectangle & rRect,GeoStat & rGeo)610 void Poly2Rect(const Polygon& rPol, Rectangle& rRect, GeoStat& rGeo)
611 {
612 rGeo.nDrehWink=GetAngle(rPol[1]-rPol[0]);
613 rGeo.nDrehWink=NormAngle360(rGeo.nDrehWink);
614 // Drehung ist damit im Kasten
615 rGeo.RecalcSinCos();
616
617 Point aPt1(rPol[1]-rPol[0]);
618 if (rGeo.nDrehWink!=0) RotatePoint(aPt1,Point(0,0),-rGeo.nSin,rGeo.nCos); // -Sin fuer Rueckdrehung
619 long nWdt=aPt1.X();
620
621 Point aPt0(rPol[0]);
622 Point aPt3(rPol[3]-rPol[0]);
623 if (rGeo.nDrehWink!=0) RotatePoint(aPt3,Point(0,0),-rGeo.nSin,rGeo.nCos); // -Sin fuer Rueckdrehung
624 long nHgt=aPt3.Y();
625
626 if(aPt3.X())
627 {
628 // #i74358# the axes are not orthogonal, so for getting the correct height,
629 // calculate the length of aPt3
630
631 // #i74358# this change was wrong, in the field of the old geometry stuff
632 // it is not an error. The new height always is the same as before; shear
633 // does not change object height at all. This is different from the interactions,
634 // but obviously wanted in the old versions.
635 //
636 // nHgt = static_cast< long >(sqrt(static_cast< double >(aPt3.X() * aPt3.X() + aPt3.Y() * aPt3.Y())));
637 }
638
639 long nShW=GetAngle(aPt3);
640 nShW-=27000; // ShearWink wird zur Senkrechten gemessen
641 nShW=-nShW; // Negieren, denn '+' ist Rechtskursivierung
642
643 FASTBOOL bMirr=aPt3.Y()<0;
644 if (bMirr) { // "Punktetausch" bei Spiegelung
645 nHgt=-nHgt;
646 nShW+=18000;
647 aPt0=rPol[3];
648 }
649 nShW=NormAngle180(nShW);
650 if (nShW<-9000 || nShW>9000) {
651 nShW=NormAngle180(nShW+18000);
652 }
653 if (nShW<-SDRMAXSHEAR) nShW=-SDRMAXSHEAR; // ShearWinkel begrenzen auf +/- 89.00 deg
654 if (nShW>SDRMAXSHEAR) nShW=SDRMAXSHEAR;
655 rGeo.nShearWink=nShW;
656 rGeo.RecalcTan();
657 Point aRU(aPt0);
658 aRU.X()+=nWdt;
659 aRU.Y()+=nHgt;
660 rRect=Rectangle(aPt0,aRU);
661 }
662
663 ////////////////////////////////////////////////////////////////////////////////////////////////////
664
OrthoDistance8(const Point & rPt0,Point & rPt,FASTBOOL bBigOrtho)665 void OrthoDistance8(const Point& rPt0, Point& rPt, FASTBOOL bBigOrtho)
666 {
667 long dx=rPt.X()-rPt0.X();
668 long dy=rPt.Y()-rPt0.Y();
669 long dxa=Abs(dx);
670 long dya=Abs(dy);
671 if (dx==0 || dy==0 || dxa==dya) return;
672 if (dxa>=dya*2) { rPt.Y()=rPt0.Y(); return; }
673 if (dya>=dxa*2) { rPt.X()=rPt0.X(); return; }
674 if ((dxa<dya) != bBigOrtho) {
675 rPt.Y()=rPt0.Y()+(dxa* (dy>=0 ? 1 : -1) );
676 } else {
677 rPt.X()=rPt0.X()+(dya* (dx>=0 ? 1 : -1) );
678 }
679 }
680
OrthoDistance4(const Point & rPt0,Point & rPt,FASTBOOL bBigOrtho)681 void OrthoDistance4(const Point& rPt0, Point& rPt, FASTBOOL bBigOrtho)
682 {
683 long dx=rPt.X()-rPt0.X();
684 long dy=rPt.Y()-rPt0.Y();
685 long dxa=Abs(dx);
686 long dya=Abs(dy);
687 if ((dxa<dya) != bBigOrtho) {
688 rPt.Y()=rPt0.Y()+(dxa* (dy>=0 ? 1 : -1) );
689 } else {
690 rPt.X()=rPt0.X()+(dya* (dx>=0 ? 1 : -1) );
691 }
692 }
693
694 ////////////////////////////////////////////////////////////////////////////////////////////////////
695
BigMulDiv(long nVal,long nMul,long nDiv)696 long BigMulDiv(long nVal, long nMul, long nDiv)
697 {
698 BigInt aVal(nVal);
699 aVal*=nMul;
700 if (aVal.IsNeg()!=(nDiv<0)) {
701 aVal-=nDiv/2; // fuer korrektes Runden
702 } else {
703 aVal+=nDiv/2; // fuer korrektes Runden
704 }
705 if(nDiv)
706 {
707 aVal/=nDiv;
708 return long(aVal);
709 }
710 return 0x7fffffff;
711 }
712
Kuerzen(Fraction & rF,unsigned nDigits)713 void Kuerzen(Fraction& rF, unsigned nDigits)
714 {
715 sal_Int32 nMul=rF.GetNumerator();
716 sal_Int32 nDiv=rF.GetDenominator();
717 FASTBOOL bNeg=sal_False;
718 if (nMul<0) { nMul=-nMul; bNeg=!bNeg; }
719 if (nDiv<0) { nDiv=-nDiv; bNeg=!bNeg; }
720 if (nMul==0 || nDiv==0) return;
721 sal_uInt32 a;
722 a=sal_uInt32(nMul); unsigned nMulZ=0; // Fuehrende Nullen zaehlen
723 while (a<0x00800000) { nMulZ+=8; a<<=8; }
724 while (a<0x80000000) { nMulZ++; a<<=1; }
725 a=sal_uInt32(nDiv); unsigned nDivZ=0; // Fuehrende Nullen zaehlen
726 while (a<0x00800000) { nDivZ+=8; a<<=8; }
727 while (a<0x80000000) { nDivZ++; a<<=1; }
728 // Anzahl der verwendeten Digits bestimmen
729 int nMulDigits=32-nMulZ;
730 int nDivDigits=32-nDivZ;
731 // Nun bestimmen, wieviele Stellen hinten weg koennen
732 int nMulWeg=nMulDigits-nDigits; if (nMulWeg<0) nMulWeg=0;
733 int nDivWeg=nDivDigits-nDigits; if (nDivWeg<0) nDivWeg=0;
734 int nWeg=Min(nMulWeg,nDivWeg);
735 nMul>>=nWeg;
736 nDiv>>=nWeg;
737 if (nMul==0 || nDiv==0) {
738 DBG_WARNING("Oups, beim kuerzen einer Fraction hat sich Joe verrechnet.");
739 return;
740 }
741 if (bNeg) nMul=-nMul;
742 rF=Fraction(nMul,nDiv);
743 }
744
745 ////////////////////////////////////////////////////////////////////////////////////////////////////
746 // Wieviele eU-Einheiten passen in einen mm bzw. Inch?
747 // Oder wie gross ist ein eU in mm bzw. Inch, und davon der Kehrwert
748
GetInchOrMM(MapUnit eU)749 FrPair GetInchOrMM(MapUnit eU)
750 {
751 switch (eU) {
752 case MAP_1000TH_INCH: return FrPair(1000,1);
753 case MAP_100TH_INCH : return FrPair( 100,1);
754 case MAP_10TH_INCH : return FrPair( 10,1);
755 case MAP_INCH : return FrPair( 1,1);
756 case MAP_POINT : return FrPair( 72,1);
757 case MAP_TWIP : return FrPair(1440,1);
758 case MAP_100TH_MM : return FrPair( 100,1);
759 case MAP_10TH_MM : return FrPair( 10,1);
760 case MAP_MM : return FrPair( 1,1);
761 case MAP_CM : return FrPair( 1,10);
762 case MAP_PIXEL : {
763 VirtualDevice aVD;
764 aVD.SetMapMode(MapMode(MAP_100TH_MM));
765 Point aP(aVD.PixelToLogic(Point(64,64))); // 64 Pixel fuer bessere Genauigkeit
766 return FrPair(6400,aP.X(),6400,aP.Y());
767 }
768 case MAP_APPFONT: case MAP_SYSFONT: {
769 VirtualDevice aVD;
770 aVD.SetMapMode(MapMode(eU));
771 Point aP(aVD.LogicToPixel(Point(32,32))); // 32 Einheiten fuer bessere Genauigkeit
772 aVD.SetMapMode(MapMode(MAP_100TH_MM));
773 aP=aVD.PixelToLogic(aP);
774 return FrPair(3200,aP.X(),3200,aP.Y());
775 }
776 default: break;
777 }
778 return Fraction(1,1);
779 }
780
GetInchOrMM(FieldUnit eU)781 FrPair GetInchOrMM(FieldUnit eU)
782 {
783 switch (eU) {
784 case FUNIT_INCH : return FrPair( 1,1);
785 case FUNIT_POINT : return FrPair( 72,1);
786 case FUNIT_TWIP : return FrPair(1440,1);
787 case FUNIT_100TH_MM : return FrPair( 100,1);
788 case FUNIT_MM : return FrPair( 1,1);
789 case FUNIT_CM : return FrPair( 1,10);
790 case FUNIT_M : return FrPair( 1,1000);
791 case FUNIT_KM : return FrPair( 1,1000000);
792 case FUNIT_PICA : return FrPair( 6,1);
793 case FUNIT_FOOT : return FrPair( 1,12);
794 case FUNIT_MILE : return FrPair( 1,63360);
795 default: break;
796 }
797 return Fraction(1,1);
798 }
799
800 // Den Faktor berechnen, der anzuwenden ist um n Einheiten von eS nach
801 // eD umzurechnen. Z.B. GetMapFactor(UNIT_MM,UNIT_100TH_MM) => 100.
802
GetMapFactor(MapUnit eS,MapUnit eD)803 FrPair GetMapFactor(MapUnit eS, MapUnit eD)
804 {
805 if (eS==eD) return FrPair(1,1,1,1);
806 FrPair aS(GetInchOrMM(eS));
807 FrPair aD(GetInchOrMM(eD));
808 FASTBOOL bSInch=IsInch(eS);
809 FASTBOOL bDInch=IsInch(eD);
810 FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
811 if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
812 if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
813 return aRet;
814 };
815
GetMapFactor(MapUnit eS,FieldUnit eD)816 FrPair GetMapFactor(MapUnit eS, FieldUnit eD)
817 {
818 FrPair aS(GetInchOrMM(eS));
819 FrPair aD(GetInchOrMM(eD));
820 FASTBOOL bSInch=IsInch(eS);
821 FASTBOOL bDInch=IsInch(eD);
822 FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
823 if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
824 if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
825 return aRet;
826 };
827
GetMapFactor(FieldUnit eS,MapUnit eD)828 FrPair GetMapFactor(FieldUnit eS, MapUnit eD)
829 {
830 FrPair aS(GetInchOrMM(eS));
831 FrPair aD(GetInchOrMM(eD));
832 FASTBOOL bSInch=IsInch(eS);
833 FASTBOOL bDInch=IsInch(eD);
834 FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
835 if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
836 if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
837 return aRet;
838 };
839
GetMapFactor(FieldUnit eS,FieldUnit eD)840 FrPair GetMapFactor(FieldUnit eS, FieldUnit eD)
841 {
842 if (eS==eD) return FrPair(1,1,1,1);
843 FrPair aS(GetInchOrMM(eS));
844 FrPair aD(GetInchOrMM(eD));
845 FASTBOOL bSInch=IsInch(eS);
846 FASTBOOL bDInch=IsInch(eD);
847 FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
848 if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
849 if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
850 return aRet;
851 };
852
853 ////////////////////////////////////////////////////////////////////////////////////////////////////
854
855 // 1 mile = 8 furlong = 63.360" = 1.609.344,0mm
856 // 1 furlong = 10 chains = 7.920" = 201.168,0mm
857 // 1 chain = 4 poles = 792" = 20.116,8mm
858 // 1 pole = 5 1/2 yd = 198" = 5.029,2mm
859 // 1 yd = 3 ft = 36" = 914,4mm
860 // 1 ft = 12 " = 1" = 304,8mm
861
GetMeterOrInch(MapUnit eMU,short & rnKomma,long & rnMul,long & rnDiv,int & rbMetr,int & rbInch)862 void GetMeterOrInch(MapUnit eMU, short& rnKomma, long& rnMul, long& rnDiv, int& rbMetr, int& rbInch)
863 {
864 rnMul=1; rnDiv=1;
865 short nKomma=0;
866 FASTBOOL bMetr=sal_False,bInch=sal_False;
867 switch (eMU) {
868 // Metrisch
869 case MAP_100TH_MM : bMetr=sal_True; nKomma=5; break;
870 case MAP_10TH_MM : bMetr=sal_True; nKomma=4; break;
871 case MAP_MM : bMetr=sal_True; nKomma=3; break;
872 case MAP_CM : bMetr=sal_True; nKomma=2; break;
873 // Inch
874 case MAP_1000TH_INCH: bInch=sal_True; nKomma=3; break;
875 case MAP_100TH_INCH : bInch=sal_True; nKomma=2; break;
876 case MAP_10TH_INCH : bInch=sal_True; nKomma=1; break;
877 case MAP_INCH : bInch=sal_True; nKomma=0; break;
878 case MAP_POINT : bInch=sal_True; rnDiv=72; break; // 1Pt = 1/72"
879 case MAP_TWIP : bInch=sal_True; rnDiv=144; nKomma=1; break; // 1Twip = 1/1440"
880 // Sonstiges
881 case MAP_PIXEL : break;
882 case MAP_SYSFONT : break;
883 case MAP_APPFONT : break;
884 case MAP_RELATIVE : break;
885 default: break;
886 } // switch
887 rnKomma=nKomma;
888 rbMetr=bMetr;
889 rbInch=bInch;
890 }
891
GetMeterOrInch(FieldUnit eFU,short & rnKomma,long & rnMul,long & rnDiv,int & rbMetr,int & rbInch)892 void GetMeterOrInch(FieldUnit eFU, short& rnKomma, long& rnMul, long& rnDiv, int& rbMetr, int& rbInch)
893 {
894 rnMul=1; rnDiv=1;
895 short nKomma=0;
896 FASTBOOL bMetr=sal_False,bInch=sal_False;
897 switch (eFU) {
898 case FUNIT_NONE : break;
899 // Metrisch
900 case FUNIT_100TH_MM : bMetr=sal_True; nKomma=5; break;
901 case FUNIT_MM : bMetr=sal_True; nKomma=3; break;
902 case FUNIT_CM : bMetr=sal_True; nKomma=2; break;
903 case FUNIT_M : bMetr=sal_True; nKomma=0; break;
904 case FUNIT_KM : bMetr=sal_True; nKomma=-3; break;
905 // Inch
906 case FUNIT_TWIP : bInch=sal_True; rnDiv=144; nKomma=1; break; // 1Twip = 1/1440"
907 case FUNIT_POINT : bInch=sal_True; rnDiv=72; break; // 1Pt = 1/72"
908 case FUNIT_PICA : bInch=sal_True; rnDiv=6; break; // 1Pica = 1/6" ?
909 case FUNIT_INCH : bInch=sal_True; break; // 1" = 1"
910 case FUNIT_FOOT : bInch=sal_True; rnMul=12; break; // 1Ft = 12"
911 case FUNIT_MILE : bInch=sal_True; rnMul=6336; nKomma=-1; break; // 1mile = 63360"
912 // sonstiges
913 case FUNIT_CUSTOM : break;
914 case FUNIT_PERCENT : nKomma=2; break;
915 } // switch
916 rnKomma=nKomma;
917 rbMetr=bMetr;
918 rbInch=bInch;
919 }
920
Undirty()921 void SdrFormatter::Undirty()
922 {
923 if (aScale.GetNumerator()==0 || aScale.GetDenominator()==0) aScale=Fraction(1,1);
924 FASTBOOL bSrcMetr,bSrcInch,bDstMetr,bDstInch;
925 long nMul1,nDiv1,nMul2,nDiv2;
926 short nKomma1,nKomma2;
927 // Zunaechst normalisieren auf m bzw. "
928 if (!bSrcFU) {
929 GetMeterOrInch(eSrcMU,nKomma1,nMul1,nDiv1,bSrcMetr,bSrcInch);
930 } else {
931 GetMeterOrInch(eSrcFU,nKomma1,nMul1,nDiv1,bSrcMetr,bSrcInch);
932 }
933 if (!bDstFU) {
934 GetMeterOrInch(eDstMU,nKomma2,nMul2,nDiv2,bDstMetr,bDstInch);
935 } else {
936 GetMeterOrInch(eDstFU,nKomma2,nMul2,nDiv2,bDstMetr,bDstInch);
937 }
938 nMul1*=nDiv2;
939 nDiv1*=nMul2;
940 nKomma1=nKomma1-nKomma2;
941
942 if (bSrcInch && bDstMetr) {
943 nKomma1+=4;
944 nMul1*=254;
945 }
946 if (bSrcMetr && bDstInch) {
947 nKomma1-=4;
948 nDiv1*=254;
949 }
950
951 // Temporaere Fraction zum Kuerzen
952 Fraction aTempFract(nMul1,nDiv1);
953 nMul1=aTempFract.GetNumerator();
954 nDiv1=aTempFract.GetDenominator();
955
956 nMul_=nMul1;
957 nDiv_=nDiv1;
958 nKomma_=nKomma1;
959 bDirty=sal_False;
960 }
961
962
TakeStr(long nVal,XubString & rStr) const963 void SdrFormatter::TakeStr(long nVal, XubString& rStr) const
964 {
965 sal_Unicode aNullCode('0');
966
967 if(!nVal)
968 {
969 rStr = UniString();
970 rStr += aNullCode;
971 return;
972 }
973
974 // Hier fallen trotzdem evtl. Nachkommastellen weg, wg. MulDiv statt Real
975 sal_Bool bNeg(nVal < 0);
976 SvtSysLocale aSysLoc;
977 const LocaleDataWrapper& rLoc = aSysLoc.GetLocaleData();
978
979 ForceUndirty();
980
981 sal_Int16 nK(nKomma_);
982 XubString aStr;
983
984 if(bNeg)
985 nVal = -nVal;
986
987 while(nK <= -3)
988 {
989 nVal *= 1000;
990 nK += 3;
991 }
992
993 while(nK <= -1)
994 {
995 nVal *= 10;
996 nK++;
997 }
998
999 if(nMul_ != nDiv_)
1000 nVal = BigMulDiv(nVal, nMul_, nDiv_);
1001
1002 aStr = UniString::CreateFromInt32(nVal);
1003
1004 if(nK > 0 && aStr.Len() <= nK )
1005 {
1006 // Komma erforderlich
1007 sal_Int16 nAnz(nK - aStr.Len());
1008
1009 if(nAnz >= 0 && rLoc.isNumLeadingZero())
1010 nAnz++;
1011
1012 for(xub_StrLen i=0; i<nAnz; i++)
1013 aStr.Insert(aNullCode, 0);
1014
1015 // zuviele Nachkommastellen abhacken
1016 xub_StrLen nNumDigits(rLoc.getNumDigits());
1017 xub_StrLen nWeg(nK - nNumDigits);
1018
1019 if(nWeg > 0)
1020 {
1021 // hier muesste eigentlich noch gerundet werden!
1022 aStr.Erase(aStr.Len() - nWeg);
1023 nK = nNumDigits;
1024 }
1025 }
1026
1027 // Vorkommastellen fuer spaeter merken
1028 xub_StrLen nVorKomma(aStr.Len() - nK);
1029
1030 if(nK > 0)
1031 {
1032 // KommaChar einfuegen
1033 // erstmal trailing Zeros abhacken
1034 while(nK > 0 && aStr.GetChar(aStr.Len() - 1) == aNullCode)
1035 {
1036 aStr.Erase(aStr.Len() - 1);
1037 nK--;
1038 }
1039
1040 if(nK > 0)
1041 {
1042 // na, noch Nachkommastellen da?
1043 sal_Unicode cDec(rLoc.getNumDecimalSep().GetChar(0));
1044 aStr.Insert(cDec, nVorKomma);
1045 }
1046 }
1047
1048 // ggf. Trennpunkte bei jedem Tausender einfuegen
1049 if( nVorKomma > 3 )
1050 {
1051 String aThoSep( rLoc.getNumThousandSep() );
1052 if ( aThoSep.Len() > 0 )
1053 {
1054 sal_Unicode cTho( aThoSep.GetChar(0) );
1055 sal_Int32 i(nVorKomma - 3);
1056
1057 while(i > 0)
1058 {
1059 rStr.Insert(cTho, (xub_StrLen)i);
1060 i -= 3;
1061 }
1062 }
1063 }
1064
1065 if(!aStr.Len())
1066 aStr += aNullCode;
1067
1068 if(bNeg && (aStr.Len() > 1 || aStr.GetChar(0) != aNullCode))
1069 {
1070 rStr.Insert(sal_Unicode('-'), 0);
1071 }
1072
1073 rStr = aStr;
1074 }
1075
TakeUnitStr(MapUnit eUnit,XubString & rStr)1076 void SdrFormatter::TakeUnitStr(MapUnit eUnit, XubString& rStr)
1077 {
1078 const sal_Char* pText;
1079
1080 switch(eUnit)
1081 {
1082 // metric units
1083 case MAP_100TH_MM : pText = "/100mm"; break;
1084 case MAP_10TH_MM : pText = "/10mm"; break;
1085 case MAP_MM : pText = "mm"; break;
1086 case MAP_CM : pText = "cm"; break;
1087
1088 // imperial units
1089 case MAP_1000TH_INCH: pText = "/1000\""; break;
1090 case MAP_100TH_INCH : pText = "/100\""; break;
1091 case MAP_10TH_INCH : pText = "/10\""; break;
1092 case MAP_INCH : pText = "\""; break;
1093 case MAP_POINT : pText = "pt"; break;
1094 case MAP_TWIP : pText = "twip"; break;
1095
1096 // other units
1097 case MAP_PIXEL : pText = "pixel"; break;
1098 case MAP_SYSFONT : pText = "sysfont"; break;
1099 case MAP_APPFONT : pText = "appfont"; break;
1100 case MAP_RELATIVE : pText = "%"; break;
1101
1102 default : pText = ""; break;
1103 }
1104
1105 rStr = XubString::CreateFromAscii( pText );
1106 }
1107
TakeUnitStr(FieldUnit eUnit,XubString & rStr)1108 void SdrFormatter::TakeUnitStr(FieldUnit eUnit, XubString& rStr)
1109 {
1110 const sal_Char* pText;
1111
1112 switch(eUnit)
1113 {
1114 // metric units
1115 case FUNIT_100TH_MM : pText = "/100mm"; break;
1116 case FUNIT_MM : pText = "mm"; break;
1117 case FUNIT_CM : pText = "cm"; break;
1118 case FUNIT_M : pText = "m"; break;
1119 case FUNIT_KM : pText = "km"; break;
1120
1121 // imperial units
1122 case FUNIT_TWIP : pText = "twip"; break;
1123 case FUNIT_POINT : pText = "pt"; break;
1124 case FUNIT_PICA : pText = "pica"; break;
1125 case FUNIT_INCH : pText = "\""; break;
1126 case FUNIT_FOOT : pText = "ft"; break;
1127 case FUNIT_MILE : pText = "mile(s)"; break;
1128
1129 // other units
1130 case FUNIT_PERCENT: pText = "%"; break;
1131
1132 // case FUNIT_NONE :
1133 // case FUNIT_CUSTOM :
1134 default : pText = ""; break;
1135 }
1136
1137 rStr = XubString::CreateFromAscii( pText );
1138 }
1139
1140 ////////////////////////////////////////////////////////////////////////////////////////////////////
1141
1142
1143