/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include namespace drawinglayer::primitive2d { DiscreteShadow::DiscreteShadow(const BitmapEx& rBitmapEx) : maBitmapEx(rBitmapEx) { maBitmapEx.Invert(); // convert transparency to alpha const Size& rBitmapSize = getBitmapEx().GetSizePixel(); if(rBitmapSize.Width() != rBitmapSize.Height() || rBitmapSize.Width() < 7) { OSL_ENSURE(false, "DiscreteShadowPrimitive2D: wrong bitmap format (!)"); maBitmapEx = BitmapEx(); } } const BitmapEx& DiscreteShadow::getTopLeft() const { if(maTopLeft.IsEmpty()) { const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); const_cast< DiscreteShadow* >(this)->maTopLeft = getBitmapEx(); const_cast< DiscreteShadow* >(this)->maTopLeft.Crop( ::tools::Rectangle(Point(0, 0), Size((nQuarter * 2) + 1, (nQuarter * 2) + 1))); } return maTopLeft; } const BitmapEx& DiscreteShadow::getTop() const { if(maTop.IsEmpty()) { const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); const_cast< DiscreteShadow* >(this)->maTop = getBitmapEx(); const_cast< DiscreteShadow* >(this)->maTop.Crop( ::tools::Rectangle(Point((nQuarter * 2) + 1, 0), Size(1, nQuarter))); } return maTop; } const BitmapEx& DiscreteShadow::getTopRight() const { if(maTopRight.IsEmpty()) { const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); const_cast< DiscreteShadow* >(this)->maTopRight = getBitmapEx(); const_cast< DiscreteShadow* >(this)->maTopRight.Crop( ::tools::Rectangle(Point((nQuarter * 2) + 2, 0), Size((nQuarter * 2) + 1, (nQuarter * 2) + 1))); } return maTopRight; } const BitmapEx& DiscreteShadow::getRight() const { if(maRight.IsEmpty()) { const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); const_cast< DiscreteShadow* >(this)->maRight = getBitmapEx(); const_cast< DiscreteShadow* >(this)->maRight.Crop( ::tools::Rectangle(Point((nQuarter * 3) + 3, (nQuarter * 2) + 1), Size(nQuarter, 1))); } return maRight; } const BitmapEx& DiscreteShadow::getBottomRight() const { if(maBottomRight.IsEmpty()) { const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); const_cast< DiscreteShadow* >(this)->maBottomRight = getBitmapEx(); const_cast< DiscreteShadow* >(this)->maBottomRight.Crop( ::tools::Rectangle(Point((nQuarter * 2) + 2, (nQuarter * 2) + 2), Size((nQuarter * 2) + 1, (nQuarter * 2) + 1))); } return maBottomRight; } const BitmapEx& DiscreteShadow::getBottom() const { if(maBottom.IsEmpty()) { const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); const_cast< DiscreteShadow* >(this)->maBottom = getBitmapEx(); const_cast< DiscreteShadow* >(this)->maBottom.Crop( ::tools::Rectangle(Point((nQuarter * 2) + 1, (nQuarter * 3) + 3), Size(1, nQuarter))); } return maBottom; } const BitmapEx& DiscreteShadow::getBottomLeft() const { if(maBottomLeft.IsEmpty()) { const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); const_cast< DiscreteShadow* >(this)->maBottomLeft = getBitmapEx(); const_cast< DiscreteShadow* >(this)->maBottomLeft.Crop( ::tools::Rectangle(Point(0, (nQuarter * 2) + 2), Size((nQuarter * 2) + 1, (nQuarter * 2) + 1))); } return maBottomLeft; } const BitmapEx& DiscreteShadow::getLeft() const { if(maLeft.IsEmpty()) { const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); const_cast< DiscreteShadow* >(this)->maLeft = getBitmapEx(); const_cast< DiscreteShadow* >(this)->maLeft.Crop( ::tools::Rectangle(Point(0, (nQuarter * 2) + 1), Size(nQuarter, 1))); } return maLeft; } } // end of namespace namespace drawinglayer::primitive2d { Primitive2DReference DiscreteShadowPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const { Primitive2DContainer xRetval; if(getDiscreteShadow().getBitmapEx().IsEmpty()) return nullptr; const sal_Int32 nQuarter((getDiscreteShadow().getBitmapEx().GetSizePixel().Width() - 3) >> 2); const basegfx::B2DVector aScale(getTransform() * basegfx::B2DVector(1.0, 1.0)); const double fSingleX(getDiscreteUnit() / aScale.getX()); const double fSingleY(getDiscreteUnit() / aScale.getY()); const double fBorderX(fSingleX * nQuarter); const double fBorderY(fSingleY * nQuarter); const double fBigLenX((fBorderX * 2.0) + fSingleX); const double fBigLenY((fBorderY * 2.0) + fSingleY); xRetval.resize(8); // TopLeft xRetval[0] = new BitmapPrimitive2D( getDiscreteShadow().getTopLeft(), basegfx::utils::createScaleTranslateB2DHomMatrix( fBigLenX, fBigLenY, -fBorderX, -fBorderY)); // Top xRetval[1] = new BitmapPrimitive2D( getDiscreteShadow().getTop(), basegfx::utils::createScaleTranslateB2DHomMatrix( 1.0 - (2.0 * (fBorderX + fSingleX)) + fSingleX, fBorderY, fBorderX + fSingleX, -fBorderY)); // TopRight xRetval[2] = new BitmapPrimitive2D( getDiscreteShadow().getTopRight(), basegfx::utils::createScaleTranslateB2DHomMatrix( fBigLenX, fBigLenY, 1.0 - fBorderX, -fBorderY)); // Right xRetval[3] = new BitmapPrimitive2D( getDiscreteShadow().getRight(), basegfx::utils::createScaleTranslateB2DHomMatrix( fBorderX, 1.0 - (2.0 * (fBorderY + fSingleY)) + fSingleY, 1.0 + fSingleX, fBorderY + fSingleY)); // BottomRight xRetval[4] = new BitmapPrimitive2D( getDiscreteShadow().getBottomRight(), basegfx::utils::createScaleTranslateB2DHomMatrix( fBigLenX, fBigLenY, 1.0 - (fBorderX + fSingleX) + fSingleX, 1.0 - (fBorderY + fSingleY) + fSingleY)); // Bottom xRetval[5] = new BitmapPrimitive2D( getDiscreteShadow().getBottom(), basegfx::utils::createScaleTranslateB2DHomMatrix( 1.0 - (2.0 * (fBorderX + fSingleX)) + fSingleX, fBorderY, fBorderX + fSingleX, 1.0 + fSingleY)); // BottomLeft xRetval[6] = new BitmapPrimitive2D( getDiscreteShadow().getBottomLeft(), basegfx::utils::createScaleTranslateB2DHomMatrix( fBigLenX, fBigLenY, -fBorderX, 1.0 - fBorderY)); // Left xRetval[7] = new BitmapPrimitive2D( getDiscreteShadow().getLeft(), basegfx::utils::createScaleTranslateB2DHomMatrix( fBorderX, 1.0 - (2.0 * (fBorderY + fSingleY)) + fSingleY, -fBorderX, fBorderY + fSingleY)); // put all in object transformation to get to target positions return new TransformPrimitive2D( getTransform(), std::move(xRetval)); } DiscreteShadowPrimitive2D::DiscreteShadowPrimitive2D( const basegfx::B2DHomMatrix& rTransform, const DiscreteShadow& rDiscreteShadow) : maTransform(rTransform), maDiscreteShadow(rDiscreteShadow) { } bool DiscreteShadowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const { if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) { const DiscreteShadowPrimitive2D& rCompare = static_cast(rPrimitive); return (getTransform() == rCompare.getTransform() && getDiscreteShadow() == rCompare.getDiscreteShadow()); } return false; } basegfx::B2DRange DiscreteShadowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const { if(getDiscreteShadow().getBitmapEx().IsEmpty()) { // no graphics without valid bitmap definition return basegfx::B2DRange(); } else { // prepare normal objectrange basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0); aRetval.transform(getTransform()); // extract discrete shadow size and grow const basegfx::B2DVector aScale(rViewInformation.getViewTransformation() * basegfx::B2DVector(1.0, 1.0)); const sal_Int32 nQuarter((getDiscreteShadow().getBitmapEx().GetSizePixel().Width() - 3) >> 2); const double fGrowX((1.0 / aScale.getX()) * nQuarter); const double fGrowY((1.0 / aScale.getY()) * nQuarter); aRetval.grow(std::max(fGrowX, fGrowY)); return aRetval; } } // provide unique ID sal_uInt32 DiscreteShadowPrimitive2D::getPrimitive2DID() const { return PRIMITIVE2D_ID_DISCRETESHADOWPRIMITIVE2D; } } // end of namespace /* vim:set shiftwidth=4 softtabstop=4 expandtab: */