xref: /AOO41X/main/oox/source/xls/drawingbase.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "oox/xls/drawingbase.hxx"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include <com/sun/star/awt/Rectangle.hpp>
31*cdf0e10cSrcweir #include "oox/helper/attributelist.hxx"
32*cdf0e10cSrcweir #include "oox/helper/binaryinputstream.hxx"
33*cdf0e10cSrcweir #include "oox/xls/unitconverter.hxx"
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir namespace oox {
36*cdf0e10cSrcweir namespace xls {
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir // ============================================================================
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir using namespace ::com::sun::star::awt;
41*cdf0e10cSrcweir using namespace ::com::sun::star::table;
42*cdf0e10cSrcweir using namespace ::oox::drawingml;
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir using ::rtl::OUString;
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir // ============================================================================
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir namespace {
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir /** Converts the passed 32-bit integer value from 1/100 mm to EMUs. */
51*cdf0e10cSrcweir inline sal_Int64 lclHmmToEmu( sal_Int32 nValue )
52*cdf0e10cSrcweir {
53*cdf0e10cSrcweir     return (nValue < 0) ? -1 : convertHmmToEmu( nValue );
54*cdf0e10cSrcweir }
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir /** Converts the passed 64-bit integer value from EMUs to 1/100 mm. */
57*cdf0e10cSrcweir inline sal_Int32 lclEmuToHmm( sal_Int64 nValue )
58*cdf0e10cSrcweir {
59*cdf0e10cSrcweir     return (nValue < 0) ? -1 : convertEmuToHmm( nValue );
60*cdf0e10cSrcweir }
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir /** Reads the cell anchor model from a BIFF or DFF stream. */
63*cdf0e10cSrcweir BinaryInputStream& operator>>( BinaryInputStream& rStrm, CellAnchorModel& rModel )
64*cdf0e10cSrcweir {
65*cdf0e10cSrcweir     // all members are given as 16-bit unsigned values
66*cdf0e10cSrcweir     rModel.mnCol = rStrm.readuInt16();
67*cdf0e10cSrcweir     rModel.mnColOffset = rStrm.readuInt16();
68*cdf0e10cSrcweir     rModel.mnRow = rStrm.readuInt16();
69*cdf0e10cSrcweir     rModel.mnRowOffset = rStrm.readuInt16();
70*cdf0e10cSrcweir     return rStrm;
71*cdf0e10cSrcweir }
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir } // namespace
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir // ============================================================================
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir CellAnchorModel::CellAnchorModel() :
78*cdf0e10cSrcweir     mnCol( -1 ),
79*cdf0e10cSrcweir     mnRow( -1 ),
80*cdf0e10cSrcweir     mnColOffset( 0 ),
81*cdf0e10cSrcweir     mnRowOffset( 0 )
82*cdf0e10cSrcweir {
83*cdf0e10cSrcweir }
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir // ----------------------------------------------------------------------------
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir AnchorClientDataModel::AnchorClientDataModel() :
88*cdf0e10cSrcweir     mbLocksWithSheet( true ),
89*cdf0e10cSrcweir     mbPrintsWithSheet( true )
90*cdf0e10cSrcweir {
91*cdf0e10cSrcweir }
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir // ============================================================================
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir ShapeAnchor::ShapeAnchor( const WorksheetHelper& rHelper ) :
96*cdf0e10cSrcweir     WorksheetHelper( rHelper ),
97*cdf0e10cSrcweir     meAnchorType( ANCHOR_INVALID ),
98*cdf0e10cSrcweir     meCellAnchorType( CELLANCHOR_EMU ),
99*cdf0e10cSrcweir     mnEditAs( XML_twoCell )
100*cdf0e10cSrcweir {
101*cdf0e10cSrcweir }
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir void ShapeAnchor::importAnchor( sal_Int32 nElement, const AttributeList& rAttribs )
104*cdf0e10cSrcweir {
105*cdf0e10cSrcweir     switch( nElement )
106*cdf0e10cSrcweir     {
107*cdf0e10cSrcweir         case XDR_TOKEN( absoluteAnchor ):
108*cdf0e10cSrcweir             meAnchorType = ANCHOR_ABSOLUTE;
109*cdf0e10cSrcweir         break;
110*cdf0e10cSrcweir         case XDR_TOKEN( oneCellAnchor ):
111*cdf0e10cSrcweir             meAnchorType = ANCHOR_ONECELL;
112*cdf0e10cSrcweir         break;
113*cdf0e10cSrcweir         case XDR_TOKEN( twoCellAnchor ):
114*cdf0e10cSrcweir             meAnchorType = ANCHOR_TWOCELL;
115*cdf0e10cSrcweir             mnEditAs = rAttribs.getToken( XML_editAs, XML_twoCell );
116*cdf0e10cSrcweir         break;
117*cdf0e10cSrcweir         default:
118*cdf0e10cSrcweir             OSL_ENSURE( false, "ShapeAnchor::importAnchor - unexpected element" );
119*cdf0e10cSrcweir     }
120*cdf0e10cSrcweir     meCellAnchorType = CELLANCHOR_EMU;
121*cdf0e10cSrcweir }
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir void ShapeAnchor::importPos( const AttributeList& rAttribs )
124*cdf0e10cSrcweir {
125*cdf0e10cSrcweir     OSL_ENSURE( meAnchorType == ANCHOR_ABSOLUTE, "ShapeAnchor::importPos - unexpected 'xdr:pos' element" );
126*cdf0e10cSrcweir     maPos.X = rAttribs.getHyper( XML_x, 0 );
127*cdf0e10cSrcweir     maPos.Y = rAttribs.getHyper( XML_y, 0 );
128*cdf0e10cSrcweir }
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir void ShapeAnchor::importExt( const AttributeList& rAttribs )
131*cdf0e10cSrcweir {
132*cdf0e10cSrcweir     OSL_ENSURE( (meAnchorType == ANCHOR_ABSOLUTE) || (meAnchorType == ANCHOR_ONECELL), "ShapeAnchor::importExt - unexpected 'xdr:ext' element" );
133*cdf0e10cSrcweir     maSize.Width = rAttribs.getHyper( XML_cx, 0 );
134*cdf0e10cSrcweir     maSize.Height = rAttribs.getHyper( XML_cy, 0 );
135*cdf0e10cSrcweir }
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir void ShapeAnchor::importClientData( const AttributeList& rAttribs )
138*cdf0e10cSrcweir {
139*cdf0e10cSrcweir     maClientData.mbLocksWithSheet  = rAttribs.getBool( XML_fLocksWithSheet, true );
140*cdf0e10cSrcweir     maClientData.mbPrintsWithSheet = rAttribs.getBool( XML_fPrintsWithSheet, true );
141*cdf0e10cSrcweir }
142*cdf0e10cSrcweir 
143*cdf0e10cSrcweir void ShapeAnchor::setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, const OUString& rValue )
144*cdf0e10cSrcweir {
145*cdf0e10cSrcweir     CellAnchorModel* pCellAnchor = 0;
146*cdf0e10cSrcweir     switch( nParentContext )
147*cdf0e10cSrcweir     {
148*cdf0e10cSrcweir         case XDR_TOKEN( from ):
149*cdf0e10cSrcweir             OSL_ENSURE( (meAnchorType == ANCHOR_ONECELL) || (meAnchorType == ANCHOR_TWOCELL), "ShapeAnchor::setCellPos - unexpected 'xdr:from' element" );
150*cdf0e10cSrcweir             pCellAnchor = &maFrom;
151*cdf0e10cSrcweir         break;
152*cdf0e10cSrcweir         case XDR_TOKEN( to ):
153*cdf0e10cSrcweir             OSL_ENSURE( meAnchorType == ANCHOR_TWOCELL, "ShapeAnchor::setCellPos - unexpected 'xdr:to' element" );
154*cdf0e10cSrcweir             pCellAnchor = &maTo;
155*cdf0e10cSrcweir         break;
156*cdf0e10cSrcweir         default:
157*cdf0e10cSrcweir             OSL_ENSURE( false, "ShapeAnchor::setCellPos - unexpected parent element" );
158*cdf0e10cSrcweir     }
159*cdf0e10cSrcweir     if( pCellAnchor ) switch( nElement )
160*cdf0e10cSrcweir     {
161*cdf0e10cSrcweir         case XDR_TOKEN( col ):      pCellAnchor->mnCol = rValue.toInt32();          break;
162*cdf0e10cSrcweir         case XDR_TOKEN( row ):      pCellAnchor->mnRow = rValue.toInt32();          break;
163*cdf0e10cSrcweir         case XDR_TOKEN( colOff ):   pCellAnchor->mnColOffset = rValue.toInt64();    break;
164*cdf0e10cSrcweir         case XDR_TOKEN( rowOff ):   pCellAnchor->mnRowOffset = rValue.toInt64();    break;
165*cdf0e10cSrcweir         default:    OSL_ENSURE( false, "ShapeAnchor::setCellPos - unexpected element" );
166*cdf0e10cSrcweir     }
167*cdf0e10cSrcweir }
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir void ShapeAnchor::importVmlAnchor( const OUString& rAnchor )
170*cdf0e10cSrcweir {
171*cdf0e10cSrcweir     meAnchorType = ANCHOR_TWOCELL;          /// VML uses two-cell anchors only
172*cdf0e10cSrcweir     meCellAnchorType = CELLANCHOR_PIXEL;    /// VML uses screen pixels for offset values
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir     ::std::vector< OUString > aTokens;
175*cdf0e10cSrcweir     sal_Int32 nIndex = 0;
176*cdf0e10cSrcweir     while( nIndex >= 0 )
177*cdf0e10cSrcweir         aTokens.push_back( rAnchor.getToken( 0, ',', nIndex ).trim() );
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir     OSL_ENSURE( aTokens.size() >= 8, "ShapeAnchor::importVmlAnchor - missing anchor tokens" );
180*cdf0e10cSrcweir     if( aTokens.size() >= 8 )
181*cdf0e10cSrcweir     {
182*cdf0e10cSrcweir         maFrom.mnCol       = aTokens[ 0 ].toInt32();
183*cdf0e10cSrcweir         maFrom.mnColOffset = aTokens[ 1 ].toInt32();
184*cdf0e10cSrcweir         maFrom.mnRow       = aTokens[ 2 ].toInt32();
185*cdf0e10cSrcweir         maFrom.mnRowOffset = aTokens[ 3 ].toInt32();
186*cdf0e10cSrcweir         maTo.mnCol         = aTokens[ 4 ].toInt32();
187*cdf0e10cSrcweir         maTo.mnColOffset   = aTokens[ 5 ].toInt32();
188*cdf0e10cSrcweir         maTo.mnRow         = aTokens[ 6 ].toInt32();
189*cdf0e10cSrcweir         maTo.mnRowOffset   = aTokens[ 7 ].toInt32();
190*cdf0e10cSrcweir     }
191*cdf0e10cSrcweir }
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir void ShapeAnchor::importBiffAnchor( BinaryInputStream& rStrm )
194*cdf0e10cSrcweir {
195*cdf0e10cSrcweir     meAnchorType = ANCHOR_TWOCELL;          /// BIFF/DFF use two-cell anchors only
196*cdf0e10cSrcweir     meCellAnchorType = CELLANCHOR_COLROW;   /// BIFF/DFF use fraction of column/row for offset values
197*cdf0e10cSrcweir     rStrm >> maFrom >> maTo;
198*cdf0e10cSrcweir }
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir EmuRectangle ShapeAnchor::calcAnchorRectEmu( const Size& rPageSizeHmm ) const
201*cdf0e10cSrcweir {
202*cdf0e10cSrcweir     AddressConverter& rAddrConv = getAddressConverter();
203*cdf0e10cSrcweir     EmuSize aPageSize( lclHmmToEmu( rPageSizeHmm.Width ), lclHmmToEmu( rPageSizeHmm.Height ) );
204*cdf0e10cSrcweir     EmuRectangle aAnchorRect( -1, -1, -1, -1 );
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir     // calculate shape position
207*cdf0e10cSrcweir     switch( meAnchorType )
208*cdf0e10cSrcweir     {
209*cdf0e10cSrcweir         case ANCHOR_ABSOLUTE:
210*cdf0e10cSrcweir             OSL_ENSURE( maPos.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid position" );
211*cdf0e10cSrcweir             if( maPos.isValid() && (maPos.X < aPageSize.Width) && (maPos.Y < aPageSize.Height) )
212*cdf0e10cSrcweir                 aAnchorRect.setPos( maPos );
213*cdf0e10cSrcweir         break;
214*cdf0e10cSrcweir         case ANCHOR_ONECELL:
215*cdf0e10cSrcweir         case ANCHOR_TWOCELL:
216*cdf0e10cSrcweir             OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid position" );
217*cdf0e10cSrcweir             if( maFrom.isValid() && rAddrConv.checkCol( maFrom.mnCol, true ) && rAddrConv.checkRow( maFrom.mnRow, true ) )
218*cdf0e10cSrcweir             {
219*cdf0e10cSrcweir                 EmuPoint aPoint = calcCellAnchorEmu( maFrom );
220*cdf0e10cSrcweir                 if( (aPoint.X < aPageSize.Width) && (aPoint.Y < aPageSize.Height) )
221*cdf0e10cSrcweir                     aAnchorRect.setPos( aPoint );
222*cdf0e10cSrcweir             }
223*cdf0e10cSrcweir         break;
224*cdf0e10cSrcweir         case ANCHOR_INVALID:
225*cdf0e10cSrcweir             OSL_ENSURE( false, "ShapeAnchor::calcAnchorRectEmu - invalid anchor" );
226*cdf0e10cSrcweir         break;
227*cdf0e10cSrcweir     }
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir     // calculate shape size
230*cdf0e10cSrcweir     if( (aAnchorRect.X >= 0) && (aAnchorRect.Y >= 0) ) switch( meAnchorType )
231*cdf0e10cSrcweir     {
232*cdf0e10cSrcweir         case ANCHOR_ABSOLUTE:
233*cdf0e10cSrcweir         case ANCHOR_ONECELL:
234*cdf0e10cSrcweir             OSL_ENSURE( maSize.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid size" );
235*cdf0e10cSrcweir             if( maSize.isValid() )
236*cdf0e10cSrcweir             {
237*cdf0e10cSrcweir                 aAnchorRect.Width = ::std::min< sal_Int64 >( maSize.Width, aPageSize.Width - aAnchorRect.X );
238*cdf0e10cSrcweir                 aAnchorRect.Height = ::std::min< sal_Int64 >( maSize.Height, aPageSize.Height - aAnchorRect.Y );
239*cdf0e10cSrcweir             }
240*cdf0e10cSrcweir         break;
241*cdf0e10cSrcweir         case ANCHOR_TWOCELL:
242*cdf0e10cSrcweir             OSL_ENSURE( maTo.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid position" );
243*cdf0e10cSrcweir             if( maTo.isValid() )
244*cdf0e10cSrcweir             {
245*cdf0e10cSrcweir                 /*  Pass a valid cell address to calcCellAnchorEmu(), otherwise
246*cdf0e10cSrcweir                     nothing useful is returned, even if either row or column is valid. */
247*cdf0e10cSrcweir                 CellAddress aToCell = rAddrConv.createValidCellAddress( BinAddress( maTo.mnCol, maTo.mnRow ), getSheetIndex(), true );
248*cdf0e10cSrcweir                 CellAnchorModel aValidTo = maTo;
249*cdf0e10cSrcweir                 aValidTo.mnCol = aToCell.Column;
250*cdf0e10cSrcweir                 aValidTo.mnRow = aToCell.Row;
251*cdf0e10cSrcweir                 EmuPoint aPoint = calcCellAnchorEmu( aValidTo );
252*cdf0e10cSrcweir                 // width (if column index is valid, use the calculated offset, otherwise stretch to maximum available X position)
253*cdf0e10cSrcweir                 aAnchorRect.Width = aPageSize.Width - aAnchorRect.X;
254*cdf0e10cSrcweir                 if( aToCell.Column == maTo.mnCol )
255*cdf0e10cSrcweir                     aAnchorRect.Width = ::std::min< sal_Int64 >( aPoint.X - aAnchorRect.X + 1, aAnchorRect.Width );
256*cdf0e10cSrcweir                 // height (if row index is valid, use the calculated offset, otherwise stretch to maximum available Y position)
257*cdf0e10cSrcweir                 aAnchorRect.Height = aPageSize.Height - aAnchorRect.Y;
258*cdf0e10cSrcweir                 if( aToCell.Row == maTo.mnRow )
259*cdf0e10cSrcweir                     aAnchorRect.Height = ::std::min< sal_Int64 >( aPoint.Y - aAnchorRect.Y + 1, aAnchorRect.Height );
260*cdf0e10cSrcweir             }
261*cdf0e10cSrcweir         break;
262*cdf0e10cSrcweir         case ANCHOR_INVALID:
263*cdf0e10cSrcweir         break;
264*cdf0e10cSrcweir     }
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir     // add 0.75 mm (27,000 EMUs) in X direction to correct display error
267*cdf0e10cSrcweir     if( aAnchorRect.X >= 0 )
268*cdf0e10cSrcweir         aAnchorRect.X += 27000;
269*cdf0e10cSrcweir     // remove 0.25 mm (9,000 EMUs) in Y direction to correct display error
270*cdf0e10cSrcweir     if( aAnchorRect.Y >= 9000 )
271*cdf0e10cSrcweir         aAnchorRect.Y -= 9000;
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir     return aAnchorRect;
274*cdf0e10cSrcweir }
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir Rectangle ShapeAnchor::calcAnchorRectHmm( const Size& rPageSizeHmm ) const
277*cdf0e10cSrcweir {
278*cdf0e10cSrcweir     EmuRectangle aAnchorRect = calcAnchorRectEmu( rPageSizeHmm );
279*cdf0e10cSrcweir     return Rectangle( lclEmuToHmm( aAnchorRect.X ), lclEmuToHmm( aAnchorRect.Y ), lclEmuToHmm( aAnchorRect.Width ), lclEmuToHmm( aAnchorRect.Height ) );
280*cdf0e10cSrcweir }
281*cdf0e10cSrcweir 
282*cdf0e10cSrcweir // private --------------------------------------------------------------------
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir EmuPoint ShapeAnchor::calcCellAnchorEmu( const CellAnchorModel& rModel ) const
285*cdf0e10cSrcweir {
286*cdf0e10cSrcweir     // calculate position of top-left edge of the cell
287*cdf0e10cSrcweir     Point aPoint = getCellPosition( rModel.mnCol, rModel.mnRow );
288*cdf0e10cSrcweir     EmuPoint aEmuPoint( lclHmmToEmu( aPoint.X ), lclHmmToEmu( aPoint.Y ) );
289*cdf0e10cSrcweir 
290*cdf0e10cSrcweir     // add the offset inside the cell
291*cdf0e10cSrcweir     switch( meCellAnchorType )
292*cdf0e10cSrcweir     {
293*cdf0e10cSrcweir         case CELLANCHOR_EMU:
294*cdf0e10cSrcweir             aEmuPoint.X += rModel.mnColOffset;
295*cdf0e10cSrcweir             aEmuPoint.Y += rModel.mnRowOffset;
296*cdf0e10cSrcweir         break;
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir         case CELLANCHOR_PIXEL:
299*cdf0e10cSrcweir         {
300*cdf0e10cSrcweir             const UnitConverter& rUnitConv = getUnitConverter();
301*cdf0e10cSrcweir             aEmuPoint.X += static_cast< sal_Int64 >( rUnitConv.scaleValue( static_cast< double >( rModel.mnColOffset ), UNIT_SCREENX, UNIT_EMU ) );
302*cdf0e10cSrcweir             aEmuPoint.Y += static_cast< sal_Int64 >( rUnitConv.scaleValue( static_cast< double >( rModel.mnRowOffset ), UNIT_SCREENY, UNIT_EMU ) );
303*cdf0e10cSrcweir         }
304*cdf0e10cSrcweir         break;
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir         case CELLANCHOR_COLROW:
307*cdf0e10cSrcweir         {
308*cdf0e10cSrcweir             Size aCellSize = getCellSize( rModel.mnCol, rModel.mnRow );
309*cdf0e10cSrcweir             EmuSize aEmuSize( lclHmmToEmu( aCellSize.Width ), lclHmmToEmu( aCellSize.Height ) );
310*cdf0e10cSrcweir             // X offset is given in 1/1024 of column width
311*cdf0e10cSrcweir             aEmuPoint.X += static_cast< sal_Int64 >( aEmuSize.Width * getLimitedValue< double >( static_cast< double >( rModel.mnColOffset ) / 1024.0, 0.0, 1.0 ) + 0.5 );
312*cdf0e10cSrcweir             // Y offset is given in 1/256 of row height
313*cdf0e10cSrcweir             aEmuPoint.Y += static_cast< sal_Int64 >( aEmuSize.Height * getLimitedValue< double >( static_cast< double >( rModel.mnRowOffset ) / 256.0, 0.0, 1.0 ) + 0.5 );
314*cdf0e10cSrcweir         }
315*cdf0e10cSrcweir         break;
316*cdf0e10cSrcweir     }
317*cdf0e10cSrcweir 
318*cdf0e10cSrcweir     return aEmuPoint;
319*cdf0e10cSrcweir }
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir // ============================================================================
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir } // namespace xls
324*cdf0e10cSrcweir } // namespace oox
325