Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

include/cinder/svg/SvgGl.h

Go to the documentation of this file.
00001 /*
00002  Copyright (c) 2012, The Cinder Project
00003  All rights reserved.
00004  
00005  This code is designed for use with the Cinder C++ library, http://libcinder.org
00006 
00007  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
00008  the following conditions are met:
00009 
00010     * Redistributions of source code must retain the above copyright notice, this list of conditions and
00011     the following disclaimer.
00012     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
00013     the following disclaimer in the documentation and/or other materials provided with the distribution.
00014 
00015  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00016  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00017  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00018  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00019  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00020  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00021  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00022  POSSIBILITY OF SUCH DAMAGE.
00023 */
00024 
00025 
00026 #pragma once
00027 
00028 #include "cinder/gl/gl.h"
00029 #include "cinder/svg/Svg.h"
00030 #include "cinder/Triangulate.h"
00031 
00032 namespace cinder {
00033 
00034 class SvgRendererGl : public svg::Renderer {
00035   public:
00036     SvgRendererGl() : svg::Renderer() { 
00037         mFillStack.push_back( svg::Paint( Color::black() ) );
00038         mStrokeStack.push_back( svg::Paint() );
00039         mFillOpacityStack.push_back( 1.0f );
00040         mStrokeOpacityStack.push_back( 1.0f );
00041         mStrokeWidthStack.push_back( 1.0f );
00042         glLineWidth( 1.0f );
00043         glMatrixMode( GL_MODELVIEW );
00044         glPushMatrix();
00045         mFillRuleStack.push_back( svg::FILL_RULE_NONZERO );
00046     }
00047     
00048     ~SvgRendererGl() {
00049         glPopMatrix();
00050     }
00051   
00052     void    pushGroup( const svg::Group &group, float opacity ) {}
00053     
00054     void    drawPath( const svg::Path &path ) {
00055         if( ! mFillStack.back().isNone() ) {
00056             gl::color( getCurFillColor() );
00057             Triangulator::Winding winding = ( mFillRuleStack.back() == svg::FILL_RULE_NONZERO ) ? Triangulator::WINDING_NONZERO : Triangulator::WINDING_ODD;
00058             gl::draw( Triangulator( path.getShape2d() ).calcMesh( winding ) );
00059         }
00060         if( ! mStrokeStack.back().isNone() ) {
00061             gl::color( getCurStrokeColor() );
00062             gl::draw( path.getShape2d() );
00063         }
00064     }
00065 
00066     void    drawPolygon( const svg::Polygon &polygon ) {
00067         if( ! mFillStack.back().isNone() ) {
00068             gl::color( getCurFillColor() );
00069             Triangulator::Winding winding = ( mFillRuleStack.back() == svg::FILL_RULE_NONZERO ) ? Triangulator::WINDING_NONZERO : Triangulator::WINDING_ODD;
00070             gl::draw( Triangulator( polygon.getPolyLine() ).calcMesh( winding ) );
00071 
00072         }
00073         if( ! mStrokeStack.back().isNone() ) {
00074             gl::color( getCurStrokeColor() );
00075             gl::draw( polygon.getPolyLine() );
00076         }
00077     }
00078 
00079     void    drawPolyline( const svg::Polyline &polyline ) {
00080         if( ! mFillStack.back().isNone() ) {
00081             gl::color( getCurFillColor() );
00082             Triangulator::Winding winding = ( mFillRuleStack.back() == svg::FILL_RULE_NONZERO ) ? Triangulator::WINDING_NONZERO : Triangulator::WINDING_ODD;
00083             gl::draw( Triangulator( polyline.getPolyLine() ).calcMesh( winding ) );
00084 
00085         }
00086         if( ! mStrokeStack.back().isNone() ) {
00087             gl::color( getCurStrokeColor() );
00088             gl::draw( polyline.getPolyLine() );
00089         }
00090     }
00091 
00092     void    drawLine( const svg::Line &line ) {
00093         if( ! mStrokeStack.back().isNone() ) {
00094             gl::color( getCurStrokeColor() );
00095             gl::drawLine( line.getPoint1(), line.getPoint2() );
00096         }
00097     }
00098 
00099     void    drawRect( const svg::Rect &rect ) {
00100         if( ! mFillStack.back().isNone() ) {
00101             gl::color( getCurFillColor() );
00102             gl::drawSolidRect( rect.getRect() );
00103         }
00104         if( ! mStrokeStack.back().isNone() ) {
00105             gl::color( getCurStrokeColor() );
00106             gl::drawStrokedRect( rect.getRect() );
00107         }
00108     }
00109 
00110     void    drawCircle( const svg::Circle &circle ) {
00111         if( ! mFillStack.back().isNone() ) {
00112             gl::color( getCurFillColor() );
00113             gl::drawSolidCircle( circle.getCenter(), circle.getRadius() );
00114         }
00115         if( ! mStrokeStack.back().isNone() ) {
00116             gl::color( getCurStrokeColor() );
00117             gl::drawStrokedCircle( circle.getCenter(), circle.getRadius() );
00118         }
00119     }
00120 
00121     void    drawEllipse( const svg::Ellipse &ellipse ) {
00122         if( ! mFillStack.back().isNone() ) {
00123             gl::color( getCurFillColor() );
00124             gl::drawSolidEllipse( ellipse.getCenter(), ellipse.getRadiusX(), ellipse.getRadiusY() );
00125         }
00126         if( ! mStrokeStack.back().isNone() ) {
00127             gl::color( getCurStrokeColor() );
00128             gl::drawStrokedEllipse( ellipse.getCenter(), ellipse.getRadiusX(), ellipse.getRadiusY() );
00129         }
00130     }   
00131     
00132     void    drawImage( const Surface8u &surface, const Rectf &drawRect ) {
00133         gl::color( Color::white() );
00134         gl::draw( gl::Texture( surface ), drawRect );
00135     }
00136 
00137     void    drawTextSpan( const svg::TextSpan &span ) {
00138     
00139     }
00140 
00141     void    popGroup() {}
00142 
00143     void    pushMatrix( const MatrixAffine2f &m ) {
00144         glPushMatrix();
00145         glMultMatrixf( Matrix44f( m ) );
00146     }
00147     void    popMatrix() {
00148         glPopMatrix();
00149     }
00150     
00151     void    pushFill( const svg::Paint &paint ) { mFillStack.push_back( paint ); }
00152     void    popFill() { mFillStack.pop_back(); }
00153     void    pushStroke( const svg::Paint &paint ) { mStrokeStack.push_back( paint ); }
00154     void    popStroke() { mStrokeStack.pop_back(); }
00155     void    pushFillOpacity( float opacity ) { mFillOpacityStack.push_back( opacity ); }
00156     void    popFillOpacity() { mFillOpacityStack.pop_back(); }
00157     void    pushStrokeOpacity( float opacity ) { mStrokeOpacityStack.push_back( opacity ); }
00158     void    popStrokeOpacity() { mStrokeOpacityStack.pop_back(); }
00159 
00160     ColorA  getCurFillColor() { ColorA result( mFillStack.back().getColor() ); result.a = mFillOpacityStack.back(); return result; }
00161     ColorA  getCurStrokeColor() { ColorA result( mStrokeStack.back().getColor() ); result.a = mStrokeOpacityStack.back(); return result; }
00162 
00163 
00164     void    pushStrokeWidth( float width ) { mStrokeWidthStack.push_back( width ); glLineWidth( width ); }
00165     void    popStrokeWidth() { mStrokeWidthStack.pop_back(); glLineWidth( mStrokeWidthStack.back() ); }
00166     void    pushFillRule( svg::FillRule rule ) { mFillRuleStack.push_back( rule ); }
00167     void    popFillRule() { mFillRuleStack.pop_back(); }    
00168 
00169 
00170     std::vector<svg::Paint>     mFillStack, mStrokeStack;
00171     std::vector<float>          mFillOpacityStack, mStrokeOpacityStack;
00172     std::vector<float>          mStrokeWidthStack;
00173     std::vector<svg::FillRule>  mFillRuleStack;
00174 };
00175 
00176 namespace gl {
00177 inline void draw( const svg::Doc &svg )
00178 {
00179     SvgRendererGl renderGl;
00180     svg.render( renderGl );
00181 }
00182 } // namespace gl
00183 
00184 } // namespace cinder