xref: /trunk/main/svx/source/sdr/contact/viewcontactofgraphic.cxx (revision c64e43daf4d868cd69bdcfc2b096656257af5a06)
1f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5f6e50924SAndrew Rist  * distributed with this work for additional information
6f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17f6e50924SAndrew Rist  * specific language governing permissions and limitations
18f6e50924SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20f6e50924SAndrew Rist  *************************************************************/
21f6e50924SAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_svx.hxx"
24cdf0e10cSrcweir #include <svx/sdr/contact/viewcontactofgraphic.hxx>
25cdf0e10cSrcweir #include <svx/sdr/contact/viewobjectcontactofgraphic.hxx>
26cdf0e10cSrcweir #include <svx/svdograf.hxx>
27cdf0e10cSrcweir #include <svx/sdr/primitive2d/sdrattributecreator.hxx>
28cdf0e10cSrcweir #include <svl/itemset.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #ifndef ITEMID_GRF_CROP
31cdf0e10cSrcweir #define ITEMID_GRF_CROP 0
32cdf0e10cSrcweir #endif
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include <svx/sdgcpitm.hxx>
35cdf0e10cSrcweir #include <svx/sdr/contact/displayinfo.hxx>
36cdf0e10cSrcweir #include <svx/sdr/contact/viewobjectcontact.hxx>
37cdf0e10cSrcweir #include <svx/sdr/contact/objectcontact.hxx>
38cdf0e10cSrcweir #include <svx/sdr/event/eventhandler.hxx>
39cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
40cdf0e10cSrcweir #include <svx/sdr/primitive2d/sdrgrafprimitive2d.hxx>
41cdf0e10cSrcweir #include "svx/svdstr.hrc"
42cdf0e10cSrcweir #include <svx/svdglob.hxx>
43cdf0e10cSrcweir #include <vcl/svapp.hxx>
44cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
45cdf0e10cSrcweir #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
46cdf0e10cSrcweir #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
47cdf0e10cSrcweir #include <drawinglayer/primitive2d/textprimitive2d.hxx>
48cdf0e10cSrcweir #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
49cdf0e10cSrcweir #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
50cdf0e10cSrcweir #include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx>
51cdf0e10cSrcweir #include <editeng/eeitem.hxx>
52cdf0e10cSrcweir #include <editeng/colritem.hxx>
53cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx>
54cdf0e10cSrcweir #include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx>
55cdf0e10cSrcweir 
56cdf0e10cSrcweir namespace sdr
57cdf0e10cSrcweir {
58cdf0e10cSrcweir     namespace contact
59cdf0e10cSrcweir     {
60cdf0e10cSrcweir         // Create a Object-Specific ViewObjectContact, set ViewContact and
61cdf0e10cSrcweir         // ObjectContact. Always needs to return something.
CreateObjectSpecificViewObjectContact(ObjectContact & rObjectContact)62cdf0e10cSrcweir         ViewObjectContact& ViewContactOfGraphic::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact)
63cdf0e10cSrcweir         {
64cdf0e10cSrcweir             ViewObjectContact* pRetval = new ViewObjectContactOfGraphic(rObjectContact, *this);
65cdf0e10cSrcweir             DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)");
66cdf0e10cSrcweir 
67cdf0e10cSrcweir             return *pRetval;
68cdf0e10cSrcweir         }
69cdf0e10cSrcweir 
ViewContactOfGraphic(SdrGrafObj & rGrafObj)70cdf0e10cSrcweir         ViewContactOfGraphic::ViewContactOfGraphic(SdrGrafObj& rGrafObj)
71cdf0e10cSrcweir         :   ViewContactOfTextObj(rGrafObj)
72cdf0e10cSrcweir         {
73cdf0e10cSrcweir         }
74cdf0e10cSrcweir 
~ViewContactOfGraphic()75cdf0e10cSrcweir         ViewContactOfGraphic::~ViewContactOfGraphic()
76cdf0e10cSrcweir         {
77cdf0e10cSrcweir         }
78cdf0e10cSrcweir 
flushGraphicObjects()79cdf0e10cSrcweir         void ViewContactOfGraphic::flushGraphicObjects()
80cdf0e10cSrcweir         {
81*c64e43daSmseidel             // #i102380# The graphic is swapped out. To let that have an effect it is necessary to
82cdf0e10cSrcweir             // delete copies of the GraphicObject which are not swapped out and have no SwapHandler set
83*c64e43daSmseidel             // (this is what happens when the GraphicObject gets copied to a SdrGrafPrimitive2D). This
84cdf0e10cSrcweir             // is best achieved for the VC by clearing the local decomposition cache. It would be possible
85*c64e43daSmseidel             // to also do this for the VOC cache, but that VOCs exist exactly express that the object
86*c64e43daSmseidel             // gets visualized, so this would be wrong.
87cdf0e10cSrcweir             flushViewIndependentPrimitive2DSequence();
88cdf0e10cSrcweir         }
89cdf0e10cSrcweir 
createVIP2DSForPresObj(const basegfx::B2DHomMatrix & rObjectMatrix,const drawinglayer::attribute::SdrLineFillShadowTextAttribute & rAttribute) const90cdf0e10cSrcweir         drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createVIP2DSForPresObj(
91cdf0e10cSrcweir             const basegfx::B2DHomMatrix& rObjectMatrix,
92c0d661f1SArmin Le Grand             const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute) const
93cdf0e10cSrcweir         {
94cdf0e10cSrcweir             drawinglayer::primitive2d::Primitive2DSequence xRetval;
95cdf0e10cSrcweir             GraphicObject aEmptyGraphicObject;
96cdf0e10cSrcweir             GraphicAttr aEmptyGraphicAttr;
97cdf0e10cSrcweir 
98cdf0e10cSrcweir             // SdrGrafPrimitive2D without content in original size which carries all eventual attributes and texts
99cdf0e10cSrcweir             const drawinglayer::primitive2d::Primitive2DReference xReferenceA(new drawinglayer::primitive2d::SdrGrafPrimitive2D(
100cdf0e10cSrcweir                 rObjectMatrix,
101cdf0e10cSrcweir                 rAttribute,
102cdf0e10cSrcweir                 aEmptyGraphicObject,
103cdf0e10cSrcweir                 aEmptyGraphicAttr));
104cdf0e10cSrcweir             xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReferenceA, 1);
105cdf0e10cSrcweir 
106cdf0e10cSrcweir             // SdrGrafPrimitive2D with content (which is the preview graphic) scaled to smaller size and
107cdf0e10cSrcweir             // without attributes
108cdf0e10cSrcweir             basegfx::B2DHomMatrix aSmallerMatrix;
109cdf0e10cSrcweir 
110cdf0e10cSrcweir             // #i94431# for some reason, i forgot to take the PrefMapMode of the graphic
111cdf0e10cSrcweir             // into account. Since EmptyPresObj's are only used in Draw/Impress, it is
112cdf0e10cSrcweir             // safe to assume 100th mm as target.
113cdf0e10cSrcweir             Size aPrefSize(GetGrafObject().GetGrafPrefSize());
114cdf0e10cSrcweir 
115cdf0e10cSrcweir             if(MAP_PIXEL == GetGrafObject().GetGrafPrefMapMode().GetMapUnit())
116cdf0e10cSrcweir             {
117cdf0e10cSrcweir                 aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MAP_100TH_MM);
118cdf0e10cSrcweir             }
119cdf0e10cSrcweir             else
120cdf0e10cSrcweir             {
121cdf0e10cSrcweir                 aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, GetGrafObject().GetGrafPrefMapMode(), MAP_100TH_MM);
122cdf0e10cSrcweir             }
123cdf0e10cSrcweir 
124cdf0e10cSrcweir             // decompose object matrix to get single values
125cdf0e10cSrcweir             basegfx::B2DVector aScale, aTranslate;
126cdf0e10cSrcweir             double fRotate, fShearX;
127cdf0e10cSrcweir             rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
128cdf0e10cSrcweir 
129cdf0e10cSrcweir             const double fOffsetX((aScale.getX() - aPrefSize.getWidth()) / 2.0);
130cdf0e10cSrcweir             const double fOffsetY((aScale.getY() - aPrefSize.getHeight()) / 2.0);
131cdf0e10cSrcweir 
132cdf0e10cSrcweir             if(basegfx::fTools::moreOrEqual(fOffsetX, 0.0) && basegfx::fTools::moreOrEqual(fOffsetY, 0.0))
133cdf0e10cSrcweir             {
134*c64e43daSmseidel                 // create the EmptyPresObj fallback visualization. The fallback graphic
135cdf0e10cSrcweir                 // is already provided in rGraphicObject in this case, use it
136cdf0e10cSrcweir                 aSmallerMatrix = basegfx::tools::createScaleTranslateB2DHomMatrix(aPrefSize.getWidth(), aPrefSize.getHeight(), fOffsetX, fOffsetY);
137cdf0e10cSrcweir                 aSmallerMatrix = basegfx::tools::createShearXRotateTranslateB2DHomMatrix(fShearX, fRotate, aTranslate)
138cdf0e10cSrcweir                     * aSmallerMatrix;
139cdf0e10cSrcweir 
140cdf0e10cSrcweir                 const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false);
141c0d661f1SArmin Le Grand                 const GraphicAttr aLocalGrafInfo;
142cdf0e10cSrcweir                 const drawinglayer::primitive2d::Primitive2DReference xReferenceB(new drawinglayer::primitive2d::SdrGrafPrimitive2D(
143cdf0e10cSrcweir                     aSmallerMatrix,
144cdf0e10cSrcweir                     drawinglayer::attribute::SdrLineFillShadowTextAttribute(),
145cdf0e10cSrcweir                     rGraphicObject,
146c0d661f1SArmin Le Grand                     aLocalGrafInfo));
147cdf0e10cSrcweir 
148cdf0e10cSrcweir                 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReferenceB);
149cdf0e10cSrcweir             }
150cdf0e10cSrcweir 
151cdf0e10cSrcweir             return xRetval;
152cdf0e10cSrcweir         }
153cdf0e10cSrcweir 
createVIP2DSForDraft(const basegfx::B2DHomMatrix & rObjectMatrix,const drawinglayer::attribute::SdrLineFillShadowTextAttribute & rAttribute) const154cdf0e10cSrcweir         drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createVIP2DSForDraft(
155cdf0e10cSrcweir             const basegfx::B2DHomMatrix& rObjectMatrix,
156cdf0e10cSrcweir             const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute) const
157cdf0e10cSrcweir         {
158cdf0e10cSrcweir             drawinglayer::primitive2d::Primitive2DSequence xRetval;
159cdf0e10cSrcweir             GraphicObject aEmptyGraphicObject;
160cdf0e10cSrcweir             GraphicAttr aEmptyGraphicAttr;
161cdf0e10cSrcweir 
162cdf0e10cSrcweir             // SdrGrafPrimitive2D without content in original size which carries all eventual attributes and texts
163cdf0e10cSrcweir             const drawinglayer::primitive2d::Primitive2DReference xReferenceA(new drawinglayer::primitive2d::SdrGrafPrimitive2D(
164cdf0e10cSrcweir                 rObjectMatrix,
165cdf0e10cSrcweir                 rAttribute,
166cdf0e10cSrcweir                 aEmptyGraphicObject,
167cdf0e10cSrcweir                 aEmptyGraphicAttr));
168cdf0e10cSrcweir             xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReferenceA, 1);
169cdf0e10cSrcweir 
170cdf0e10cSrcweir             if(rAttribute.getLine().isDefault())
171cdf0e10cSrcweir             {
172cdf0e10cSrcweir                 // create a surrounding frame when no linestyle given
173cdf0e10cSrcweir                 const Color aColor(Application::GetSettings().GetStyleSettings().GetShadowColor());
174cdf0e10cSrcweir                 const basegfx::BColor aBColor(aColor.getBColor());
175cdf0e10cSrcweir                 basegfx::B2DPolygon aOutline(basegfx::tools::createUnitPolygon());
176cdf0e10cSrcweir                 aOutline.transform(rObjectMatrix);
177cdf0e10cSrcweir 
178cdf0e10cSrcweir                 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval,
179cdf0e10cSrcweir                     drawinglayer::primitive2d::Primitive2DReference(
180cdf0e10cSrcweir                         new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
181cdf0e10cSrcweir                             aOutline,
182cdf0e10cSrcweir                             aBColor)));
183cdf0e10cSrcweir             }
184cdf0e10cSrcweir 
185cdf0e10cSrcweir             // decompose object matrix to get single values
186cdf0e10cSrcweir             basegfx::B2DVector aScale, aTranslate;
187cdf0e10cSrcweir             double fRotate, fShearX;
188cdf0e10cSrcweir             rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
189cdf0e10cSrcweir 
190cdf0e10cSrcweir             // define a distance value, used for distance from bitmap to borders and from bitmap
191cdf0e10cSrcweir             // to text, too (2 mm)
192cdf0e10cSrcweir             const double fDistance(200.0);
193cdf0e10cSrcweir 
194cdf0e10cSrcweir             // consume borders from values
195cdf0e10cSrcweir             aScale.setX(std::max(0.0, aScale.getX() - (2.0 * fDistance)));
196cdf0e10cSrcweir             aScale.setY(std::max(0.0, aScale.getY() - (2.0 * fDistance)));
197cdf0e10cSrcweir             aTranslate.setX(aTranslate.getX() + fDistance);
198cdf0e10cSrcweir             aTranslate.setY(aTranslate.getY() + fDistance);
199cdf0e10cSrcweir 
200cdf0e10cSrcweir             // draw a draft bitmap
201cdf0e10cSrcweir             const Bitmap aDraftBitmap(ResId(BMAP_GrafikEi, *ImpGetResMgr()));
202cdf0e10cSrcweir 
203cdf0e10cSrcweir             if(!aDraftBitmap.IsEmpty())
204cdf0e10cSrcweir             {
205cdf0e10cSrcweir                 Size aPrefSize(aDraftBitmap.GetPrefSize());
206cdf0e10cSrcweir 
207cdf0e10cSrcweir                 if(MAP_PIXEL == aDraftBitmap.GetPrefMapMode().GetMapUnit())
208cdf0e10cSrcweir                 {
209cdf0e10cSrcweir                     aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aDraftBitmap.GetSizePixel(), MAP_100TH_MM);
210cdf0e10cSrcweir                 }
211cdf0e10cSrcweir                 else
212cdf0e10cSrcweir                 {
213cdf0e10cSrcweir                     aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, aDraftBitmap.GetPrefMapMode(), MAP_100TH_MM);
214cdf0e10cSrcweir                 }
215cdf0e10cSrcweir 
216cdf0e10cSrcweir                 const double fBitmapScaling(2.0);
217cdf0e10cSrcweir                 const double fWidth(aPrefSize.getWidth() * fBitmapScaling);
218cdf0e10cSrcweir                 const double fHeight(aPrefSize.getHeight() * fBitmapScaling);
219cdf0e10cSrcweir 
220cdf0e10cSrcweir                 if(basegfx::fTools::more(fWidth, 1.0)
221cdf0e10cSrcweir                     && basegfx::fTools::more(fHeight, 1.0)
222cdf0e10cSrcweir                     && basegfx::fTools::lessOrEqual(fWidth, aScale.getX())
223cdf0e10cSrcweir                     && basegfx::fTools::lessOrEqual(fHeight, aScale.getY()))
224cdf0e10cSrcweir                 {
225cdf0e10cSrcweir                     const basegfx::B2DHomMatrix aBitmapMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
226cdf0e10cSrcweir                         fWidth, fHeight, fShearX, fRotate, aTranslate.getX(), aTranslate.getY()));
227cdf0e10cSrcweir 
228cdf0e10cSrcweir                     drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval,
229cdf0e10cSrcweir                         drawinglayer::primitive2d::Primitive2DReference(
230cdf0e10cSrcweir                             new drawinglayer::primitive2d::BitmapPrimitive2D(
231cdf0e10cSrcweir                                 BitmapEx(aDraftBitmap),
232cdf0e10cSrcweir                                 aBitmapMatrix)));
233cdf0e10cSrcweir 
234cdf0e10cSrcweir                     // consume bitmap size in X
235cdf0e10cSrcweir                     aScale.setX(std::max(0.0, aScale.getX() - (fWidth + fDistance)));
236cdf0e10cSrcweir                     aTranslate.setX(aTranslate.getX() + fWidth + fDistance);
237cdf0e10cSrcweir                 }
238cdf0e10cSrcweir             }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir             // Build the text for the draft object
241cdf0e10cSrcweir             XubString aDraftText = GetGrafObject().GetFileName();
242cdf0e10cSrcweir 
243cdf0e10cSrcweir             if(!aDraftText.Len())
244cdf0e10cSrcweir             {
245cdf0e10cSrcweir                 aDraftText = GetGrafObject().GetName();
246cdf0e10cSrcweir                 aDraftText.AppendAscii(" ...");
247cdf0e10cSrcweir             }
248cdf0e10cSrcweir 
249cdf0e10cSrcweir             if(aDraftText.Len() && GetGrafObject().GetModel())
250cdf0e10cSrcweir             {
251cdf0e10cSrcweir                 // #i103255# Goal is to produce TextPrimitives which hold the given text as
252cdf0e10cSrcweir                 // BlockText in the available space. It would be very tricky to do
253cdf0e10cSrcweir                 // an own word wrap/line layout here.
254cdf0e10cSrcweir                 // Using SdrBlockTextPrimitive2D OTOH is critical since it internally
255cdf0e10cSrcweir                 // uses the SdrObject it references. To solve this, create a temp
256cdf0e10cSrcweir                 // SdrObject with Attributes and Text, generate a SdrBlockTextPrimitive2D
257cdf0e10cSrcweir                 // directly and immediately decompose it. After that, it is no longer
258cdf0e10cSrcweir                 // needed and can be deleted.
259cdf0e10cSrcweir 
260cdf0e10cSrcweir                 // create temp RectObj as TextObj and set needed attributes
261cdf0e10cSrcweir                 SdrRectObj aRectObj(OBJ_TEXT);
262cdf0e10cSrcweir                 aRectObj.SetModel(GetGrafObject().GetModel());
263cdf0e10cSrcweir                 aRectObj.NbcSetText(aDraftText);
264cdf0e10cSrcweir                 aRectObj.SetMergedItem(SvxColorItem(Color(COL_LIGHTRED), EE_CHAR_COLOR));
265cdf0e10cSrcweir 
266cdf0e10cSrcweir                 // get SdrText and OPO
267cdf0e10cSrcweir                 SdrText* pSdrText = aRectObj.getText(0);
268cdf0e10cSrcweir                 OutlinerParaObject* pOPO = aRectObj.GetOutlinerParaObject();
269cdf0e10cSrcweir 
270cdf0e10cSrcweir                 if(pSdrText && pOPO)
271cdf0e10cSrcweir                 {
272cdf0e10cSrcweir                     // directly use the remaining space as TextRangeTransform
273cdf0e10cSrcweir                     const basegfx::B2DHomMatrix aTextRangeTransform(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
274cdf0e10cSrcweir                         aScale, fShearX, fRotate, aTranslate));
275cdf0e10cSrcweir 
276cdf0e10cSrcweir                     // directly create temp SdrBlockTextPrimitive2D
277cdf0e10cSrcweir                     drawinglayer::primitive2d::SdrBlockTextPrimitive2D aBlockTextPrimitive(
278cdf0e10cSrcweir                         pSdrText,
279cdf0e10cSrcweir                         *pOPO,
280cdf0e10cSrcweir                         aTextRangeTransform,
281cdf0e10cSrcweir                         SDRTEXTHORZADJUST_LEFT,
282cdf0e10cSrcweir                         SDRTEXTVERTADJUST_TOP,
283cdf0e10cSrcweir                         false,
284cdf0e10cSrcweir                         false,
285cdf0e10cSrcweir                         false,
286cdf0e10cSrcweir                         false,
287cdf0e10cSrcweir                         false);
288cdf0e10cSrcweir 
289cdf0e10cSrcweir                     // decompose immediately with neutral ViewInformation. This will
290cdf0e10cSrcweir                     // layout the text to more simple TextPrimitives from drawinglayer
291cdf0e10cSrcweir                     const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
292cdf0e10cSrcweir 
293cdf0e10cSrcweir                     drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(
294cdf0e10cSrcweir                         xRetval,
295cdf0e10cSrcweir                         aBlockTextPrimitive.get2DDecomposition(aViewInformation2D));
296cdf0e10cSrcweir                 }
297cdf0e10cSrcweir             }
298cdf0e10cSrcweir 
299cdf0e10cSrcweir             return xRetval;
300cdf0e10cSrcweir         }
301cdf0e10cSrcweir 
createViewIndependentPrimitive2DSequence() const302cdf0e10cSrcweir         drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createViewIndependentPrimitive2DSequence() const
303cdf0e10cSrcweir         {
304cdf0e10cSrcweir             drawinglayer::primitive2d::Primitive2DSequence xRetval;
305cdf0e10cSrcweir             const SfxItemSet& rItemSet = GetGrafObject().GetMergedItemSet();
306cdf0e10cSrcweir 
307cdf0e10cSrcweir             // create and fill GraphicAttr
308cdf0e10cSrcweir             GraphicAttr aLocalGrafInfo;
309cdf0e10cSrcweir             const sal_uInt16 nTrans(((SdrGrafTransparenceItem&)rItemSet.Get(SDRATTR_GRAFTRANSPARENCE)).GetValue());
310cdf0e10cSrcweir             const SdrGrafCropItem& rCrop((const SdrGrafCropItem&)rItemSet.Get(SDRATTR_GRAFCROP));
311cdf0e10cSrcweir             aLocalGrafInfo.SetLuminance(((SdrGrafLuminanceItem&)rItemSet.Get(SDRATTR_GRAFLUMINANCE)).GetValue());
312cdf0e10cSrcweir             aLocalGrafInfo.SetContrast(((SdrGrafContrastItem&)rItemSet.Get(SDRATTR_GRAFCONTRAST)).GetValue());
313cdf0e10cSrcweir             aLocalGrafInfo.SetChannelR(((SdrGrafRedItem&)rItemSet.Get(SDRATTR_GRAFRED)).GetValue());
314cdf0e10cSrcweir             aLocalGrafInfo.SetChannelG(((SdrGrafGreenItem&)rItemSet.Get(SDRATTR_GRAFGREEN)).GetValue());
315cdf0e10cSrcweir             aLocalGrafInfo.SetChannelB(((SdrGrafBlueItem&)rItemSet.Get(SDRATTR_GRAFBLUE)).GetValue());
316cdf0e10cSrcweir             aLocalGrafInfo.SetGamma(((SdrGrafGamma100Item&)rItemSet.Get(SDRATTR_GRAFGAMMA)).GetValue() * 0.01);
317cdf0e10cSrcweir             aLocalGrafInfo.SetTransparency((sal_uInt8)::basegfx::fround(Min(nTrans, (sal_uInt16)100) * 2.55));
318cdf0e10cSrcweir             aLocalGrafInfo.SetInvert(((SdrGrafInvertItem&)rItemSet.Get(SDRATTR_GRAFINVERT)).GetValue());
319cdf0e10cSrcweir             aLocalGrafInfo.SetDrawMode(((SdrGrafModeItem&)rItemSet.Get(SDRATTR_GRAFMODE)).GetValue());
320cdf0e10cSrcweir             aLocalGrafInfo.SetCrop(rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom());
321cdf0e10cSrcweir 
3224bf7a51aSArmin Le Grand             // we have content if graphic is not completely transparent
3234bf7a51aSArmin Le Grand             const bool bHasContent(255L != aLocalGrafInfo.GetTransparency());
3244bf7a51aSArmin Le Grand             drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute(
3254bf7a51aSArmin Le Grand                 drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute(
3264bf7a51aSArmin Le Grand                     rItemSet,
3274bf7a51aSArmin Le Grand                     GetGrafObject().getText(0),
3284bf7a51aSArmin Le Grand                     bHasContent));
329cdf0e10cSrcweir 
330cdf0e10cSrcweir             // take unrotated snap rect for position and size. Directly use model data, not getBoundRect() or getSnapRect()
331cdf0e10cSrcweir             // which will use the primitive data we just create in the near future
332cdf0e10cSrcweir             const Rectangle& rRectangle = GetGrafObject().GetGeoRect();
333cdf0e10cSrcweir             const ::basegfx::B2DRange aObjectRange(
334cdf0e10cSrcweir                 rRectangle.Left(), rRectangle.Top(),
335cdf0e10cSrcweir                 rRectangle.Right(), rRectangle.Bottom());
336cdf0e10cSrcweir 
337cdf0e10cSrcweir             // look for mirroring
338cdf0e10cSrcweir             const GeoStat& rGeoStat(GetGrafObject().GetGeoStat());
339cdf0e10cSrcweir             const sal_Int32 nDrehWink(rGeoStat.nDrehWink);
340cdf0e10cSrcweir             const bool bRota180(18000 == nDrehWink);
341cdf0e10cSrcweir             const bool bMirrored(GetGrafObject().IsMirrored());
342cdf0e10cSrcweir             const sal_uInt16 nMirrorCase(bRota180 ? (bMirrored ? 3 : 4) : (bMirrored ? 2 : 1));
343cdf0e10cSrcweir             bool bHMirr((2 == nMirrorCase ) || (4 == nMirrorCase));
344cdf0e10cSrcweir             bool bVMirr((3 == nMirrorCase ) || (4 == nMirrorCase));
345cdf0e10cSrcweir 
346cdf0e10cSrcweir             // set mirror flags at LocalGrafInfo. Take into account that the geometry in
347cdf0e10cSrcweir             // aObjectRange is already changed and rotated when bRota180 is used. To rebuild
348*c64e43daSmseidel             // that old behavior (as long as part of the model data), correct the H/V flags
349cdf0e10cSrcweir             // accordingly. The created bitmapPrimitive WILL use the rotation, too.
350cdf0e10cSrcweir             if(bRota180)
351cdf0e10cSrcweir             {
352cdf0e10cSrcweir                 // if bRota180 which is used for vertical mirroring, the graphic will already be rotated
353cdf0e10cSrcweir                 // by 180 degrees. To correct, switch off VMirror and invert HMirroring.
354cdf0e10cSrcweir                 bHMirr = !bHMirr;
355cdf0e10cSrcweir                 bVMirr = false;
356cdf0e10cSrcweir             }
357cdf0e10cSrcweir 
358cdf0e10cSrcweir             if(bHMirr || bVMirr)
359cdf0e10cSrcweir             {
360cdf0e10cSrcweir                 aLocalGrafInfo.SetMirrorFlags((bHMirr ? BMP_MIRROR_HORZ : 0)|(bVMirr ? BMP_MIRROR_VERT : 0));
361cdf0e10cSrcweir             }
362cdf0e10cSrcweir 
363cdf0e10cSrcweir             // fill object matrix
364cdf0e10cSrcweir             const double fShearX(rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0);
365cdf0e10cSrcweir             const double fRotate(nDrehWink ? (36000 - nDrehWink) * F_PI18000 : 0.0);
366cdf0e10cSrcweir             const basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
367cdf0e10cSrcweir                 aObjectRange.getWidth(), aObjectRange.getHeight(),
368cdf0e10cSrcweir                 fShearX, fRotate,
369cdf0e10cSrcweir                 aObjectRange.getMinX(), aObjectRange.getMinY()));
370cdf0e10cSrcweir 
371*c64e43daSmseidel             // get the current, unchanged graphic object from SdrGrafObj
372cdf0e10cSrcweir             const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false);
373cdf0e10cSrcweir 
374cdf0e10cSrcweir             if(visualisationUsesPresObj())
375cdf0e10cSrcweir             {
376cdf0e10cSrcweir                 // it's an EmptyPresObj, create the SdrGrafPrimitive2D without content and another scaled one
377cdf0e10cSrcweir                 // with the content which is the placeholder graphic
378c0d661f1SArmin Le Grand                 xRetval = createVIP2DSForPresObj(aObjectMatrix, aAttribute);
379cdf0e10cSrcweir             }
380cdf0e10cSrcweir             else if(visualisationUsesDraft())
381cdf0e10cSrcweir             {
382cdf0e10cSrcweir                 // #i102380# The graphic is swapped out. To not force a swap-in here, there is a mechanism
383*c64e43daSmseidel                 // which shows a swapped-out-visualization (which gets created here now) and an asynchronous
384*c64e43daSmseidel                 // visual update mechanism for swapped-out graphics when they were loaded (see AsynchGraphicLoadingEvent
385cdf0e10cSrcweir                 // and ViewObjectContactOfGraphic implementation). Not forcing the swap-in here allows faster
386cdf0e10cSrcweir                 // (non-blocking) processing here and thus in the effect e.g. fast scrolling through pages
387cdf0e10cSrcweir                 xRetval = createVIP2DSForDraft(aObjectMatrix, aAttribute);
388cdf0e10cSrcweir             }
389cdf0e10cSrcweir             else
390cdf0e10cSrcweir             {
391cdf0e10cSrcweir                 // create primitive. Info: Calling the copy-constructor of GraphicObject in this
392cdf0e10cSrcweir                 // SdrGrafPrimitive2D constructor will force a full swap-in of the graphic
393ddde725dSArmin Le Grand                 const drawinglayer::primitive2d::Primitive2DReference xReference(
394ddde725dSArmin Le Grand                     new drawinglayer::primitive2d::SdrGrafPrimitive2D(
395cdf0e10cSrcweir                         aObjectMatrix,
396cdf0e10cSrcweir                         aAttribute,
397cdf0e10cSrcweir                         rGraphicObject,
398cdf0e10cSrcweir                         aLocalGrafInfo));
399cdf0e10cSrcweir 
400cdf0e10cSrcweir                 xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
401cdf0e10cSrcweir             }
402cdf0e10cSrcweir 
403cdf0e10cSrcweir             // always append an invisible outline for the cases where no visible content exists
404cdf0e10cSrcweir             drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval,
405cdf0e10cSrcweir                 drawinglayer::primitive2d::createHiddenGeometryPrimitives2D(
406cdf0e10cSrcweir                     false, aObjectMatrix));
407cdf0e10cSrcweir 
408cdf0e10cSrcweir             return xRetval;
409cdf0e10cSrcweir         }
410cdf0e10cSrcweir 
visualisationUsesPresObj() const411cdf0e10cSrcweir         bool ViewContactOfGraphic::visualisationUsesPresObj() const
412cdf0e10cSrcweir         {
413cdf0e10cSrcweir             return GetGrafObject().IsEmptyPresObj();
414cdf0e10cSrcweir         }
415cdf0e10cSrcweir 
visualisationUsesDraft() const416cdf0e10cSrcweir         bool ViewContactOfGraphic::visualisationUsesDraft() const
417cdf0e10cSrcweir         {
418cdf0e10cSrcweir             // no draft when already PresObj
419cdf0e10cSrcweir             if(visualisationUsesPresObj())
420cdf0e10cSrcweir                 return false;
421cdf0e10cSrcweir 
422cdf0e10cSrcweir             // draft when swapped out
423cdf0e10cSrcweir             const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false);
424cdf0e10cSrcweir             static bool bAllowReplacements(true);
425cdf0e10cSrcweir 
426cdf0e10cSrcweir             if(rGraphicObject.IsSwappedOut() && bAllowReplacements)
427cdf0e10cSrcweir                 return true;
428cdf0e10cSrcweir 
429cdf0e10cSrcweir             // draft when no graphic
430cdf0e10cSrcweir             if(GRAPHIC_NONE == rGraphicObject.GetType() || GRAPHIC_DEFAULT == rGraphicObject.GetType())
431cdf0e10cSrcweir                 return true;
432cdf0e10cSrcweir 
433cdf0e10cSrcweir             return false;
434cdf0e10cSrcweir         }
435cdf0e10cSrcweir 
436cdf0e10cSrcweir     } // end of namespace contact
437cdf0e10cSrcweir } // end of namespace sdr
438cdf0e10cSrcweir 
439*c64e43daSmseidel /* vim: set noet sw=4 ts=4: */
440