KHtml

SVGPreserveAspectRatio.cpp
1 /*
2  Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <[email protected]>
3  2004, 2005, 2006, 2007 Rob Buis <[email protected]>
4 
5  This file is part of the KDE project
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #include "wtf/Platform.h"
24 
25 #if ENABLE(SVG)
26 #include "SVGPreserveAspectRatio.h"
27 
28 #include "SVGParserUtilities.h"
29 #include "SVGSVGElement.h"
30 
31 namespace WebCore
32 {
33 
34 SVGPreserveAspectRatio::SVGPreserveAspectRatio()
35  : m_align(SVG_PRESERVEASPECTRATIO_XMIDYMID)
36  , m_meetOrSlice(SVG_MEETORSLICE_MEET)
37 {
38  // FIXME: Should the two values default to UNKNOWN instead?
39 }
40 
41 SVGPreserveAspectRatio::~SVGPreserveAspectRatio()
42 {
43 }
44 
45 void SVGPreserveAspectRatio::setAlign(unsigned short align)
46 {
47  m_align = align;
48 }
49 
50 unsigned short SVGPreserveAspectRatio::align() const
51 {
52  return m_align;
53 }
54 
55 void SVGPreserveAspectRatio::setMeetOrSlice(unsigned short meetOrSlice)
56 {
57  m_meetOrSlice = meetOrSlice;
58 }
59 
60 unsigned short SVGPreserveAspectRatio::meetOrSlice() const
61 {
62  return m_meetOrSlice;
63 }
64 
65 bool SVGPreserveAspectRatio::parsePreserveAspectRatio(const UChar *&currParam, const UChar *end, bool validate)
66 {
67  SVGPreserveAspectRatioType align = SVG_PRESERVEASPECTRATIO_NONE;
68  SVGMeetOrSliceType meetOrSlice = SVG_MEETORSLICE_MEET;
69  bool ret = false;
70 
71  if (!skipOptionalSpaces(currParam, end)) {
72  goto bail_out;
73  }
74 
75  if (*currParam == 'd') {
76  /*if (!skipString(currParam, end, "defer"))
77  goto bail_out;
78  // FIXME: We just ignore the "defer" here.
79  if (!skipOptionalSpaces(currParam, end))
80  goto bail_out;*/
81  }
82 
83  if (*currParam == 'n') {
84  /*if (!skipString(currParam, end, "none"))
85  goto bail_out;*/
86  skipOptionalSpaces(currParam, end);
87  } else if (*currParam == 'x') {
88  if ((end - currParam) < 8) {
89  goto bail_out;
90  }
91  if (currParam[1] != 'M' || currParam[4] != 'Y' || currParam[5] != 'M') {
92  goto bail_out;
93  }
94  if (currParam[2] == 'i') {
95  if (currParam[3] == 'n') {
96  if (currParam[6] == 'i') {
97  if (currParam[7] == 'n') {
98  align = SVG_PRESERVEASPECTRATIO_XMINYMIN;
99  } else if (currParam[7] == 'd') {
100  align = SVG_PRESERVEASPECTRATIO_XMINYMID;
101  } else {
102  goto bail_out;
103  }
104  } else if (currParam[6] == 'a' && currParam[7] == 'x') {
105  align = SVG_PRESERVEASPECTRATIO_XMINYMAX;
106  } else {
107  goto bail_out;
108  }
109  } else if (currParam[3] == 'd') {
110  if (currParam[6] == 'i') {
111  if (currParam[7] == 'n') {
112  align = SVG_PRESERVEASPECTRATIO_XMIDYMIN;
113  } else if (currParam[7] == 'd') {
114  align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
115  } else {
116  goto bail_out;
117  }
118  } else if (currParam[6] == 'a' && currParam[7] == 'x') {
119  align = SVG_PRESERVEASPECTRATIO_XMIDYMAX;
120  } else {
121  goto bail_out;
122  }
123  } else {
124  goto bail_out;
125  }
126  } else if (currParam[2] == 'a' && currParam[3] == 'x') {
127  if (currParam[6] == 'i') {
128  if (currParam[7] == 'n') {
129  align = SVG_PRESERVEASPECTRATIO_XMAXYMIN;
130  } else if (currParam[7] == 'd') {
131  align = SVG_PRESERVEASPECTRATIO_XMAXYMID;
132  } else {
133  goto bail_out;
134  }
135  } else if (currParam[6] == 'a' && currParam[7] == 'x') {
136  align = SVG_PRESERVEASPECTRATIO_XMAXYMAX;
137  } else {
138  goto bail_out;
139  }
140  } else {
141  goto bail_out;
142  }
143  currParam += 8;
144  skipOptionalSpaces(currParam, end);
145  } else {
146  goto bail_out;
147  }
148 
149  if (currParam < end) {
150  if (*currParam == 'm') {
151  /*if (!skipString(currParam, end, "meet"))
152  goto bail_out;
153  skipOptionalSpaces(currParam, end);*/
154  } else if (*currParam == 's') {
155  /*if (!skipString(currParam, end, "slice"))
156  goto bail_out;
157  skipOptionalSpaces(currParam, end);
158  if (align != SVG_PRESERVEASPECTRATIO_NONE)
159  meetOrSlice = SVG_MEETORSLICE_SLICE;*/
160  }
161  }
162 
163  if (end != currParam && validate) {
164  bail_out:
165  // FIXME: Should the two values be set to UNKNOWN instead?
166  align = SVG_PRESERVEASPECTRATIO_NONE;
167  meetOrSlice = SVG_MEETORSLICE_MEET;
168  } else {
169  ret = true;
170  }
171 
172  if (m_align == align && m_meetOrSlice == meetOrSlice) {
173  return ret;
174  }
175 
176  m_align = align;
177  m_meetOrSlice = meetOrSlice;
178  return ret;
179 }
180 
181 AffineTransform SVGPreserveAspectRatio::getCTM(double logicX, double logicY,
182  double logicWidth, double logicHeight,
183  double /*physX*/, double /*physY*/,
184  double physWidth, double physHeight)
185 {
186  AffineTransform temp;
187 
188  if (align() == SVG_PRESERVEASPECTRATIO_UNKNOWN) {
189  return temp;
190  }
191 
192  double vpar = logicWidth / logicHeight;
193  double svgar = physWidth / physHeight;
194 
195  if (align() == SVG_PRESERVEASPECTRATIO_NONE) {
196  temp.scale(physWidth / logicWidth, physHeight / logicHeight);
197  temp.translate(-logicX, -logicY);
198  } else if ((vpar < svgar && meetOrSlice() == SVG_MEETORSLICE_MEET) || (vpar >= svgar && meetOrSlice() == SVG_MEETORSLICE_SLICE)) {
199  temp.scale(physHeight / logicHeight, physHeight / logicHeight);
200 
201  if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMINYMID || align() == SVG_PRESERVEASPECTRATIO_XMINYMAX) {
202  temp.translate(-logicX, -logicY);
203  } else if (align() == SVG_PRESERVEASPECTRATIO_XMIDYMIN || align() == SVG_PRESERVEASPECTRATIO_XMIDYMID || align() == SVG_PRESERVEASPECTRATIO_XMIDYMAX) {
204  temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight) / 2, -logicY);
205  } else {
206  temp.translate(-logicX - (logicWidth - physWidth * logicHeight / physHeight), -logicY);
207  }
208  } else {
209  temp.scale(physWidth / logicWidth, physWidth / logicWidth);
210 
211  if (align() == SVG_PRESERVEASPECTRATIO_XMINYMIN || align() == SVG_PRESERVEASPECTRATIO_XMIDYMIN || align() == SVG_PRESERVEASPECTRATIO_XMAXYMIN) {
212  temp.translate(-logicX, -logicY);
213  } else if (align() == SVG_PRESERVEASPECTRATIO_XMINYMID || align() == SVG_PRESERVEASPECTRATIO_XMIDYMID || align() == SVG_PRESERVEASPECTRATIO_XMAXYMID) {
214  temp.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth) / 2);
215  } else {
216  temp.translate(-logicX, -logicY - (logicHeight - physHeight * logicWidth / physWidth));
217  }
218  }
219 
220  return temp;
221 }
222 
223 }
224 
225 #endif // ENABLE(SVG)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 16 2021 22:48:02 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.