00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #pragma once
00026
00027 #include "cinder/Cinder.h"
00028 #include "cinder/Xml.h"
00029 #include "cinder/Vector.h"
00030 #include "cinder/Color.h"
00031 #include "cinder/Shape2d.h"
00032 #include "cinder/PolyLine.h"
00033 #include "cinder/Exception.h"
00034 #include "cinder/MatrixAffine2.h"
00035 #include "cinder/Surface.h"
00036 #include "cinder/Font.h"
00037 #include "cinder/Function.h"
00038
00039 #include <map>
00040
00041 namespace cinder { namespace svg {
00042
00043 typedef enum { FILL_RULE_NONZERO, FILL_RULE_EVENODD } FillRule;
00044 typedef enum { LINE_CAP_BUTT, LINE_CAP_ROUND, LINE_CAP_SQUARE } LineCap;
00045 typedef enum { LINE_JOIN_MITER, LINE_JOIN_ROUND, LINE_JOIN_BEVEL } LineJoin;
00046 typedef enum { WEIGHT_100, WEIGHT_200, WEIGHT_300, WEIGHT_400, WEIGHT_NORMAL = WEIGHT_400, WEIGHT_500, WEIGHT_600, WEIGHT_700, WEIGHT_BOLD = WEIGHT_700, WEIGHT_800, WEIGHT_900 } FontWeight;
00047
00048 class Node;
00049 class Group;
00050 class Rect;
00051 class Circle;
00052 class Path;
00053 class TextSpan;
00054 class Style;
00055 class Line;
00056 class Ellipse;
00057 class Polyline;
00058 class Polygon;
00059 class Image;
00060 class ExcChildNotFound;
00061
00062 typedef std::function<bool(const Node&, svg::Style *)> RenderVisitor;
00063
00065 class Renderer {
00066 public:
00067 Renderer() {}
00068
00069 virtual ~Renderer() {}
00070
00071 void setVisitor( const RenderVisitor &visitor ) { mVisitor = visitor; }
00072
00073 virtual void pushGroup( const Group &group, float opacity ) {}
00074 virtual void popGroup() {}
00075 virtual void drawPath( const svg::Path &path ) {}
00076 virtual void drawPolyline( const svg::Polyline &polyline ) {}
00077 virtual void drawPolygon( const svg::Polygon &polygon ) {}
00078 virtual void drawLine( const svg::Line &line ) {}
00079 virtual void drawRect( const svg::Rect &rect ) {}
00080 virtual void drawCircle( const svg::Circle &circle ) {}
00081 virtual void drawEllipse( const svg::Ellipse &ellipse ) {}
00082 virtual void drawImage( const svg::Image &image ) {}
00083 virtual void drawTextSpan( const svg::TextSpan &span ) {}
00084
00085 virtual void pushMatrix( const MatrixAffine2f &m ) {}
00086 virtual void popMatrix() {}
00087 virtual void pushStyle( const svg::Style &style ) {}
00088 virtual void popStyle( const svg::Style &style ) {}
00089 virtual void pushFill( const class Paint &paint ) {}
00090 virtual void popFill() {}
00091 virtual void pushStroke( const class Paint &paint ) {}
00092 virtual void popStroke() {}
00093 virtual void pushFillOpacity( float opacity ) {}
00094 virtual void popFillOpacity() {}
00095 virtual void pushStrokeOpacity( float opacity ) {}
00096 virtual void popStrokeOpacity() {}
00097 virtual void pushStrokeWidth( float width ) {}
00098 virtual void popStrokeWidth() {}
00099 virtual void pushFillRule( FillRule rule ) {}
00100 virtual void popFillRule() {}
00101 virtual void pushLineCap( LineCap lineCap ) {}
00102 virtual void popLineCap() {}
00103 virtual void pushLineJoin( LineJoin lineJoin ) {}
00104 virtual void popLineJoin() {}
00105 virtual void pushTextPen( const Vec2f &penPos ) {}
00106 virtual void popTextPen() {}
00107 virtual void pushTextRotation( float rotation ) {}
00108 virtual void popTextRotation() {}
00109
00110 bool visit( const Node &node, svg::Style *style ) const {
00111 if( mVisitor )
00112 return mVisitor( node, style );
00113 else
00114 return true;
00115 }
00116
00117 protected:
00118 RenderVisitor mVisitor;
00119
00120 friend class svg::Node;
00121 };
00122
00124 class Value {
00125 public:
00126 enum Unit { USER, PX, PERCENT, PT, PC, MM, CM, INCH, EM, EX };
00127
00128 Value() : mValue( 0 ), mUnit( USER ) {}
00129 Value( float value, Unit unit = USER ) : mValue( value ), mUnit( unit ) {}
00130
00131 float asUser( float percentOf = 100, float dpi = 72, float fontSize = 12, float fontXHeight = 7 ) const;
00132
00133 bool isUser() const { return mUnit == USER; }
00134 bool isPercent() const { return mUnit == PERCENT; }
00135 bool isPixels() const { return mUnit == PX; }
00136
00137 static Value parse( const char **sInOut );
00138 static Value parse( const std::string &s );
00139
00140 Unit mUnit;
00141 float mValue;
00142 };
00143
00145 class Paint {
00146 public:
00147 enum { NONE, COLOR, LINEAR_GRADIENT, RADIAL_GRADIENT };
00148
00149 Paint();
00150 Paint( uint8_t type );
00151 Paint( const ColorA8u &color );
00152
00153 static Paint parse( const char *value, bool *specified, const Node *parentNode );
00154
00155 bool isNone() const { return mType == NONE; }
00156 bool isLinearGradient() const { return mType == LINEAR_GRADIENT; }
00157 bool isRadialGradient() const { return mType == RADIAL_GRADIENT; }
00158 const ColorA8u& getColor( size_t idx = 0 ) const { return mStops[idx].second; }
00159 float getOffset( size_t idx ) const { return mStops[idx].first; }
00160 size_t getNumColors() const { return mStops.size(); }
00161
00162
00163 Vec2f getCoords0() const { return mCoords0; }
00164 Vec2f getCoords1() const { return mCoords1; }
00165 float getRadius() const { return mRadius; }
00166 bool useObjectBoundingBox() const { return mUseObjectBoundingBox; }
00167 bool specifiesTransform() const { return mSpecifiesTransform; }
00168 MatrixAffine2f getTransform() const { return mTransform; }
00169
00170 uint8_t mType;
00171 std::vector<std::pair<float,ColorA8u> > mStops;
00172
00173 Vec2f mCoords0, mCoords1;
00174 float mRadius;
00175 bool mUseObjectBoundingBox;
00176 MatrixAffine2f mTransform;
00177 bool mSpecifiesTransform;
00178 };
00179
00181 class Style {
00182 public:
00183 Style();
00184 Style( const XmlTree &xml, const Node *parent );
00185
00187 static Style makeGlobalDefaults();
00189 void clear();
00190
00191 bool specifiesFill() const { return mSpecifiesFill; }
00192 void unspecifyFill() { mSpecifiesFill = false; }
00193 const Paint& getFill() const { return mFill; }
00194 void setFill( const Paint &fill ) { mSpecifiesFill = true; mFill = fill; }
00195 static const Paint& getFillDefault() { return sPaintBlack; }
00196
00197 bool specifiesStroke() const { return mSpecifiesStroke; }
00198 void unspecifyStroke() { mSpecifiesStroke = false; }
00199 const Paint& getStroke() const { return mStroke; }
00200 void setStroke( const Paint &stroke ) { mSpecifiesStroke = true; mStroke = stroke; }
00201 static const Paint& getStrokeDefault() { return sPaintNone; }
00202
00203 bool specifiesOpacity() const { return mSpecifiesOpacity; }
00204 void unspecifyOpacity() { mSpecifiesOpacity = false; }
00205 float getOpacity() const { return mOpacity; }
00206 void setOpacity( float opacity ) { mSpecifiesOpacity = true; mOpacity = opacity; }
00207 static float getOpacityDefault() { return 1.0f; }
00208
00209 bool specifiesStrokeOpacity() const { return mSpecifiesStrokeOpacity; }
00210 void unspecifyStrokeOpacity() { mSpecifiesStrokeOpacity = false; }
00211 float getStrokeOpacity() const { return mStrokeOpacity; }
00212 void setStrokeOpacity( float strokeOpacity ) { mSpecifiesStrokeOpacity = true; mStrokeOpacity = strokeOpacity; }
00213 static float getStrokeOpacityDefault() { return 1.0f; }
00214
00215 bool specifiesFillOpacity() const { return mSpecifiesFillOpacity; }
00216 void unspecifyFillOpacity() { mSpecifiesFillOpacity = false; }
00217 float getFillOpacity() const { return mFillOpacity; }
00218 void setFillOpacity( float fillOpacity ) { mSpecifiesFillOpacity = true; mFillOpacity = fillOpacity; }
00219 static float getFillOpacityDefault() { return 1.0f; }
00220
00221 bool specifiesStrokeWidth() const { return mSpecifiesStrokeWidth; }
00222 void unspecifyStrokeWidth() { mSpecifiesStrokeWidth = false; }
00223 float getStrokeWidth() const { return mStrokeWidth; }
00224 void setStrokeWidth( float strokeWidth ) { mSpecifiesStrokeWidth = true; mStrokeWidth = strokeWidth; }
00225 static float getStrokeWidthDefault() { return 1.0f; }
00226
00227 bool specifiesFillRule() const { return mSpecifiesFillRule; }
00228 void unspecifyFillRule() { mSpecifiesFillRule = false; }
00229 FillRule getFillRule() const { return mFillRule; }
00230 void setFillRule( FillRule fillRule ) { mSpecifiesFillRule = true; mFillRule = fillRule; }
00231 static FillRule getFillRuleDefault() { return svg::FILL_RULE_NONZERO; }
00232
00233 bool specifiesLineCap() const { return mSpecifiesLineCap; }
00234 void unspecifyLineCap() { mSpecifiesLineCap = false; }
00235 LineCap getLineCap() const { return mLineCap; }
00236 void setLineCap( LineCap lineCap ) { mSpecifiesLineCap = true; mLineCap = lineCap; }
00237 static LineCap getLineCapDefault() { return svg::LINE_CAP_BUTT; }
00238
00239 bool specifiesLineJoin() const { return mSpecifiesLineJoin; }
00240 void unspecifyLineJoin() { mSpecifiesLineJoin = false; }
00241 LineJoin getLineJoin() const { return mLineJoin; }
00242 void setLineJoin( LineJoin lineJoin ) { mSpecifiesLineJoin = true; mLineJoin = lineJoin; }
00243 static LineJoin getLineJoinDefault() { return svg::LINE_JOIN_MITER; }
00244
00245
00246 bool specifiesFontFamilies() const { return mSpecifiesFontFamilies; }
00247 void unspecifyFontFamilies() { mSpecifiesFontFamilies = false; }
00248 const std::vector<std::string>& getFontFamilies() const { return mFontFamilies; }
00249 std::vector<std::string>& getFontFamilies() { return mFontFamilies; }
00250 void setFontFamily( const std::string &family ) { mSpecifiesFontFamilies = true; mFontFamilies.clear(); mFontFamilies.push_back( family ); }
00251 void setFontFamilies( const std::vector<std::string> &families ) { mSpecifiesFontFamilies = true; mFontFamilies = families; }
00252 static const std::vector<std::string>& getFontFamiliesDefault();
00253
00254 bool specifiesFontSize() const { return mSpecifiesFontSize; }
00255 void unspecifyFontSize() { mSpecifiesFontSize = false; }
00256 Value getFontSize() const { return mFontSize; }
00257 void setFontSize( const Value &fontSize ) { mSpecifiesFontSize = true; mFontSize = fontSize; }
00258 static Value getFontSizeDefault() { return Value( 12 ); }
00259
00260 bool specifiesFontWeight() const { return mSpecifiesFontWeight; }
00261 void unspecifyFontWeight() { mSpecifiesFontWeight = false; }
00262 FontWeight getFontWeight() const { return mFontWeight; }
00263 void setFontWeight( FontWeight weight ) { mSpecifiesFontWeight = true; mFontWeight = weight; }
00264 static FontWeight getFontWeightDefault() { return svg::WEIGHT_NORMAL; }
00265
00266 bool specifiesVisible() const { return mSpecifiesVisible; }
00267 bool isVisible() const { return mVisible; }
00268 void setVisible( bool visible ) { mSpecifiesVisible = true; mVisible = visible; }
00269 void unspecifyVisible() { mSpecifiesVisible = false; }
00270
00271 bool isDisplayNone() const { return mDisplayNone; }
00272 void setDisplayNone( bool displayNone ) { mDisplayNone = displayNone; }
00273
00274 void startRender( Renderer &renderer, bool isNodeDrawable ) const;
00275 void finishRender( Renderer &renderer, bool isNodeDrawable ) const;
00276
00277 void parseStyleAttribute( const std::string &stylePropertyString, const Node *parent );
00278 bool parseProperty( const std::string &key, const std::string &value, const Node *parent );
00279
00280 protected:
00281 bool mSpecifiesOpacity;
00282 float mOpacity;
00283 bool mSpecifiesFillOpacity, mSpecifiesStrokeOpacity;
00284 float mFillOpacity, mStrokeOpacity;
00285
00286 bool mSpecifiesFill, mSpecifiesStroke;
00287 Paint mFill, mStroke;
00288 bool mSpecifiesStrokeWidth;
00289 float mStrokeWidth;
00290 bool mSpecifiesFillRule;
00291 FillRule mFillRule;
00292 bool mSpecifiesLineCap;
00293 LineCap mLineCap;
00294 bool mSpecifiesLineJoin;
00295 LineJoin mLineJoin;
00296
00297
00298 bool mSpecifiesFontFamilies, mSpecifiesFontSize, mSpecifiesFontWeight;
00299 std::vector<std::string> mFontFamilies;
00300 Value mFontSize;
00301 FontWeight mFontWeight;
00302
00303
00304 bool mSpecifiesVisible, mVisible, mDisplayNone;
00305
00306 private:
00307 static Paint sPaintNone, sPaintBlack;
00308 };
00309
00311 class Node {
00312 public:
00313 Node( const Node *parent ) : mParent( parent ), mSpecifiesTransform( false ), mBoundingBoxCached( false ) {}
00314 virtual ~Node() {}
00315
00317 class Doc* getDoc() const;
00319 const Node* getParent() const { return mParent; }
00321 const std::string& getId() const { return mId; }
00323 std::string getDomPath() const;
00325 const Style& getStyle() const { return mStyle; }
00327 void setStyle( const Style &style ) { mStyle = style; }
00329 Style calcInheritedStyle() const;
00330
00332 virtual bool containsPoint( const Vec2f &pt ) const { return false; }
00333
00335 void render( Renderer &renderer ) const;
00336
00338 virtual const Node* findInAncestors( const std::string &elementId ) const;
00340 Paint findPaintInAncestors( const std::string &paintName ) const;
00341
00343 bool specifiesTransform() const { return mSpecifiesTransform; }
00345 MatrixAffine2f getTransform() const { return mTransform; }
00347 void setTransform( const MatrixAffine2f &transform ) { mTransform = transform; mSpecifiesTransform = true; }
00349 void unspecifyTransform() { mSpecifiesTransform = false; }
00351 MatrixAffine2f getTransformInverse() const { return ( mSpecifiesTransform ) ? mTransform.invertCopy() : MatrixAffine2f::identity(); }
00353 MatrixAffine2f getTransformAbsolute() const;
00355 MatrixAffine2f getTransformAbsoluteInverse() const { return getTransformAbsolute().invertCopy(); }
00356
00358 Rectf getBoundingBox() const { if( ! mBoundingBoxCached ) { mBoundingBox = calcBoundingBox(); mBoundingBoxCached = true; } return mBoundingBox; }
00360 Rectf getBoundingBoxAbsolute() const { return getBoundingBox().transformCopy( getTransformAbsolute() ); }
00361
00363 virtual Shape2d getShape() const { return Shape2d(); }
00365 Shape2d getShapeAbsolute() const { return getShape().transformCopy( getTransformAbsolute() ); }
00366
00368 const Paint& getFill() const;
00370 const Paint& getStroke() const;
00372 float getOpacity() const;
00374 float getFillOpacity() const;
00376 float getStrokeOpacity() const;
00378 FillRule getFillRule() const;
00380 LineCap getLineCap() const;
00382 LineJoin getLineJoin() const;
00384 float getStrokeWidth() const;
00386 const std::vector<std::string>& getFontFamilies() const;
00388 Value getFontSize() const;
00390 bool isVisible() const;
00392 bool isDisplayNone() const { return mStyle.isDisplayNone(); }
00393
00394
00395 protected:
00396 Node( const Node *parent, const XmlTree &xml );
00397
00398 virtual bool isDrawable() const { return true; }
00399
00400 void startRender( Renderer &renderer, const Style &style ) const;
00401 void finishRender( Renderer &renderer, const Style &style ) const;
00402 virtual void renderSelf( Renderer &renderer ) const = 0;
00403
00404 virtual Rectf calcBoundingBox() const { return Rectf( 0, 0, 0, 0 ); }
00405
00406 static Paint parsePaint( const char *value, bool *specified, const Node *parentNode );
00407 static MatrixAffine2f parseTransform( const std::string &value );
00408 static bool parseTransformComponent( const char **c, MatrixAffine2f *result );
00409
00410 static std::string findStyleValue( const std::string &styleString, const std::string &key );
00411 void parseStyle( const std::string &value );
00412
00413 protected:
00414 const Node *mParent;
00415 std::string mId;
00416 Style mStyle;
00417 bool mSpecifiesTransform;
00418 MatrixAffine2f mTransform;
00419 mutable bool mBoundingBoxCached;
00420 mutable Rectf mBoundingBox;
00421
00422 private:
00423 void firstStartRender( Renderer &renderer ) const;
00424
00425 friend class Group;
00426 friend class Use;
00427 };
00428
00430 class Gradient : public Node {
00431 public:
00432 Gradient( const Node *parent, const XmlTree &xml );
00433
00434 class Stop {
00435 public:
00436 Stop( const Node *parent, const XmlTree &xml );
00437
00438 float mOffset;
00439 ColorA8u mColor;
00440 float mOpacity;
00441 bool mSpecifiesColor, mSpecifiesOpacity;
00442 };
00443
00444 bool useObjectBoundingBox() const { return mUseObjectBoundingBox; }
00445 bool specifiesTransform() const { return mSpecifiesTransform; }
00446
00447 protected:
00448 virtual void renderSelf( Renderer &renderer ) const {}
00449
00450 void parse( const Node *parent, const XmlTree &xml );
00451 void copyAttributesFrom( const Gradient &rhs );
00452 Paint asPaint() const;
00453
00454 std::vector<Stop> mStops;
00455 Vec2f mCoords0, mCoords1;
00456 bool mUseObjectBoundingBox;
00457 bool mSpecifiesTransform;
00458 MatrixAffine2f mTransform;
00459 };
00460
00462 class LinearGradient : public Gradient {
00463 public:
00464 LinearGradient( const Node *parent, const XmlTree &xml );
00465
00466 Paint asPaint() const;
00467
00468 protected:
00469 void parse( const XmlTree &xml );
00470
00471 virtual bool isDrawable() const { return false; }
00472 };
00473
00475 class RadialGradient : public Gradient {
00476 public:
00477 RadialGradient( const Node *parent, const XmlTree &xml );
00478
00479 Paint asPaint() const;
00480
00481 protected:
00482 void parse( const XmlTree &xml );
00483
00484 virtual bool isDrawable() const { return false; }
00485 float mRadius;
00486 };
00487
00489 class Circle : public Node {
00490 public:
00491 Circle( const Node *parent ) : Node( parent ) {}
00492 Circle( const Node *parent, const XmlTree &xml );
00493
00494 Vec2f getCenter() const { return mCenter; }
00495 float getRadius() const { return mRadius; }
00496
00497 virtual bool containsPoint( const Vec2f &pt ) const { return pt.distanceSquared( mCenter ) < mRadius * mRadius; }
00498
00499 virtual Shape2d getShape() const;
00500
00501 protected:
00502 virtual void renderSelf( Renderer &renderer ) const;
00503 virtual Rectf calcBoundingBox() const { return Rectf( mCenter.x - mRadius, mCenter.y - mRadius, mCenter.x + mRadius, mCenter.y + mRadius ); }
00504
00505 Vec2f mCenter;
00506 float mRadius;
00507 };
00508
00510 class Ellipse : public Node {
00511 public:
00512 Ellipse( const Node *parent ) : Node( parent ) {}
00513 Ellipse( const Node *parent, const XmlTree &xml );
00514
00515 Vec2f getCenter() const { return mCenter; }
00516 float getRadiusX() const { return mRadiusX; }
00517 float getRadiusY() const { return mRadiusY; }
00518
00519 bool containsPoint( const Vec2f &pt ) const;
00520
00521 virtual Shape2d getShape() const;
00522
00523 protected:
00524 virtual void renderSelf( Renderer &renderer ) const;
00525 virtual Rectf calcBoundingBox() const { return Rectf( mCenter.x - mRadiusX, mCenter.y - mRadiusY, mCenter.x + mRadiusX, mCenter.y + mRadiusY ); }
00526
00527 Vec2f mCenter;
00528 float mRadiusX, mRadiusY;
00529 };
00530
00532 class Path : public Node {
00533 public:
00534 Path( const Node *parent ) : Node( parent ) {}
00535 Path( const Node *parent, const XmlTree &xml );
00536
00537 const Shape2d& getShape2d() const { return mPath; }
00538 void appendShape2d( Shape2d *appendTo ) const;
00539
00540 virtual bool containsPoint( const Vec2f &pt ) const { return mPath.contains( pt ); }
00541
00542 virtual Shape2d getShape() const { return mPath; }
00543
00544 protected:
00545 virtual void renderSelf( Renderer &renderer ) const;
00546 virtual Rectf calcBoundingBox() const { return mPath.calcPreciseBoundingBox(); }
00547
00548 Shape2d mPath;
00549 };
00550
00552 class Line : public Node {
00553 public:
00554 Line( const Node *parent ) : Node( parent ) {}
00555 Line( const Node *parent, const XmlTree &xml );
00556
00557 const Vec2f& getPoint1() const { return mPoint1; }
00558 const Vec2f& getPoint2() const { return mPoint2; }
00559
00560 virtual Shape2d getShape() const;
00561
00562 protected:
00563 virtual void renderSelf( Renderer &renderer ) const;
00564 virtual Rectf calcBoundingBox() const { return Rectf( mPoint1, mPoint2 ); }
00565
00566 Vec2f mPoint1, mPoint2;
00567 };
00568
00570 class Rect : public Node {
00571 public:
00572 Rect( const Node *parent ) : Node( parent ) {}
00573 Rect( const Node *parent, const XmlTree &xml );
00574
00575 const Rectf& getRect() const { return mRect; }
00576
00577 virtual bool containsPoint( const Vec2f &pt ) const { return mRect.contains( pt ); }
00578
00579 virtual Shape2d getShape() const;
00580
00581 protected:
00582 virtual void renderSelf( Renderer &renderer ) const;
00583 virtual Rectf calcBoundingBox() const { return mRect; }
00584
00585 Rectf mRect;
00586 };
00587
00589 class Polygon : public Node {
00590 public:
00591 Polygon( const Node *parent ) : Node( parent ) {}
00592 Polygon( const Node *parent, const XmlTree &xml );
00593
00594 const PolyLine2f& getPolyLine() const { return mPolyLine; }
00595 PolyLine2f& getPolyLine() { return mPolyLine; }
00596
00597 virtual bool containsPoint( const Vec2f &pt ) const { return mPolyLine.contains( pt ); }
00598
00599 virtual Shape2d getShape() const;
00600
00601 protected:
00602 virtual void renderSelf( Renderer &renderer ) const;
00603 virtual Rectf calcBoundingBox() const { return Rectf( mPolyLine.getPoints() ); }
00604
00605 PolyLine2f mPolyLine;
00606 };
00607
00609 class Polyline : public Node {
00610 public:
00611 Polyline( const Node *parent ) : Node( parent ) {}
00612 Polyline( const Node *parent, const XmlTree &xml );
00613
00614 const PolyLine2f& getPolyLine() const { return mPolyLine; }
00615 PolyLine2f& getPolyLine() { return mPolyLine; }
00616
00617 virtual bool containsPoint( const Vec2f &pt ) const { return mPolyLine.contains( pt ); }
00618
00619 virtual Shape2d getShape() const;
00620
00621 protected:
00622 virtual void renderSelf( Renderer &renderer ) const;
00623 virtual Rectf calcBoundingBox() const { return Rectf( mPolyLine.getPoints() ); }
00624
00625 PolyLine2f mPolyLine;
00626 };
00627
00629 class Use : public Node {
00630 public:
00631 Use( const Node *parent, const XmlTree &xml );
00632
00633 virtual bool isDrawable() const { return false; }
00634
00635 virtual Shape2d getShape() const{ if( mReferenced ) return mReferenced->getShape(); else return Shape2d(); }
00636
00637 protected:
00638 virtual void renderSelf( Renderer &renderer ) const;
00639 virtual Rectf calcBoundingBox() const { if( mReferenced ) return mReferenced->getBoundingBox(); else return Rectf(0,0,0,0); }
00640
00641 void parse( const XmlTree &xml );
00642
00643 const Node *mReferenced;
00644 };
00645
00647 class Image : public Node {
00648 public:
00649 Image( const Node *parent, const XmlTree &xml );
00650
00651 const Rectf& getRect() const { return mRect; }
00652 const std::shared_ptr<Surface8u> getSurface() const { return mImage; }
00653
00654 virtual bool containsPoint( const Vec2f &pt ) const { return mRect.contains( pt ); }
00655
00656 protected:
00657 virtual void renderSelf( Renderer &renderer ) const;
00658 virtual Rectf calcBoundingBox() const { return mRect; }
00659
00660 static std::shared_ptr<Surface8u> parseDataImage( const std::string &data );
00661
00662 Rectf mRect;
00663 fs::path mFilePath;
00664 std::shared_ptr<Surface8u> mImage;
00665 };
00666
00667 typedef std::shared_ptr<TextSpan> TextSpanRef;
00668
00670 class TextSpan : public Node {
00671 public:
00672 class Attributes {
00673 public:
00674 Attributes() {}
00675 Attributes( const XmlTree &xml );
00676
00677 void startRender( Renderer &renderer ) const;
00678 void finishRender( Renderer &renderer ) const;
00679
00680 std::vector<Value> mX, mY;
00681 float mDx, mDy;
00682 std::vector<Value> mRotate;
00683 float mTextLength;
00684 float mLengthAdjust;
00685 };
00686
00687 TextSpan( const Node *parent, const XmlTree &xml );
00688 TextSpan( const Node *parent, const std::string &spanString );
00689
00690 const std::string& getString() const { return mString; }
00691 const std::shared_ptr<Font> getFont() const;
00693 std::vector<std::pair<uint16_t,Vec2f> > getGlyphMeasures() const;
00694 Vec2f getTextPen() const;
00695 float getRotation() const;
00696
00697 protected:
00698 virtual void renderSelf( Renderer &renderer ) const;
00699
00700 bool mIgnoreAttributes;
00701 Attributes mAttributes;
00702 std::string mString;
00703 mutable std::shared_ptr<Font> mFont;
00704 mutable std::shared_ptr<std::vector<std::pair<uint16_t,Vec2f> > > mGlyphMeasures;
00705 mutable std::shared_ptr<Shape2d> mShape;
00706
00707 std::vector<TextSpanRef> mSpans;
00708
00709 friend class Text;
00710 };
00711
00713 class Text : public Node {
00714 public:
00715 Text( const Node *parent, const XmlTree &xml );
00716
00717 Vec2f getTextPen() const;
00718 float getRotation() const;
00719
00720 protected:
00721 virtual void renderSelf( Renderer &renderer ) const;
00722
00723 TextSpan::Attributes mAttributes;
00724
00725 std::vector<TextSpanRef> mSpans;
00726 };
00727
00729 class Group : public Node {
00730 public:
00731 Group( const Node *parent ) : Node( parent ) {}
00732 Group( const Node *parent, const XmlTree &xml );
00733 ~Group();
00734
00736 template<typename T>
00737 const T* find( const std::string &id ) { return dynamic_cast<const T*>( findNode( id ) ); }
00739 const Node* findNode( const std::string &id, bool recurse = true ) const;
00740 virtual const Node* findInAncestors( const std::string &elementId ) const;
00742 const Node& getChild( const std::string &id ) const;
00744 const Node& operator/( const std::string &id ) const { return getChild( id ); }
00745
00747 virtual Shape2d getShape() const { return getMergedShape2d(); }
00748
00750 void appendMergedShape2d( Shape2d *appendTo ) const;
00751
00753 const std::list<Node*>& getChildren() const { return mChildren; }
00755 std::list<Node*>& getChildren() { return mChildren; }
00756
00757 protected:
00758 Node* nodeUnderPoint( const Vec2f &absolutePoint, const MatrixAffine2f &parentInverseMatrix ) const;
00759 Shape2d getMergedShape2d() const;
00760
00761 virtual void renderSelf( Renderer &renderer ) const;
00762 virtual Rectf calcBoundingBox() const;
00763
00764 virtual bool isDrawable() const { return false; }
00765 void parse( const XmlTree &xml );
00766
00767 std::list<Node*> mChildren;
00768 std::shared_ptr<Group> mDefs;
00769 };
00770
00771
00772 typedef std::shared_ptr<Doc> DocRef;
00774 class Doc : public Group {
00775 public:
00776 Doc() : Group( 0 ), mWidth( 0 ), mHeight( 0 ) {}
00777 Doc( const fs::path &filePath );
00778 Doc( DataSourceRef dataSource, const fs::path &filePath = fs::path() );
00779
00780 static DocRef create( const fs::path &filePath );
00781 static DocRef create( DataSourceRef dataSource, const fs::path &filePath = fs::path() );
00782 static DocRef createFromSvgz( DataSourceRef dataSource, const fs::path &filePath = fs::path() );
00783
00785 int32_t getWidth() const { return mWidth; }
00787 int32_t getHeight() const { return mHeight; }
00789 Vec2i getSize() const { return Vec2i( getWidth(), getHeight() ); }
00791 float getAspectRatio() const { return getWidth() / (float)getHeight(); }
00793 Area getBounds() const { return Area( 0, 0, mWidth, mHeight ); }
00794
00796 float getDpi() const { return 72.0f; }
00797
00799 Node* nodeUnderPoint( const Vec2f &pt );
00800
00802 std::shared_ptr<Surface8u> loadImage( fs::path relativePath );
00803 private:
00804 void loadDoc( DataSourceRef source, fs::path filePath );
00805
00806 virtual void renderSelf( Renderer &renderer ) const;
00807
00808 std::shared_ptr<XmlTree> mXmlTree;
00809 std::map<fs::path,std::shared_ptr<Surface8u> > mImageCache;
00810
00811 fs::path mFilePath;
00812 Area mViewBox;
00813 int32_t mWidth, mHeight;
00814 };
00815
00817 class Exc : public Exception
00818 {};
00819
00820 class ValueExc : public Exc
00821 {};
00822
00823 class FloatParseExc : public Exc
00824 {};
00825
00826 class PathParseExc : public Exc
00827 {};
00828
00829 class TransformParseExc : public Exc
00830 {};
00831
00832 class ExcChildNotFound : public Exc {
00833 public:
00834 ExcChildNotFound( const std::string &child ) throw();
00835
00836 virtual const char* what() const throw() { return mMessage; }
00837
00838 private:
00839 char mMessage[2048];
00840 };
00841
00842
00843 } }