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 <hintids.hxx>
21 #include <tools/poly.hxx>
22 #include <svl/stritem.hxx>
23 #include <svx/contdlg.hxx>
24 #include <vcl/svapp.hxx>
25 #include <doc.hxx>
26 #include <fmtcol.hxx>
27 #include <ndnotxt.hxx>
28 #include <ndgrf.hxx>
29 #include <ndole.hxx>
30 #include <ndindex.hxx>
31 #include <istyleaccess.hxx>
32 #include <SwStyleNameMapper.hxx>
33 
34 #include <frmfmt.hxx>
35 
SwNoTextNode(const SwNodeIndex & rWhere,const SwNodeType nNdType,SwGrfFormatColl * pGrfColl,SwAttrSet const * pAutoAttr)36 SwNoTextNode::SwNoTextNode( const SwNodeIndex & rWhere,
37                   const SwNodeType nNdType,
38                   SwGrfFormatColl *pGrfColl,
39                   SwAttrSet const * pAutoAttr ) :
40     SwContentNode( rWhere, nNdType, pGrfColl ),
41     m_bAutomaticContour( false ),
42     m_bContourMapModeValid( true ),
43     m_bPixelContour( false )
44 {
45     // Should this set a hard attribute?
46     if( pAutoAttr )
47         SetAttr( *pAutoAttr );
48 }
49 
~SwNoTextNode()50 SwNoTextNode::~SwNoTextNode()
51 {
52 }
53 
54 /// Creates an AttrSet for all derivations with ranges for frame-
55 /// and graphics-attributes.
NewAttrSet(SwAttrPool & rPool)56 void SwNoTextNode::NewAttrSet( SwAttrPool& rPool )
57 {
58     OSL_ENSURE( !mpAttrSet.get(), "AttrSet is already set" );
59     SwAttrSet aNewAttrSet( rPool, aNoTextNodeSetRange );
60 
61     // put names of parent style and conditional style:
62     const SwFormatColl* pFormatColl = GetFormatColl();
63     OUString sVal;
64     SwStyleNameMapper::FillProgName( pFormatColl->GetName(), sVal, SwGetPoolIdFromName::TxtColl );
65     SfxStringItem aFormatColl( RES_FRMATR_STYLE_NAME, sVal );
66     aNewAttrSet.Put( aFormatColl );
67 
68     aNewAttrSet.SetParent( &GetFormatColl()->GetAttrSet() );
69     mpAttrSet = GetDoc()->GetIStyleAccess().getAutomaticStyle( aNewAttrSet, IStyleAccess::AUTO_STYLE_NOTXT );
70 }
71 
72 /// Dummies for loading/saving of persistent data
73 /// when working with graphics and OLE objects
RestorePersistentData()74 bool SwNoTextNode::RestorePersistentData()
75 {
76     return true;
77 }
78 
SavePersistentData()79 bool SwNoTextNode::SavePersistentData()
80 {
81     return true;
82 }
83 
SetContour(const tools::PolyPolygon * pPoly,bool bAutomatic)84 void SwNoTextNode::SetContour( const tools::PolyPolygon *pPoly, bool bAutomatic )
85 {
86     if ( pPoly )
87         m_pContour.reset( new tools::PolyPolygon( *pPoly ) );
88     else
89         m_pContour.reset();
90     m_bAutomaticContour = bAutomatic;
91     m_bContourMapModeValid = true;
92     m_bPixelContour = false;
93 }
94 
CreateContour()95 void SwNoTextNode::CreateContour()
96 {
97     OSL_ENSURE( !m_pContour, "Contour available." );
98     m_pContour.reset( new tools::PolyPolygon(SvxContourDlg::CreateAutoContour(GetGraphic())) );
99     m_bAutomaticContour = true;
100     m_bContourMapModeValid = true;
101     m_bPixelContour = false;
102 }
103 
HasContour() const104 const tools::PolyPolygon *SwNoTextNode::HasContour() const
105 {
106     if( !m_bContourMapModeValid )
107     {
108         const MapMode aGrfMap( GetGraphic().GetPrefMapMode() );
109         bool bPixelGrf = aGrfMap.GetMapUnit() == MapUnit::MapPixel;
110         const MapMode aContourMap( bPixelGrf ? MapUnit::MapPixel : MapUnit::Map100thMM );
111         if( bPixelGrf ? !m_bPixelContour : aGrfMap != aContourMap )
112         {
113             double nGrfDPIx = 0.0;
114             double nGrfDPIy = 0.0;
115             {
116                 if ( !bPixelGrf && m_bPixelContour )
117                 {
118                     basegfx::B2DSize aDPI = GetGraphic().GetPPI();
119                     nGrfDPIx = aDPI.getX();
120                     nGrfDPIy = aDPI.getY();
121                 }
122             }
123             OSL_ENSURE( !bPixelGrf || aGrfMap == aContourMap,
124                         "scale factor for pixel unsupported" );
125             OutputDevice* pOutDev =
126                 (bPixelGrf || m_bPixelContour) ? Application::GetDefaultDevice()
127                                              : nullptr;
128             sal_uInt16 nPolyCount = m_pContour->Count();
129             for( sal_uInt16 j=0; j<nPolyCount; j++ )
130             {
131                 tools::Polygon& rPoly = (*m_pContour)[j];
132 
133                 sal_uInt16 nCount = rPoly.GetSize();
134                 for( sal_uInt16 i=0 ; i<nCount; i++ )
135                 {
136                     if( bPixelGrf )
137                         rPoly[i] = pOutDev->LogicToPixel( rPoly[i],
138                                                           aContourMap );
139                     else if( m_bPixelContour )
140                     {
141                         rPoly[i] = pOutDev->PixelToLogic( rPoly[i], aGrfMap );
142 
143                         if ( nGrfDPIx != 0 && nGrfDPIy != 0 )
144                         {
145                             rPoly[i] = Point( rPoly[i].getX() * pOutDev->GetDPIX() / nGrfDPIx,
146                                               rPoly[i].getY() * pOutDev->GetDPIY() / nGrfDPIy );
147                         }
148                     }
149                     else
150                         rPoly[i] = OutputDevice::LogicToLogic( rPoly[i],
151                                                                  aContourMap,
152                                                                  aGrfMap );
153                 }
154             }
155         }
156         const_cast<SwNoTextNode *>(this)->m_bContourMapModeValid = true;
157         const_cast<SwNoTextNode *>(this)->m_bPixelContour = false;
158     }
159 
160     return m_pContour.get();
161 }
162 
GetContour(tools::PolyPolygon & rPoly) const163 void SwNoTextNode::GetContour( tools::PolyPolygon &rPoly ) const
164 {
165     OSL_ENSURE( m_pContour, "Contour not available." );
166     rPoly = *HasContour();
167 }
168 
SetContourAPI(const tools::PolyPolygon * pPoly)169 void SwNoTextNode::SetContourAPI( const tools::PolyPolygon *pPoly )
170 {
171     if ( pPoly )
172         m_pContour.reset( new tools::PolyPolygon( *pPoly ) );
173     else
174         m_pContour.reset();
175     m_bContourMapModeValid = false;
176 }
177 
GetContourAPI(tools::PolyPolygon & rContour) const178 bool SwNoTextNode::GetContourAPI( tools::PolyPolygon &rContour ) const
179 {
180     if( !m_pContour )
181         return false;
182 
183     rContour = *m_pContour;
184     if( m_bContourMapModeValid )
185     {
186         const MapMode aGrfMap( GetGraphic().GetPrefMapMode() );
187         const MapMode aContourMap( MapUnit::Map100thMM );
188         OSL_ENSURE( aGrfMap.GetMapUnit() != MapUnit::MapPixel ||
189                 aGrfMap == MapMode( MapUnit::MapPixel ),
190                     "scale factor for pixel unsupported" );
191         if( aGrfMap.GetMapUnit() != MapUnit::MapPixel &&
192             aGrfMap != aContourMap )
193         {
194             sal_uInt16 nPolyCount = rContour.Count();
195             for( sal_uInt16 j=0; j<nPolyCount; j++ )
196             {
197                 tools::Polygon& rPoly = rContour[j];
198 
199                 sal_uInt16 nCount = rPoly.GetSize();
200                 for( sal_uInt16 i=0 ; i<nCount; i++ )
201                 {
202                     rPoly[i] = OutputDevice::LogicToLogic( rPoly[i], aGrfMap,
203                                                            aContourMap );
204                 }
205             }
206         }
207     }
208 
209     return true;
210 }
211 
IsPixelContour() const212 bool SwNoTextNode::IsPixelContour() const
213 {
214     bool bRet;
215     if( m_bContourMapModeValid )
216     {
217         const MapMode aGrfMap( GetGraphic().GetPrefMapMode() );
218         bRet = aGrfMap.GetMapUnit() == MapUnit::MapPixel;
219     }
220     else
221     {
222         bRet = m_bPixelContour;
223     }
224 
225     return bRet;
226 }
227 
GetGraphic() const228 Graphic SwNoTextNode::GetGraphic() const
229 {
230     Graphic aRet;
231     if ( GetGrfNode() )
232     {
233         aRet = static_cast<const SwGrfNode*>(this)->GetGrf(true);
234     }
235     else
236     {
237         OSL_ENSURE( GetOLENode(), "new type of Node?" );
238         aRet = *const_cast<SwOLENode*>(static_cast<const SwOLENode*>(this))->SwOLENode::GetGraphic();
239     }
240     return aRet;
241 }
242 
243 // #i73249#
SetTitle(const OUString & rTitle)244 void SwNoTextNode::SetTitle( const OUString& rTitle )
245 {
246     // Title attribute of <SdrObject> replaces own AlternateText attribute
247     SwFlyFrameFormat* pFlyFormat = dynamic_cast<SwFlyFrameFormat*>(GetFlyFormat());
248     OSL_ENSURE( pFlyFormat, "<SwNoTextNode::SetTitle(..)> - missing <SwFlyFrameFormat> instance" );
249     if ( !pFlyFormat )
250     {
251         return;
252     }
253 
254     pFlyFormat->SetObjTitle( rTitle );
255 }
256 
GetTitle() const257 OUString SwNoTextNode::GetTitle() const
258 {
259     const SwFlyFrameFormat* pFlyFormat = dynamic_cast<const SwFlyFrameFormat*>(GetFlyFormat());
260     OSL_ENSURE( pFlyFormat, "<SwNoTextNode::GetTitle(..)> - missing <SwFlyFrameFormat> instance" );
261     if ( !pFlyFormat )
262     {
263         return OUString();
264     }
265 
266     return pFlyFormat->GetObjTitle();
267 }
268 
SetDescription(const OUString & rDescription)269 void SwNoTextNode::SetDescription( const OUString& rDescription )
270 {
271     SwFlyFrameFormat* pFlyFormat = dynamic_cast<SwFlyFrameFormat*>(GetFlyFormat());
272     OSL_ENSURE( pFlyFormat, "<SwNoTextNode::SetDescription(..)> - missing <SwFlyFrameFormat> instance" );
273     if ( !pFlyFormat )
274     {
275         return;
276     }
277 
278     pFlyFormat->SetObjDescription( rDescription );
279 }
280 
GetDescription() const281 OUString SwNoTextNode::GetDescription() const
282 {
283     const SwFlyFrameFormat* pFlyFormat = dynamic_cast<const SwFlyFrameFormat*>(GetFlyFormat());
284     OSL_ENSURE( pFlyFormat, "<SwNoTextNode::GetDescription(..)> - missing <SwFlyFrameFormat> instance" );
285     if ( !pFlyFormat )
286     {
287         return OUString();
288     }
289 
290     return pFlyFormat->GetObjDescription();
291 }
292 
293 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
294