2
* Phoebe DOM Implementation.
4
* This is a C++ approximation of the W3C DOM model, which follows
5
* fairly closely the specifications in the various .idl files, copies of
6
* which are provided for reference. Most important is this one:
8
* http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html
13
* Copyright (C) 2005-2008 Bob Jamison
15
* This library is free software; you can redistribute it and/or
16
* modify it under the terms of the GNU Lesser General Public
17
* License as published by the Free Software Foundation; either
18
* version 2.1 of the License, or (at your option) any later version.
20
* This library is distributed in the hope that it will be useful,
21
* but WITHOUT ANY WARRANTY; without even the implied warranty of
22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23
* Lesser General Public License for more details.
25
* You should have received a copy of the GNU Lesser General Public
26
* License along with this library; if not, write to the Free Software
27
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29
* =======================================================================
36
#include "svgreader.h"
37
#include "dom/cssreader.h"
39
#include "xmlreader.h"
55
//#########################################################################
57
//#########################################################################
63
void SVGReader::error(char const *fmt, ...)
66
fprintf(stderr, "SVGReader:error: ");
68
vfprintf(stderr, fmt, args);
70
fprintf(stderr, "\n");
77
void SVGReader::trace(char const *fmt, ...)
80
fprintf(stdout, "SVGReader: ");
82
vfprintf(stdout, fmt, args);
84
fprintf(stdout, "\n");
89
//#########################################################################
91
//#########################################################################
96
* Get the character at the position and record the fact
98
XMLCh SVGReader::get(int p)
102
XMLCh ch = parsebuf[p];
111
* Test if the given substring exists at the given position
112
* in parsebuf. Use get() in case of out-of-bounds
114
bool SVGReader::match(int pos, char const *str)
118
if (get(pos++) != (XMLCh) *str++)
127
int SVGReader::skipwhite(int p)
132
if (match(p, "<!--"))
149
error("unterminated <!-- .. --> comment");
154
else if (match(p, "/*"))
171
error("unterminated /* .. */ comment");
175
else if (!uni_is_space(get(p)))
185
* get a word from the buffer
187
int SVGReader::getWord(int p, DOMString &result)
190
if (!uni_is_letter(ch))
199
if (uni_is_letter_or_digit(ch) || ch=='-' || ch=='_')
218
* get a word from the buffer
220
int SVGReader::getNumber(int p0, double &result)
235
if (ch<'0' || ch>'9')
240
if (get(p) == '.' && get(p+1)>='0' && get(p+1)<='9')
247
if (ch<'0' || ch>'9')
255
char *start = (char *)str.c_str();
257
double val = strtod(start, &end);
272
* get a word from the buffer
274
int SVGReader::getNumber(int p0, double &result)
281
for (i=0 ; i<63 && p<parselen ; i++)
283
buf[i] = (char) get(p++);
289
double val = strtod(start, &end);
293
int count = (int)(end - start);
303
bool SVGReader::parseTransform(const DOMString &str)
306
parselen = str.size();
308
//printf("transform:%s\n", str.c_str());
310
SVGTransformList transformList;
318
int p2 = getWord(p, name);
323
error("transform: need transform name");
328
//printf("transform name:%s\n", name.c_str());
331
if (name == "matrix")
336
error("matrix transform needs opening '('");
341
bool seenBrace = false;
342
while (p < parselen && nrVals < 6)
346
p2 = getNumber(p, val);
351
error("matrix() expected number");
354
vals[nrVals++] = val;
372
error("matrix() needs closing brace");
377
error("matrix() requires exactly 6 arguments");
380
//We got our arguments
381
//printf("translate: %f %f %f %f %f %f\n",
382
// vals[0], vals[1], vals[2], vals[3], vals[4], vals[5]);
383
SVGMatrix matrix(vals[0], vals[1], vals[2],
384
vals[3], vals[4], vals[5]);
385
SVGTransform transform;
386
transform.setMatrix(matrix);
387
transformList.appendItem(transform);
390
//######### TRANSLATE
391
else if (name == "translate")
396
error("matrix transform needs opening '('");
401
p2 = getNumber(p, x);
406
error("translate() expected 'x' value");
416
p2 = getNumber(p, y);
419
if (p2<=p) //no y specified. use default
424
error("translate() needs closing ')'");
427
//printf("translate: %f %f\n", x, y);
428
SVGTransform transform;
429
transform.setTranslate(x, y);
430
transformList.appendItem(transform);
434
else if (name == "scale")
439
error("scale transform needs opening '('");
444
p2 = getNumber(p, x);
449
error("scale() expected 'x' value");
459
p2 = getNumber(p, y);
462
if (p2<=p) //no y specified. use default
463
y = x; // y is same as x. uniform scaling
467
error("scale() needs closing ')'");
470
//printf("scale: %f %f\n", x, y);
471
SVGTransform transform;
472
transform.setScale(x, y);
473
transformList.appendItem(transform);
477
else if (name == "rotate")
482
error("rotate transform needs opening '('");
487
p2 = getNumber(p, angle);
492
error("rotate() expected 'angle' value");
503
p2 = getNumber(p, cx);
512
p2 = getNumber(p, cy);
517
error("rotate() arguments should be either rotate(angle) or rotate(angle, cx, cy)");
524
error("rotate() needs closing ')'");
527
//printf("rotate: %f %f %f\n", angle, cx, cy);
528
SVGTransform transform;
529
transform.setRotate(angle, cx, cy);
530
transformList.appendItem(transform);
534
else if (name == "skewX")
539
error("skewX transform needs opening '('");
544
p2 = getNumber(p, x);
549
error("skewX() expected 'x' value");
555
error("skewX() needs closing ')'");
558
//printf("skewX: %f\n", x);
559
SVGTransform transform;
560
transform.setSkewX(x);
561
transformList.appendItem(transform);
565
else if (name == "skewY")
570
error("skewY transform needs opening '('");
575
p2 = getNumber(p, y);
580
error("skewY() expected 'y' value");
586
error("skewY() needs closing ')'");
589
//printf("skewY: %f\n", y);
590
SVGTransform transform;
591
transform.setSkewY(y);
592
transformList.appendItem(transform);
595
//### NONE OF THE ABOVE
598
error("unknown transform type:'%s'", name.c_str());
618
bool SVGReader::parseElement(SVGElementImplPtr parent,
619
ElementImplPtr sourceElem)
623
error("NULL dest element");
628
error("NULL source element");
632
DOMString namespaceURI = sourceElem->getNamespaceURI();
633
//printf("namespaceURI:%s\n", namespaceURI.c_str());
634
DOMString tagName = sourceElem->getTagName();
635
printf("tag name:%s\n", tagName.c_str());
636
ElementPtr newElement = doc->createElementNS(namespaceURI, tagName);
641
NamedNodeMap &attrs = sourceElem->getAttributes();
642
for (unsigned int i=0 ; i<attrs.getLength() ; i++)
644
NodePtr n = attrs.item(i);
645
newElement->setAttribute(n->getNodeName(), n->getNodeValue());//should be exception here
647
parent->appendChild(newElement);
650
NodeList children = sourceElem->getChildNodes();
651
int nodeCount = children.getLength();
652
for (int i=0 ; i<nodeCount ; i++)
654
NodePtr child = children.item(i);
655
int typ = child->getNodeType();
656
if (typ == Node::TEXT_NODE)
658
NodePtr newNode = doc->createTextNode(child->getNodeValue());
659
parent->appendChild(newNode);
661
else if (typ == Node::CDATA_SECTION_NODE)
663
NodePtr newNode = doc->createCDATASection(child->getNodeValue());
664
parent->appendChild(newNode);
666
else if (newElement.get() && typ == Node::ELEMENT_NODE)
668
//ElementImplPtr childElement = dynamic_cast<ElementImpl *>(child.get());
669
//parseElement(newElement, childElement);
679
SVGDocumentPtr SVGReader::parse(const DocumentPtr src)
683
error("NULL source document");
687
DOMImplementationImpl impl;
688
doc = new SVGDocumentImpl(&impl, SVG_NAMESPACE, "svg" , NULL);
690
SVGElementImplPtr destElem = dynamic_pointer_cast<SVGElementImpl, SVGElement>(doc->getRootElement());
691
ElementImplPtr srcElem = dynamic_pointer_cast<ElementImpl, Element>(src->getDocumentElement());
692
if (!parseElement(destElem, srcElem))
705
SVGDocumentPtr SVGReader::parse(const DOMString &buf)
707
/* remember, smartptrs are null-testable*/
708
SVGDocumentPtr svgdoc;
710
DocumentPtr doc = parser.parse(buf);
724
SVGDocumentPtr SVGReader::parseFile(const DOMString &fileName)
726
/* remember, smartptrs are null-testable*/
727
SVGDocumentPtr svgdoc;
729
DocumentPtr doc = parser.parseFile(fileName);
732
error("Could not load xml doc");
747
/*#########################################################################
749
#########################################################################*/