1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <vcl/mapmod.hxx>
22 #include <tools/gen.hxx>
23 #include <tools/fract.hxx>
24 #include <tools/stream.hxx>
25 #include <tools/vcompat.hxx>
26 #include <tools/debug.hxx>
31 struct MapMode::ImplMapMode
36 // NOTE: these Fraction must NOT have more than 32 bits precision
37 // because ReadFraction / WriteFraction do only 32 bits, so more than
38 // that cannot be stored in MetaFiles!
39 // => call ReduceInaccurate whenever setting these
44 friend SvStream
& ReadImplMapMode(SvStream
& rIStm
, ImplMapMode
& rMapMode
);
45 friend SvStream
& WriteImplMapMode(SvStream
& rOStm
, const ImplMapMode
& rMapMode
);
47 static ImplMapMode
* ImplGetStaticMapMode( MapUnit eUnit
);
50 ImplMapMode(const ImplMapMode
& rImpMapMode
);
53 MapMode::ImplMapMode::ImplMapMode() :
63 MapMode::ImplMapMode::ImplMapMode( const ImplMapMode
& rImplMapMode
) :
64 maOrigin( rImplMapMode
.maOrigin
),
65 maScaleX( rImplMapMode
.maScaleX
),
66 maScaleY( rImplMapMode
.maScaleY
)
69 meUnit
= rImplMapMode
.meUnit
;
73 SvStream
& ReadImplMapMode(SvStream
& rIStm
, MapMode::ImplMapMode
& rImplMapMode
)
75 VersionCompat
aCompat( rIStm
, StreamMode::READ
);
78 rIStm
.ReadUInt16( nTmp16
); rImplMapMode
.meUnit
= (MapUnit
) nTmp16
;
79 ReadPair( rIStm
, rImplMapMode
.maOrigin
);
80 ReadFraction( rIStm
, rImplMapMode
.maScaleX
);
81 ReadFraction( rIStm
, rImplMapMode
.maScaleY
);
82 rIStm
.ReadCharAsBool( rImplMapMode
.mbSimple
);
87 SvStream
& WriteImplMapMode(SvStream
& rOStm
, const MapMode::ImplMapMode
& rImplMapMode
)
89 VersionCompat
aCompat( rOStm
, StreamMode::WRITE
, 1 );
91 rOStm
.WriteUInt16( rImplMapMode
.meUnit
);
92 WritePair( rOStm
, rImplMapMode
.maOrigin
);
93 WriteFraction( rOStm
, rImplMapMode
.maScaleX
);
94 WriteFraction( rOStm
, rImplMapMode
.maScaleY
);
95 rOStm
.WriteBool( rImplMapMode
.mbSimple
);
100 MapMode::ImplMapMode
*
101 MapMode::ImplMapMode::ImplGetStaticMapMode(MapUnit eUnit
)
103 static long aStaticImplMapModeAry
[(MAP_LASTENUMDUMMY
)*sizeof(ImplMapMode
)/sizeof(long)];
105 // #i19496 check for out-of-bounds
106 if( eUnit
>= MAP_LASTENUMDUMMY
)
107 return reinterpret_cast<ImplMapMode
*>(aStaticImplMapModeAry
);
109 ImplMapMode
* pImplMapMode
= reinterpret_cast<ImplMapMode
*>(aStaticImplMapModeAry
)+eUnit
;
110 if ( !pImplMapMode
->mbSimple
)
112 Fraction
aDefFraction( 1, 1 );
113 pImplMapMode
->maScaleX
= aDefFraction
;
114 pImplMapMode
->maScaleY
= aDefFraction
;
115 pImplMapMode
->meUnit
= eUnit
;
116 pImplMapMode
->mbSimple
= true;
122 inline void MapMode::ImplMakeUnique()
124 // If there are other references, copy
125 if ( mpImplMapMode
->mnRefCount
!= 1 )
127 if ( mpImplMapMode
->mnRefCount
)
128 mpImplMapMode
->mnRefCount
--;
129 mpImplMapMode
= new ImplMapMode( *mpImplMapMode
);
136 mpImplMapMode
= ImplMapMode::ImplGetStaticMapMode( MAP_PIXEL
);
139 MapMode::MapMode( const MapMode
& rMapMode
)
141 DBG_ASSERT( rMapMode
.mpImplMapMode
->mnRefCount
< 0xFFFFFFFE, "MapMode: RefCount overflow" );
143 // Take over Shared Instance Data and increment refcount
144 mpImplMapMode
= rMapMode
.mpImplMapMode
;
145 // RefCount == 0 for static objects
146 if ( mpImplMapMode
->mnRefCount
)
147 mpImplMapMode
->mnRefCount
++;
150 MapMode::MapMode( MapUnit eUnit
)
153 mpImplMapMode
= ImplMapMode::ImplGetStaticMapMode( eUnit
);
156 MapMode::MapMode( MapUnit eUnit
, const Point
& rLogicOrg
,
157 const Fraction
& rScaleX
, const Fraction
& rScaleY
)
160 mpImplMapMode
= new ImplMapMode
;
161 mpImplMapMode
->meUnit
= eUnit
;
162 mpImplMapMode
->maOrigin
= rLogicOrg
;
163 mpImplMapMode
->maScaleX
= rScaleX
;
164 mpImplMapMode
->maScaleY
= rScaleY
;
165 mpImplMapMode
->maScaleX
.ReduceInaccurate(32);
166 mpImplMapMode
->maScaleY
.ReduceInaccurate(32);
172 // If it's not static ImpData and it's the last reference, delete it,
173 // else decrement refcounter
174 if ( mpImplMapMode
->mnRefCount
)
176 if ( mpImplMapMode
->mnRefCount
== 1 )
177 delete mpImplMapMode
;
179 mpImplMapMode
->mnRefCount
--;
183 void MapMode::SetMapUnit( MapUnit eUnit
)
187 mpImplMapMode
->meUnit
= eUnit
;
190 void MapMode::SetOrigin( const Point
& rLogicOrg
)
194 mpImplMapMode
->maOrigin
= rLogicOrg
;
197 void MapMode::SetScaleX( const Fraction
& rScaleX
)
201 mpImplMapMode
->maScaleX
= rScaleX
;
202 mpImplMapMode
->maScaleX
.ReduceInaccurate(32);
205 void MapMode::SetScaleY( const Fraction
& rScaleY
)
209 mpImplMapMode
->maScaleY
= rScaleY
;
210 mpImplMapMode
->maScaleY
.ReduceInaccurate(32);
213 MapMode
& MapMode::operator=( const MapMode
& rMapMode
)
215 DBG_ASSERT( rMapMode
.mpImplMapMode
->mnRefCount
< 0xFFFFFFFE, "MapMode: RefCount overflow" );
217 // First increment refcount so that we can reference ourselves
218 // RefCount == 0 for static objects
219 if ( rMapMode
.mpImplMapMode
->mnRefCount
)
220 rMapMode
.mpImplMapMode
->mnRefCount
++;
222 // If it's not static ImpData and it's the last reference, delete it,
223 // else decrement refcounter
224 if ( mpImplMapMode
->mnRefCount
)
226 if ( mpImplMapMode
->mnRefCount
== 1 )
227 delete mpImplMapMode
;
229 mpImplMapMode
->mnRefCount
--;
232 mpImplMapMode
= rMapMode
.mpImplMapMode
;
237 bool MapMode::operator==( const MapMode
& rMapMode
) const
240 if ( mpImplMapMode
== rMapMode
.mpImplMapMode
)
243 if ( (mpImplMapMode
->meUnit
== rMapMode
.mpImplMapMode
->meUnit
) &&
244 (mpImplMapMode
->maOrigin
== rMapMode
.mpImplMapMode
->maOrigin
) &&
245 (mpImplMapMode
->maScaleX
== rMapMode
.mpImplMapMode
->maScaleX
) &&
246 (mpImplMapMode
->maScaleY
== rMapMode
.mpImplMapMode
->maScaleY
) )
252 bool MapMode::IsDefault() const
255 ImplMapMode
* pDefMapMode
= ImplMapMode::ImplGetStaticMapMode( MAP_PIXEL
);
256 if ( mpImplMapMode
== pDefMapMode
)
259 if ( (mpImplMapMode
->meUnit
== pDefMapMode
->meUnit
) &&
260 (mpImplMapMode
->maOrigin
== pDefMapMode
->maOrigin
) &&
261 (mpImplMapMode
->maScaleX
== pDefMapMode
->maScaleX
) &&
262 (mpImplMapMode
->maScaleY
== pDefMapMode
->maScaleY
) )
268 SvStream
& ReadMapMode( SvStream
& rIStm
, MapMode
& rMapMode
)
270 rMapMode
.ImplMakeUnique();
271 return ReadImplMapMode( rIStm
, *rMapMode
.mpImplMapMode
);
274 SvStream
& WriteMapMode( SvStream
& rOStm
, const MapMode
& rMapMode
)
276 return WriteImplMapMode( rOStm
, *rMapMode
.mpImplMapMode
);
280 MapUnit
MapMode::GetMapUnit() const { return mpImplMapMode
->meUnit
; }
282 const Point
& MapMode::GetOrigin() const { return mpImplMapMode
->maOrigin
; }
284 const Fraction
& MapMode::GetScaleX() const { return mpImplMapMode
->maScaleX
; }
286 const Fraction
& MapMode::GetScaleY() const { return mpImplMapMode
->maScaleY
; }
288 bool MapMode::IsSimple() const { return mpImplMapMode
->mbSimple
; }
290 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */