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_drawinglayer.hxx" 26 27 #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> 28 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 29 #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 30 #include <basegfx/polygon/b2dpolygontools.hxx> 31 #include <basegfx/polygon/b2dpolygon.hxx> 32 #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 33 #include <basegfx/matrix/b2dhommatrixtools.hxx> 34 35 ////////////////////////////////////////////////////////////////////////////// 36 37 using namespace com::sun::star; 38 39 ////////////////////////////////////////////////////////////////////////////// 40 41 namespace drawinglayer 42 { 43 namespace primitive2d 44 { create2DDecomposition(const geometry::ViewInformation2D & rViewInformation) const45 Primitive2DSequence PagePreviewPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 46 { 47 Primitive2DSequence xRetval; 48 Primitive2DSequence aContent(getPageContent()); 49 50 if(aContent.hasElements() 51 && basegfx::fTools::more(getContentWidth(), 0.0) 52 && basegfx::fTools::more(getContentHeight(), 0.0)) 53 { 54 // the decomposed matrix will be needed 55 basegfx::B2DVector aScale, aTranslate; 56 double fRotate, fShearX; 57 getTransform().decompose(aScale, aTranslate, fRotate, fShearX); 58 59 if(basegfx::fTools::more(aScale.getX(), 0.0) && basegfx::fTools::more(aScale.getY(), 0.0)) 60 { 61 // check if content overlaps with targeted size and needs to be embedded with a 62 // clipping primitive 63 const basegfx::B2DRange aRealContentRange(getB2DRangeFromPrimitive2DSequence(aContent, rViewInformation)); 64 const basegfx::B2DRange aAllowedContentRange(0.0, 0.0, getContentWidth(), getContentHeight()); 65 66 if(!aAllowedContentRange.isInside(aRealContentRange)) 67 { 68 const Primitive2DReference xReferenceA( 69 new MaskPrimitive2D( 70 basegfx::B2DPolyPolygon( 71 basegfx::tools::createPolygonFromRect(aAllowedContentRange)), aContent)); 72 aContent = Primitive2DSequence(&xReferenceA, 1); 73 } 74 75 // create a mapping from content to object. 76 basegfx::B2DHomMatrix aPageTrans; 77 78 if(getKeepAspectRatio()) 79 { 80 // #i101075# when keeping the aspect ratio is wanted, it is necessary to calculate 81 // an equidistant scaling in X and Y and a corresponding translation to 82 // center the output. Calculate needed scale factors 83 const double fScaleX(aScale.getX() / getContentWidth()); 84 const double fScaleY(aScale.getY() / getContentHeight()); 85 86 // to keep the aspect, use the smaller scale and adapt missing size by translation 87 if(fScaleX < fScaleY) 88 { 89 // height needs to be adapted 90 const double fNeededHeight(aScale.getY() / fScaleX); 91 const double fSpaceToAdd(fNeededHeight - getContentHeight()); 92 93 aPageTrans.translate(0.0, fSpaceToAdd * 0.5); 94 aPageTrans.scale(fScaleX, aScale.getY() / fNeededHeight); 95 } 96 else 97 { 98 // width needs to be adapted 99 const double fNeededWidth(aScale.getX() / fScaleY); 100 const double fSpaceToAdd(fNeededWidth - getContentWidth()); 101 102 aPageTrans.translate(fSpaceToAdd * 0.5, 0.0); 103 aPageTrans.scale(aScale.getX() / fNeededWidth, fScaleY); 104 } 105 106 // add the missing object transformation aspects 107 const basegfx::B2DHomMatrix aCombined(basegfx::tools::createShearXRotateTranslateB2DHomMatrix( 108 fShearX, fRotate, aTranslate.getX(), aTranslate.getY())); 109 aPageTrans = aCombined * aPageTrans; 110 } 111 else 112 { 113 // completely scale to PageObject size. Scale to unit size. 114 aPageTrans.scale(1.0/ getContentWidth(), 1.0 / getContentHeight()); 115 116 // apply object matrix 117 aPageTrans *= getTransform(); 118 } 119 120 // embed in necessary transformation to map from SdrPage to SdrPageObject 121 const Primitive2DReference xReferenceB(new TransformPrimitive2D(aPageTrans, aContent)); 122 xRetval = Primitive2DSequence(&xReferenceB, 1); 123 } 124 } 125 126 return xRetval; 127 } 128 PagePreviewPrimitive2D(const::com::sun::star::uno::Reference<::com::sun::star::drawing::XDrawPage> & rxDrawPage,const basegfx::B2DHomMatrix & rTransform,double fContentWidth,double fContentHeight,const Primitive2DSequence & rPageContent,bool bKeepAspectRatio)129 PagePreviewPrimitive2D::PagePreviewPrimitive2D( 130 const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage >& rxDrawPage, 131 const basegfx::B2DHomMatrix& rTransform, 132 double fContentWidth, 133 double fContentHeight, 134 const Primitive2DSequence& rPageContent, 135 bool bKeepAspectRatio) 136 : BufferedDecompositionPrimitive2D(), 137 mxDrawPage(rxDrawPage), 138 maPageContent(rPageContent), 139 maTransform(rTransform), 140 mfContentWidth(fContentWidth), 141 mfContentHeight(fContentHeight), 142 mbKeepAspectRatio(bKeepAspectRatio) 143 { 144 } 145 operator ==(const BasePrimitive2D & rPrimitive) const146 bool PagePreviewPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 147 { 148 if(BasePrimitive2D::operator==(rPrimitive)) 149 { 150 const PagePreviewPrimitive2D& rCompare = static_cast< const PagePreviewPrimitive2D& >(rPrimitive); 151 152 return (getXDrawPage() == rCompare.getXDrawPage() 153 && getPageContent() == rCompare.getPageContent() 154 && getTransform() == rCompare.getTransform() 155 && getContentWidth() == rCompare.getContentWidth() 156 && getContentHeight() == rCompare.getContentHeight() 157 && getKeepAspectRatio() == rCompare.getKeepAspectRatio()); 158 } 159 160 return false; 161 } 162 getB2DRange(const geometry::ViewInformation2D &) const163 basegfx::B2DRange PagePreviewPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation`*/) const 164 { 165 // nothing is allowed to stick out of a PagePreviewPrimitive, thus we 166 // can quickly deliver our range here 167 basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0); 168 aRetval.transform(getTransform()); 169 return aRetval; 170 } 171 172 // provide unique ID 173 ImplPrimitrive2DIDBlock(PagePreviewPrimitive2D, PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D) 174 175 } // end of namespace primitive2d 176 } // end of namespace drawinglayer 177 178 /* vim: set noet sw=4 ts=4: */ 179