KHtml

css_svgcssparser.cpp
1 /*
2  Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <[email protected]>
3  2004, 2005, 2007 Rob Buis <[email protected]>
4  Copyright (C) 2005, 2006 Apple Computer, Inc.
5 
6  This file is part of the KDE project
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Library General Public
10  License as published by the Free Software Foundation; either
11  version 2 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Library General Public License for more details.
17 
18  You should have received a copy of the GNU Library General Public License
19  along with this library; see the file COPYING.LIB. If not, write to
20  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  Boston, MA 02110-1301, USA.
22 */
23 
24 #include "cssparser.h"
25 #include "cssproperties.h"
26 #include "cssvalues.h"
27 
28 #include "css/css_valueimpl.h"
29 #include "css/css_svgvalueimpl.h"
30 
31 using namespace std;
32 
33 namespace DOM
34 {
35 
36 bool CSSParser::parseSVGValue(int propId, bool important)
37 {
38  Value *value = valueList->current();
39  if (!value) {
40  return false;
41  }
42 
43  int id = value->id;
44 
45  bool valid_primitive = false;
46  CSSValueImpl *parsedValue = nullptr;
47 
48  switch (propId) {
49  /* The comment to the right defines all valid value of these
50  * properties as defined in SVG 1.1, Appendix N. Property index */
51  case CSS_PROP_ALIGNMENT_BASELINE:
52  // auto | baseline | before-edge | text-before-edge | middle |
53  // central | after-edge | text-after-edge | ideographic | alphabetic |
54  // hanging | mathematical | inherit
55  if (id == CSS_VAL_AUTO || id == CSS_VAL_BASELINE || id == CSS_VAL_MIDDLE ||
56  (id >= CSS_VAL_BEFORE_EDGE && id <= CSS_VAL_MATHEMATICAL)) {
57  valid_primitive = true;
58  }
59  break;
60 
61  case CSS_PROP_BASELINE_SHIFT:
62  // baseline | super | sub | <percentage> | <length> | inherit
63  if (id == CSS_VAL_BASELINE || id == CSS_VAL_SUB || id >= CSS_VAL_SUPER) {
64  valid_primitive = true;
65  } else {
66  valid_primitive = validUnit(value, FLength | FPercent, false);
67  }
68  break;
69 
70  case CSS_PROP_DOMINANT_BASELINE:
71  // auto | use-script | no-change | reset-size | ideographic |
72  // alphabetic | hanging | mathematical | central | middle |
73  // text-after-edge | text-before-edge | inherit
74  if (id == CSS_VAL_AUTO || id == CSS_VAL_MIDDLE ||
75  (id >= CSS_VAL_USE_SCRIPT && id <= CSS_VAL_RESET_SIZE) ||
76  (id >= CSS_VAL_CENTRAL && id <= CSS_VAL_MATHEMATICAL)) {
77  valid_primitive = true;
78  }
79  break;
80 
81  case CSS_PROP_ENABLE_BACKGROUND:
82  // accumulate | new [x] [y] [width] [height] | inherit
83  if (id == CSS_VAL_ACCUMULATE) { // ### TODO: new
84  valid_primitive = true;
85  }
86  break;
87 
88  case CSS_PROP_MARKER_START:
89  case CSS_PROP_MARKER_MID:
90  case CSS_PROP_MARKER_END:
91  case CSS_PROP_MASK:
92  if (id == CSS_VAL_NONE) {
93  valid_primitive = true;
94  } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
95  parsedValue = new CSSPrimitiveValueImpl(domString(value->string), CSSPrimitiveValue::CSS_URI);
96  if (parsedValue) {
97  valueList->next();
98  }
99  }
100  break;
101 
102  case CSS_PROP_CLIP_RULE: // nonzero | evenodd | inherit
103  case CSS_PROP_FILL_RULE:
104  if (id == CSS_VAL_NONZERO || id == CSS_VAL_EVENODD) {
105  valid_primitive = true;
106  }
107  break;
108 
109  case CSS_PROP_STROKE_MITERLIMIT: // <miterlimit> | inherit
110  valid_primitive = validUnit(value, FNumber | FNonNeg, false);
111  break;
112 
113  case CSS_PROP_STROKE_LINEJOIN: // miter | round | bevel | inherit
114  if (id == CSS_VAL_MITER || id == CSS_VAL_ROUND || id == CSS_VAL_BEVEL) {
115  valid_primitive = true;
116  }
117  break;
118 
119  case CSS_PROP_STROKE_LINECAP: // butt | round | square | inherit
120  if (id == CSS_VAL_BUTT || id == CSS_VAL_ROUND || id == CSS_VAL_SQUARE) {
121  valid_primitive = true;
122  }
123  break;
124 
125  case CSS_PROP_STROKE_OPACITY: // <opacity-value> | inherit
126  case CSS_PROP_FILL_OPACITY:
127  case CSS_PROP_STOP_OPACITY:
128  case CSS_PROP_FLOOD_OPACITY:
129  valid_primitive = (!id && validUnit(value, FNumber | FPercent, false));
130  break;
131 
132  case CSS_PROP_SHAPE_RENDERING:
133  // auto | optimizeSpeed | crispEdges | geometricPrecision | inherit
134  if (id == CSS_VAL_AUTO || id == CSS_VAL_OPTIMIZESPEED ||
135  id == CSS_VAL_CRISPEDGES || id == CSS_VAL_GEOMETRICPRECISION) {
136  valid_primitive = true;
137  }
138  break;
139 
140  case CSS_PROP_TEXT_RENDERING: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit
141  if (id == CSS_VAL_AUTO || id == CSS_VAL_OPTIMIZESPEED || id == CSS_VAL_OPTIMIZELEGIBILITY ||
142  id == CSS_VAL_GEOMETRICPRECISION) {
143  valid_primitive = true;
144  }
145  break;
146 
147  case CSS_PROP_IMAGE_RENDERING: // auto | optimizeSpeed |
148  case CSS_PROP_COLOR_RENDERING: // optimizeQuality | inherit
149  if (id == CSS_VAL_AUTO || id == CSS_VAL_OPTIMIZESPEED ||
150  id == CSS_VAL_OPTIMIZEQUALITY) {
151  valid_primitive = true;
152  }
153  break;
154 
155  case CSS_PROP_COLOR_PROFILE: // auto | sRGB | <name> | <uri> inherit
156  if (id == CSS_VAL_AUTO || id == CSS_VAL_SRGB) {
157  valid_primitive = true;
158  }
159  break;
160 
161  case CSS_PROP_COLOR_INTERPOLATION: // auto | sRGB | linearRGB | inherit
162  case CSS_PROP_COLOR_INTERPOLATION_FILTERS:
163  if (id == CSS_VAL_AUTO || id == CSS_VAL_SRGB || id == CSS_VAL_LINEARRGB) {
164  valid_primitive = true;
165  }
166  break;
167 
168  case CSS_PROP_POINTER_EVENTS:
169  // visiblePainted | visibleFill | visibleStroke | visible |
170  // painted | fill | stroke | all | none | inherit
171  if (id == CSS_VAL_VISIBLE || id == CSS_VAL_NONE ||
172  (id >= CSS_VAL_VISIBLEPAINTED && id <= CSS_VAL_ALL)) {
173  valid_primitive = true;
174  }
175  break;
176 
177  case CSS_PROP_TEXT_ANCHOR: // start | middle | end | inherit
178  if (id == CSS_VAL_START || id == CSS_VAL_MIDDLE || id == CSS_VAL_END) {
179  valid_primitive = true;
180  }
181  break;
182 
183  case CSS_PROP_GLYPH_ORIENTATION_VERTICAL: // auto | <angle> | inherit
184  if (id == CSS_VAL_AUTO) {
185  valid_primitive = true;
186  break;
187  }
188  /* fallthrough intentional */
189  case CSS_PROP_GLYPH_ORIENTATION_HORIZONTAL: // <angle> (restricted to _deg_ per SVG 1.1 spec) | inherit
190  if (value->unit == CSSPrimitiveValue::CSS_DEG || value->unit == CSSPrimitiveValue::CSS_NUMBER) {
191  parsedValue = new CSSPrimitiveValueImpl(value->fValue, CSSPrimitiveValue::CSS_DEG);
192 
193  if (parsedValue) {
194  valueList->next();
195  }
196  }
197  break;
198 
199  case CSS_PROP_FILL: // <paint> | inherit
200  case CSS_PROP_STROKE: { // <paint> | inherit
201  if (id == CSS_VAL_NONE) {
202  parsedValue = new SVGPaintImpl(SVGPaintImpl::SVG_PAINTTYPE_NONE);
203  } else if (id == CSS_VAL_CURRENTCOLOR) {
204  parsedValue = new SVGPaintImpl(SVGPaintImpl::SVG_PAINTTYPE_CURRENTCOLOR);
205  } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
206  CSSPrimitiveValueImpl *val;
207  if (valueList->next() && (val = parseColorFromValue(valueList->current()/*, c, true*/))) {
208  parsedValue = new SVGPaintImpl(domString(value->string), val->getRGBColorValue());
209  delete val;
210  } else {
211  parsedValue = new SVGPaintImpl(SVGPaintImpl::SVG_PAINTTYPE_URI, domString(value->string));
212  }
213  } else {
214  parsedValue = parseSVGPaint();
215  }
216 
217  if (parsedValue) {
218  valueList->next();
219  }
220  }
221  break;
222 
223  /*case CSS_PROP_Color: // <color> | inherit
224  if ((id >= CSS_VAL_Aqua && id <= CSS_VAL_Windowtext) ||
225  (id >= CSS_VAL_Aliceblue && id <= CSS_VAL_Yellowgreen))
226  parsedValue = new SVGColor(value->string);
227  else
228  parsedValue = parseSVGColor();
229 
230  if (parsedValue)
231  valueList->next();
232  break;*/
233 
234  case CSS_PROP_STOP_COLOR: // TODO : icccolor
235  case CSS_PROP_FLOOD_COLOR:
236  case CSS_PROP_LIGHTING_COLOR:
237  if ((id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT)/* ||
238  (id >= CSS_VAL_Aliceblue && id <= CSS_VAL_Yellowgreen)*/) {
239  parsedValue = new SVGColorImpl(domString(value->string));
240  } else if (id == CSS_VAL_CURRENTCOLOR) {
241  parsedValue = new SVGColorImpl(SVGColorImpl::SVG_COLORTYPE_CURRENTCOLOR);
242  } else { // TODO : svgcolor (iccColor)
243  parsedValue = parseSVGColor();
244  }
245 
246  if (parsedValue) {
247  valueList->next();
248  }
249 
250  break;
251 
252  case CSS_PROP_WRITING_MODE:
253  // lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit
254  if (id >= CSS_VAL_LR_TB && id <= CSS_VAL_TB) {
255  valid_primitive = true;
256  }
257  break;
258 
259  case CSS_PROP_STROKE_WIDTH: // <length> | inherit
260  case CSS_PROP_STROKE_DASHOFFSET:
261  valid_primitive = validUnit(value, FLength | FPercent, false);
262  break;
263 
264  case CSS_PROP_STROKE_DASHARRAY: // none | <dasharray> | inherit
265  if (id == CSS_VAL_NONE) {
266  valid_primitive = true;
267  } else {
268  parsedValue = parseSVGStrokeDasharray();
269  }
270 
271  break;
272 
273  case CSS_PROP_KERNING: // auto | normal | <length> | inherit
274  if (id == CSS_VAL_AUTO || id == CSS_VAL_NORMAL) {
275  valid_primitive = true;
276  } else {
277  valid_primitive = validUnit(value, FLength, false);
278  }
279  break;
280 
281  case CSS_PROP_CLIP_PATH: // <uri> | none | inherit
282  case CSS_PROP_FILTER:
283  if (id == CSS_VAL_NONE) {
284  valid_primitive = true;
285  } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
286  parsedValue = new CSSPrimitiveValueImpl(domString(value->string), (CSSPrimitiveValue::UnitTypes) value->unit);
287  if (parsedValue) {
288  valueList->next();
289  }
290  }
291  break;
292 
293  /* shorthand properties */
294  case CSS_PROP_MARKER: {
295  const int properties[3] = { CSS_PROP_MARKER_START, CSS_PROP_MARKER_MID,
296  CSS_PROP_MARKER_END
297  };
298  return parseShortHand(propId, properties, 3, important);
299 
300  }
301  default:
302  // If you crash here, it's because you added a css property and are not handling it
303  // in either this switch statement or the one in CSSParser::parseValue
304  //ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propId);
305  //return false;
306  break;
307  }
308 
309  if (valid_primitive) {
310  if (id != 0) {
311  parsedValue = new CSSPrimitiveValueImpl(id);
312  } else if (value->unit == CSSPrimitiveValue::CSS_STRING) {
313  parsedValue = new CSSPrimitiveValueImpl(domString(value->string), (CSSPrimitiveValue::UnitTypes)value->unit);
314  } else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) {
315  parsedValue = new CSSPrimitiveValueImpl(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
316  } else if (value->unit >= Value::Q_EMS) {
317  parsedValue = new CSSQuirkPrimitiveValueImpl(value->fValue, CSSPrimitiveValue::CSS_EMS);
318  }
319  valueList->next();
320  }
321  if (!parsedValue || (valueList->current() && !inShorthand())) {
322  delete parsedValue;
323  return false;
324  }
325 
326  addProperty(propId, parsedValue, important);
327  return true;
328 }
329 
330 CSSValueImpl *CSSParser::parseSVGStrokeDasharray()
331 {
332  CSSValueListImpl *ret = new CSSValueListImpl(CSSValueListImpl::Comma);
333  Value *value = valueList->current();
334  bool valid_primitive = true;
335  while (value) {
336  valid_primitive = validUnit(value, FLength | FPercent | FNonNeg, false);
337  if (!valid_primitive) {
338  break;
339  }
340  if (value->id != 0) {
341  ret->append(new CSSPrimitiveValueImpl(value->id));
342  } else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ) {
343  ret->append(new CSSPrimitiveValueImpl(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit));
344  }
345  value = valueList->next();
346  if (value && value->unit == Value::Operator && value->iValue == ',') {
347  value = valueList->next();
348  }
349  }
350  if (!valid_primitive) {
351  delete ret;
352  ret = nullptr;
353  }
354 
355  return ret;
356 }
357 
358 CSSValueImpl *CSSParser::parseSVGPaint()
359 {
360  CSSPrimitiveValueImpl *val;
361 
362  if (!(val = parseColorFromValue(valueList->current()/*, c, true*/))) {
363  return new SVGPaintImpl();
364  }
365 
366  SVGPaintImpl *paint = new SVGPaintImpl(QColor(val->getRGBColorValue()));
367  delete val;
368  return paint;
369 }
370 
371 CSSValueImpl *CSSParser::parseSVGColor()
372 {
373  CSSPrimitiveValueImpl *val;
374  if (!(val = parseColorFromValue(valueList->current()/*, c, true*/))) {
375  return nullptr;
376  }
377  SVGColorImpl *color = new SVGColorImpl(QColor(val->getRGBColorValue()));
378  delete val;
379  return color;
380 }
381 
382 }
383 
KGuiItem properties()
This library provides a full-featured HTML parser and widget.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 16 2021 22:47:51 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.