• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
  • svgicons
ksvgiconengine.cpp
1/*
2 Copyright (C) 2002 Nikolas Zimmermann <wildfox@kde.org>
3 This file is part of the KDE project
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include <tqdom.h>
22#include <tqfile.h>
23#include <tqcolor.h>
24#include <tqimage.h>
25#include <tqwmatrix.h>
26#include <tqregexp.h>
27
28#include <kmdcodec.h>
29
30#include <zlib.h>
31
32#include "ksvgiconpainter.h"
33#include "ksvgiconengine.h"
34
35class KSVGIconEngineHelper
36{
37public:
38 KSVGIconEngineHelper(KSVGIconEngine *engine)
39 {
40 m_engine = engine;
41 }
42
43 ~KSVGIconEngineHelper()
44 {
45 }
46
47 double toPixel(const TQString &s, bool hmode)
48 {
49 return m_engine->painter()->toPixel(s, hmode);
50 }
51
52 ArtGradientStop *parseGradientStops(TQDomElement element, int &offsets)
53 {
54 if (!element.hasChildNodes())
55 return 0;
56
57 TQValueList<ArtGradientStop> stopList;
58
59 float oldOffset = -1, newOffset = -1;
60 for(TQDomNode node = element.firstChild(); !node.isNull(); node = node.nextSibling())
61 {
62 TQDomElement element = node.toElement();
63
64 oldOffset = newOffset;
65 TQString temp = element.attribute("offset");
66
67 if(temp.contains("%"))
68 {
69 temp = temp.left(temp.length() - 1);
70 newOffset = temp.toFloat() / 100.0;
71 }
72 else
73 newOffset = temp.toFloat();
74
75 // Spec skip double offset specifications
76 if(oldOffset == newOffset)
77 continue;
78
79 offsets++;
80 stopList.append(ArtGradientStop());
81
82 ArtGradientStop &stop = stopList.last();
83
84 stop.offset = newOffset;
85
86 TQString parseOpacity;
87 TQString parseColor;
88
89 if(element.hasAttribute("stop-opacity"))
90 parseOpacity = element.attribute("stop-opacity");
91
92 if(element.hasAttribute("stop-color"))
93 parseColor = element.attribute("stop-color");
94
95 if(parseOpacity.isEmpty() || parseColor.isEmpty())
96 {
97 TQString style = element.attribute("style");
98
99 TQStringList substyles = TQStringList::split(';', style);
100 for(TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it)
101 {
102 TQStringList substyle = TQStringList::split(':', (*it));
103 TQString command = substyle[0];
104 TQString params = substyle[1];
105 command = command.stripWhiteSpace();
106 params = params.stripWhiteSpace();
107
108 if(command == "stop-color")
109 {
110 parseColor = params;
111
112 if(!parseOpacity.isEmpty())
113 break;
114 }
115 else if(command == "stop-opacity")
116 {
117 parseOpacity = params;
118
119 if(!parseColor.isEmpty())
120 break;
121 }
122 }
123 }
124
125 // Parse color using KSVGIconPainter (which uses Qt)
126 // Supports all svg-needed color formats
127 TQColor qStopColor = m_engine->painter()->parseColor(parseColor);
128
129 // Convert in a libart suitable form
130 TQ_UINT32 stopColor = m_engine->painter()->toArtColor(qStopColor);
131
132 int opacity = m_engine->painter()->parseOpacity(parseOpacity);
133
134 TQ_UINT32 rgba = (stopColor << 8) | opacity;
135 TQ_UINT32 r, g, b, a;
136
137 // Convert from separated to premultiplied alpha
138 a = rgba & 0xff;
139 r = (rgba >> 24) * a + 0x80;
140 r = (r + (r >> 8)) >> 8;
141 g = ((rgba >> 16) & 0xff) * a + 0x80;
142 g = (g + (g >> 8)) >> 8;
143 b = ((rgba >> 8) & 0xff) * a + 0x80;
144 b = (b + (b >> 8)) >> 8;
145
146 stop.color[0] = ART_PIX_MAX_FROM_8(r);
147 stop.color[1] = ART_PIX_MAX_FROM_8(g);
148 stop.color[2] = ART_PIX_MAX_FROM_8(b);
149 stop.color[3] = ART_PIX_MAX_FROM_8(a);
150 }
151
152 if (stopList.isEmpty())
153 return 0;
154
155 ArtGradientStop *stops = new ArtGradientStop[stopList.count()];
156
157 TQValueList<ArtGradientStop>::iterator it = stopList.begin();
158 TQValueList<ArtGradientStop>::iterator end = stopList.end();
159
160 for (int i = 0; it != end; ++i, ++it)
161 stops[i] = *it;
162
163 return stops;
164 }
165
166 TQPointArray parsePoints(TQString points)
167 {
168 if(points.isEmpty())
169 return TQPointArray();
170
171 points = points.simplifyWhiteSpace();
172
173 if(points.contains(",,") || points.contains(", ,"))
174 return TQPointArray();
175
176 points.replace(',', ' ');
177 points.replace('\r', TQString());
178 points.replace('\n', TQString());
179
180 points = points.simplifyWhiteSpace();
181
182 TQStringList pointList = TQStringList::split(' ', points);
183
184 TQPointArray array(pointList.count() / 2);
185 int i = 0;
186
187 for(TQStringList::Iterator it = pointList.begin(); it != pointList.end(); it++)
188 {
189 float x = (*(it++)).toFloat();
190 float y = (*(it)).toFloat();
191
192 array.setPoint(i, static_cast<int>(x), static_cast<int>(y));
193 i++;
194 }
195
196 return array;
197 }
198
199 void parseTransform(const TQString &transform)
200 {
201 // Combine new and old matrix
202 TQWMatrix matrix = m_engine->painter()->parseTransform(transform);
203
204 TQWMatrix *current = m_engine->painter()->worldMatrix();
205 *current = matrix * *current;
206 }
207
208 void parseCommonAttributes(TQDomNode &node)
209 {
210 // Set important default attributes
211 m_engine->painter()->setFillColor("black");
212 m_engine->painter()->setStrokeColor("none");
213 m_engine->painter()->setStrokeDashArray("");
214 m_engine->painter()->setStrokeWidth(1);
215 m_engine->painter()->setJoinStyle("");
216 m_engine->painter()->setCapStyle("");
217 // m_engine->painter()->setFillOpacity(255, true);
218 // m_engine->painter()->setStrokeOpacity(255, true);
219
220 // Collect parent node's attributes
221 TQPtrList<TQDomNamedNodeMap> applyList;
222 applyList.setAutoDelete(true);
223
224 TQDomNode shape = node.parentNode();
225 for(; !shape.isNull() ; shape = shape.parentNode())
226 applyList.prepend(new TQDomNamedNodeMap(shape.attributes()));
227
228 // Apply parent attributes
229 for(TQDomNamedNodeMap *map = applyList.first(); map != 0; map = applyList.next())
230 {
231 TQDomNamedNodeMap attr = *map;
232
233 for(unsigned int i = 0; i < attr.count(); i++)
234 {
235 TQString name, value;
236
237 name = attr.item(i).nodeName().lower();
238 value = attr.item(i).nodeValue();
239
240 if(name == "transform")
241 parseTransform(value);
242 else if(name == "style")
243 parseStyle(value);
244 else
245 parsePA(name, value);
246 }
247 }
248
249 // Apply local attributes
250 TQDomNamedNodeMap attr = node.attributes();
251
252 for(unsigned int i = 0; i < attr.count(); i++)
253 {
254 TQDomNode current = attr.item(i);
255
256 if(current.nodeName().lower() == "transform")
257 parseTransform(current.nodeValue());
258 else if(current.nodeName().lower() == "style")
259 parseStyle(current.nodeValue());
260 else
261 parsePA(current.nodeName().lower(), current.nodeValue());
262 }
263 }
264
265 bool handleTags(TQDomElement element, bool paint)
266 {
267 if(element.attribute("display") == "none")
268 return false;
269 if(element.tagName() == "linearGradient")
270 {
271 ArtGradientLinear *gradient = new ArtGradientLinear();
272
273 int offsets = -1;
274 gradient->stops = parseGradientStops(element, offsets);
275 gradient->n_stops = offsets + 1;
276
277 TQString spread = element.attribute("spreadMethod");
278 if(spread == "repeat")
279 gradient->spread = ART_GRADIENT_REPEAT;
280 else if(spread == "reflect")
281 gradient->spread = ART_GRADIENT_REFLECT;
282 else
283 gradient->spread = ART_GRADIENT_PAD;
284
285 m_engine->painter()->addLinearGradient(element.attribute("id"), gradient);
286 m_engine->painter()->addLinearGradientElement(gradient, element);
287 return true;
288 }
289 else if(element.tagName() == "radialGradient")
290 {
291 ArtGradientRadial *gradient = new ArtGradientRadial();
292
293 int offsets = -1;
294 gradient->stops = parseGradientStops(element, offsets);
295 gradient->n_stops = offsets + 1;
296
297 m_engine->painter()->addRadialGradient(element.attribute("id"), gradient);
298 m_engine->painter()->addRadialGradientElement(gradient, element);
299 return true;
300 }
301
302 if(!paint)
303 return true;
304
305 // TODO: Default attribute values
306 if(element.tagName() == "rect")
307 {
308 double x = toPixel(element.attribute("x"), true);
309 double y = toPixel(element.attribute("y"), false);
310 double w = toPixel(element.attribute("width"), true);
311 double h = toPixel(element.attribute("height"), false);
312
313 double rx = 0.0;
314 double ry = 0.0;
315
316 if(element.hasAttribute("rx"))
317 rx = toPixel(element.attribute("rx"), true);
318
319 if(element.hasAttribute("ry"))
320 ry = toPixel(element.attribute("ry"), false);
321
322 m_engine->painter()->drawRectangle(x, y, w, h, rx, ry);
323 }
324 else if(element.tagName() == "switch")
325 {
326 TQDomNode iterate = element.firstChild();
327
328 while(!iterate.isNull())
329 {
330 // Reset matrix
331 m_engine->painter()->setWorldMatrix(new TQWMatrix(m_initialMatrix));
332
333 // Parse common attributes, style / transform
334 parseCommonAttributes(iterate);
335
336 if(handleTags(iterate.toElement(), true))
337 return true;
338 iterate = iterate.nextSibling();
339 }
340 return true;
341 }
342 else if(element.tagName() == "g" || element.tagName() == "defs")
343 {
344 TQDomNode iterate = element.firstChild();
345
346 while(!iterate.isNull())
347 {
348 // Reset matrix
349 m_engine->painter()->setWorldMatrix(new TQWMatrix(m_initialMatrix));
350
351 // Parse common attributes, style / transform
352 parseCommonAttributes(iterate);
353
354 TQDomElement element2 = iterate.toElement();
355
356 handleTags(element2, (element.tagName() == "defs") ? false : true);
357
358 if(element2.attribute("type") == "text/css") {
359 //tqDebug(" ->point:001");
360 TQString el2text = element2.text().remove(" ").remove('"').remove("'").remove('\r').remove('\n');
361 //tqDebug(element.tagName() + " > " + element2.tagName() + " > " + + "type=" + element2.attribute("type") + " > " + el2text);
362 if(! el2text.isEmpty()) { //maybe remove this condition
363 flg_svg_has_css_colors = true;
364 cssColorSchemeText = el2text.section(".ColorScheme-Text{color:", 1).section(";", 0, 0);
365 cssColorSchemeHighlight = el2text.section(".ColorScheme-Highlight{color:", 1).section(";", 0, 0);
366 cssColorSchemeNeutralText = el2text.section(".ColorScheme-NeutralText{color:", 1).section(";", 0, 0);
367 cssColorSchemePositiveText = el2text.section(".ColorScheme-PositiveText{color:", 1).section(";", 0, 0);
368 cssColorSchemeNegativeText = el2text.section(".ColorScheme-NegativeText{color:", 1).section(";", 0, 0);
369 //tqDebug(".ColorScheme-Text=" + cssColorSchemeText);
370 //tqDebug(".ColorScheme-Highlight=" + cssColorSchemeHighlight);
371 //tqDebug(".ColorScheme-NeutralText=" + cssColorSchemeNeutralText);
372 //tqDebug(".ColorScheme-PositiveText=" + cssColorSchemePositiveText);
373 //tqDebug(".ColorScheme-NegativeText=" + cssColorSchemeNegativeText);
374 }
375 }
376
377 iterate = iterate.nextSibling();
378 }
379 return true;
380 }
381 else if(element.tagName() == "line")
382 {
383 double x1 = toPixel(element.attribute("x1"), true);
384 double y1 = toPixel(element.attribute("y1"), false);
385 double x2 = toPixel(element.attribute("x2"), true);
386 double y2 = toPixel(element.attribute("y2"), false);
387
388 m_engine->painter()->drawLine(x1, y1, x2, y2);
389 return true;
390 }
391 else if(element.tagName() == "circle")
392 {
393 double cx = toPixel(element.attribute("cx"), true);
394 double cy = toPixel(element.attribute("cy"), false);
395
396 double r = toPixel(element.attribute("r"), true); // TODO: horiz correct?
397
398 m_engine->painter()->drawEllipse(cx, cy, r, r);
399 return true;
400 }
401 else if(element.tagName() == "ellipse")
402 {
403 double cx = toPixel(element.attribute("cx"), true);
404 double cy = toPixel(element.attribute("cy"), false);
405
406 double rx = toPixel(element.attribute("rx"), true);
407 double ry = toPixel(element.attribute("ry"), false);
408
409 m_engine->painter()->drawEllipse(cx, cy, rx, ry);
410 return true;
411 }
412 else if(element.tagName() == "polyline")
413 {
414 TQPointArray polyline = parsePoints(element.attribute("points"));
415 m_engine->painter()->drawPolyline(polyline);
416 return true;
417 }
418 else if(element.tagName() == "polygon")
419 {
420 TQPointArray polygon = parsePoints(element.attribute("points"));
421 m_engine->painter()->drawPolygon(polygon);
422 return true;
423 }
424 else if(element.tagName() == "path")
425 {
426 bool filled = true;
427
428 if(element.hasAttribute("fill") && element.attribute("fill").contains("none"))
429 filled = false;
430
431 if(element.attribute("style").contains("fill") && element.attribute("style").stripWhiteSpace().contains("fill:none"))
432 filled = false;
433
434 if(filled && (flg_apply_css_fill_color || flg_apply_css_stroke_color)) {
435 //tqDebug(" ->point:004");
436 TQString attr1 = element.attribute("class");
437 //tqDebug("[handleTags]:" + attr1);
438 TQString hlp1_csscolor;
439 if(attr1.isEmpty()) {
440 hlp1_csscolor = "#888888";
441 //tqDebug("[*warning - css_color]: empty *");
442 } else if(attr1 == "ColorScheme-Text") {
443 hlp1_csscolor = cssColorSchemeText;
444 } else if(attr1 == "ColorScheme-Highlight") {
445 hlp1_csscolor = cssColorSchemeHighlight;
446 } else if(attr1 == "ColorScheme-NeutralText") {
447 hlp1_csscolor = cssColorSchemeNeutralText;
448 } else if(attr1 == "ColorScheme-PositiveText") {
449 hlp1_csscolor = cssColorSchemePositiveText;
450 } else if(attr1 == "ColorScheme-NegativeText") {
451 hlp1_csscolor = cssColorSchemeNegativeText;
452 } else {
453 hlp1_csscolor = "#888888";
454 //tqDebug("[*warning - css_color]: fallback *");
455 }
456
457 if(flg_apply_css_fill_color) {
458 //tqDebug("setFillColor >>" + hlp1_csscolor + "<<");
459 m_engine->painter()->setFillColor(hlp1_csscolor);
460 flg_apply_css_fill_color = false;
461 } else if(flg_apply_css_stroke_color) {
462 //tqDebug("setStrokeColor >>" + hlp1_csscolor + "<<");
463 m_engine->painter()->setStrokeColor(hlp1_csscolor);
464 flg_apply_css_stroke_color = false;
465 }
466 }
467
468 m_engine->painter()->drawPath(element.attribute("d"), filled);
469 return true;
470 }
471 else if(element.tagName() == "image")
472 {
473 double x = toPixel(element.attribute("x"), true);
474 double y = toPixel(element.attribute("y"), false);
475 double w = toPixel(element.attribute("width"), true);
476 double h = toPixel(element.attribute("height"), false);
477
478 TQString href = element.attribute("xlink:href");
479
480 TQImage image;
481 if(href.startsWith("data:"))
482 {
483 // Get input
484 TQCString input = TQString(href.remove(TQRegExp("^data:image/.*;base64,"))).utf8();
485
486 // Decode into 'output'
487 TQByteArray output;
488 KCodecs::base64Decode(input, output);
489
490 // Display
491 image.loadFromData(output);
492 }
493 else
494 image.load(href);
495
496 if (!image.isNull())
497 {
498 // Scale, if needed
499 if(image.width() != (int) w || image.height() != (int) h)
500 image = image.smoothScale((int) w, (int) h, TQImage::ScaleFree);
501
502 m_engine->painter()->drawImage(x, y, image);
503 }
504
505 return true;
506 }
507 return false;
508 }
509
510 void parseStyle(const TQString &style)
511 {
512 TQStringList substyles = TQStringList::split(';', style);
513 for(TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it)
514 {
515 TQStringList substyle = TQStringList::split(':', (*it));
516 TQString command = substyle[0];
517 TQString params = substyle[1];
518 command = command.stripWhiteSpace();
519 params = params.stripWhiteSpace();
520
521 //if(flg_svg_has_css_colors) {
522 // tqDebug(" ->point:002");
523 // tqDebug(style + " >>> " + command + " >>> " + params);
524 //}
525
526 parsePA(command, params);
527 }
528 }
529
530 void parsePA(const TQString &command, const TQString &value)
531 {
532 if(command == "stroke-width") // TODO: horiz:false correct?
533 m_engine->painter()->setStrokeWidth(toPixel(value, false));
534 else if(command == "stroke-miterlimit")
535 m_engine->painter()->setStrokeMiterLimit(value);
536 else if(command == "stroke-linecap")
537 m_engine->painter()->setCapStyle(value);
538 else if(command == "stroke-linejoin")
539 m_engine->painter()->setJoinStyle(value);
540 else if(command == "stroke-dashoffset")
541 m_engine->painter()->setStrokeDashOffset(value);
542 else if(command == "stroke-dasharray" && value != "none")
543 m_engine->painter()->setStrokeDashArray(value);
544 else if(command == "stroke")
545 {
546 if(flg_svg_has_css_colors && (value == "currentColor")) {
547 //tqDebug(" ->point:003");
548 //tqDebug("[parsePA] - flg_apply_css_stroke_color=true >> " + value);
549 flg_apply_css_stroke_color = true;
550 } else {
551 m_engine->painter()->setStrokeColor(value);
552 }
553 }
554 else if(command == "fill")
555 {
556 if(flg_svg_has_css_colors && (value == "currentColor")) {
557 //tqDebug(" ->point:003");
558 //tqDebug("[parsePA] - flg_apply_css_fill_color=true >> " + value);
559 flg_apply_css_fill_color = true;
560 } else {
561 m_engine->painter()->setFillColor(value);
562 }
563 }
564 else if(command == "fill-rule")
565 m_engine->painter()->setFillRule(value);
566 else if(command == "fill-opacity" || command == "stroke-opacity" || command == "opacity")
567 {
568 if(command == "fill-opacity")
569 m_engine->painter()->setFillOpacity(value);
570 else if(command == "stroke-value")
571 m_engine->painter()->setStrokeOpacity(value);
572 else
573 {
574 m_engine->painter()->setOpacity(value);
575 m_engine->painter()->setFillOpacity(value);
576 m_engine->painter()->setStrokeOpacity(value);
577 }
578 }
579 }
580
581private:
582 friend class KSVGIconEngine;
583
584 KSVGIconEngine *m_engine;
585 TQWMatrix m_initialMatrix;
586
587 TQString cssColorSchemeText;
588 TQString cssColorSchemeHighlight;
589 TQString cssColorSchemeNeutralText;
590 TQString cssColorSchemePositiveText;
591 TQString cssColorSchemeNegativeText;
592 bool flg_svg_has_css_colors = false;
593 bool flg_apply_css_fill_color = false;
594 bool flg_apply_css_stroke_color = false;
595};
596
597struct KSVGIconEngine::Private
598{
599 KSVGIconPainter *painter;
600 KSVGIconEngineHelper *helper;
601
602 double width;
603 double height;
604};
605
606KSVGIconEngine::KSVGIconEngine() : d(new Private())
607{
608 d->painter = 0;
609 d->helper = new KSVGIconEngineHelper(this);
610
611 d->width = 0.0;
612 d->height = 0.0;
613}
614
615KSVGIconEngine::~KSVGIconEngine()
616{
617 if(d->painter)
618 delete d->painter;
619
620 delete d->helper;
621
622 delete d;
623}
624
625bool KSVGIconEngine::load(int width, int height, const TQString &path)
626{
627 if(path.isNull()) return false;
628
629 //tqDebug("****icon****: " + path);
630
631 TQDomDocument svgDocument("svg");
632 TQFile file(path);
633
634 if(path.right(3).upper() == "SVG")
635 {
636 // Open SVG Icon
637 if(!file.open(IO_ReadOnly))
638 return false;
639
640 svgDocument.setContent(&file);
641 }
642 else // SVGZ
643 {
644 gzFile svgz = gzopen(path.latin1(), "ro");
645 if(!svgz)
646 return false;
647
648 TQString data;
649 bool done = false;
650
651 TQCString buffer(1024);
652 int length = 0;
653
654 while(!done)
655 {
656 int ret = gzread(svgz, buffer.data() + length, 1024);
657 if(ret == 0)
658 done = true;
659 else if(ret == -1)
660 return false;
661 else {
662 buffer.resize(buffer.size()+1024);
663 length += ret;
664 }
665 }
666
667 gzclose(svgz);
668
669 svgDocument.setContent(buffer);
670 }
671
672 if(svgDocument.isNull())
673 return false;
674
675 // Check for root element
676 TQDomNode rootNode = svgDocument.namedItem("svg");
677 if(rootNode.isNull() || !rootNode.isElement())
678 return false;
679
680 // Detect width and height
681 TQDomElement rootElement = rootNode.toElement();
682
683 // Create icon painter
684 d->painter = new KSVGIconPainter(width, height);
685
686 d->width = width; // this sets default for no width -> 100% case
687 if(rootElement.hasAttribute("width"))
688 d->width = d->helper->toPixel(rootElement.attribute("width"), true);
689
690 d->height = height; // this sets default for no height -> 100% case
691 if(rootElement.hasAttribute("height"))
692 d->height = d->helper->toPixel(rootElement.attribute("height"), false);
693
694 // Create icon painter
695 d->painter->setDrawWidth(static_cast<int>(d->width));
696 d->painter->setDrawHeight(static_cast<int>(d->height));
697
698 // Set viewport clipping rect
699 d->painter->setClippingRect(0, 0, width, height);
700
701 // Apply viewbox
702 if(rootElement.hasAttribute("viewBox"))
703 {
704 TQStringList points = TQStringList::split(' ', rootElement.attribute("viewBox").simplifyWhiteSpace());
705
706 float w = points[2].toFloat();
707 float h = points[3].toFloat();
708
709 double vratiow = width / w;
710 double vratioh = height / h;
711
712 d->width = w;
713 d->height = h;
714
715 d->painter->worldMatrix()->scale(vratiow, vratioh);
716 }
717 else
718 {
719 // Fit into 'width' and 'height'
720 // FIXME: Use an aspect ratio
721 double ratiow = width / d->width;
722 double ratioh = height / d->height;
723
724 d->painter->worldMatrix()->scale(ratiow, ratioh);
725 }
726
727 TQWMatrix initialMatrix = *d->painter->worldMatrix();
728 d->helper->m_initialMatrix = initialMatrix;
729
730 // Apply transform
731 if(rootElement.hasAttribute("transform"))
732 d->helper->parseTransform(rootElement.attribute("transform"));
733
734 // Go through all elements
735 TQDomNode svgNode = rootElement.firstChild();
736 while(!svgNode.isNull())
737 {
738 TQDomElement svgChild = svgNode.toElement();
739 if(!svgChild.isNull())
740 {
741 d->helper->parseCommonAttributes(svgNode);
742 d->helper->handleTags(svgChild, true);
743 }
744
745 svgNode = svgNode.nextSibling();
746
747 // Reset matrix
748 d->painter->setWorldMatrix(new TQWMatrix(initialMatrix));
749 }
750
751 d->painter->finish();
752
753 return true;
754}
755
756KSVGIconPainter *KSVGIconEngine::painter()
757{
758 return d->painter;
759}
760
761TQImage *KSVGIconEngine::image()
762{
763 return d->painter->image();
764}
765
766double KSVGIconEngine::width()
767{
768 return d->width;
769}
770
771double KSVGIconEngine::height()
772{
773 return d->height;
774}
KCodecs::base64Decode
static TQCString base64Decode(const TQByteArray &in)
Decodes the given data that was encoded using the base64 algorithm.
Definition kmdcodec.cpp:462
KStdAction::name
const char * name(StdAction id)
TDEStdAccel::end
const TDEShortcut & end()
Goto end of the document.
Definition tdestdaccel.cpp:289

tdecore

Skip menu "tdecore"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.15.0
This website is maintained by Timothy Pearson.