You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegraphics/ksvg/plugin/backends/agg/AggCanvasItems.h

501 lines
13 KiB

/*
Copyright (C) 2001-2003 KSVG Team
This file is part of the KDE project
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
aint with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef AGGCANVASITEMS_H
#define AGGCANVASITEMS_H
#include "CanvasItem.h"
#include "CanvasItems.h"
#include "BezierPathAgg.h"
#include "SVGPathElementImpl.h"
#include "SVGPolyElementImpl.h"
#include "SVGLineElementImpl.h"
#include "SVGRectElementImpl.h"
#include "SVGTextElementImpl.h"
#include "SVGImageElementImpl.h"
#include "SVGCircleElementImpl.h"
#include "SVGEllipseElementImpl.h"
#include "agg_basics.h"
#include "agg_conv_transform.h"
#include "agg_conv_curve.h"
#include "agg_conv_dash.h"
#include "agg_conv_stroke.h"
#include "agg_conv_clip_polygon.h"
#include "agg_span_gradient.h"
#include "SVGBBoxTarget.h"
// gradient helpers
//------------------------------------------------------------------------
class gradient_polymorphic_wrapper_base
{
public:
virtual int calculate(int x, int y, int) const = 0;
};
template<class GradientF>
class gradient_polymorphic_wrapper : public gradient_polymorphic_wrapper_base
{
public:
virtual int calculate(int x, int y, int d) const
{
return m_gradient.calculate(x, y, d);
}
private:
GradientF m_gradient;
};
class gradient_radial_repeat
{
public:
int calculate(int x, int y, int d) const
{
return int(sqrt(pow(x, 2) + pow(y, 2))) % d;
}
};
class gradient_radial_reflect
{
public:
int calculate(int x, int y, int d) const
{
int dist = int(sqrt(pow(x, 2) + pow(y, 2)));
if((dist / d) % 2 == 0)
return dist % d;
else
return d - (dist % d);
}
};
class gradient_linear_repeat
{
public:
int calculate(int x, int y, int d) const
{
return (x < 0) ? (d - (-x % d)) : (x % d);
}
};
class gradient_linear_reflect
{
public:
int calculate(int x, int y, int d) const
{
if((abs(x) / d) % 2 == 0)
return (x < 0) ? (-x % d) : (x % d);
else
return (x > 0) ? (d - (x % d)) : (d - (-x % d));
}
};
#define AGG_CLASS(Class, Type, Member) \
class Agg##Class : public AggShape \
{ \
public: \
Agg##Class(AggCanvas *c, Type *Member); \
virtual ~Agg##Class() { } \
virtual void draw(); \
virtual bool isVisible(); \
virtual void init(); \
virtual void init(const SVGMatrixImpl *screenCTM); \
virtual SVGElementImpl *element() const { return m_##Member; } \
protected: \
Type *m_##Member; \
};
class stroke_dash_base
{
public:
virtual ~stroke_dash_base() {}
virtual void rewind(unsigned) = 0;
virtual unsigned vertex(double*, double*) = 0;
};
template<class Source>
class stroke : public stroke_dash_base
{
public:
typedef agg::conv_stroke<Source> stroke_type;
stroke(Source& src, KSVG::SVGStylableImpl *style);
void rewind(unsigned id) { m_s.rewind(id); }
unsigned vertex(double* x, double* y) { return m_s.vertex(x, y); }
private:
stroke_type m_s;
};
template<class Source>
class dash_stroke : public stroke_dash_base
{
public:
typedef agg::conv_dash<Source> dash_type;
typedef agg::conv_stroke<dash_type> dash_stroke_type;
dash_stroke(Source& src, KSVG::SVGStylableImpl *style);
void rewind(unsigned id) { m_ds.rewind(id); }
unsigned vertex(double* x, double* y) { return m_ds.vertex(x, y); }
private:
dash_type m_d;
dash_stroke_type m_ds;
};
template<class Source>
class dash_stroke_simple
{
public:
dash_stroke_simple(Source& src, KSVG::SVGStylableImpl *style);
~dash_stroke_simple() { delete impl; }
void rewind(unsigned id) { impl->rewind(id); }
unsigned vertex(double* x, double* y) { return impl->vertex(x, y); }
private:
stroke_dash_base *impl;
};
typedef dash_stroke_simple<curved> curved_stroked;
typedef agg::conv_transform<curved_stroked> curved_stroked_trans;
typedef agg::conv_clip_polygon<curved_stroked_trans> curved_stroked_trans_clipped;
typedef agg::conv_clip_polygon<curved_trans> curved_trans_clipped;
//typedef agg::conv_contour<curved_trans> curved_trans_contour;
//typedef agg::conv_clip_polygon<curved_trans_contour> curved_trans_contour_clipped;
namespace KSVG
{
class SVGGradientElementImpl;
class SVGRadialGradientElementImpl;
class SVGLinearGradientElementImpl;
class SVGPatternElementImpl;
class AggPaintServer : public CanvasPaintServer
{
public:
AggPaintServer() : CanvasPaintServer() {}
virtual ~AggPaintServer() {}
virtual void finalizePaintServer() = 0;
virtual void reference(const QString &href) = 0;
virtual void render(AggCanvas *c) = 0;
};
class AggGradient : public AggPaintServer
{
public:
AggGradient(SVGGradientElementImpl *gradient);
virtual ~AggGradient() {}
void parseGradientStops(SVGGradientElementImpl *gradient);
virtual void finalizePaintServer();
virtual void reference(const QString &href);
protected:
SVGGradientElementImpl *m_gradient;
agg::rgba8 m_colorprofile[256];
};
class AggLinearGradient : public AggGradient
{
public:
AggLinearGradient(SVGLinearGradientElementImpl *linear) : AggGradient(linear) {}
virtual void render(AggCanvas *c);
protected:
gradient_polymorphic_wrapper<agg::gradient_x> m_linPad;
gradient_polymorphic_wrapper<gradient_linear_repeat> m_linRepeat;
gradient_polymorphic_wrapper<gradient_linear_reflect> m_linReflect;
};
class AggRadialGradient : public AggGradient
{
public:
AggRadialGradient(SVGRadialGradientElementImpl *radial) : AggGradient(radial) {}
virtual void render(AggCanvas *c);
protected:
gradient_polymorphic_wrapper<agg::gradient_circle> m_radialPad;
gradient_polymorphic_wrapper<gradient_radial_repeat> m_radialRepeat;
gradient_polymorphic_wrapper<gradient_radial_reflect> m_radialReflect;
};
class AggPattern : public AggPaintServer
{
public:
AggPattern(SVGPatternElementImpl *pattern);
virtual ~AggPattern() {}
virtual void finalizePaintServer();
virtual void reference(const QString &);
virtual void render(AggCanvas *c);
protected:
SVGPatternElementImpl *m_pattern;
};
class AggCanvas;
class AggFillPaintServer
{
public:
AggFillPaintServer(SVGStylableImpl *style);
void update(SVGStylableImpl *style);
template<class VertexSource>
void draw(AggCanvas *canvas, VertexSource &vs, SVGStylableImpl *style, SVGShapeImpl *shape);
private:
agg::rgba8 m_color;
};
class AggStrokePaintServer
{
public:
AggStrokePaintServer(SVGStylableImpl *style);
void update(SVGStylableImpl *style);
template<class VertexSource>
void draw(AggCanvas *canvas, VertexSource &vs, SVGStylableImpl *style, SVGShapeImpl *shape);
private:
agg::rgba8 m_color;
};
class BezierPathAggStroked : public T2P::BezierPathAgg
{
public:
BezierPathAggStroked(SVGStylableImpl *style);
BezierPathAggStroked(const T2P::BezierPathAgg &other, SVGStylableImpl *style);
curved_trans_clipped m_curved_trans_clipped;
curved_stroked m_curved_stroked;
curved_stroked_trans m_curved_stroked_trans;
curved_stroked_trans_clipped m_curved_stroked_trans_clipped;
SVGStylableImpl *m_style;
};
class AggShape : public CanvasItem, public BezierPathAggStroked
{
public:
AggShape(AggCanvas *c, SVGStylableImpl *style);
virtual ~AggShape();
virtual QRect bbox() const;
virtual bool fillContains(const QPoint &p);
virtual bool strokeContains(const QPoint &p);
virtual void update(CanvasItemUpdate reason, int param1 = 0, int param2 = 0);
void draw(SVGShapeImpl *shape);
void calcSVPs(const SVGMatrixImpl *matrix);
virtual void init();
virtual void init(const SVGMatrixImpl *);
bool isVisible(SVGShapeImpl *shape);
void setRenderContext(RenderContext context) { m_context = context; }
agg::path_storage &storage() { return m_storage; }
agg::trans_affine &transform() { return m_transform; }
protected:
void freeSVPs();
RenderContext m_context;
AggCanvas *m_canvas;
QRect m_bbox;
AggFillPaintServer *m_fillPainter;
AggStrokePaintServer *m_strokePainter;
};
AGG_CLASS(Rectangle, SVGRectElementImpl, rect)
AGG_CLASS(Ellipse, SVGEllipseElementImpl, ellipse)
AGG_CLASS(Circle, SVGCircleElementImpl, circle)
class AggLine : public AggShape, public MarkerHelper
{
public:
AggLine(AggCanvas *c, SVGLineElementImpl *line);
virtual ~AggLine();
virtual void draw();
virtual bool isVisible();
virtual void init();
virtual void init(const SVGMatrixImpl *screenCTM);
virtual SVGElementImpl *element() const { return m_line; }
protected:
SVGLineElementImpl *m_line;
};
class AggPoly : public AggShape, public MarkerHelper
{
public:
AggPoly(AggCanvas *c, SVGPolyElementImpl *poly);
virtual ~AggPoly();
virtual void draw();
virtual bool isVisible();
virtual void init();
virtual void init(const SVGMatrixImpl *screenCTM) = 0;
virtual SVGElementImpl *element() const { return m_poly; }
protected:
SVGPolyElementImpl *m_poly;
};
class AggPolyline : public AggPoly
{
public:
AggPolyline(AggCanvas *c, SVGPolylineElementImpl *poly);
virtual ~AggPolyline();
virtual void init(const SVGMatrixImpl *screenCTM);
};
class AggPolygon : public AggPoly
{
public:
AggPolygon(AggCanvas *c, SVGPolygonElementImpl *poly);
virtual ~AggPolygon();
virtual void init(const SVGMatrixImpl *screenCTM);
};
class AggPath : public AggShape, public ::SVGPathParser, public MarkerHelper
{
public:
AggPath(AggCanvas *c, SVGPathElementImpl *path);
virtual ~AggPath();
virtual void draw();
virtual bool isVisible();
virtual void init();
virtual void init(const SVGMatrixImpl *screenCTM);
virtual SVGElementImpl *element() const { return m_path; }
protected:
SVGPathElementImpl *m_path;
virtual void svgMoveTo(double x1, double y1, bool closed, bool abs = true);
virtual void svgLineTo(double x1, double y1, bool abs = true);
virtual void svgCurveToCubic(double x1, double y1, double x2, double y2, double x, double y, bool abs = true);
virtual void svgClosePath();
};
class AggMarker : public CanvasMarker
{
public:
AggMarker(AggCanvas *c, SVGMarkerElementImpl *marker);
virtual ~AggMarker();
virtual QRect bbox() const { return QRect(); }
virtual bool fillContains(const QPoint &) { return true; }
virtual bool strokeContains(const QPoint &) { return true; }
virtual void update(CanvasItemUpdate, int = 0, int = 0) { }
virtual void init();
virtual void draw();
virtual bool isVisible() { return false; }
void draw(SVGShapeImpl *obj, int x, int y, float lwidth = 1.0, double angle = 0.0);
//const ArtSVP *clippingRectangle() const { return m_clippingRectangle; }
protected:
AggCanvas *m_canvas;
//ArtSVP *m_clippingRectangle;
};
class AggImage : public CanvasItem
{
public:
AggImage(AggCanvas *c, SVGImageElementImpl *image);
virtual ~AggImage();
virtual QRect bbox() const;
virtual bool fillContains(const QPoint &) { return true; }
virtual bool strokeContains(const QPoint &) { return true; }
virtual void update(CanvasItemUpdate, int = 0, int = 0) { }
virtual void init();
virtual void draw();
virtual bool isVisible();
virtual SVGElementImpl *element() const { return m_image; }
protected:
AggCanvas *m_canvas;
SVGImageElementImpl *m_image;
};
class AggText : public CanvasText
{
public:
AggText(AggCanvas *c, SVGTextElementImpl *text);
virtual ~AggText();
virtual QRect bbox() const;
virtual bool fillContains(const QPoint &p);
virtual bool strokeContains(const QPoint &p);
virtual void update(CanvasItemUpdate, int param1 = 0, int param2 = 0);
virtual void draw();
virtual bool isVisible();
virtual void init();
virtual void init(const SVGMatrixImpl *screenCTM);
virtual void renderCallback(SVGTextContentElementImpl *element, const SVGMatrixImpl *screenCTM, T2P::GlyphSet *glyph, T2P::GlyphLayoutParams *params, double anchor) const;
virtual void addTextDecoration(SVGTextContentElementImpl *element, double x, double y, double w, double h) const;
unsigned operator [](unsigned) const { return 0; }
protected:
AggCanvas *m_canvas;
private:
void clearCurved();
class SVPElement
{
public:
SVPElement() { svp = 0; element = 0; fillPainter = 0; strokePainter = 0; }
~SVPElement();
BezierPathAggStroked *svp;
SVGTextContentElementImpl *element;
AggFillPaintServer *fillPainter;
AggStrokePaintServer *strokePainter;
};
mutable QPtrList<SVPElement> m_drawItems;
};
};
#endif
// vim:ts=4:noet