| /************************************************************** |
| * |
| * 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 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_drawinglayer.hxx" |
| |
| #include <drawinglayer/primitive2d/graphicprimitive2d.hxx> |
| #include <drawinglayer/primitive2d/cropprimitive2d.hxx> |
| #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> |
| #include <drawinglayer/primitive2d/maskprimitive2d.hxx> |
| #include <drawinglayer/primitive2d/graphicprimitivehelper2d.hxx> |
| #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> |
| #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> |
| #include <basegfx/matrix/b2dhommatrixtools.hxx> |
| #include <vcl/svapp.hxx> |
| #include <vcl/outdev.hxx> |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| namespace drawinglayer |
| { |
| namespace primitive2d |
| { |
| Primitive2DSequence GraphicPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& |
| #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE |
| rViewInformation |
| #else |
| /*rViewInformation*/ |
| #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE |
| ) const |
| { |
| Primitive2DSequence aRetval; |
| |
| if(255L == getGraphicAttr().GetTransparency()) |
| { |
| // content is invisible, done |
| return aRetval; |
| } |
| |
| // do not apply mirroring from GraphicAttr to the Metafile by calling |
| // GetTransformedGraphic, this will try to mirror the Metafile using Scale() |
| // at the Metafile. This again calls Scale at the single MetaFile actions, |
| // but this implementation never worked. I reworked that implementations, |
| // but for security reasons i will try not to use it. |
| basegfx::B2DHomMatrix aTransform(getTransform()); |
| |
| if(getGraphicAttr().IsMirrored()) |
| { |
| // content needs mirroring |
| const bool bHMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_HORZ); |
| const bool bVMirr(getGraphicAttr().GetMirrorFlags() & BMP_MIRROR_VERT); |
| |
| // mirror by applying negative scale to the unit primitive and |
| // applying the object transformation on it. |
| aTransform = basegfx::tools::createScaleB2DHomMatrix( |
| bHMirr ? -1.0 : 1.0, |
| bVMirr ? -1.0 : 1.0); |
| aTransform.translate( |
| bHMirr ? 1.0 : 0.0, |
| bVMirr ? 1.0 : 0.0); |
| aTransform = getTransform() * aTransform; |
| } |
| |
| // Get transformed graphic. Suppress rotation and cropping, only filtering is needed |
| // here (and may be replaced later on). Cropping is handled below as mask primitive (if set). |
| // Also need to suppress mirroring, it is part of the transformation now (see above). |
| // Also move transparency handling to embedding to a UnifiedTransparencePrimitive2D; do |
| // that by remembering original transparency and applying that later if needed |
| GraphicAttr aSuppressGraphicAttr(getGraphicAttr()); |
| |
| aSuppressGraphicAttr.SetCrop(0, 0, 0, 0); |
| aSuppressGraphicAttr.SetRotation(0); |
| aSuppressGraphicAttr.SetMirrorFlags(0); |
| aSuppressGraphicAttr.SetTransparency(0); |
| |
| const GraphicObject& rGraphicObject = getGraphicObject(); |
| Graphic aTransformedGraphic(rGraphicObject.GetGraphic()); |
| const bool isBitmap(GRAPHIC_BITMAP == aTransformedGraphic.GetType() && !aTransformedGraphic.getSvgData().get()); |
| const bool isAdjusted(getGraphicAttr().IsAdjusted()); |
| const bool isDrawMode(GRAPHICDRAWMODE_STANDARD != getGraphicAttr().GetDrawMode()); |
| |
| if(isBitmap && (isAdjusted || isDrawMode)) |
| { |
| // the pure primitive solution with the color modifiers works well, too, but when |
| // it is a bitmap graphic the old modification currently is faster; so use it here |
| // instead of creating all as in create2DColorModifierEmbeddingsAsNeeded (see below). |
| // Still, crop, rotation, mirroring and transparency is handled by primitives already |
| // (see above). |
| // This could even be done when vector graphic, but we explicitely want to have the |
| // pure primitive solution for this; this will allow vector graphics to stay vector |
| // geraphics, independent from the color filtering stuff. This will enhance e.g. |
| // SVG and print quality while reducing data size at the same time. |
| // The other way around the old modifications when only used on already bitmap objects |
| // will not loose any quality. |
| aTransformedGraphic = rGraphicObject.GetTransformedGraphic(&aSuppressGraphicAttr); |
| |
| // reset GraphicAttr after use to not apply double |
| aSuppressGraphicAttr = GraphicAttr(); |
| } |
| |
| // create sub-content; helper takes care of correct handling of |
| // bitmap, svg or metafile content |
| aRetval = create2DDecompositionOfGraphic( |
| aTransformedGraphic, |
| aTransform); |
| |
| if(!aRetval.getLength()) |
| { |
| // content is invisible, done |
| return aRetval; |
| } |
| |
| if(isAdjusted || isDrawMode) |
| { |
| // embed to needed ModifiedColorPrimitive2D's if necessary. Do this for |
| // adjustments and draw mode specials |
| aRetval = create2DColorModifierEmbeddingsAsNeeded( |
| aRetval, |
| aSuppressGraphicAttr.GetDrawMode(), |
| basegfx::clamp(aSuppressGraphicAttr.GetLuminance() * 0.01, -1.0, 1.0), |
| basegfx::clamp(aSuppressGraphicAttr.GetContrast() * 0.01, -1.0, 1.0), |
| basegfx::clamp(aSuppressGraphicAttr.GetChannelR() * 0.01, -1.0, 1.0), |
| basegfx::clamp(aSuppressGraphicAttr.GetChannelG() * 0.01, -1.0, 1.0), |
| basegfx::clamp(aSuppressGraphicAttr.GetChannelB() * 0.01, -1.0, 1.0), |
| basegfx::clamp(aSuppressGraphicAttr.GetGamma(), 0.0, 10.0), |
| aSuppressGraphicAttr.IsInvert()); |
| |
| if(!aRetval.getLength()) |
| { |
| // content is invisible, done |
| return aRetval; |
| } |
| } |
| |
| if(getGraphicAttr().IsTransparent()) |
| { |
| // check for transparency |
| const double fTransparency(basegfx::clamp(getGraphicAttr().GetTransparency() * (1.0 / 255.0), 0.0, 1.0)); |
| |
| if(!basegfx::fTools::equalZero(fTransparency)) |
| { |
| const Primitive2DReference aUnifiedTransparence( |
| new UnifiedTransparencePrimitive2D( |
| aRetval, |
| fTransparency)); |
| |
| aRetval = Primitive2DSequence(&aUnifiedTransparence, 1); |
| } |
| } |
| |
| if(getGraphicAttr().IsCropped()) |
| { |
| // check for cropping |
| // calculate scalings between real image size and logic object size. This |
| // is necessary since the crop values are relative to original bitmap size |
| const basegfx::B2DVector aObjectScale(aTransform * basegfx::B2DVector(1.0, 1.0)); |
| const basegfx::B2DVector aCropScaleFactor( |
| rGraphicObject.calculateCropScaling( |
| aObjectScale.getX(), |
| aObjectScale.getY(), |
| getGraphicAttr().GetLeftCrop(), |
| getGraphicAttr().GetTopCrop(), |
| getGraphicAttr().GetRightCrop(), |
| getGraphicAttr().GetBottomCrop())); |
| |
| // embed content in cropPrimitive |
| Primitive2DReference xPrimitive( |
| new CropPrimitive2D( |
| aRetval, |
| aTransform, |
| getGraphicAttr().GetLeftCrop() * aCropScaleFactor.getX(), |
| getGraphicAttr().GetTopCrop() * aCropScaleFactor.getY(), |
| getGraphicAttr().GetRightCrop() * aCropScaleFactor.getX(), |
| getGraphicAttr().GetBottomCrop() * aCropScaleFactor.getY())); |
| |
| aRetval = Primitive2DSequence(&xPrimitive, 1); |
| } |
| |
| return aRetval; |
| } |
| |
| GraphicPrimitive2D::GraphicPrimitive2D( |
| const basegfx::B2DHomMatrix& rTransform, |
| const GraphicObject& rGraphicObject, |
| const GraphicAttr& rGraphicAttr) |
| : BufferedDecompositionPrimitive2D(), |
| maTransform(rTransform), |
| maGraphicObject(rGraphicObject), |
| maGraphicAttr(rGraphicAttr) |
| { |
| } |
| |
| GraphicPrimitive2D::GraphicPrimitive2D( |
| const basegfx::B2DHomMatrix& rTransform, |
| const GraphicObject& rGraphicObject) |
| : BufferedDecompositionPrimitive2D(), |
| maTransform(rTransform), |
| maGraphicObject(rGraphicObject), |
| maGraphicAttr() |
| { |
| } |
| |
| bool GraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const |
| { |
| if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) |
| { |
| const GraphicPrimitive2D& rCompare = (GraphicPrimitive2D&)rPrimitive; |
| |
| return (getTransform() == rCompare.getTransform() |
| && getGraphicObject() == rCompare.getGraphicObject() |
| && getGraphicAttr() == rCompare.getGraphicAttr()); |
| } |
| |
| return false; |
| } |
| |
| basegfx::B2DRange GraphicPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const |
| { |
| basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0); |
| aRetval.transform(getTransform()); |
| return aRetval; |
| } |
| |
| // provide unique ID |
| ImplPrimitrive2DIDBlock(GraphicPrimitive2D, PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D) |
| |
| } // end of namespace primitive2d |
| } // end of namespace drawinglayer |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // eof |