📄 q3paintengine_svg.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt3Support module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <private/qpainter_p.h>#include <private/qpaintengine_p.h>#include "qfile.h"#include "qimage.h"#include "qlist.h"#include "qmap.h"#include "q3paintengine_svg_p.h"#include "qpainter.h"#include "qpixmap.h"#include "qregexp.h"#include "qtextstream.h"#include <math.h>static const double deg2rad = 0.017453292519943295769; // pi/180static const char piData[] = "version=\"1.0\" standalone=\"no\"";static const char publicId[] = "-//W3C//DTD SVG 20001102//EN";static const char systemId[] = "http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd";static QString qt_svg_compose_path(const QPainterPath &path);struct QImgElement { QDomElement element; QImage image; Q_DUMMY_COMPARISON_OPERATOR(QImgElement)};struct QPixElement { QDomElement element; QPixmap pixmap; Q_DUMMY_COMPARISON_OPERATOR(QPixElement)};struct Q3SVGPaintEngineState { double textx, texty; // current text position int textalign; // text alignment Q_DUMMY_COMPARISON_OPERATOR(Q3SVGPaintEngineState)};typedef QList<QImgElement> ImageList;typedef QList<QPixElement> PixmapList;typedef QList<Q3SVGPaintEngineState> StateList;enum ElementType { InvalidElement = 0, AnchorElement, CircleElement, ClipElement, CommentElement, DescElement, EllipseElement, GroupElement, ImageElement, LineElement, PolylineElement, PolygonElement, PathElement, RectElement, SvgElement, TextElement, TitleElement, TSpanElement};typedef QMap<QString,ElementType> QSvgTypeMap;static QSvgTypeMap *qSvgTypeMap=0; // element typesstatic QMap<QString,QString> *qSvgColMap=0; // recognized color keyword namesclass Q3SVGPaintEnginePrivate : public QPaintEnginePrivate{ Q_DECLARE_PUBLIC(Q3SVGPaintEngine)public: Q3SVGPaintEnginePrivate() : dirtyTransform(false), dirtyStyle(false), currentClip(0), dev(0), wwidth(0), wheight(0) {} void appendChild(QDomElement &e, QPicturePrivate::PaintCommand c); void applyStyle(QDomElement *e, QPicturePrivate::PaintCommand c) const; void applyTransform(QDomElement *e) const; double parseLen(const QString &str, bool *ok=0, bool horiz=true) const; int lenToInt(const QDomNamedNodeMap &map, const QString &attr, int def = 0) const; double lenToDouble(const QDomNamedNodeMap &map, const QString &attr, int def = 0) const; bool play(const QDomNode &node, QPainter *p); void setTransform(const QString &tr, QPainter *p); void restoreAttributes(QPainter *p); void saveAttributes(QPainter *p); void setStyle(const QString &s, QPainter *p); void setStyleProperty(const QString &prop, const QString &val, QPen *pen, QFont *font, int *talign, QPainter *p); void drawPath(const QString &data, QPainter *p); QColor parseColor(const QString &col); void init() { QDomImplementation domImpl; QDomDocumentType docType = domImpl.createDocumentType(QLatin1String("svg"), QLatin1String(publicId), QLatin1String(systemId)); doc = domImpl.createDocument(QLatin1String("http://www.w3.org/2000/svg"), QLatin1String("svg"), docType); doc.insertBefore(doc.createProcessingInstruction(QLatin1String("xml"), QLatin1String(piData)), doc.firstChild()); current = doc.documentElement(); images.clear(); pixmaps.clear(); doc.documentElement().setAttribute(QLatin1String("xmlns:xlink"), QLatin1String("http://www.w3.org/1999/xlink")); } bool dirtyTransform; bool dirtyStyle; QRect brect; // bounding rectangle QDomDocument doc; // document tree QDomNode current; ImageList images; // old private PixmapList pixmaps; StateList stack; int currentClip;// QPoint curPt; Q3SVGPaintEngineState *curr;// QPainter *pt; // only used by recursive play() et al QPen cpen; QBrush cbrush; QFont cfont; QMatrix worldMatrix; const QPaintDevice *dev; int wwidth; int wheight;};Q3SVGPaintEngine::Q3SVGPaintEngine() : QPaintEngine(*(new Q3SVGPaintEnginePrivate), AllFeatures){ Q_D(Q3SVGPaintEngine); d->init();}Q3SVGPaintEngine::Q3SVGPaintEngine(Q3SVGPaintEnginePrivate &dptr) : QPaintEngine(dptr, AllFeatures){ Q_D(Q3SVGPaintEngine); d->init();}Q3SVGPaintEngine::~Q3SVGPaintEngine(){ delete qSvgTypeMap; qSvgTypeMap = 0; // static delete qSvgColMap; qSvgColMap = 0;}bool Q3SVGPaintEngine::begin(QPaintDevice *pdev){ Q_D(Q3SVGPaintEngine); d->dirtyTransform = d->dirtyStyle = false; d->dev = pdev; setActive(true); return true;}bool Q3SVGPaintEngine::end(){ Q_D(Q3SVGPaintEngine); d->dev = 0; setActive(false); return true;}void Q3SVGPaintEngine::updateState(const QPaintEngineState &state){ QPaintEngine::DirtyFlags flags = state.state(); if (flags & DirtyPen) updatePen(state.pen()); if ((flags & DirtyBrush) || (flags & DirtyBrushOrigin)) updateBrush(state.brush(), state.brushOrigin()); if (flags & DirtyBackground) updateBackground(state.backgroundMode(), state.backgroundBrush()); if (flags & DirtyFont) updateFont(state.font()); if (flags & DirtyTransform) updateMatrix(state.matrix()); if (flags & DirtyClipRegion) updateClipRegion(state.clipRegion(), state.clipOperation()); if (flags & DirtyClipPath) updateClipPath(state.clipPath(), state.clipOperation());}void Q3SVGPaintEngine::updatePen(const QPen &pen){ Q_D(Q3SVGPaintEngine); d->cpen = pen; d->dirtyStyle = true;}void Q3SVGPaintEngine::updateBrush(const QBrush &brush, const QPointF &){ Q_D(Q3SVGPaintEngine); d->cbrush = brush; d->dirtyStyle = true;}void Q3SVGPaintEngine::updateFont(const QFont &font){ Q_D(Q3SVGPaintEngine); d->cfont = font; d->dirtyStyle = true;}void Q3SVGPaintEngine::updateBackground(Qt::BGMode, const QBrush &){ Q_D(Q3SVGPaintEngine); d->dirtyStyle = true;}void Q3SVGPaintEngine::updateMatrix(const QMatrix &matrix){ Q_D(Q3SVGPaintEngine); d->dirtyTransform = true; d->worldMatrix = matrix;// d->wwidth = ps->ww;// d->wheight = ps->wh;}void Q3SVGPaintEngine::updateClipPath(const QPainterPath &path, Qt::ClipOperation op){ Q_D(Q3SVGPaintEngine); if (op == Qt::NoClip) return; QDomElement e; d->currentClip++; e = d->doc.createElement(QLatin1String("clipPath")); e.setAttribute(QLatin1String("id"), QString(QLatin1String("clip%1")).arg(d->currentClip)); QDomElement path_element = d->doc.createElement(QLatin1String("path")); path_element.setAttribute(QLatin1String("d"), qt_svg_compose_path(path)); e.appendChild(path_element); d->appendChild(e, QPicturePrivate::PdcSetClipPath);}void Q3SVGPaintEngine::updateClipRegion(const QRegion &clipRegion, Qt::ClipOperation op){ QPainterPath clipPath; clipPath.addRegion(clipRegion); updateClipPath(clipPath, op);}void Q3SVGPaintEngine::updateRenderHints(QPainter::RenderHints){}void Q3SVGPaintEngine::drawRect(const QRectF &r){ Q_D(Q3SVGPaintEngine); QDomElement e; e = d->doc.createElement(QLatin1String("rect")); e.setAttribute(QLatin1String("x"), r.x()); e.setAttribute(QLatin1String("y"), r.y()); e.setAttribute(QLatin1String("width"), r.width()); e.setAttribute(QLatin1String("height"), r.height()); d->appendChild(e, QPicturePrivate::PdcDrawRect);}void Q3SVGPaintEngine::drawPoint(const QPointF &p){ QLineF l(p, p); drawLines(&l, 1);}void Q3SVGPaintEngine::drawPoints(const QPointF *points, int pointCount){ for (int i = 0; i < pointCount; ++i) { QLineF l(points[i], points[i]); drawLines(&l, 1); }}void Q3SVGPaintEngine::drawEllipse(const QRect &r){ Q_D(Q3SVGPaintEngine); QDomElement e; if (r.width() == r.height()) { e = d->doc.createElement(QLatin1String("circle")); double cx = r.x() + (r.width() / 2.0); double cy = r.y() + (r.height() / 2.0); e.setAttribute(QLatin1String("cx"), cx); e.setAttribute(QLatin1String("cy"), cy); e.setAttribute(QLatin1String("r"), cx - r.x()); } else { e = d->doc.createElement(QLatin1String("ellipse")); double cx = r.x() + (r.width() / 2.0); double cy = r.y() + (r.height() / 2.0); e.setAttribute(QLatin1String("cx"), cx); e.setAttribute(QLatin1String("cy"), cy); e.setAttribute(QLatin1String("rx"), cx - r.x()); e.setAttribute(QLatin1String("ry"), cy - r.y()); } d->appendChild(e, QPicturePrivate::PdcDrawEllipse);}void Q3SVGPaintEngine::drawLine(const QLineF &line){ drawLines(&line, 1);}void Q3SVGPaintEngine::drawLines(const QLineF *lines, int lineCount){ Q_D(Q3SVGPaintEngine); QDomElement e; for (int i = 0; i < lineCount; ++i) { e = d->doc.createElement(QLatin1String("line")); e.setAttribute(QLatin1String("x1"), lines[i].x1()); e.setAttribute(QLatin1String("y1"), lines[i].y1()); e.setAttribute(QLatin1String("x2"), lines[i].x2()); e.setAttribute(QLatin1String("y2"), lines[i].y2()); d->appendChild(e, QPicturePrivate::PdcDrawLineSegments); }}void Q3SVGPaintEngine::drawPath(const QPainterPath &path){ Q_D(Q3SVGPaintEngine); QDomElement e = d->doc.createElement(QLatin1String("path")); e.setAttribute(QLatin1String("d"), qt_svg_compose_path(path)); d->appendChild(e, QPicturePrivate::PdcDrawPath);}void Q3SVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode){ Q_D(Q3SVGPaintEngine); QString str; if (mode == PolylineMode) { QDomElement e = d->doc.createElement(QLatin1String("polyline")); for (int i = 0; i < pointCount; ++i) { QString tmp; tmp.sprintf("%f %f ", points[i].x(), points[i].y()); str += tmp; } e.setAttribute(QLatin1String("points"), str.trimmed()); d->appendChild(e, QPicturePrivate::PdcDrawPolyline); } else { QDomElement e = d->doc.createElement(QLatin1String("polygon")); for (int i = 0; i < pointCount; ++i) { QString tmp; tmp.sprintf("%f %f ", points[i].x(), points[i].y()); str += tmp; } e.setAttribute(QLatin1String("points"), str.trimmed()); d->appendChild(e, QPicturePrivate::PdcDrawPolygon); }}void Q3SVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -