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_chart2.hxx" 26 #include "CommonConverters.hxx" 27 #include <com/sun/star/drawing/DoubleSequence.hpp> 28 #include <com/sun/star/text/WritingMode2.hpp> 29 #include <com/sun/star/chart2/data/XNumericalDataSequence.hpp> 30 #include <com/sun/star/chart2/data/XTextualDataSequence.hpp> 31 #include <rtl/math.hxx> 32 #include <basegfx/matrix/b3dhommatrix.hxx> 33 34 #include <cstdarg> 35 36 37 //............................................................................. 38 namespace chart 39 { 40 //............................................................................. 41 42 using namespace ::com::sun::star; 43 44 //----------------------------------------------------------------------------- 45 //----------------------------------------------------------------------------- 46 // diverse methods for class conversions; e.g. ::basegfx::B3DHomMatrix to HomogenMatrix 47 //----------------------------------------------------------------------------- 48 //----------------------------------------------------------------------------- 49 50 drawing::HomogenMatrix B3DHomMatrixToHomogenMatrix( const ::basegfx::B3DHomMatrix& rM ) 51 { 52 drawing::HomogenMatrix aHM; 53 aHM.Line1.Column1 = rM.get(0, 0); 54 aHM.Line1.Column2 = rM.get(0, 1); 55 aHM.Line1.Column3 = rM.get(0, 2); 56 aHM.Line1.Column4 = rM.get(0, 3); 57 aHM.Line2.Column1 = rM.get(1, 0); 58 aHM.Line2.Column2 = rM.get(1, 1); 59 aHM.Line2.Column3 = rM.get(1, 2); 60 aHM.Line2.Column4 = rM.get(1, 3); 61 aHM.Line3.Column1 = rM.get(2, 0); 62 aHM.Line3.Column2 = rM.get(2, 1); 63 aHM.Line3.Column3 = rM.get(2, 2); 64 aHM.Line3.Column4 = rM.get(2, 3); 65 aHM.Line4.Column1 = rM.get(3, 0); 66 aHM.Line4.Column2 = rM.get(3, 1); 67 aHM.Line4.Column3 = rM.get(3, 2); 68 aHM.Line4.Column4 = rM.get(3, 3); 69 return aHM; 70 } 71 72 ::basegfx::B3DHomMatrix HomogenMatrixToB3DHomMatrix( const drawing::HomogenMatrix& rHM ) 73 { 74 ::basegfx::B3DHomMatrix aM; 75 aM.set(0, 0, rHM.Line1.Column1); 76 aM.set(0, 1, rHM.Line1.Column2); 77 aM.set(0, 2, rHM.Line1.Column3); 78 aM.set(0, 3, rHM.Line1.Column4); 79 aM.set(1, 0, rHM.Line2.Column1); 80 aM.set(1, 1, rHM.Line2.Column2); 81 aM.set(1, 2, rHM.Line2.Column3); 82 aM.set(1, 3, rHM.Line2.Column4); 83 aM.set(2, 0, rHM.Line3.Column1); 84 aM.set(2, 1, rHM.Line3.Column2); 85 aM.set(2, 2, rHM.Line3.Column3); 86 aM.set(2, 3, rHM.Line3.Column4); 87 aM.set(3, 0, rHM.Line4.Column1); 88 aM.set(3, 1, rHM.Line4.Column2); 89 aM.set(3, 2, rHM.Line4.Column3); 90 aM.set(3, 3, rHM.Line4.Column4); 91 return aM; 92 } 93 94 ::basegfx::B2DHomMatrix IgnoreZ( const ::basegfx::B3DHomMatrix& rM ) 95 { 96 ::basegfx::B2DHomMatrix aM; 97 aM.set(0, 0, rM.get(0, 0)); 98 aM.set(0, 1, rM.get(0, 1)); 99 aM.set(0, 2, rM.get(0, 3)); 100 aM.set(1, 0, rM.get(1, 0)); 101 aM.set(1, 1, rM.get(1, 1)); 102 aM.set(1, 2, rM.get(1, 3)); 103 aM.set(2, 0, rM.get(3, 0)); 104 aM.set(2, 1, rM.get(3, 1)); 105 aM.set(2, 2, rM.get(3, 3)); 106 return aM; 107 } 108 109 110 drawing::HomogenMatrix3 B2DHomMatrixToHomogenMatrix3( const ::basegfx::B2DHomMatrix& rM ) 111 { 112 drawing::HomogenMatrix3 aHM; 113 aHM.Line1.Column1 = rM.get(0, 0); 114 aHM.Line1.Column2 = rM.get(0, 1); 115 aHM.Line1.Column3 = rM.get(0, 2); 116 aHM.Line2.Column1 = rM.get(1, 0); 117 aHM.Line2.Column2 = rM.get(1, 1); 118 aHM.Line2.Column3 = rM.get(1, 2); 119 aHM.Line3.Column1 = rM.get(2, 0); 120 aHM.Line3.Column2 = rM.get(2, 1); 121 aHM.Line3.Column3 = rM.get(2, 2); 122 return aHM; 123 } 124 125 ::basegfx::B3DPoint Position3DToB3DPoint( const drawing::Position3D& rPosition ) 126 { 127 return ::basegfx::B3DPoint( 128 rPosition.PositionX , 129 rPosition.PositionY , 130 rPosition.PositionZ ); 131 } 132 133 drawing::Direction3D B3DVectorToDirection3D( const ::basegfx::B3DVector& rVector) 134 { 135 return drawing::Direction3D( 136 rVector.getX() 137 , rVector.getY() 138 , rVector.getZ() 139 ); 140 } 141 142 drawing::Position3D B3DPointToPosition3D( const ::basegfx::B3DPoint& rPoint) 143 { 144 return drawing::Position3D( 145 rPoint.getX() 146 , rPoint.getY() 147 , rPoint.getZ() 148 ); 149 } 150 151 ::basegfx::B3DVector Direction3DToB3DVector( const drawing::Direction3D& rDirection) 152 { 153 return ::basegfx::B3DVector( 154 rDirection.DirectionX 155 , rDirection.DirectionY 156 , rDirection.DirectionZ 157 ); 158 } 159 160 void AddPointToPoly( drawing::PolyPolygonShape3D& rPoly, const drawing::Position3D& rPos, sal_Int32 nPolygonIndex ) 161 { 162 if(nPolygonIndex<0) 163 { 164 OSL_ENSURE( false, "The polygon index needs to be > 0"); 165 nPolygonIndex=0; 166 } 167 168 //make sure that we have enough polygons 169 if(nPolygonIndex >= rPoly.SequenceX.getLength() ) 170 { 171 rPoly.SequenceX.realloc(nPolygonIndex+1); 172 rPoly.SequenceY.realloc(nPolygonIndex+1); 173 rPoly.SequenceZ.realloc(nPolygonIndex+1); 174 } 175 176 drawing::DoubleSequence* pOuterSequenceX = &rPoly.SequenceX.getArray()[nPolygonIndex]; 177 drawing::DoubleSequence* pOuterSequenceY = &rPoly.SequenceY.getArray()[nPolygonIndex]; 178 drawing::DoubleSequence* pOuterSequenceZ = &rPoly.SequenceZ.getArray()[nPolygonIndex]; 179 180 sal_Int32 nOldPointCount = pOuterSequenceX->getLength(); 181 182 pOuterSequenceX->realloc(nOldPointCount+1); 183 pOuterSequenceY->realloc(nOldPointCount+1); 184 pOuterSequenceZ->realloc(nOldPointCount+1); 185 186 double* pInnerSequenceX = pOuterSequenceX->getArray(); 187 double* pInnerSequenceY = pOuterSequenceY->getArray(); 188 double* pInnerSequenceZ = pOuterSequenceZ->getArray(); 189 190 pInnerSequenceX[nOldPointCount] = rPos.PositionX; 191 pInnerSequenceY[nOldPointCount] = rPos.PositionY; 192 pInnerSequenceZ[nOldPointCount] = rPos.PositionZ; 193 } 194 195 drawing::Position3D getPointFromPoly( const drawing::PolyPolygonShape3D& rPolygon, sal_Int32 nPointIndex, sal_Int32 nPolyIndex ) 196 { 197 drawing::Position3D aRet(0.0,0.0,0.0); 198 199 if( nPolyIndex>=0 && nPolyIndex<rPolygon.SequenceX.getLength()) 200 { 201 if(nPointIndex<rPolygon.SequenceX[nPolyIndex].getLength()) 202 { 203 aRet.PositionX = rPolygon.SequenceX[nPolyIndex][nPointIndex]; 204 aRet.PositionY = rPolygon.SequenceY[nPolyIndex][nPointIndex]; 205 aRet.PositionZ = rPolygon.SequenceZ[nPolyIndex][nPointIndex]; 206 } 207 else 208 { 209 ;DBG_ERROR("polygon was accessed with a wrong index"); 210 } 211 } 212 else 213 { 214 ;DBG_ERROR("polygon was accessed with a wrong index"); 215 } 216 return aRet; 217 } 218 219 void addPolygon( drawing::PolyPolygonShape3D& rRet, const drawing::PolyPolygonShape3D& rAdd ) 220 { 221 sal_Int32 nAddOuterCount = rAdd.SequenceX.getLength(); 222 sal_Int32 nOuterCount = rRet.SequenceX.getLength() + nAddOuterCount; 223 rRet.SequenceX.realloc( nOuterCount ); 224 rRet.SequenceY.realloc( nOuterCount ); 225 rRet.SequenceZ.realloc( nOuterCount ); 226 227 sal_Int32 nIndex = 0; 228 sal_Int32 nOuter = nOuterCount - nAddOuterCount; 229 for( ; nOuter < nOuterCount; nOuter++ ) 230 { 231 if( nIndex >= nAddOuterCount ) 232 break; 233 234 rRet.SequenceX[nOuter] = rAdd.SequenceX[nIndex]; 235 rRet.SequenceY[nOuter] = rAdd.SequenceY[nIndex]; 236 rRet.SequenceZ[nOuter] = rAdd.SequenceZ[nIndex]; 237 238 nIndex++; 239 } 240 } 241 242 void appendPoly( drawing::PolyPolygonShape3D& rRet, const drawing::PolyPolygonShape3D& rAdd ) 243 { 244 sal_Int32 nOuterCount = Max( rRet.SequenceX.getLength(), rAdd.SequenceX.getLength() ); 245 rRet.SequenceX.realloc(nOuterCount); 246 rRet.SequenceY.realloc(nOuterCount); 247 rRet.SequenceZ.realloc(nOuterCount); 248 249 for( sal_Int32 nOuter=0;nOuter<nOuterCount;nOuter++ ) 250 { 251 sal_Int32 nOldPointCount = rRet.SequenceX[nOuter].getLength(); 252 sal_Int32 nAddPointCount = 0; 253 if(nOuter<rAdd.SequenceX.getLength()) 254 nAddPointCount = rAdd.SequenceX[nOuter].getLength(); 255 if(!nAddPointCount) 256 continue; 257 258 sal_Int32 nNewPointCount = nOldPointCount + nAddPointCount; 259 260 rRet.SequenceX[nOuter].realloc(nNewPointCount); 261 rRet.SequenceY[nOuter].realloc(nNewPointCount); 262 rRet.SequenceZ[nOuter].realloc(nNewPointCount); 263 264 sal_Int32 nPointTarget=nOldPointCount; 265 sal_Int32 nPointSource=nAddPointCount; 266 for( ; nPointSource-- ; nPointTarget++ ) 267 { 268 rRet.SequenceX[nOuter][nPointTarget] = rAdd.SequenceX[nOuter][nPointSource]; 269 rRet.SequenceY[nOuter][nPointTarget] = rAdd.SequenceY[nOuter][nPointSource]; 270 rRet.SequenceZ[nOuter][nPointTarget] = rAdd.SequenceZ[nOuter][nPointSource]; 271 } 272 } 273 } 274 275 drawing::PolyPolygonShape3D BezierToPoly( 276 const drawing::PolyPolygonBezierCoords& rBezier ) 277 { 278 const drawing::PointSequenceSequence& rPointSequence = rBezier.Coordinates; 279 // const drawing::FlagSequenceSequence& rFlags = rBezier.Flags; 280 281 drawing::PolyPolygonShape3D aRet; 282 aRet.SequenceX.realloc( rPointSequence.getLength() ); 283 aRet.SequenceY.realloc( rPointSequence.getLength() ); 284 aRet.SequenceZ.realloc( rPointSequence.getLength() ); 285 286 sal_Int32 nRealOuter = 0; 287 for(sal_Int32 nN = 0; nN < rPointSequence.getLength(); nN++) 288 { 289 sal_Int32 nInnerLength = rPointSequence[nN].getLength(); 290 aRet.SequenceX[nN].realloc( nInnerLength ); 291 aRet.SequenceY[nN].realloc( nInnerLength ); 292 aRet.SequenceZ[nN].realloc( nInnerLength ); 293 294 bool bHasOuterFlags = nN < rBezier.Flags.getLength(); 295 296 sal_Int32 nRealInner = 0; 297 for( sal_Int32 nM = 0; nM < nInnerLength; nM++) 298 { 299 bool bHasInnerFlags = bHasOuterFlags && (nM < rBezier.Flags[nN].getLength()); 300 301 if( !bHasInnerFlags || (rBezier.Flags[nN][nM] == drawing::PolygonFlags_NORMAL) ) 302 { 303 aRet.SequenceX[nRealOuter][nRealInner] = rPointSequence[nN][nM].X; 304 aRet.SequenceY[nRealOuter][nRealInner] = rPointSequence[nN][nM].Y; 305 aRet.SequenceZ[nRealOuter][nRealInner] = 0.0; 306 nRealInner++; 307 } 308 } 309 310 aRet.SequenceX[nRealOuter].realloc( nRealInner ); 311 aRet.SequenceY[nRealOuter].realloc( nRealInner ); 312 aRet.SequenceZ[nRealOuter].realloc( nRealInner ); 313 314 if( nRealInner>0 ) 315 nRealOuter++; 316 } 317 318 aRet.SequenceX.realloc( nRealOuter ); 319 aRet.SequenceY.realloc( nRealOuter ); 320 aRet.SequenceZ.realloc( nRealOuter ); 321 322 return aRet; 323 } 324 325 drawing::PointSequenceSequence PolyToPointSequence( 326 const drawing::PolyPolygonShape3D& rPolyPolygon ) 327 { 328 drawing::PointSequenceSequence aRet; 329 aRet.realloc( rPolyPolygon.SequenceX.getLength() ); 330 331 for(sal_Int32 nN = 0; nN < rPolyPolygon.SequenceX.getLength(); nN++) 332 { 333 sal_Int32 nInnerLength = rPolyPolygon.SequenceX[nN].getLength(); 334 aRet[nN].realloc( nInnerLength ); 335 for( sal_Int32 nM = 0; nM < nInnerLength; nM++) 336 { 337 aRet[nN][nM].X = static_cast<sal_Int32>(rPolyPolygon.SequenceX[nN][nM]); 338 aRet[nN][nM].Y = static_cast<sal_Int32>(rPolyPolygon.SequenceY[nN][nM]); 339 } 340 } 341 return aRet; 342 } 343 344 void appendPointSequence( drawing::PointSequenceSequence& rTarget 345 , drawing::PointSequenceSequence& rAdd ) 346 { 347 sal_Int32 nAddCount = rAdd.getLength(); 348 if(!nAddCount) 349 return; 350 sal_Int32 nOldCount = rTarget.getLength(); 351 352 rTarget.realloc(nOldCount+nAddCount); 353 for(sal_Int32 nS=0; nS<nAddCount; nS++ ) 354 rTarget[nOldCount+nS]=rAdd[nS]; 355 } 356 357 drawing::Position3D operator+( const drawing::Position3D& rPos 358 , const drawing::Direction3D& rDirection) 359 { 360 return drawing::Position3D( 361 rPos.PositionX + rDirection.DirectionX 362 , rPos.PositionY + rDirection.DirectionY 363 , rPos.PositionZ + rDirection.DirectionZ 364 ); 365 } 366 367 drawing::Direction3D operator-( const drawing::Position3D& rPos1 368 , const drawing::Position3D& rPos2) 369 { 370 return drawing::Direction3D( 371 rPos1.PositionX - rPos2.PositionX 372 , rPos1.PositionY - rPos2.PositionY 373 , rPos1.PositionZ - rPos2.PositionZ 374 ); 375 } 376 377 bool operator==( const drawing::Position3D& rPos1 378 , const drawing::Position3D& rPos2) 379 { 380 return rPos1.PositionX == rPos2.PositionX 381 && rPos1.PositionY == rPos2.PositionY 382 && rPos1.PositionZ == rPos2.PositionZ; 383 } 384 385 awt::Point Position3DToAWTPoint( const drawing::Position3D& rPos ) 386 { 387 awt::Point aRet; 388 aRet.X = static_cast<sal_Int32>(rPos.PositionX); 389 aRet.Y = static_cast<sal_Int32>(rPos.PositionY); 390 return aRet; 391 } 392 393 awt::Point ToPoint( const awt::Rectangle& rRectangle ) 394 { 395 return awt::Point( rRectangle.X, rRectangle.Y ); 396 } 397 398 awt::Size ToSize( const awt::Rectangle& rRectangle ) 399 { 400 return awt::Size( rRectangle.Width, rRectangle.Height ); 401 } 402 403 awt::Size Direction3DToAWTSize( const drawing::Direction3D& rDirection ) 404 { 405 awt::Size aRet; 406 aRet.Width = static_cast<sal_Int32>(rDirection.DirectionX); 407 aRet.Height = static_cast<sal_Int32>(rDirection.DirectionY); 408 return aRet; 409 } 410 411 uno::Sequence< double > B3DPointToSequence( const ::basegfx::B3DPoint& rPoint ) 412 { 413 uno::Sequence< double > aRet(3); 414 aRet[0] = rPoint.getX(); 415 aRet[1] = rPoint.getY(); 416 aRet[2] = rPoint.getZ(); 417 return aRet; 418 } 419 420 drawing::Position3D SequenceToPosition3D( const uno::Sequence< double >& rSeq ) 421 { 422 OSL_ENSURE(rSeq.getLength()==3,"The sequence needs to have length 3 for conversion into vector"); 423 424 drawing::Position3D aRet; 425 aRet.PositionX = rSeq.getLength()>0?rSeq[0]:0.0; 426 aRet.PositionY = rSeq.getLength()>1?rSeq[1]:0.0; 427 aRet.PositionZ = rSeq.getLength()>2?rSeq[2]:0.0; 428 return aRet; 429 } 430 431 uno::Sequence< double > Position3DToSequence( const drawing::Position3D& rPosition ) 432 { 433 uno::Sequence< double > aRet(3); 434 aRet[0] = rPosition.PositionX; 435 aRet[1] = rPosition.PositionY; 436 aRet[2] = rPosition.PositionZ; 437 return aRet; 438 } 439 440 using namespace ::com::sun::star::chart2; 441 442 uno::Sequence< double > DataSequenceToDoubleSequence( 443 const uno::Reference< data::XDataSequence >& xDataSequence ) 444 { 445 uno::Sequence< double > aResult; 446 OSL_ASSERT( xDataSequence.is()); 447 if(!xDataSequence.is()) 448 return aResult; 449 450 uno::Reference< data::XNumericalDataSequence > xNumericalDataSequence( xDataSequence, uno::UNO_QUERY ); 451 if( xNumericalDataSequence.is() ) 452 { 453 aResult = xNumericalDataSequence->getNumericalData(); 454 } 455 else 456 { 457 uno::Sequence< uno::Any > aValues = xDataSequence->getData(); 458 aResult.realloc(aValues.getLength()); 459 for(sal_Int32 nN=aValues.getLength();nN--;) 460 { 461 if( !(aValues[nN] >>= aResult[nN]) ) 462 ::rtl::math::setNan( &aResult[nN] ); 463 } 464 } 465 466 return aResult; 467 } 468 469 uno::Sequence< rtl::OUString > DataSequenceToStringSequence( 470 const uno::Reference< data::XDataSequence >& xDataSequence ) 471 { 472 uno::Sequence< rtl::OUString > aResult; 473 if(!xDataSequence.is()) 474 return aResult; 475 476 uno::Reference< data::XTextualDataSequence > xTextualDataSequence( xDataSequence, uno::UNO_QUERY ); 477 if( xTextualDataSequence.is() ) 478 { 479 aResult = xTextualDataSequence->getTextualData(); 480 } 481 else 482 { 483 uno::Sequence< uno::Any > aValues = xDataSequence->getData(); 484 aResult.realloc(aValues.getLength()); 485 486 for(sal_Int32 nN=aValues.getLength();nN--;) 487 aValues[nN] >>= aResult[nN]; 488 } 489 490 return aResult; 491 } 492 493 sal_Bool hasDoubleValue( const uno::Any& rAny ) 494 { 495 sal_Bool bRet = sal_False; 496 double fValue = 0.0; 497 if( rAny >>= fValue ) 498 bRet = sal_True; 499 return bRet; 500 } 501 502 sal_Bool hasLongOrShortValue( const uno::Any& rAny ) 503 { 504 sal_Bool bRet = sal_False; 505 sal_Int32 n32 = 0; 506 if( rAny >>= n32 ) 507 bRet = sal_True; 508 else 509 { 510 sal_Int16 n16 = 0; 511 if( rAny >>= n16 ) 512 bRet = sal_True; 513 } 514 return bRet; 515 } 516 sal_Int16 getShortForLongAlso( const uno::Any& rAny ) 517 { 518 sal_Int16 nRet = 0; 519 520 if( !(rAny >>= nRet) ) 521 { 522 sal_Int32 n32 = 0; 523 if( rAny >>= n32 ) 524 nRet = static_cast<sal_Int16>(n32); 525 } 526 return nRet; 527 } 528 529 bool replaceParamterInString( rtl::OUString & rInOutResourceString, 530 const rtl::OUString & rParamToReplace, 531 const rtl::OUString & rReplaceWith ) 532 { 533 sal_Int32 nPos = rInOutResourceString.indexOf( rParamToReplace ); 534 if( nPos == -1 ) 535 return false; 536 537 rInOutResourceString = rInOutResourceString.replaceAt( nPos 538 , rParamToReplace.getLength(), rReplaceWith ); 539 return true; 540 } 541 542 //............................................................................. 543 } //namespace chart 544 //............................................................................. 545