1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include <drawinglayer/primitive2d/embedded3dprimitive2d.hxx> 21 #include <basegfx/polygon/b2dpolygon.hxx> 22 #include <basegfx/polygon/b2dpolygontools.hxx> 23 #include <basegfx/color/bcolor.hxx> 24 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 25 #include <basegfx/utils/canvastools.hxx> 26 #include <drawinglayer/geometry/viewinformation2d.hxx> 27 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 28 #include <drawinglayer/geometry/viewinformation3d.hxx> 29 #include <drawinglayer/processor3d/shadow3dextractor.hxx> 30 31 32 using namespace com::sun::star; 33 34 35 namespace drawinglayer 36 { 37 namespace primitive2d 38 { impGetShadow3D() const39 bool Embedded3DPrimitive2D::impGetShadow3D() const 40 { 41 osl::MutexGuard aGuard( m_aMutex ); 42 43 // create on demand 44 if(!mbShadow3DChecked && !getChildren3D().empty()) 45 { 46 // create shadow extraction processor 47 processor3d::Shadow3DExtractingProcessor aShadowProcessor( 48 getViewInformation3D(), 49 getObjectTransformation(), 50 getLightNormal(), 51 getShadowSlant(), 52 getScene3DRange()); 53 54 // process local primitives 55 aShadowProcessor.process(getChildren3D()); 56 57 // fetch result and set checked flag 58 const_cast< Embedded3DPrimitive2D* >(this)->maShadowPrimitives = aShadowProcessor.getPrimitive2DSequence(); 59 const_cast< Embedded3DPrimitive2D* >(this)->mbShadow3DChecked = true; 60 } 61 62 // return if there are shadow primitives 63 return !maShadowPrimitives.empty(); 64 } 65 create2DDecomposition(Primitive2DContainer & rContainer,const geometry::ViewInformation2D & rViewInformation) const66 void Embedded3DPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation) const 67 { 68 // use info to create a yellow 2d rectangle, similar to empty 3d scenes and/or groups 69 const basegfx::B2DRange aLocal2DRange(getB2DRange(rViewInformation)); 70 const basegfx::B2DPolygon aOutline(basegfx::utils::createPolygonFromRect(aLocal2DRange)); 71 const basegfx::BColor aYellow(1.0, 1.0, 0.0); 72 rContainer.push_back(new PolygonHairlinePrimitive2D(aOutline, aYellow)); 73 } 74 Embedded3DPrimitive2D(const primitive3d::Primitive3DContainer & rxChildren3D,const basegfx::B2DHomMatrix & rObjectTransformation,const geometry::ViewInformation3D & rViewInformation3D,const basegfx::B3DVector & rLightNormal,double fShadowSlant,const basegfx::B3DRange & rScene3DRange)75 Embedded3DPrimitive2D::Embedded3DPrimitive2D( 76 const primitive3d::Primitive3DContainer& rxChildren3D, 77 const basegfx::B2DHomMatrix& rObjectTransformation, 78 const geometry::ViewInformation3D& rViewInformation3D, 79 const basegfx::B3DVector& rLightNormal, 80 double fShadowSlant, 81 const basegfx::B3DRange& rScene3DRange) 82 : BufferedDecompositionPrimitive2D(), 83 mxChildren3D(rxChildren3D), 84 maObjectTransformation(rObjectTransformation), 85 maViewInformation3D(rViewInformation3D), 86 maLightNormal(rLightNormal), 87 mfShadowSlant(fShadowSlant), 88 maScene3DRange(rScene3DRange), 89 maShadowPrimitives(), 90 maB2DRange(), 91 mbShadow3DChecked(false) 92 { 93 maLightNormal.normalize(); 94 } 95 operator ==(const BasePrimitive2D & rPrimitive) const96 bool Embedded3DPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 97 { 98 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 99 { 100 const Embedded3DPrimitive2D& rCompare = static_cast< const Embedded3DPrimitive2D& >(rPrimitive); 101 102 return (getChildren3D() == rCompare.getChildren3D() 103 && getObjectTransformation() == rCompare.getObjectTransformation() 104 && getViewInformation3D() == rCompare.getViewInformation3D() 105 && getLightNormal() == rCompare.getLightNormal() 106 && getShadowSlant() == rCompare.getShadowSlant() 107 && getScene3DRange() == rCompare.getScene3DRange()); 108 } 109 110 return false; 111 } 112 getB2DRange(const geometry::ViewInformation2D & rViewInformation) const113 basegfx::B2DRange Embedded3DPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 114 { 115 if(maB2DRange.isEmpty()) 116 { 117 // use the 3d transformation stack to create a projection of the 3D range 118 basegfx::B3DRange a3DRange(getChildren3D().getB3DRange(getViewInformation3D())); 119 a3DRange.transform(getViewInformation3D().getObjectToView()); 120 121 // create 2d range from projected 3d and transform with scene's object transformation 122 basegfx::B2DRange aNewRange; 123 aNewRange.expand(basegfx::B2DPoint(a3DRange.getMinX(), a3DRange.getMinY())); 124 aNewRange.expand(basegfx::B2DPoint(a3DRange.getMaxX(), a3DRange.getMaxY())); 125 aNewRange.transform(getObjectTransformation()); 126 127 // check for 3D shadows and their 2D projections. If those exist, they need to be 128 // taken into account 129 if(impGetShadow3D()) 130 { 131 const basegfx::B2DRange aShadow2DRange(maShadowPrimitives.getB2DRange(rViewInformation)); 132 133 if(!aShadow2DRange.isEmpty()) 134 { 135 aNewRange.expand(aShadow2DRange); 136 } 137 } 138 139 // assign to buffered value 140 const_cast< Embedded3DPrimitive2D* >(this)->maB2DRange = aNewRange; 141 } 142 143 return maB2DRange; 144 } 145 146 // provide unique ID 147 ImplPrimitive2DIDBlock(Embedded3DPrimitive2D, PRIMITIVE2D_ID_EMBEDDED3DPRIMITIVE2D) 148 149 } // end of namespace primitive2d 150 } // end of namespace drawinglayer 151 152 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 153