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