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/.
11 #include <basegfx/range/b2drange.hxx>
12 #include "gfxtypes.hxx"
13 #include <rtl/ustring.hxx>
14 #include <osl/diagnose.h>
15 #include <boost/spirit/include/classic.hpp>
20 double convLength( const OUString
& value
, SvgUnit unit
, const State
& rState
, char dir
)
22 // convert svg unit to internal coordinates ("pixel"). Since the
23 // OOo drawing layer is still largely integer-based, the initial
24 // viewport transformation includes a certain scale factor
25 double fRet(value
.toDouble());
28 case SVG_LENGTH_UNIT_CM
: fRet
*= F_SVG_PIXEL_PER_INCH
/2.54; break;
29 case SVG_LENGTH_UNIT_IN
: fRet
*= F_SVG_PIXEL_PER_INCH
; break;
30 case SVG_LENGTH_UNIT_MM
: fRet
*= F_SVG_PIXEL_PER_INCH
/25.4; break;
31 case SVG_LENGTH_UNIT_PC
: fRet
*= F_SVG_PIXEL_PER_INCH
/6.0; break;
32 case SVG_LENGTH_UNIT_PT
: fRet
*= F_SVG_PIXEL_PER_INCH
/72.0; break;
33 case SVG_LENGTH_UNIT_EM
: fRet
*= rState
.mnFontSize
; break;
34 case SVG_LENGTH_UNIT_EX
: fRet
*= rState
.mnFontSize
/ 2.0; break;
35 case SVG_LENGTH_UNIT_USER
:
36 case SVG_LENGTH_UNIT_PX
:
37 // no unit defaults to PX in svg, assume display to have 90DPI
39 case SVG_LENGTH_FONT_SIZE
:
41 //In CSS2, the suggested scaling factor between adjacent indexes is 1.2
42 if ( value
== "xx-small" )
43 fRet
= rState
.mnFontSize
/ 1.728;
44 else if ( value
== "x-small" )
45 fRet
= rState
.mnFontSize
/ 1.44;
46 else if ( value
== "small" )
47 fRet
= rState
.mnFontSize
/ 1.2;
48 else if ( value
== "smaller" )
49 fRet
= rState
.mnParentFontSize
/ 1.2;
50 else if ( value
== "initial" || value
== "medium" )
51 fRet
= rState
.mnFontSize
;
52 else if ( value
== "larger" )
53 fRet
= rState
.mnParentFontSize
* 1.2;
54 else if ( value
== "large" )
55 fRet
= rState
.mnFontSize
* 1.2;
56 else if ( value
== "x-large" )
57 fRet
= rState
.mnFontSize
* 1.44;
58 else if ( value
== "xx-large" )
59 fRet
= rState
.mnFontSize
* 1.728;
63 case SVG_LENGTH_UNIT_PERCENTAGE
:
66 if (rState
.maViewBox
.isEmpty())
68 basegfx::B2DRange
aDefaultBox(0, 0,
69 convLength("210", SVG_LENGTH_UNIT_MM
, rState
, 'h'),
70 convLength("297", SVG_LENGTH_UNIT_MM
, rState
, 'v'));
71 fBoxLen
= (dir
=='h' ? aDefaultBox
.getWidth() :
72 (dir
=='v' ? aDefaultBox
.getHeight() :
73 aDefaultBox
.getRange().getLength()));
77 fBoxLen
= (dir
=='h' ? rState
.maViewBox
.getWidth() :
78 (dir
=='v' ? rState
.maViewBox
.getHeight() :
79 rState
.maViewBox
.getRange().getLength()));
82 fRet
*= fBoxLen
/100.0;
85 default: OSL_TRACE( "Unknown length type" ); break;
91 double convLength( const OUString
& sValue
, const State
& rState
, char dir
)
93 //FIXME: convert deprecated spirit::classic to use spirit::qi
94 using namespace ::boost::spirit::classic
;
96 OString aUTF8
= OUStringToOString( sValue
,
97 RTL_TEXTENCODING_UTF8
);
100 SvgUnit eUnit
=SVG_LENGTH_UNIT_PX
;
101 const bool bRes
= parse(aUTF8
.getStr(),
104 //parse font-size keywords (ie: xx-large, medium )
105 ( +(alpha_p
) >> !(str_p("-") >> +alpha_p
) )[assign_a(sVal
)]
106 >> str_p("")[assign_a(eUnit
,SVG_LENGTH_FONT_SIZE
)] |
107 //take the first part and ignore the units
119 >> ( str_p("cm") [assign_a(eUnit
,SVG_LENGTH_UNIT_CM
)]
120 | str_p("em") [assign_a(eUnit
,SVG_LENGTH_UNIT_EM
)]
121 | str_p("ex") [assign_a(eUnit
,SVG_LENGTH_UNIT_EX
)]
122 | str_p("in") [assign_a(eUnit
,SVG_LENGTH_UNIT_IN
)]
123 | str_p("mm") [assign_a(eUnit
,SVG_LENGTH_UNIT_MM
)]
124 | str_p("pc") [assign_a(eUnit
,SVG_LENGTH_UNIT_PC
)]
125 | str_p("pt") [assign_a(eUnit
,SVG_LENGTH_UNIT_PT
)]
126 | str_p("px") [assign_a(eUnit
,SVG_LENGTH_UNIT_PX
)]
127 | str_p("%") [assign_a(eUnit
,SVG_LENGTH_UNIT_PERCENTAGE
)]
128 | str_p("") [assign_a(eUnit
,SVG_LENGTH_UNIT_USER
)]
137 OUString oVal
= OUString::createFromAscii(sVal
.c_str()).replaceAll(",",".");
139 return convLength(oVal
,eUnit
,rState
,dir
);
144 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */