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 #include "precompiled_svx.hxx" 25 #include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx> 26 #include <svx/svdotext.hxx> 27 #include <basegfx/color/bcolor.hxx> 28 #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> 29 #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> 30 #include <editeng/outlobj.hxx> 31 #include <editeng/editobj.hxx> 32 #include <editeng/flditem.hxx> 33 #include <drawinglayer/geometry/viewinformation2d.hxx> 34 #include <svx/unoapi.hxx> 35 #include <svx/svdpage.hxx> 36 #include <svx/svdmodel.hxx> 37 #include <svx/svdoutl.hxx> 38 #include <com/sun/star/beans/XPropertySet.hpp> 39 40 ////////////////////////////////////////////////////////////////////////////// 41 42 using namespace com::sun::star; 43 44 ////////////////////////////////////////////////////////////////////////////// 45 46 namespace 47 { getPageNumber(const uno::Reference<drawing::XDrawPage> & rxDrawPage)48 sal_Int16 getPageNumber(const uno::Reference< drawing::XDrawPage >& rxDrawPage) 49 { 50 sal_Int16 nRetval(0); 51 uno::Reference< beans::XPropertySet > xSet(rxDrawPage, uno::UNO_QUERY); 52 53 if (xSet.is()) 54 { 55 try 56 { 57 const uno::Any aNumber(xSet->getPropertyValue(::rtl::OUString::createFromAscii("Number"))); 58 aNumber >>= nRetval; 59 } 60 catch(const uno::Exception&) 61 { 62 OSL_ASSERT(false); 63 } 64 } 65 66 return nRetval; 67 } 68 getPageCount(const uno::Reference<drawing::XDrawPage> & rxDrawPage)69 sal_Int16 getPageCount(const uno::Reference< drawing::XDrawPage >& rxDrawPage) 70 { 71 sal_Int16 nRetval(0); 72 SdrPage* pPage = GetSdrPageFromXDrawPage(rxDrawPage); 73 74 if(pPage && pPage->GetModel()) 75 { 76 if( (pPage->GetPageNum() == 0) && !pPage->IsMasterPage() ) 77 { 78 // handout page! 79 return pPage->GetModel()->getHandoutPageCount(); 80 } 81 else 82 { 83 const sal_uInt16 nPageCount(pPage->GetModel()->GetPageCount()); 84 nRetval = ((sal_Int16)nPageCount - 1) / 2; 85 } 86 } 87 88 return nRetval; 89 } 90 } // end of anonymous namespace 91 92 ////////////////////////////////////////////////////////////////////////////// 93 94 namespace drawinglayer 95 { 96 namespace primitive2d 97 { 98 // support for XTEXT_PAINTSHAPE_BEGIN/XTEXT_PAINTSHAPE_END Metafile comments 99 // for slideshow. This uses TextHierarchyBlockPrimitive2D to mark a text block. 100 // ATM there is only one text block per SdrObject, this may get more in the future encapsulateWithTextHierarchyBlockPrimitive2D(const Primitive2DSequence & rCandidate) const101 Primitive2DSequence SdrTextPrimitive2D::encapsulateWithTextHierarchyBlockPrimitive2D(const Primitive2DSequence& rCandidate) const 102 { 103 Primitive2DReference xReference(new TextHierarchyBlockPrimitive2D(rCandidate)); 104 Primitive2DSequence xRetval(&xReference, 1); 105 106 return xRetval; 107 } 108 SdrTextPrimitive2D(const SdrText * pSdrText,const OutlinerParaObject & rOutlinerParaObject)109 SdrTextPrimitive2D::SdrTextPrimitive2D( 110 const SdrText* pSdrText, 111 const OutlinerParaObject& rOutlinerParaObject) 112 : BufferedDecompositionPrimitive2D(), 113 mrSdrText(const_cast< SdrText* >(pSdrText)), 114 maOutlinerParaObject(rOutlinerParaObject), 115 mxLastVisualizingPage(), 116 mnLastPageNumber(0), 117 mnLastPageCount(0), 118 maLastTextBackgroundColor(), 119 mbContainsPageField(false), 120 mbContainsPageCountField(false), 121 mbContainsOtherFields(false) 122 { 123 const EditTextObject& rETO = maOutlinerParaObject.GetTextObject(); 124 125 mbContainsPageField = rETO.HasField(SvxPageField::StaticType()); 126 mbContainsPageCountField = rETO.HasField(SvxPagesField::StaticType()); 127 mbContainsOtherFields = rETO.HasField(SvxHeaderField::StaticType()) 128 || rETO.HasField(SvxFooterField::StaticType()) 129 || rETO.HasField(SvxDateTimeField::StaticType()) 130 || rETO.HasField(SvxAuthorField::StaticType()); 131 } 132 operator ==(const BasePrimitive2D & rPrimitive) const133 bool SdrTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 134 { 135 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 136 { 137 const SdrTextPrimitive2D& rCompare = (SdrTextPrimitive2D&)rPrimitive; 138 139 return ( 140 141 // compare OPO and content, but not WrongList 142 getOutlinerParaObject() == rCompare.getOutlinerParaObject() 143 144 // also compare WrongList (not-persistent data, but visualized) 145 && getOutlinerParaObject().isWrongListEqual(rCompare.getOutlinerParaObject())); 146 } 147 148 return false; 149 } 150 get2DDecomposition(const geometry::ViewInformation2D & rViewInformation) const151 Primitive2DSequence SdrTextPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 152 { 153 uno::Reference< drawing::XDrawPage > xCurrentlyVisualizingPage; 154 bool bCurrentlyVisualizingPageIsSet(false); 155 Color aNewTextBackgroundColor; 156 bool bNewTextBackgroundColorIsSet(false); 157 sal_Int16 nCurrentlyValidPageNumber(0); 158 sal_Int16 nCurrentlyValidPageCount(0); 159 160 if(getBuffered2DDecomposition().hasElements()) 161 { 162 bool bDoDelete(false); 163 164 // check visualized page 165 if(mbContainsPageField || mbContainsPageCountField || mbContainsOtherFields) 166 { 167 // get visualized page and remember 168 xCurrentlyVisualizingPage = rViewInformation.getVisualizedPage(); 169 bCurrentlyVisualizingPageIsSet = true; 170 171 if(xCurrentlyVisualizingPage != mxLastVisualizingPage) 172 { 173 bDoDelete = true; 174 } 175 176 // #i98870# check visualized PageNumber 177 if(!bDoDelete && mbContainsPageField) 178 { 179 nCurrentlyValidPageNumber = getPageNumber(xCurrentlyVisualizingPage); 180 181 if(nCurrentlyValidPageNumber != mnLastPageNumber) 182 { 183 bDoDelete = true; 184 } 185 } 186 187 // #i98870# check visualized PageCount, too 188 if(!bDoDelete && mbContainsPageCountField) 189 { 190 nCurrentlyValidPageCount = getPageCount(xCurrentlyVisualizingPage); 191 192 if(nCurrentlyValidPageCount != mnLastPageCount) 193 { 194 bDoDelete = true; 195 } 196 } 197 } 198 199 // #i101443# check change of TextBackgroundolor 200 if(!bDoDelete && getSdrText() && getSdrText()->GetModel()) 201 { 202 SdrOutliner& rDrawOutliner = getSdrText()->GetModel()->GetDrawOutliner(0); 203 aNewTextBackgroundColor = rDrawOutliner.GetBackgroundColor(); 204 bNewTextBackgroundColorIsSet = true; 205 206 if(aNewTextBackgroundColor != maLastTextBackgroundColor) 207 { 208 bDoDelete = true; 209 } 210 } 211 212 if(bDoDelete) 213 { 214 const_cast< SdrTextPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); 215 } 216 } 217 218 if(!getBuffered2DDecomposition().hasElements()) 219 { 220 if(!bCurrentlyVisualizingPageIsSet && mbContainsPageField) 221 { 222 xCurrentlyVisualizingPage = rViewInformation.getVisualizedPage(); 223 } 224 225 if(!nCurrentlyValidPageNumber && mbContainsPageField) 226 { 227 nCurrentlyValidPageNumber = getPageNumber(xCurrentlyVisualizingPage); 228 } 229 230 if(!nCurrentlyValidPageCount && mbContainsPageCountField) 231 { 232 nCurrentlyValidPageCount = getPageCount(xCurrentlyVisualizingPage); 233 } 234 235 if(!bNewTextBackgroundColorIsSet && getSdrText() && getSdrText()->GetModel()) 236 { 237 SdrOutliner& rDrawOutliner = getSdrText()->GetModel()->GetDrawOutliner(0); 238 aNewTextBackgroundColor = rDrawOutliner.GetBackgroundColor(); 239 } 240 241 const_cast< SdrTextPrimitive2D* >(this)->mxLastVisualizingPage = xCurrentlyVisualizingPage; 242 const_cast< SdrTextPrimitive2D* >(this)->mnLastPageNumber = nCurrentlyValidPageNumber; 243 const_cast< SdrTextPrimitive2D* >(this)->mnLastPageCount = nCurrentlyValidPageCount; 244 const_cast< SdrTextPrimitive2D* >(this)->maLastTextBackgroundColor = aNewTextBackgroundColor; 245 } 246 247 // call parent 248 return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); 249 } 250 } // end of namespace primitive2d 251 } // end of namespace drawinglayer 252 253 ////////////////////////////////////////////////////////////////////////////// 254 255 namespace drawinglayer 256 { 257 namespace primitive2d 258 { create2DDecomposition(const geometry::ViewInformation2D & aViewInformation) const259 Primitive2DSequence SdrContourTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const 260 { 261 Primitive2DSequence aRetval; 262 getSdrText()->GetObject().impDecomposeContourTextPrimitive(aRetval, *this, aViewInformation); 263 264 return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval); 265 } 266 SdrContourTextPrimitive2D(const SdrText * pSdrText,const OutlinerParaObject & rOutlinerParaObject,const basegfx::B2DPolyPolygon & rUnitPolyPolygon,const basegfx::B2DHomMatrix & rObjectTransform)267 SdrContourTextPrimitive2D::SdrContourTextPrimitive2D( 268 const SdrText* pSdrText, 269 const OutlinerParaObject& rOutlinerParaObject, 270 const basegfx::B2DPolyPolygon& rUnitPolyPolygon, 271 const basegfx::B2DHomMatrix& rObjectTransform) 272 : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), 273 maUnitPolyPolygon(rUnitPolyPolygon), 274 maObjectTransform(rObjectTransform) 275 { 276 } 277 operator ==(const BasePrimitive2D & rPrimitive) const278 bool SdrContourTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 279 { 280 if(SdrTextPrimitive2D::operator==(rPrimitive)) 281 { 282 const SdrContourTextPrimitive2D& rCompare = (SdrContourTextPrimitive2D&)rPrimitive; 283 284 return (getUnitPolyPolygon() == rCompare.getUnitPolyPolygon() 285 && getObjectTransform() == rCompare.getObjectTransform()); 286 } 287 288 return false; 289 } 290 createTransformedClone(const basegfx::B2DHomMatrix & rTransform) const291 SdrTextPrimitive2D* SdrContourTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const 292 { 293 return new SdrContourTextPrimitive2D( 294 getSdrText(), 295 getOutlinerParaObject(), 296 getUnitPolyPolygon(), 297 rTransform * getObjectTransform()); 298 } 299 300 // provide unique ID 301 ImplPrimitrive2DIDBlock(SdrContourTextPrimitive2D, PRIMITIVE2D_ID_SDRCONTOURTEXTPRIMITIVE2D) 302 303 } // end of namespace primitive2d 304 } // end of namespace drawinglayer 305 306 ////////////////////////////////////////////////////////////////////////////// 307 308 namespace drawinglayer 309 { 310 namespace primitive2d 311 { create2DDecomposition(const geometry::ViewInformation2D & aViewInformation) const312 Primitive2DSequence SdrPathTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const 313 { 314 Primitive2DSequence aRetval; 315 getSdrText()->GetObject().impDecomposePathTextPrimitive(aRetval, *this, aViewInformation); 316 317 return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval); 318 } 319 SdrPathTextPrimitive2D(const SdrText * pSdrText,const OutlinerParaObject & rOutlinerParaObject,const basegfx::B2DPolyPolygon & rPathPolyPolygon,const attribute::SdrFormTextAttribute & rSdrFormTextAttribute)320 SdrPathTextPrimitive2D::SdrPathTextPrimitive2D( 321 const SdrText* pSdrText, 322 const OutlinerParaObject& rOutlinerParaObject, 323 const basegfx::B2DPolyPolygon& rPathPolyPolygon, 324 const attribute::SdrFormTextAttribute& rSdrFormTextAttribute) 325 : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), 326 maPathPolyPolygon(rPathPolyPolygon), 327 maSdrFormTextAttribute(rSdrFormTextAttribute) 328 { 329 } 330 operator ==(const BasePrimitive2D & rPrimitive) const331 bool SdrPathTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 332 { 333 if(SdrTextPrimitive2D::operator==(rPrimitive)) 334 { 335 const SdrPathTextPrimitive2D& rCompare = (SdrPathTextPrimitive2D&)rPrimitive; 336 337 return (getPathPolyPolygon() == rCompare.getPathPolyPolygon() 338 && getSdrFormTextAttribute() == rCompare.getSdrFormTextAttribute()); 339 } 340 341 return false; 342 } 343 createTransformedClone(const basegfx::B2DHomMatrix & rTransform) const344 SdrTextPrimitive2D* SdrPathTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const 345 { 346 basegfx::B2DPolyPolygon aNewPolyPolygon(getPathPolyPolygon()); 347 aNewPolyPolygon.transform(rTransform); 348 349 return new SdrPathTextPrimitive2D( 350 getSdrText(), 351 getOutlinerParaObject(), 352 aNewPolyPolygon, 353 getSdrFormTextAttribute()); 354 } 355 356 // provide unique ID 357 ImplPrimitrive2DIDBlock(SdrPathTextPrimitive2D, PRIMITIVE2D_ID_SDRPATHTEXTPRIMITIVE2D) 358 359 } // end of namespace primitive2d 360 } // end of namespace drawinglayer 361 362 ////////////////////////////////////////////////////////////////////////////// 363 364 namespace drawinglayer 365 { 366 namespace primitive2d 367 { create2DDecomposition(const geometry::ViewInformation2D & aViewInformation) const368 Primitive2DSequence SdrBlockTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const 369 { 370 Primitive2DSequence aRetval; 371 getSdrText()->GetObject().impDecomposeBlockTextPrimitive(aRetval, *this, aViewInformation); 372 373 return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval); 374 } 375 SdrBlockTextPrimitive2D(const SdrText * pSdrText,const OutlinerParaObject & rOutlinerParaObject,const basegfx::B2DHomMatrix & rTextRangeTransform,SdrTextHorzAdjust aSdrTextHorzAdjust,SdrTextVertAdjust aSdrTextVertAdjust,bool bFixedCellHeight,bool bUnlimitedPage,bool bCellText,bool bWordWrap,bool bClipOnBounds)376 SdrBlockTextPrimitive2D::SdrBlockTextPrimitive2D( 377 const SdrText* pSdrText, 378 const OutlinerParaObject& rOutlinerParaObject, 379 const basegfx::B2DHomMatrix& rTextRangeTransform, 380 SdrTextHorzAdjust aSdrTextHorzAdjust, 381 SdrTextVertAdjust aSdrTextVertAdjust, 382 bool bFixedCellHeight, 383 bool bUnlimitedPage, 384 bool bCellText, 385 bool bWordWrap, 386 bool bClipOnBounds) 387 : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), 388 maTextRangeTransform(rTextRangeTransform), 389 maSdrTextHorzAdjust(aSdrTextHorzAdjust), 390 maSdrTextVertAdjust(aSdrTextVertAdjust), 391 mbFixedCellHeight(bFixedCellHeight), 392 mbUnlimitedPage(bUnlimitedPage), 393 mbCellText(bCellText), 394 mbWordWrap(bWordWrap), 395 mbClipOnBounds(bClipOnBounds) 396 { 397 } 398 operator ==(const BasePrimitive2D & rPrimitive) const399 bool SdrBlockTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 400 { 401 if(SdrTextPrimitive2D::operator==(rPrimitive)) 402 { 403 const SdrBlockTextPrimitive2D& rCompare = (SdrBlockTextPrimitive2D&)rPrimitive; 404 405 return (getTextRangeTransform() == rCompare.getTextRangeTransform() 406 && getSdrTextHorzAdjust() == rCompare.getSdrTextHorzAdjust() 407 && getSdrTextVertAdjust() == rCompare.getSdrTextVertAdjust() 408 && isFixedCellHeight() == rCompare.isFixedCellHeight() 409 && getUnlimitedPage() == rCompare.getUnlimitedPage() 410 && getCellText() == rCompare.getCellText() 411 && getWordWrap() == rCompare.getWordWrap() 412 && getClipOnBounds() == rCompare.getClipOnBounds()); 413 } 414 415 return false; 416 } 417 createTransformedClone(const basegfx::B2DHomMatrix & rTransform) const418 SdrTextPrimitive2D* SdrBlockTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const 419 { 420 return new SdrBlockTextPrimitive2D( 421 getSdrText(), 422 getOutlinerParaObject(), 423 rTransform * getTextRangeTransform(), 424 getSdrTextHorzAdjust(), 425 getSdrTextVertAdjust(), 426 isFixedCellHeight(), 427 getUnlimitedPage(), 428 getCellText(), 429 getWordWrap(), 430 getClipOnBounds()); 431 } 432 433 // provide unique ID 434 ImplPrimitrive2DIDBlock(SdrBlockTextPrimitive2D, PRIMITIVE2D_ID_SDRBLOCKTEXTPRIMITIVE2D) 435 436 } // end of namespace primitive2d 437 } // end of namespace drawinglayer 438 439 ////////////////////////////////////////////////////////////////////////////// 440 441 namespace drawinglayer 442 { 443 namespace primitive2d 444 { create2DDecomposition(const geometry::ViewInformation2D & aViewInformation) const445 Primitive2DSequence SdrStretchTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const 446 { 447 Primitive2DSequence aRetval; 448 getSdrText()->GetObject().impDecomposeStretchTextPrimitive(aRetval, *this, aViewInformation); 449 450 return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval); 451 } 452 SdrStretchTextPrimitive2D(const SdrText * pSdrText,const OutlinerParaObject & rOutlinerParaObject,const basegfx::B2DHomMatrix & rTextRangeTransform,bool bFixedCellHeight)453 SdrStretchTextPrimitive2D::SdrStretchTextPrimitive2D( 454 const SdrText* pSdrText, 455 const OutlinerParaObject& rOutlinerParaObject, 456 const basegfx::B2DHomMatrix& rTextRangeTransform, 457 bool bFixedCellHeight) 458 : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), 459 maTextRangeTransform(rTextRangeTransform), 460 mbFixedCellHeight(bFixedCellHeight) 461 { 462 } 463 operator ==(const BasePrimitive2D & rPrimitive) const464 bool SdrStretchTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 465 { 466 if(SdrTextPrimitive2D::operator==(rPrimitive)) 467 { 468 const SdrStretchTextPrimitive2D& rCompare = (SdrStretchTextPrimitive2D&)rPrimitive; 469 470 return (getTextRangeTransform() == rCompare.getTextRangeTransform() 471 && isFixedCellHeight() == rCompare.isFixedCellHeight()); 472 } 473 474 return false; 475 } 476 createTransformedClone(const basegfx::B2DHomMatrix & rTransform) const477 SdrTextPrimitive2D* SdrStretchTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const 478 { 479 return new SdrStretchTextPrimitive2D( 480 getSdrText(), 481 getOutlinerParaObject(), 482 rTransform * getTextRangeTransform(), 483 isFixedCellHeight()); 484 } 485 486 // provide unique ID 487 ImplPrimitrive2DIDBlock(SdrStretchTextPrimitive2D, PRIMITIVE2D_ID_SDRSTRETCHTEXTPRIMITIVE2D) 488 489 } // end of namespace primitive2d 490 } // end of namespace drawinglayer 491 492 ////////////////////////////////////////////////////////////////////////////// 493 // eof 494