diff --git a/desmume/src/agg2d.h b/desmume/src/agg2d.h new file mode 100644 index 000000000..9f2a76c86 --- /dev/null +++ b/desmume/src/agg2d.h @@ -0,0 +1,704 @@ +//---------------------------------------------------------------------------- +// Agg2D - Version 1.0 +// Based on Anti-Grain Geometry +// Copyright (C) 2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// +// 25 Jan 2007 - Ported to AGG 2.4 Jerry Evans (jerry@novadsp.com) +// +//---------------------------------------------------------------------------- + +#ifndef AGG2D_INCLUDED +#define AGG2D_INCLUDED + +// With this define uncommented you can use FreeType font engine + +#ifdef UNDER_CE +#define AGG2D_USE_FREETYPE +#endif + +#pragma warning(disable: 4786) + +// JME +#include "agg_basics.h" +#include "agg_math_stroke.h" +#include "agg_trans_affine.h" +#include "agg_trans_viewport.h" +#include "agg_path_storage.h" +#include "agg_conv_stroke.h" +#include "agg_conv_transform.h" +#include "agg_conv_curve.h" +#include "agg_rendering_buffer.h" +#include "agg_renderer_base.h" +#include "agg_renderer_scanline.h" +#include "agg_span_gradient.h" +#include "agg_span_image_filter_rgba.h" +//#include "agg_span_image_resample_rgba.h" + +//+ JME +#include "agg_span_allocator.h" +#include "agg_span_converter.h" +#include "agg_span_interpolator_linear.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_gamma_functions.h" +#include "agg_scanline_u.h" +#include "agg_bezier_arc.h" +#include "agg_rounded_rect.h" +#include "agg_font_cache_manager.h" + +#ifdef AGG2D_USE_FREETYPE +#include "../font_freetype/agg_font_freetype.h" +#else +#include "../font_win32_tt/agg_font_win32_tt.h" +#endif + +#include "agg_pixfmt_rgba.h" +//+ JME +#include "agg_image_accessors.h" + +#define AGG2D_TEMPLATE template +#define AGG2D_TEMPLATE_ARG + +class Agg2DBase +{ +public: + // JME + //typedef agg::rect Rect; + typedef agg::rect_i Rect; + typedef agg::rect_d RectD; + typedef agg::trans_affine Affine; + + enum LineJoin + { + JOIN_MITER = agg::miter_join, + JOIN_ROUND = agg::round_join, + JOIN_BEVEL = agg::bevel_join + }; + + enum LineCap + { + CAP_BUTT = agg::butt_cap, + CAP_SQUARE = agg::square_cap, + CAP_ROUND = agg::round_cap + }; + + enum TextAlignment + { + AlignLeft, + AlignRight, + AlignCenter, + AlignBaseline, + AlignTop = AlignRight, + AlignBottom = AlignLeft + }; + + + enum DrawPathFlag + { + FillOnly, + StrokeOnly, + FillAndStroke, + FillWithLineColor + }; + + enum ViewportOption + { + Anisotropic, + XMinYMin, + XMidYMin, + XMaxYMin, + XMinYMid, + XMidYMid, + XMaxYMid, + XMinYMax, + XMidYMax, + XMaxYMax + }; + + enum WindowFitLogic + { + WindowFitLogic_meet, + WindowFitLogic_slice + }; + + struct Transformations + { + double affineMatrix[6]; + }; + + struct Image + { + agg::rendering_buffer renBuf; + + Image() {} + Image(unsigned char* buf, unsigned width, unsigned height, int stride) : + renBuf(buf, width, height, stride) {} + void attach(unsigned char* buf, unsigned width, unsigned height, int stride) + { + renBuf.attach(buf, width, height, stride); + } + int width() const { return renBuf.width(); } + int height() const { return renBuf.height(); } + AGG2D_TEMPLATE void premultiply(); + AGG2D_TEMPLATE void demultiply(); + }; + + enum ImageFilter + { + NoFilter, + Bilinear, + Hanning, + Hermite, + Quadric, + Bicubic, + Catrom, + Spline16, + Spline36, + Blackman144 + }; + + enum ImageResample + { + NoResample, + ResampleAlways, + ResampleOnZoomOut + }; + + enum FontCacheType + { + RasterFontCache, + VectorFontCache + }; + + enum BlendMode + { + BlendAlpha = agg::end_of_comp_op_e, + BlendClear = agg::comp_op_clear, + BlendSrc = agg::comp_op_src, + BlendDst = agg::comp_op_dst, + BlendSrcOver = agg::comp_op_src_over, + BlendDstOver = agg::comp_op_dst_over, + BlendSrcIn = agg::comp_op_src_in, + BlendDstIn = agg::comp_op_dst_in, + BlendSrcOut = agg::comp_op_src_out, + BlendDstOut = agg::comp_op_dst_out, + BlendSrcAtop = agg::comp_op_src_atop, + BlendDstAtop = agg::comp_op_dst_atop, + BlendXor = agg::comp_op_xor, + BlendAdd = agg::comp_op_plus, + BlendSub = agg::comp_op_minus, + BlendMultiply = agg::comp_op_multiply, + BlendScreen = agg::comp_op_screen, + BlendOverlay = agg::comp_op_overlay, + BlendDarken = agg::comp_op_darken, + BlendLighten = agg::comp_op_lighten, + BlendColorDodge = agg::comp_op_color_dodge, + BlendColorBurn = agg::comp_op_color_burn, + BlendHardLight = agg::comp_op_hard_light, + BlendSoftLight = agg::comp_op_soft_light, + BlendDifference = agg::comp_op_difference, + BlendExclusion = agg::comp_op_exclusion, + BlendContrast = agg::comp_op_contrast + }; + + enum Direction + { + CW, CCW + }; + +}; + +AGG2D_TEMPLATE class Agg2D : public Agg2DBase +{ +public: + typedef agg::order_bgra ComponentOrder; // Platform dependent! + + typedef agg::rgba8 ColorType; + typedef agg::blender_rgba Blender; + typedef agg::comp_op_adaptor_rgba BlenderComp; + typedef agg::blender_rgba_pre BlenderPre; + typedef agg::comp_op_adaptor_rgba_pre BlenderCompPre; + + // JME + //typedef agg::pixel_formats_rgba PixFormat; + //typedef agg::pixfmt_bgra32 PixFormat; + // JME + //typedef agg::pixfmt_custom_blend_rgba PixFormatComp; + typedef agg::pixfmt_custom_blend_rgba PixFormatComp; + // JME + //typedef agg::pixel_formats_rgba PixFormatPre; + typedef agg::pixfmt_bgra32_pre PixFormatPre; + // JME + //typedef agg::pixfmt_custom_blend_rgba PixFormatCompPre; + typedef agg::pixfmt_custom_blend_rgba PixFormatCompPre; + + typedef agg::renderer_base RendererBase; + typedef agg::renderer_base RendererBaseComp; + typedef agg::renderer_base RendererBasePre; + typedef agg::renderer_base RendererBaseCompPre; + + typedef agg::renderer_scanline_aa_solid RendererSolid; + typedef agg::renderer_scanline_aa_solid RendererSolidComp; + + typedef agg::span_allocator SpanAllocator; + typedef agg::pod_auto_array GradientArray; + + typedef agg::span_gradient, agg::gradient_x, GradientArray> LinearGradientSpan; + typedef agg::span_gradient, agg::gradient_circle, GradientArray> RadialGradientSpan; + +#ifdef AGG2D_USE_FREETYPE + typedef agg::font_engine_freetype_int32 FontEngine; +#else + typedef agg::font_engine_win32_tt_int32 FontEngine; +#endif + typedef agg::font_cache_manager FontCacheManager; + typedef FontCacheManager::gray8_adaptor_type FontRasterizer; + typedef FontCacheManager::gray8_scanline_type FontScanline; + + typedef agg::conv_curve ConvCurve; + typedef agg::conv_stroke ConvStroke; + typedef agg::conv_transform PathTransform; + typedef agg::conv_transform StrokeTransform; + + enum Gradient + { + Solid, + Linear, + Radial + }; + +public: + AGG2D_TEMPLATE friend class Agg2DRenderer; + + typedef ColorType Color; + + + + struct State + { + RectD m_clipBox; + + BlendMode m_blendMode; + BlendMode m_imageBlendMode; + Color m_imageBlendColor; + + double m_masterAlpha; + double m_antiAliasGamma; + + Color m_fillColor; + Color m_lineColor; + GradientArray m_fillGradient; + GradientArray m_lineGradient; + + LineCap m_lineCap; + LineJoin m_lineJoin; + + Gradient m_fillGradientFlag; + Gradient m_lineGradientFlag; + agg::trans_affine m_fillGradientMatrix; + agg::trans_affine m_lineGradientMatrix; + double m_fillGradientD1; + double m_lineGradientD1; + double m_fillGradientD2; + double m_lineGradientD2; + + double m_textAngle; + TextAlignment m_textAlignX; + TextAlignment m_textAlignY; + bool m_textHints; + double m_fontHeight; + double m_fontAscent; + double m_fontDescent; + FontCacheType m_fontCacheType; + + double m_lineWidth; + bool m_evenOddFlag; + + agg::trans_affine m_transform; + agg::trans_affine m_affine; + + }; + + + ~Agg2D(); + Agg2D(); + + // Setup + //----------------------- + void attach(unsigned char* buf, unsigned width, unsigned height, int stride); + void attach(Image& img); + + void clipBox(double x1, double y1, double x2, double y2); + RectD clipBox() const; + + void clearAll(Color c); + void clearAll(unsigned r, unsigned g, unsigned b, unsigned a = 255); + + void clearClipBox(Color c); + void clearClipBox(unsigned r, unsigned g, unsigned b, unsigned a = 255); + + unsigned width() const { return m_rbuf.width(); } + unsigned height() const { return m_rbuf.height(); } + + // Conversions + //----------------------- + void worldToScreen(double& x, double& y) const; + void screenToWorld(double& x, double& y) const; + double worldToScreen(double scalar) const; + double screenToWorld(double scalar) const; + void alignPoint(double& x, double& y) const; + bool inBox(double worldX, double worldY) const; + + // General Attributes + //----------------------- + void blendMode(BlendMode m); + BlendMode blendMode() const; + + void imageBlendMode(BlendMode m); + BlendMode imageBlendMode() const; + + void imageBlendColor(Color c); + void imageBlendColor(unsigned r, unsigned g, unsigned b, unsigned a = 255); + Color imageBlendColor() const; + + void masterAlpha(double a); + double masterAlpha() const; + + void antiAliasGamma(double g); + double antiAliasGamma() const; + + void fillColor(Color c); + void fillColor(unsigned r, unsigned g, unsigned b, unsigned a = 255); + void noFill(); + + void lineColor(Color c); + void lineColor(unsigned r, unsigned g, unsigned b, unsigned a = 255); + void noLine(); + + Color fillColor() const; + Color lineColor() const; + + void fillLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile=1.0); + void lineLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile=1.0); + + void fillRadialGradient(double x, double y, double r, Color c1, Color c2, double profile=1.0); + void lineRadialGradient(double x, double y, double r, Color c1, Color c2, double profile=1.0); + + void fillRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3); + void lineRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3); + + void fillRadialGradient(double x, double y, double r); + void lineRadialGradient(double x, double y, double r); + + void lineWidth(double w); + double lineWidth(double w) const; + + void lineCap(LineCap cap); + LineCap lineCap() const; + + void lineJoin(LineJoin join); + LineJoin lineJoin() const; + + void fillEvenOdd(bool evenOddFlag); + bool fillEvenOdd() const; + + // Transformations + //----------------------- + Transformations transformations() const; + void transformations(const Transformations& tr); + + const Affine& affine() const; + void affine(const Affine&); + + void resetTransformations(); + void matrix(const Affine& tr); + void matrix(const Transformations& tr); + void rotate(double angle); + void rotate(double angle, double cx, double cy); + void scale(double s); + void scale(double sx, double sy); + void skew(double sx, double sy); + void translate(double x, double y); + void parallelogram(double x1, double y1, double x2, double y2, const double* para); + void viewport(double worldX1, double worldY1, double worldX2, double worldY2, + double screenX1, double screenY1, double screenX2, double screenY2, + ViewportOption opt=XMidYMid, WindowFitLogic fl = WindowFitLogic_meet); + + // Basic Shapes + //----------------------- + void line(double x1, double y1, double x2, double y2); + void triangle(double x1, double y1, double x2, double y2, double x3, double y3); + void rectangle(double x1, double y1, double x2, double y2); + void roundedRect(double x1, double y1, double x2, double y2, double r); + void roundedRect(double x1, double y1, double x2, double y2, double rx, double ry); + void roundedRect(double x1, double y1, double x2, double y2, + double rxBottom, double ryBottom, + double rxTop, double ryTop); + void ellipse(double cx, double cy, double rx, double ry); + void arc(double cx, double cy, double rx, double ry, double start, double sweep); + void star(double cx, double cy, double r1, double r2, double startAngle, int numRays); + void curve(double x1, double y1, double x2, double y2, double x3, double y3); + void curve(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4); + void polygon(double* xy, int numPoints); + void polyline(double* xy, int numPoints); + + + // Text + //----------------------- + void flipText(bool flip); + void font(const char* fileName, double height, + bool bold = false, + bool italic = false, + FontCacheType ch = RasterFontCache, + double angle = 0.0); + double fontHeight() const; + double fontAscent() const; + void textAlignment(TextAlignment alignX, TextAlignment alignY); + bool textHints() const; + void textHints(bool hints); + double textWidth(const char* str, unsigned int len); + double textWidth(const wchar_t* str, unsigned int len); + void text(double x, double y, const char* str, unsigned int len, bool roundOff=false, double dx=0.0, double dy=0.0); + void text(double x, double y, const wchar_t* str, unsigned int len, bool roundOff=false, double dx=0.0, double dy=0.0); + + double textWidth(const char* str); + void text(double x, double y, const char* str, bool roundOff=false, double dx=0.0, double dy=0.0); + + + // Path commands + //----------------------- + void resetPath(); + + void moveTo(double x, double y); + void moveRel(double dx, double dy); + + void lineTo(double x, double y); + void lineRel(double dx, double dy); + + void horLineTo(double x); + void horLineRel(double dx); + + void verLineTo(double y); + void verLineRel(double dy); + + void arcTo(double rx, double ry, + double angle, + bool largeArcFlag, + bool sweepFlag, + double x, double y); + + void arcRel(double rx, double ry, + double angle, + bool largeArcFlag, + bool sweepFlag, + double dx, double dy); + + void quadricCurveTo(double xCtrl, double yCtrl, + double xTo, double yTo); + void quadricCurveRel(double dxCtrl, double dyCtrl, + double dxTo, double dyTo); + void quadricCurveTo(double xTo, double yTo); + void quadricCurveRel(double dxTo, double dyTo); + + void cubicCurveTo(double xCtrl1, double yCtrl1, + double xCtrl2, double yCtrl2, + double xTo, double yTo); + + void cubicCurveRel(double dxCtrl1, double dyCtrl1, + double dxCtrl2, double dyCtrl2, + double dxTo, double dyTo); + + void cubicCurveTo(double xCtrl2, double yCtrl2, + double xTo, double yTo); + + void cubicCurveRel(double xCtrl2, double yCtrl2, + double xTo, double yTo); + + void addEllipse(double cx, double cy, double rx, double ry, Direction dir); + void closePolygon(); + + void drawPath(DrawPathFlag flag = FillAndStroke); + void drawPathNoTransform(DrawPathFlag flag = FillAndStroke); + + + // Image Transformations + //----------------------- + void imageFilter(ImageFilter f); + ImageFilter imageFilter() const; + + void imageResample(ImageResample f); + ImageResample imageResample() const; + + void transformImage(const Image& img, + int imgX1, int imgY1, int imgX2, int imgY2, + double dstX1, double dstY1, double dstX2, double dstY2); + + void transformImage(const Image& img, + double dstX1, double dstY1, double dstX2, double dstY2); + + void transformImage(const Image& img, + int imgX1, int imgY1, int imgX2, int imgY2, + const double* parallelogram); + + void transformImage(const Image& img, const double* parallelogram); + + + void transformImagePath(const Image& img, + int imgX1, int imgY1, int imgX2, int imgY2, + double dstX1, double dstY1, double dstX2, double dstY2); + + void transformImagePath(const Image& img, + double dstX1, double dstY1, double dstX2, double dstY2); + + void transformImagePath(const Image& img, + int imgX1, int imgY1, int imgX2, int imgY2, + const double* parallelogram); + + void transformImagePath(const Image& img, const double* parallelogram); + + + // Image Blending (no transformations available) + void blendImage(Image& img, + int imgX1, int imgY1, int imgX2, int imgY2, + double dstX, double dstY, unsigned alpha=255); + void blendImage(Image& img, double dstX, double dstY, unsigned alpha=255); + + + // Copy image directly, together with alpha-channel + void copyImage(Image& img, + int imgX1, int imgY1, int imgX2, int imgY2, + double dstX, double dstY); + void copyImage(Image& img, double dstX, double dstY); + + // State + //----------------------- + + void saveStateTo(State& st); + void restoreStateFrom(const State& st); + + + + // Auxiliary + //----------------------- + static double pi() { return agg::pi; } + static double deg2Rad(double v) { return v * agg::pi / 180.0; } + static double rad2Deg(double v) { return v * 180.0 / agg::pi; } + + PixFormat & pixFormat() { return m_pixFormat; } + +private: + void render(bool fillColor); + +#if !defined( UNDER_CE ) + void render(FontRasterizer& ras, FontScanline& sl); +#endif + + void addLine(double x1, double y1, double x2, double y2); + void updateRasterizerGamma(); + void renderImage(const Image& img, int x1, int y1, int x2, int y2, const double* parl); + + void updateTransformations(); + + agg::rendering_buffer m_rbuf; + PixFormat m_pixFormat; + PixFormatComp m_pixFormatComp; + PixFormatPre m_pixFormatPre; + PixFormatCompPre m_pixFormatCompPre; + RendererBase m_renBase; + RendererBaseComp m_renBaseComp; + RendererBasePre m_renBasePre; + RendererBaseCompPre m_renBaseCompPre; + RendererSolid m_renSolid; + RendererSolidComp m_renSolidComp; + + SpanAllocator m_allocator; + RectD m_clipBox; + + BlendMode m_blendMode; + BlendMode m_imageBlendMode; + Color m_imageBlendColor; + + agg::scanline_u8 m_scanline; + agg::rasterizer_scanline_aa<> m_rasterizer; + + double m_masterAlpha; + double m_antiAliasGamma; + + Color m_fillColor; + Color m_lineColor; + GradientArray m_fillGradient; + GradientArray m_lineGradient; + + LineCap m_lineCap; + LineJoin m_lineJoin; + + Gradient m_fillGradientFlag; + Gradient m_lineGradientFlag; + agg::trans_affine m_fillGradientMatrix; + agg::trans_affine m_lineGradientMatrix; + double m_fillGradientD1; + double m_lineGradientD1; + double m_fillGradientD2; + double m_lineGradientD2; + + double m_textAngle; + TextAlignment m_textAlignX; + TextAlignment m_textAlignY; + bool m_textHints; + double m_fontHeight; + double m_fontAscent; + double m_fontDescent; + FontCacheType m_fontCacheType; + + ImageFilter m_imageFilter; + ImageResample m_imageResample; + agg::image_filter_lut m_imageFilterLut; + + agg::span_interpolator_linear<> m_fillGradientInterpolator; + agg::span_interpolator_linear<> m_lineGradientInterpolator; + + agg::gradient_x m_linearGradientFunction; + agg::gradient_circle m_radialGradientFunction; + + double m_lineWidth; + bool m_evenOddFlag; + + double m_start_x; + double m_start_y; + + agg::path_storage m_path; + agg::trans_affine m_transform; + + agg::trans_affine m_viewport; + agg::trans_affine m_affine; + + ConvCurve m_convCurve; + ConvStroke m_convStroke; + + PathTransform m_pathTransform; + StrokeTransform m_strokeTransform; + +#ifndef AGG2D_USE_FREETYPE + HDC m_fontDC; +#endif + FontEngine m_fontEngine; + FontCacheManager m_fontCacheManager; + +}; + + + +#include "agg2d.inl" + +#endif diff --git a/desmume/src/agg2d.inl b/desmume/src/agg2d.inl new file mode 100644 index 000000000..4761055ad --- /dev/null +++ b/desmume/src/agg2d.inl @@ -0,0 +1,2471 @@ +//---------------------------------------------------------------------------- +// Agg2D - Version 1.0 +// Based on Anti-Grain Geometry +// Copyright (C) 2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// +// 25 Jan 2007 - Ported to AGG 2.4 Jerry Evans (jerry@novadsp.com) +// +//---------------------------------------------------------------------------- +#include "GPU.h" +#include "agg2d.h" + +static const double g_approxScale = 2.0; + +#define TAGG2D Agg2D AGG2D_TEMPLATE_ARG +#define TAGG2DRENDERER Agg2DRenderer AGG2D_TEMPLATE_ARG + +//AGG2D_TEMPLATE inline bool operator == (const TAGG2D::Color& c1, const TAGG2D::Color& c2) +//{ +// return c1.r == c2.r && c1.g == c2.g && c1.b == c2.b && c1.a == c2.a; +//} +// +//AGG2D_TEMPLATE inline bool operator != (const Agg2D::Color& c1, const Agg2D::Color& c2) +//{ +// return !(c1 == c2); +//} + +AGG2D_TEMPLATE inline TAGG2D::~Agg2D() +{ +#ifndef AGG2D_USE_FREETYPE + ::ReleaseDC(0, m_fontDC); +#endif +} + +AGG2D_TEMPLATE inline TAGG2D::Agg2D() : + m_rbuf(), + m_pixFormat(m_rbuf), + m_pixFormatComp(m_rbuf), + m_pixFormatPre(m_rbuf), + m_pixFormatCompPre(m_rbuf), + m_renBase(m_pixFormat), + m_renBaseComp(m_pixFormatComp), + m_renBasePre(m_pixFormatPre), + m_renBaseCompPre(m_pixFormatCompPre), + m_renSolid(m_renBase), + m_renSolidComp(m_renBaseComp), + + m_allocator(), + m_clipBox(0,0,0,0), + + m_blendMode(BlendAlpha), + m_imageBlendMode(BlendDst), + m_imageBlendColor(0,0,0), + + m_scanline(), + m_rasterizer(), + + m_masterAlpha(1.0), + m_antiAliasGamma(1.0), + + m_fillColor(255, 255, 255), + m_lineColor(0, 0, 0), + m_fillGradient(), + m_lineGradient(), + + m_lineCap(CAP_ROUND), + m_lineJoin(JOIN_ROUND), + + m_fillGradientFlag(Solid), + m_lineGradientFlag(Solid), + m_fillGradientMatrix(), + m_lineGradientMatrix(), + m_fillGradientD1(0.0), + m_lineGradientD1(0.0), + m_fillGradientD2(100.0), + m_lineGradientD2(100.0), + + m_textAngle(0.0), + m_textAlignX(AlignLeft), + m_textAlignY(AlignBottom), + m_textHints(true), + m_fontHeight(0.0), + m_fontAscent(0.0), + m_fontDescent(0.0), + m_fontCacheType(RasterFontCache), + + m_imageFilter(Bilinear), + m_imageResample(NoResample), + m_imageFilterLut(agg::image_filter_bilinear(), true), + + m_fillGradientInterpolator(m_fillGradientMatrix), + m_lineGradientInterpolator(m_lineGradientMatrix), + + m_linearGradientFunction(), + m_radialGradientFunction(), + + m_lineWidth(1), + m_evenOddFlag(false), + + m_start_x(0.0), + m_start_y(0.0), + + m_path(), + m_transform(), + + m_convCurve(m_path), + m_convStroke(m_convCurve), + + m_pathTransform(m_convCurve, m_transform), + m_strokeTransform(m_convStroke, m_transform), + +#ifdef AGG2D_USE_FREETYPE + m_fontEngine(), +#else + m_fontDC(::GetDC(0)), + m_fontEngine(m_fontDC), +#endif + + m_fontCacheManager(m_fontEngine) +{ + lineCap(m_lineCap); + lineJoin(m_lineJoin); +} + +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::saveStateTo(State& st) +{ + + st.m_clipBox = m_clipBox; + + st.m_blendMode = m_blendMode; + st.m_imageBlendMode = m_imageBlendMode; + st.m_imageBlendColor = m_imageBlendColor; + + st.m_masterAlpha = m_masterAlpha; + st.m_antiAliasGamma = m_antiAliasGamma; + + st.m_fillColor = m_fillColor; + st.m_lineColor = m_lineColor; + st.m_fillGradient = m_fillGradient; + st.m_lineGradient = m_lineGradient; + + st.m_lineCap = m_lineCap; + st.m_lineJoin = m_lineJoin; + + st.m_fillGradientFlag = m_fillGradientFlag; + st.m_lineGradientFlag = m_lineGradientFlag; + st.m_fillGradientMatrix = m_fillGradientMatrix; + st.m_lineGradientMatrix = m_lineGradientMatrix; + st.m_fillGradientD1 = m_fillGradientD1; + st.m_lineGradientD1 = m_lineGradientD1; + st.m_fillGradientD2 = m_fillGradientD2; + st.m_lineGradientD2 = m_lineGradientD2; + + st.m_textAngle = m_textAngle; + st.m_textAlignX = m_textAlignX; + st.m_textAlignY = m_textAlignY; + st.m_textHints = m_textHints; + st.m_fontHeight = m_fontHeight; + st.m_fontAscent = m_fontAscent; + st.m_fontDescent = m_fontDescent; + st.m_fontCacheType = m_fontCacheType; + + st.m_lineWidth = m_lineWidth; + st.m_evenOddFlag = m_evenOddFlag; + + st.m_transform = m_transform; + st.m_affine = m_affine; + +} + +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::restoreStateFrom(const State& st) +{ + + m_clipBox = st.m_clipBox; + + m_blendMode = st.m_blendMode; + m_imageBlendMode = st.m_imageBlendMode; + m_imageBlendColor = st.m_imageBlendColor; + + m_masterAlpha = st.m_masterAlpha; + m_antiAliasGamma = st.m_antiAliasGamma; + + m_fillColor = st.m_fillColor; + m_lineColor = st.m_lineColor; + m_fillGradient = st.m_fillGradient; + m_lineGradient = st.m_lineGradient; + + m_lineCap = st.m_lineCap; + m_lineJoin = st.m_lineJoin; + + m_fillGradientFlag = st.m_fillGradientFlag; + m_lineGradientFlag = st.m_lineGradientFlag; + m_fillGradientMatrix = st.m_fillGradientMatrix; + m_lineGradientMatrix = st.m_lineGradientMatrix; + m_fillGradientD1 = st.m_fillGradientD1; + m_lineGradientD1 = st.m_lineGradientD1; + m_fillGradientD2 = st.m_fillGradientD2; + m_lineGradientD2 = st.m_lineGradientD2; + + m_textAngle = st.m_textAngle; + m_textAlignX = st.m_textAlignX; + m_textAlignY = st.m_textAlignY; + m_textHints = st.m_textHints; + m_fontHeight = st.m_fontHeight; + m_fontAscent = st.m_fontAscent; + m_fontDescent = st.m_fontDescent; + m_fontCacheType = st.m_fontCacheType; + + m_lineWidth = st.m_lineWidth; + m_evenOddFlag = st.m_evenOddFlag; + + m_affine = st.m_affine; + m_transform = st.m_transform; + +} + + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::attach(unsigned char* buf, unsigned width, unsigned height, int stride) +{ + m_rbuf.attach(buf, width, height, stride); + + m_renBase.reset_clipping(true); + m_renBaseComp.reset_clipping(true); + m_renBasePre.reset_clipping(true); + m_renBaseCompPre.reset_clipping(true); + + resetTransformations(); + lineWidth(1.0), + lineColor(0,0,0); + fillColor(255,255,255); + textAlignment(AlignLeft, AlignBottom); + clipBox(0, 0, width, height); + lineCap(CAP_ROUND); + lineJoin(JOIN_ROUND); + flipText(false); + imageFilter(Bilinear); + imageResample(NoResample); + m_masterAlpha = 1.0; + m_antiAliasGamma = 1.0; + m_rasterizer.gamma(agg::gamma_none()); + m_blendMode = BlendAlpha; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::attach(Image& img) +{ + attach(img.renBuf.buf(), img.renBuf.width(), img.renBuf.height(), img.renBuf.stride()); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::clipBox(double x1, double y1, double x2, double y2) +{ + m_viewport.transform(&x1, &y1); // + m_viewport.transform(&x2, &y2); // see: http://article.gmane.org/gmane.comp.graphics.agg/3543 + + m_clipBox = RectD(x1, y1, x2, y2); + + int rx1 = int(x1); + int ry1 = int(y1); + int rx2 = int(x2); + int ry2 = int(y2); + + m_renBase.clip_box(rx1, ry1, rx2, ry2); + m_renBaseComp.clip_box(rx1, ry1, rx2, ry2); + m_renBasePre.clip_box(rx1, ry1, rx2, ry2); + m_renBaseCompPre.clip_box(rx1, ry1, rx2, ry2); + + // m_rasterizer.clip_box(x1, y1, x2, y2); + m_rasterizer.clip_box(m_renBase.xmin(), m_renBase.ymin(), + m_renBase.xmax()+1, m_renBase.ymax()+1); // see link above + +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::blendMode(BlendMode m) +{ + m_blendMode = m; + m_pixFormatComp.comp_op(m); + m_pixFormatCompPre.comp_op(m); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE typename Agg2D AGG2D_TEMPLATE_ARG ::BlendMode Agg2D AGG2D_TEMPLATE_ARG ::blendMode() const +{ + return m_blendMode; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::imageBlendMode(BlendMode m) +{ + m_imageBlendMode = m; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE typename Agg2D AGG2D_TEMPLATE_ARG ::BlendMode Agg2D AGG2D_TEMPLATE_ARG ::imageBlendMode() const +{ + return m_imageBlendMode; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::imageBlendColor(Color c) +{ + m_imageBlendColor = c; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::imageBlendColor(unsigned r, unsigned g, unsigned b, unsigned a) +{ + imageBlendColor(Color(r, g, b, a)); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE typename Agg2D AGG2D_TEMPLATE_ARG ::Color Agg2D AGG2D_TEMPLATE_ARG ::imageBlendColor() const +{ + return m_imageBlendColor; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::masterAlpha(double a) +{ + m_masterAlpha = a; + updateRasterizerGamma(); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE double Agg2D AGG2D_TEMPLATE_ARG ::masterAlpha() const +{ + return m_masterAlpha; +} + +//------------------------------------------------------------------------+ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::antiAliasGamma(double g) +{ + m_antiAliasGamma = g; + updateRasterizerGamma(); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE double Agg2D AGG2D_TEMPLATE_ARG ::antiAliasGamma() const +{ + return m_antiAliasGamma; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE Agg2DBase::RectD Agg2D AGG2D_TEMPLATE_ARG ::clipBox() const +{ + return m_clipBox; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::clearAll(Color c) +{ + m_renBase.clear(c); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::clearAll(unsigned r, unsigned g, unsigned b, unsigned a) +{ + clearAll(Color(r, g, b, a)); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::clearClipBox(Color c) +{ + m_renBase.copy_bar(0, 0, m_renBase.width(), m_renBase.height(), c); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::clearClipBox(unsigned r, unsigned g, unsigned b, unsigned a) +{ + clearClipBox(Color(r, g, b, a)); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::worldToScreen(double& x, double& y) const +{ + m_transform.transform(&x, &y); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::screenToWorld(double& x, double& y) const +{ + m_transform.inverse_transform(&x, &y); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE double Agg2D AGG2D_TEMPLATE_ARG ::worldToScreen(double scalar) const +{ + double x1 = 0; + double y1 = 0; + double x2 = scalar; + double y2 = scalar; + worldToScreen(x1, y1); + worldToScreen(x2, y2); + return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) * 0.7071068; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE double Agg2D AGG2D_TEMPLATE_ARG ::screenToWorld(double scalar) const +{ + double x1 = 0; + double y1 = 0; + double x2 = scalar; + double y2 = scalar; + screenToWorld(x1, y1); + screenToWorld(x2, y2); + return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) * 0.7071068; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::alignPoint(double& x, double& y) const +{ + worldToScreen(x, y); + x = floor(x) + 0.5; + y = floor(y) + 0.5; + screenToWorld(x, y); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE bool Agg2D AGG2D_TEMPLATE_ARG ::inBox(double worldX, double worldY) const +{ + worldToScreen(worldX, worldY); + return m_renBase.inbox(int(worldX), int(worldY)); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE Agg2DBase::Transformations Agg2D AGG2D_TEMPLATE_ARG ::transformations() const +{ + Transformations tr; + m_transform.store_to(tr.affineMatrix); + return tr; +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE const Agg2DBase::Affine& Agg2D AGG2D_TEMPLATE_ARG ::affine() const +{ + return m_affine; +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::affine(const Affine& af) +{ + m_affine = af; + updateTransformations(); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::transformations(const Transformations& tr) +{ + m_transform.load_from(tr.affineMatrix); + m_convCurve.approximation_scale(worldToScreen(1.0) * g_approxScale); + m_convStroke.approximation_scale(worldToScreen(1.0) * g_approxScale); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::resetTransformations() +{ + m_transform.reset(); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::updateTransformations() +{ + m_transform = m_affine; + m_transform *= m_viewport; + m_convCurve.approximation_scale(worldToScreen(1.0) * g_approxScale); + m_convStroke.approximation_scale(worldToScreen(1.0) * g_approxScale); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::rotate(double angle) +{ + m_affine.premultiply(agg::trans_affine_rotation(angle)); + updateTransformations(); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::rotate(double angle, double cx, double cy) +{ + agg::trans_affine_translation m(-cx, -cy); + m *= agg::trans_affine_rotation(angle); + m *= agg::trans_affine_translation(cx, cy); + m_affine.premultiply(m); + updateTransformations(); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::skew(double sx, double sy) +{ + m_affine.premultiply(agg::trans_affine_skewing(sx, sy)); + updateTransformations(); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::translate(double x, double y) +{ + m_affine.premultiply(agg::trans_affine_translation(x, y)); + updateTransformations(); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::matrix(const Affine& tr) +{ + m_affine.premultiply(tr); + updateTransformations(); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::matrix(const Transformations& tr) +{ + matrix(agg::trans_affine(tr.affineMatrix[0], tr.affineMatrix[1], tr.affineMatrix[2], + tr.affineMatrix[3], tr.affineMatrix[4], tr.affineMatrix[5])); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::scale(double s) +{ + m_affine.premultiply(agg::trans_affine_scaling(s)); + updateTransformations(); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::scale(double sx, double sy) +{ + m_affine.premultiply(agg::trans_affine_scaling(sx, sy)); + updateTransformations(); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::parallelogram(double x1, double y1, double x2, double y2, const double* para) +{ + m_affine.premultiply(agg::trans_affine(x1, y1, x2, y2, para)); + updateTransformations(); +} +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::viewport(double worldX1, double worldY1, double worldX2, double worldY2, + double screenX1, double screenY1, double screenX2, double screenY2, + ViewportOption opt, WindowFitLogic fl) +{ + agg::trans_viewport vp; + + agg::aspect_ratio_e ar = + (fl == WindowFitLogic_meet) ? agg::aspect_ratio_meet : + agg::aspect_ratio_slice; + switch(opt) + { + case Anisotropic: vp.preserve_aspect_ratio(0.0, 0.0, agg::aspect_ratio_stretch); break; + case XMinYMin: vp.preserve_aspect_ratio(0.0, 0.0, ar); break; + case XMidYMin: vp.preserve_aspect_ratio(0.5, 0.0, ar); break; + case XMaxYMin: vp.preserve_aspect_ratio(1.0, 0.0, ar); break; + case XMinYMid: vp.preserve_aspect_ratio(0.0, 0.5, ar); break; + case XMidYMid: vp.preserve_aspect_ratio(0.5, 0.5, ar); break; + case XMaxYMid: vp.preserve_aspect_ratio(1.0, 0.5, ar); break; + case XMinYMax: vp.preserve_aspect_ratio(0.0, 1.0, ar); break; + case XMidYMax: vp.preserve_aspect_ratio(0.5, 1.0, ar); break; + case XMaxYMax: vp.preserve_aspect_ratio(1.0, 1.0, ar); break; + } + vp.world_viewport(worldX1, worldY1, worldX2, worldY2); + vp.device_viewport(screenX1, screenY1, screenX2, screenY2); + + m_viewport = vp.to_affine(); + updateTransformations(); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::fillColor(Color c) +{ + m_fillColor = c; + m_fillGradientFlag = Solid; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::fillColor(unsigned r, unsigned g, unsigned b, unsigned a) +{ + fillColor(Color(r, g, b, a)); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::noFill() +{ + fillColor(Color(0, 0, 0, 0)); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::lineColor(Color c) +{ + m_lineColor = c; + m_lineGradientFlag = Solid; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::lineColor(unsigned r, unsigned g, unsigned b, unsigned a) +{ + lineColor(Color(r, g, b, a)); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2D AGG2D_TEMPLATE_ARG ::noLine() +{ + lineColor(Color(0, 0, 0, 0)); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE typename TAGG2D::Color TAGG2D::fillColor() const +{ + return m_fillColor; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE typename TAGG2D::Color TAGG2D::lineColor() const +{ + return m_lineColor; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::fillLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile) +{ + int i; + int startGradient = 128 - int(profile * 127.0); + int endGradient = 128 + int(profile * 127.0); + if (endGradient <= startGradient) endGradient = startGradient + 1; + double k = 1.0 / double(endGradient - startGradient); + for (i = 0; i < startGradient; i++) + { + m_fillGradient[i] = c1; + } + for (; i < endGradient; i++) + { + m_fillGradient[i] = c1.gradient(c2, double(i - startGradient) * k); + } + for (; i < 256; i++) + { + m_fillGradient[i] = c2; + } + double angle = atan2(y2-y1, x2-x1); + m_fillGradientMatrix.reset(); + m_fillGradientMatrix *= agg::trans_affine_rotation(angle); + m_fillGradientMatrix *= agg::trans_affine_translation(x1, y1); + m_fillGradientMatrix *= m_transform; + m_fillGradientMatrix.invert(); + m_fillGradientD1 = 0.0; + m_fillGradientD2 = sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1)); + m_fillGradientFlag = Linear; + m_fillColor = Color(0,0,0); // Set some real color +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::lineLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile) +{ + int i; + int startGradient = 128 - int(profile * 128.0); + int endGradient = 128 + int(profile * 128.0); + if (endGradient <= startGradient) endGradient = startGradient + 1; + double k = 1.0 / double(endGradient - startGradient); + for (i = 0; i < startGradient; i++) + { + m_lineGradient[i] = c1; + } + for (; i < endGradient; i++) + { + m_lineGradient[i] = c1.gradient(c2, double(i - startGradient) * k); + } + for (; i < 256; i++) + { + m_lineGradient[i] = c2; + } + double angle = atan2(y2-y1, x2-x1); + m_lineGradientMatrix.reset(); + m_lineGradientMatrix *= agg::trans_affine_rotation(angle); + m_lineGradientMatrix *= agg::trans_affine_translation(x1, y1); + m_fillGradientMatrix *= m_transform; + m_lineGradientMatrix.invert(); + m_lineGradientD1 = 0; + m_lineGradientD2 = sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1)); + m_lineGradientFlag = Linear; + m_lineColor = Color(0,0,0); // Set some real color +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::fillRadialGradient(double x, double y, double r, Color c1, Color c2, double profile) +{ + int i; + int startGradient = 128 - int(profile * 127.0); + int endGradient = 128 + int(profile * 127.0); + if (endGradient <= startGradient) endGradient = startGradient + 1; + double k = 1.0 / double(endGradient - startGradient); + for (i = 0; i < startGradient; i++) + { + m_fillGradient[i] = c1; + } + for (; i < endGradient; i++) + { + m_fillGradient[i] = c1.gradient(c2, double(i - startGradient) * k); + } + for (; i < 256; i++) + { + m_fillGradient[i] = c2; + } + m_fillGradientD2 = worldToScreen(r); + worldToScreen(x, y); + m_fillGradientMatrix.reset(); + m_fillGradientMatrix *= agg::trans_affine_translation(x, y); + m_fillGradientMatrix.invert(); + m_fillGradientD1 = 0; + m_fillGradientFlag = Radial; + m_fillColor = Color(0,0,0); // Set some real color +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::lineRadialGradient(double x, double y, double r, Color c1, Color c2, double profile) +{ + int i; + int startGradient = 128 - int(profile * 128.0); + int endGradient = 128 + int(profile * 128.0); + if (endGradient <= startGradient) endGradient = startGradient + 1; + double k = 1.0 / double(endGradient - startGradient); + for (i = 0; i < startGradient; i++) + { + m_lineGradient[i] = c1; + } + for (; i < endGradient; i++) + { + m_lineGradient[i] = c1.gradient(c2, double(i - startGradient) * k); + } + for (; i < 256; i++) + { + m_lineGradient[i] = c2; + } + m_lineGradientD2 = worldToScreen(r); + worldToScreen(x, y); + m_lineGradientMatrix.reset(); + m_lineGradientMatrix *= agg::trans_affine_translation(x, y); + m_lineGradientMatrix.invert(); + m_lineGradientD1 = 0; + m_lineGradientFlag = Radial; + m_lineColor = Color(0,0,0); // Set some real color +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::fillRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3) +{ + int i; + for (i = 0; i < 128; i++) + { + m_fillGradient[i] = c1.gradient(c2, double(i) / 127.0); + } + for (; i < 256; i++) + { + m_fillGradient[i] = c2.gradient(c3, double(i - 128) / 127.0); + } + m_fillGradientD2 = worldToScreen(r); + worldToScreen(x, y); + m_fillGradientMatrix.reset(); + m_fillGradientMatrix *= agg::trans_affine_translation(x, y); + m_fillGradientMatrix.invert(); + m_fillGradientD1 = 0; + m_fillGradientFlag = Radial; + m_fillColor = Color(0,0,0); // Set some real color +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::lineRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3) +{ + int i; + for (i = 0; i < 128; i++) + { + m_lineGradient[i] = c1.gradient(c2, double(i) / 127.0); + } + for (; i < 256; i++) + { + m_lineGradient[i] = c2.gradient(c3, double(i - 128) / 127.0); + } + m_lineGradientD2 = worldToScreen(r); + worldToScreen(x, y); + m_lineGradientMatrix.reset(); + m_lineGradientMatrix *= agg::trans_affine_translation(x, y); + m_lineGradientMatrix.invert(); + m_lineGradientD1 = 0; + m_lineGradientFlag = Radial; + m_lineColor = Color(0,0,0); // Set some real color +} + + +AGG2D_TEMPLATE void TAGG2D::fillRadialGradient(double x, double y, double r) +{ + m_fillGradientD2 = worldToScreen(r); + worldToScreen(x, y); + m_fillGradientMatrix.reset(); + m_fillGradientMatrix *= agg::trans_affine_translation(x, y); + m_fillGradientMatrix.invert(); + m_fillGradientD1 = 0; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::lineRadialGradient(double x, double y, double r) +{ + m_lineGradientD2 = worldToScreen(r); + worldToScreen(x, y); + m_lineGradientMatrix.reset(); + m_lineGradientMatrix *= agg::trans_affine_translation(x, y); + m_lineGradientMatrix.invert(); + m_lineGradientD1 = 0; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::lineWidth(double w) +{ + m_lineWidth = w; + m_convStroke.width(w); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE double TAGG2D::lineWidth(double w) const +{ + return m_lineWidth; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::fillEvenOdd(bool evenOddFlag) +{ + m_evenOddFlag = evenOddFlag; + m_rasterizer.filling_rule(evenOddFlag ? agg::fill_even_odd : agg::fill_non_zero); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE bool TAGG2D::fillEvenOdd() const +{ + return m_evenOddFlag; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::lineCap(LineCap cap) +{ + m_lineCap = cap; + m_convStroke.line_cap((agg::line_cap_e)cap); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE Agg2DBase::LineCap TAGG2D::lineCap() const +{ + return m_lineCap; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::lineJoin(LineJoin join) +{ + m_lineJoin = join; + m_convStroke.line_join((agg::line_join_e)join); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE Agg2DBase::LineJoin TAGG2D::lineJoin() const +{ + return m_lineJoin; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::addLine(double x1, double y1, double x2, double y2) +{ + m_path.move_to(x1, y1); + m_path.line_to(x2, y2); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::line(double x1, double y1, double x2, double y2) +{ + m_path.remove_all(); + addLine(x1, y1, x2, y2); + drawPath(StrokeOnly); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::triangle(double x1, double y1, double x2, double y2, double x3, double y3) +{ + m_path.remove_all(); + m_path.move_to(x1, y1); + m_path.line_to(x2, y2); + m_path.line_to(x3, y3); + m_path.close_polygon(); + drawPath(FillAndStroke); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::rectangle(double x1, double y1, double x2, double y2) +{ + m_path.remove_all(); + m_path.move_to(x1, y1); + m_path.line_to(x2, y1); + m_path.line_to(x2, y2); + m_path.line_to(x1, y2); + m_path.close_polygon(); + drawPath(FillAndStroke); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::roundedRect(double x1, double y1, double x2, double y2, double r) +{ + m_path.remove_all(); + agg::rounded_rect rc(x1, y1, x2, y2, r); + rc.normalize_radius(); + rc.approximation_scale(worldToScreen(1.0) * g_approxScale); + // JME audit + //m_path.add_path(rc, 0, false); + m_path.concat_path(rc,0); + drawPath(FillAndStroke); +} + + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::roundedRect(double x1, double y1, double x2, double y2, double rx, double ry) +{ + m_path.remove_all(); + agg::rounded_rect rc; + rc.rect(x1, y1, x2, y2); + rc.radius(rx, ry); + rc.normalize_radius(); + //m_path.add_path(rc, 0, false); + m_path.concat_path(rc,0); // JME + drawPath(FillAndStroke); +} + + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::roundedRect(double x1, double y1, double x2, double y2, + double rx_bottom, double ry_bottom, + double rx_top, double ry_top) +{ + m_path.remove_all(); + agg::rounded_rect rc; + rc.rect(x1, y1, x2, y2); + rc.radius(rx_bottom, ry_bottom, rx_top, ry_top); + rc.normalize_radius(); + rc.approximation_scale(worldToScreen(1.0) * g_approxScale); + //m_path.add_path(rc, 0, false); + m_path.concat_path(rc,0); // JME + drawPath(FillAndStroke); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::ellipse(double cx, double cy, double rx, double ry) +{ + m_path.remove_all(); + agg::bezier_arc arc(cx, cy, rx, ry, 0, 2*pi()); + //m_path.add_path(arc, 0, false); + m_path.concat_path(arc,0); // JME + m_path.close_polygon(); + drawPath(FillAndStroke); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::arc(double cx, double cy, double rx, double ry, double start, double sweep) +{ + m_path.remove_all(); + agg::bezier_arc arc(cx, cy, rx, ry, start, sweep); + //m_path.add_path(arc, 0, false); + m_path.concat_path(arc,0); // JME + drawPath(StrokeOnly); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::star(double cx, double cy, double r1, double r2, double startAngle, int numRays) +{ + m_path.remove_all(); + double da = agg::pi / double(numRays); + double a = startAngle; + int i; + for (i = 0; i < numRays; i++) + { + double x = cos(a) * r2 + cx; + double y = sin(a) * r2 + cy; + if (i) m_path.line_to(x, y); + else m_path.move_to(x, y); + a += da; + m_path.line_to(cos(a) * r1 + cx, sin(a) * r1 + cy); + a += da; + } + closePolygon(); + drawPath(FillAndStroke); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::curve(double x1, double y1, double x2, double y2, double x3, double y3) +{ + m_path.remove_all(); + m_path.move_to(x1, y1); + m_path.curve3(x2, y2, x3, y3); + drawPath(StrokeOnly); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::curve(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) +{ + m_path.remove_all(); + m_path.move_to(x1, y1); + m_path.curve4(x2, y2, x3, y3, x4, y4); + drawPath(StrokeOnly); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::polygon(double* xy, int numPoints) +{ + m_path.remove_all(); + //m_path.add_poly(xy, numPoints); + m_path.concat_poly(xy,numPoints,true); // JME, AF + closePolygon(); + drawPath(FillAndStroke); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::polyline(double* xy, int numPoints) +{ + m_path.remove_all(); + //m_path.add_poly(xy, numPoints); + m_path.concat_poly(xy,numPoints,true); // JME, AF + drawPath(StrokeOnly); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::flipText(bool flip) +{ + m_fontEngine.flip_y(flip); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::font(const char* fontName, + double height, + bool bold, + bool italic, + FontCacheType ch, + double angle) +{ + m_textAngle = angle; + m_fontHeight = height; + m_fontCacheType = ch; + + +#ifdef AGG2D_USE_FREETYPE + m_fontEngine.load_font(fontName, + 0, + (ch == VectorFontCache) ? + agg::glyph_ren_outline : + agg::glyph_ren_agg_gray8); + m_fontEngine.hinting(m_textHints); + m_fontEngine.height((ch == VectorFontCache) ? height : worldToScreen(height)); +#else + m_fontEngine.hinting(m_textHints); + + m_fontEngine.create_font(fontName, + (ch == VectorFontCache) ? + agg::glyph_ren_outline : + agg::glyph_ren_agg_gray8, + (ch == VectorFontCache) ? height : worldToScreen(height), + 0.0, + bold ? 700 : 400, + italic); +#endif + +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE double TAGG2D::fontHeight() const +{ + return m_fontHeight; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE double TAGG2D::fontAscent() const +{ + return m_fontAscent; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::textAlignment(TextAlignment alignX, TextAlignment alignY) +{ + m_textAlignX = alignX; + m_textAlignY = alignY; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE double TAGG2D::textWidth(const char* str, unsigned int len) +{ +#if defined( UNDER_CE ) + return 0; +#else + double x = 0; + double y = 0; + bool first = true; + while(*str && len) + { + const agg::glyph_cache* glyph = m_fontCacheManager.glyph(*str); + if(glyph) + { + if(!first) m_fontCacheManager.add_kerning(&x, &y); + x += glyph->advance_x; + y += glyph->advance_y; + first = true; + } + ++str; --len; + } + return (m_fontCacheType == VectorFontCache) ? x : screenToWorld(x); +#endif +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE double TAGG2D::textWidth(const wchar_t* str, unsigned int len) +{ +#if defined( UNDER_CE ) + return 0; +#else + double x = 0; + double y = 0; + bool first = true; + while(*str && len) + { + const agg::glyph_cache* glyph = m_fontCacheManager.glyph(*str); + if(glyph) + { + if(!first) m_fontCacheManager.add_kerning(&x, &y); + x += glyph->advance_x; + y += glyph->advance_y; + first = true; + } + ++str; --len; + } + return (m_fontCacheType == VectorFontCache) ? x : screenToWorld(x); +#endif +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE bool TAGG2D::textHints() const +{ + return m_textHints; +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::textHints(bool hints) +{ + m_textHints = hints; +} + + + +//------------------------------------------------------------------------ + +AGG2D_TEMPLATE void TAGG2D::text(double x, double y, const char* str, unsigned int len, bool roundOff, double ddx, double ddy) +{ + + double dx = 0.0; + double dy = 0.0; + + switch(m_textAlignX) + { + case AlignCenter: dx = -textWidth(str,len) * 0.5; break; + case AlignRight: dx = -textWidth(str,len); break; + default: break; + } + + + double asc = fontHeight(); + const agg::glyph_cache* glyph = m_fontCacheManager.glyph('H'); + if(glyph) + { + asc = glyph->bounds.y2 - glyph->bounds.y1; + } + + if(m_fontCacheType == RasterFontCache) + { + asc = screenToWorld(asc); + } + + switch(m_textAlignY) + { + case AlignCenter: dy = -asc * 0.5; break; + case AlignTop: dy = -asc; break; + case AlignBaseline: dy = -fontAscent(); break; + default: break; + } + + if(m_fontEngine.flip_y()) dy = -dy; + + agg::trans_affine mtx; + + double start_x = x + dx; + double start_y = y + dy; + + if (roundOff) + { + start_x = int(start_x); + start_y = int(start_y); + } + start_x += ddx; + start_y += ddy; + + mtx *= agg::trans_affine_translation(-x, -y); + mtx *= agg::trans_affine_rotation(m_textAngle); + mtx *= agg::trans_affine_translation(x, y); + + agg::conv_transform tr(m_fontCacheManager.path_adaptor(), mtx); + + if(m_fontCacheType == RasterFontCache) + { + worldToScreen(start_x, start_y); + } + + unsigned int i; + for (i = 0; i < len && str[i]; i++) + { + glyph = m_fontCacheManager.glyph(str[i]); + if(glyph) + { + if(i) m_fontCacheManager.add_kerning(&x, &y); + m_fontCacheManager.init_embedded_adaptors(glyph, start_x, start_y); + + if(glyph->data_type == agg::glyph_data_outline) + { + m_path.remove_all(); + m_path.concat_path(tr, 0); + drawPath(); + } + + if(glyph->data_type == agg::glyph_data_gray8) + { + render(m_fontCacheManager.gray8_adaptor(), + m_fontCacheManager.gray8_scanline()); + } + start_x += glyph->advance_x; + start_y += glyph->advance_y; + } + } + +} + +AGG2D_TEMPLATE void TAGG2D::text(double x, double y, const wchar_t* str, unsigned int len, bool roundOff, double ddx, double ddy) +{ + + double dx = 0.0; + double dy = 0.0; + + switch(m_textAlignX) + { + case AlignCenter: dx = -textWidth(str,len) * 0.5; break; + case AlignRight: dx = -textWidth(str,len); break; + default: break; + } + + double asc = fontHeight(); + const agg::glyph_cache* glyph = m_fontCacheManager.glyph('H'); + if(glyph) + { + asc = glyph->bounds.y2 - glyph->bounds.y1; + } + + if(m_fontCacheType == RasterFontCache) + { + asc = screenToWorld(asc); + } + + switch(m_textAlignY) + { + case AlignCenter: dy = -asc * 0.5; break; + case AlignTop: dy = -asc; break; + case AlignBaseline: dy = -fontAscent(); break; + default: break; + } + + if(m_fontEngine.flip_y()) dy = -dy; + + agg::trans_affine mtx; + + double start_x = x + dx; + double start_y = y + dy; + + if (roundOff) + { + start_x = int(start_x); + start_y = int(start_y); + } + start_x += ddx; + start_y += ddy; + + mtx *= agg::trans_affine_translation(-x, -y); + mtx *= agg::trans_affine_rotation(m_textAngle); + mtx *= agg::trans_affine_translation(x, y); + + agg::conv_transform tr(m_fontCacheManager.path_adaptor(), mtx); + + if(m_fontCacheType == RasterFontCache) + { + worldToScreen(start_x, start_y); + } + + unsigned int i; + for (i = 0; i < len && str[i]; i++) + { + glyph = m_fontCacheManager.glyph(str[i]); + if(glyph) + { + if(i) m_fontCacheManager.add_kerning(&x, &y); + m_fontCacheManager.init_embedded_adaptors(glyph, start_x, start_y); + + if(glyph->data_type == agg::glyph_data_outline) + { + m_path.remove_all(); + //m_path.add_path(tr, 0, false); + m_path.concat_path(tr,0); // JME + drawPath(); + } + + if(glyph->data_type == agg::glyph_data_gray8) + { + render(m_fontCacheManager.gray8_adaptor(), + m_fontCacheManager.gray8_scanline()); + } + start_x += glyph->advance_x; + start_y += glyph->advance_y; + } + } + +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::resetPath() { m_path.remove_all(); } + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::moveTo(double x, double y) +{ + m_start_x = x; + m_start_y = y; + + m_path.move_to(x, y); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::moveRel(double dx, double dy) +{ + if(m_path.vertices().total_vertices()) + { + double x2; + double y2; + m_path.vertices().last_vertex(&x2, &y2); + + dx += x2; + dy += y2; + } + + moveTo(dx, dy); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::lineTo(double x, double y) +{ + m_path.line_to(x, y); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::lineRel(double dx, double dy) +{ + m_path.line_rel(dx, dy); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::horLineTo(double x) +{ + m_path.hline_to(x); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::horLineRel(double dx) +{ + m_path.hline_rel(dx); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::verLineTo(double y) +{ + m_path.vline_to(y); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::verLineRel(double dy) +{ + m_path.vline_rel(dy); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::arcTo(double rx, double ry, + double angle, + bool largeArcFlag, + bool sweepFlag, + double x, double y) +{ + m_path.arc_to(rx, ry, angle, largeArcFlag, sweepFlag, x, y); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::arcRel(double rx, double ry, + double angle, + bool largeArcFlag, + bool sweepFlag, + double dx, double dy) +{ + m_path.arc_rel(rx, ry, angle, largeArcFlag, sweepFlag, dx, dy); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::quadricCurveTo(double xCtrl, double yCtrl, + double xTo, double yTo) +{ + m_path.curve3(xCtrl, yCtrl, xTo, yTo); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::quadricCurveRel(double dxCtrl, double dyCtrl, + double dxTo, double dyTo) +{ + m_path.curve3_rel(dxCtrl, dyCtrl, dxTo, dyTo); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::quadricCurveTo(double xTo, double yTo) +{ + m_path.curve3(xTo, yTo); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::quadricCurveRel(double dxTo, double dyTo) +{ + m_path.curve3_rel(dxTo, dyTo); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::cubicCurveTo(double xCtrl1, double yCtrl1, + double xCtrl2, double yCtrl2, + double xTo, double yTo) +{ + m_path.curve4(xCtrl1, yCtrl1, xCtrl2, yCtrl2, xTo, yTo); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::cubicCurveRel(double dxCtrl1, double dyCtrl1, + double dxCtrl2, double dyCtrl2, + double dxTo, double dyTo) +{ + m_path.curve4_rel(dxCtrl1, dyCtrl1, dxCtrl2, dyCtrl2, dxTo, dyTo); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::cubicCurveTo(double xCtrl2, double yCtrl2, + double xTo, double yTo) +{ + m_path.curve4(xCtrl2, yCtrl2, xTo, yTo); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::cubicCurveRel(double xCtrl2, double yCtrl2, + double xTo, double yTo) +{ + m_path.curve4_rel(xCtrl2, yCtrl2, xTo, yTo); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::addEllipse(double cx, double cy, double rx, double ry, Direction dir) +{ + agg::bezier_arc arc(cx, cy, rx, ry, 0, (dir == CCW) ? 2*pi() : -2*pi()); + //m_path.add_path(arc, 0, false); + m_path.concat_path(arc,0); // JME + m_path.close_polygon(); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::closePolygon() +{ + if(agg::is_vertex(m_path.vertices().last_command())) + { + m_path.vertices().add_vertex(m_start_x, m_start_y, + agg::path_cmd_end_poly | agg::path_flags_close); + } +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::imageFilter(ImageFilter f) +{ + m_imageFilter = f; + switch(f) + { + case NoFilter: break; + case Bilinear: m_imageFilterLut.calculate(agg::image_filter_bilinear(), true); break; + case Hanning: m_imageFilterLut.calculate(agg::image_filter_hanning(), true); break; + case Hermite: m_imageFilterLut.calculate(agg::image_filter_hermite(), true); break; + case Quadric: m_imageFilterLut.calculate(agg::image_filter_quadric(), true); break; + case Bicubic: m_imageFilterLut.calculate(agg::image_filter_bicubic(), true); break; + case Catrom: m_imageFilterLut.calculate(agg::image_filter_catrom(), true); break; + case Spline16: m_imageFilterLut.calculate(agg::image_filter_spline16(), true); break; + case Spline36: m_imageFilterLut.calculate(agg::image_filter_spline36(), true); break; + case Blackman144: m_imageFilterLut.calculate(agg::image_filter_blackman144(), true); break; + } +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE Agg2DBase::ImageFilter TAGG2D::imageFilter() const +{ + return m_imageFilter; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::imageResample(ImageResample f) +{ + m_imageResample = f; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE Agg2DBase::ImageResample TAGG2D::imageResample() const +{ + return m_imageResample; +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::transformImage(const Image& img, int imgX1, int imgY1, int imgX2, int imgY2, + double dstX1, double dstY1, double dstX2, double dstY2) +{ + resetPath(); + moveTo(dstX1, dstY1); + lineTo(dstX2, dstY1); + lineTo(dstX2, dstY2); + lineTo(dstX1, dstY2); + closePolygon(); + double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 }; + renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::transformImage(const Image& img, double dstX1, double dstY1, double dstX2, double dstY2) +{ + resetPath(); + moveTo(dstX1, dstY1); + lineTo(dstX2, dstY1); + lineTo(dstX2, dstY2); + lineTo(dstX1, dstY2); + closePolygon(); + double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 }; + renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::transformImage(const Image& img, int imgX1, int imgY1, int imgX2, int imgY2, + const double* parallelogram) +{ + resetPath(); + moveTo(parallelogram[0], parallelogram[1]); + lineTo(parallelogram[2], parallelogram[3]); + lineTo(parallelogram[4], parallelogram[5]); + lineTo(parallelogram[0] + parallelogram[4] - parallelogram[2], + parallelogram[1] + parallelogram[5] - parallelogram[3]); + closePolygon(); + renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::transformImage(const Image& img, const double* parallelogram) +{ + resetPath(); + moveTo(parallelogram[0], parallelogram[1]); + lineTo(parallelogram[2], parallelogram[3]); + lineTo(parallelogram[4], parallelogram[5]); + lineTo(parallelogram[0] + parallelogram[4] - parallelogram[2], + parallelogram[1] + parallelogram[5] - parallelogram[3]); + closePolygon(); + renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::transformImagePath(const Image& img, int imgX1, int imgY1, int imgX2, int imgY2, + double dstX1, double dstY1, double dstX2, double dstY2) +{ + double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 }; + renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::transformImagePath(const Image& img, double dstX1, double dstY1, double dstX2, double dstY2) +{ + double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 }; + renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::transformImagePath(const Image& img, int imgX1, int imgY1, int imgX2, int imgY2, + const double* parallelogram) +{ + renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::transformImagePath(const Image& img, const double* parallelogram) +{ + renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); +} + + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::drawPath(DrawPathFlag flag) +{ + m_rasterizer.reset(); + switch(flag) + { + case FillOnly: + if (m_fillColor.a) + { + m_rasterizer.add_path(m_pathTransform); + render(true); + } + break; + + case StrokeOnly: + if (m_lineColor.a && m_lineWidth > 0.0) + { + m_rasterizer.add_path(m_strokeTransform); + render(false); + } + break; + + case FillAndStroke: + if (m_fillColor.a) + { + m_rasterizer.add_path(m_pathTransform); + render(true); + } + + if (m_lineColor.a && m_lineWidth > 0.0) + { + m_rasterizer.add_path(m_strokeTransform); + render(false); + } + break; + + case FillWithLineColor: + if (m_lineColor.a) + { + m_rasterizer.add_path(m_pathTransform); + render(false); + } + break; + } +} + + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE class Agg2DRenderer +{ +public: + typedef typename TAGG2D::Color Color; + typedef typename TAGG2D::Image Image; + //-------------------------------------------------------------------- + template + void static render(TAGG2D& gr, BaseRenderer& renBase, SolidRenderer& renSolid, bool fillColor) + { + // JME + typedef agg::span_allocator span_allocator_type; + //- typedef agg::renderer_scanline_aa RendererLinearGradient; + typedef agg::renderer_scanline_aa RendererLinearGradient; + //- typedef agg::renderer_scanline_aa RendererRadialGradient; + typedef agg::renderer_scanline_aa RendererRadialGradient; + + if ((fillColor && gr.m_fillGradientFlag == TAGG2D::Linear) || + (!fillColor && gr.m_lineGradientFlag == TAGG2D::Linear)) + { + if (fillColor) + { + TAGG2D::LinearGradientSpan span(/*gr.m_allocator, */ + gr.m_fillGradientInterpolator, + gr.m_linearGradientFunction, + gr.m_fillGradient, + gr.m_fillGradientD1, + gr.m_fillGradientD2); + //-RendererLinearGradient ren(renBase,span); + RendererLinearGradient ren(renBase,gr.m_allocator,span); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ren); + } + else + { + TAGG2D::LinearGradientSpan span(/*gr.m_allocator,*/ + gr.m_lineGradientInterpolator, + gr.m_linearGradientFunction, + gr.m_lineGradient, + gr.m_lineGradientD1, + gr.m_lineGradientD2); + //- RendererLinearGradient ren(renBase, span); + RendererLinearGradient ren(renBase,gr.m_allocator,span); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ren); + } + } + else + { + if ((fillColor && gr.m_fillGradientFlag == TAGG2D::Radial) || + (!fillColor && gr.m_lineGradientFlag == TAGG2D::Radial)) + { + if (fillColor) + { + TAGG2D::RadialGradientSpan span(/*gr.m_allocator, */ + gr.m_fillGradientInterpolator, + gr.m_radialGradientFunction, + gr.m_fillGradient, + gr.m_fillGradientD1, + gr.m_fillGradientD2); + //-RendererRadialGradient ren(renBase, span); + RendererRadialGradient ren(renBase,gr.m_allocator,span); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ren); + } + else + { + TAGG2D::RadialGradientSpan span(/*gr.m_allocator,*/ + gr.m_lineGradientInterpolator, + gr.m_radialGradientFunction, + gr.m_lineGradient, + gr.m_lineGradientD1, + gr.m_lineGradientD2); + //-RendererRadialGradient ren(renBase, span); + RendererRadialGradient ren(renBase,gr.m_allocator,span); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ren); + } + } + else + { + renSolid.color(fillColor ? gr.m_fillColor : gr.m_lineColor); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, renSolid); + } + } + } + + + //-------------------------------------------------------------------- + class SpanConvImageBlend + { + public: + SpanConvImageBlend(Agg2D::BlendMode m, Color c) : + m_mode(m), m_color(c) + {} + + void convert(Color* span, int x, int y, unsigned len) const + { + unsigned l2; + TAGG2D::Color* s2; + if(m_mode != TAGG2D::BlendDst) + { + l2 = len; + s2 = span; + typedef agg::comp_op_adaptor_clip_to_dst_rgba_pre OpType; + do + { + OpType::blend_pix(m_mode, + (TAGG2D::Color::value_type*)s2, + m_color.r, + m_color.g, + m_color.b, + TAGG2D::Color::base_mask, + agg::cover_full); + ++s2; + } + while(--l2); + } + if(m_color.a < TAGG2D::Color::base_mask) + { + l2 = len; + s2 = span; + unsigned a = m_color.a; + do + { + s2->r = (s2->r * a) >> TAGG2D::Color::base_shift; + s2->g = (s2->g * a) >> TAGG2D::Color::base_shift; + s2->b = (s2->b * a) >> TAGG2D::Color::base_shift; + s2->a = (s2->a * a) >> TAGG2D::Color::base_shift; + ++s2; + } + while(--l2); + } + } + + private: + Agg2DBase::BlendMode m_mode; + Color m_color; + }; + + + + + //-------------------------------------------------------------------- + template + void static render(TAGG2D& gr, BaseRenderer& renBase, SolidRenderer& renSolid, Rasterizer& ras, Scanline& sl) + { + // JME + typedef agg::span_allocator span_allocator_type; + typedef agg::renderer_scanline_aa RendererLinearGradient; + typedef agg::renderer_scanline_aa RendererRadialGradient; + + if(gr.m_fillGradientFlag == TAGG2D::Linear) + { + TAGG2D::LinearGradientSpan span( + gr.m_fillGradientInterpolator, + gr.m_linearGradientFunction, + gr.m_fillGradient, + gr.m_fillGradientD1, + gr.m_fillGradientD2); + RendererLinearGradient ren(renBase,gr.m_allocator,span); + agg::render_scanlines(ras, sl, ren); + } + else + { + if(gr.m_fillGradientFlag == TAGG2D::Radial) + { + TAGG2D::RadialGradientSpan span( + gr.m_fillGradientInterpolator, + gr.m_radialGradientFunction, + gr.m_fillGradient, + gr.m_fillGradientD1, + gr.m_fillGradientD2); + RendererRadialGradient ren(renBase,gr.m_allocator,span); + agg::render_scanlines(ras, sl, ren); + } + else + { + renSolid.color(gr.m_fillColor); + agg::render_scanlines(ras, sl, renSolid); + } + } + } + + + + //-------------------------------------------------------------------- + //! JME - this is where the bulk of the changes have taken place. + template + static void renderImage(TAGG2D& gr, const Image& img, + BaseRenderer& renBase, Interpolator& interpolator) + { + //! JME - have not quite figured which part of this is not const-correct + // hence the cast. + Image& imgc = const_cast(img); + TAGG2D::PixFormat img_pixf(imgc.renBuf); + typedef agg::image_accessor_clone img_source_type; + img_source_type source(img_pixf); + + SpanConvImageBlend blend(gr.m_imageBlendMode, gr.m_imageBlendColor); + if(gr.m_imageFilter == TAGG2D::NoFilter) + { + + typedef agg::span_image_filter_rgba_nn SpanGenType; + typedef agg::span_converter SpanConvType; + typedef agg::renderer_scanline_aa RendererType; + + SpanGenType sg(source,interpolator); + SpanConvType sc(sg, blend); + RendererType ri(renBase,gr.m_allocator,sg); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + } + else + { + bool resample = (gr.m_imageResample == TAGG2D::ResampleAlways); + if(gr.m_imageResample == TAGG2D::ResampleOnZoomOut) + { + double sx, sy; + interpolator.transformer().scaling_abs(&sx, &sy); + if (sx > 1.125 || sy > 1.125) + { + resample = true; + } + } + + if(resample) + { + typedef agg::span_image_resample_rgba_affine SpanGenType; + typedef agg::span_converter SpanConvType; + typedef agg::renderer_scanline_aa RendererType; + + SpanGenType sg(source,interpolator,gr.m_imageFilterLut); + SpanConvType sc(sg, blend); + RendererType ri(renBase,gr.m_allocator,sg); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + } + else + { + // this is the AGG2D default + if(gr.m_imageFilter == TAGG2D::Bilinear) + { + typedef agg::span_image_filter_rgba_bilinear SpanGenType; + typedef agg::span_converter SpanConvType; + typedef agg::renderer_scanline_aa RendererType; + + SpanGenType sg(source,interpolator); + SpanConvType sc(sg, blend); + RendererType ri(renBase,gr.m_allocator,sg); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + } + else + { + if(gr.m_imageFilterLut.diameter() == 2) + { + typedef agg::span_image_filter_rgba_2x2 SpanGenType; + typedef agg::span_converter SpanConvType; + typedef agg::renderer_scanline_aa RendererType; + + SpanGenType sg(source,interpolator,gr.m_imageFilterLut); + SpanConvType sc(sg, blend); + RendererType ri(renBase,gr.m_allocator,sg); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + } + else + { + typedef agg::span_image_filter_rgba SpanGenType; + typedef agg::span_converter SpanConvType; + typedef agg::renderer_scanline_aa RendererType; + SpanGenType sg(source,interpolator,gr.m_imageFilterLut); + SpanConvType sc(sg, blend); + RendererType ri(renBase,gr.m_allocator,sg); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + } + } + } + } + } +}; + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::render(bool fillColor) +{ + if(m_blendMode == BlendAlpha) + { + TAGG2DRENDERER::render(*this, m_renBase, m_renSolid, fillColor); + } + else + { + TAGG2DRENDERER::render(*this, m_renBaseComp, m_renSolidComp, fillColor); + } +} +#if !defined( UNDER_CE ) + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::render(FontRasterizer& ras, FontScanline& sl) +{ + if(m_blendMode == BlendAlpha) + { + Agg2DRenderer::render(*this, m_renBase, m_renSolid, ras, sl); + } + else + { + Agg2DRenderer::render(*this, m_renBaseComp, m_renSolidComp, ras, sl); + } +} + +#endif + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::renderImage(const Image& img, int x1, int y1, int x2, int y2, + const double* parl) +{ + agg::trans_affine mtx((double)x1, + (double)y1, + (double)x2, + (double)y2, + parl); + mtx *= m_transform; + mtx.invert(); + + m_rasterizer.reset(); + m_rasterizer.add_path(m_pathTransform); + + typedef agg::span_interpolator_linear Interpolator; + Interpolator interpolator(mtx); + + if(m_blendMode == BlendAlpha) + { + // JME audit - + Agg2DRenderer::renderImage(*this, img, m_renBasePre, interpolator); + } + else + { + Agg2DRenderer::renderImage(*this, img, m_renBaseCompPre, interpolator); + } +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE struct Agg2DRasterizerGamma +{ + + Agg2DRasterizerGamma(double alpha, double gamma) : + m_alpha(alpha), m_gamma(gamma) {} + + double operator() (double x) const + { + return m_alpha(m_gamma(x)); + } + agg::gamma_multiply m_alpha; + agg::gamma_power m_gamma; +}; + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::updateRasterizerGamma() +{ + m_rasterizer.gamma(Agg2DRasterizerGamma(m_masterAlpha, m_antiAliasGamma)); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::blendImage(Image& img, + int imgX1, int imgY1, int imgX2, int imgY2, + double dstX, double dstY, unsigned alpha) +{ + worldToScreen(dstX, dstY); + PixFormat pixF(img.renBuf); + // JME + //agg::rect r(imgX1, imgY1, imgX2, imgY2); + Rect r(imgX1, imgY1, imgX2, imgY2); + if(m_blendMode == BlendAlpha) + { + m_renBasePre.blend_from(pixF, &r, int(dstX)-imgX1, int(dstY)-imgY1, alpha); + } + else + { + m_renBaseCompPre.blend_from(pixF, &r, int(dstX)-imgX1, int(dstY)-imgY1, alpha); + } +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::blendImage(Image& img, double dstX, double dstY, unsigned alpha) +{ + worldToScreen(dstX, dstY); + PixFormat pixF(img.renBuf); + m_renBasePre.blend_from(pixF, 0, int(dstX), int(dstY), alpha); + if(m_blendMode == BlendAlpha) + { + m_renBasePre.blend_from(pixF, 0, int(dstX), int(dstY), alpha); + } + else + { + m_renBaseCompPre.blend_from(pixF, 0, int(dstX), int(dstY), alpha); + } +} + + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::copyImage(Image& img, + int imgX1, int imgY1, int imgX2, int imgY2, + double dstX, double dstY) +{ + worldToScreen(dstX, dstY); + // JME + //agg::rect r(imgX1, imgY1, imgX2, imgY2); + Rect r(imgX1, imgY1, imgX2, imgY2); + m_renBase.copy_from(img.renBuf, &r, int(dstX)-imgX1, int(dstY)-imgY1); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void TAGG2D::copyImage(Image& img, double dstX, double dstY) +{ + worldToScreen(dstX, dstY); + m_renBase.copy_from(img.renBuf, 0, int(dstX), int(dstY)); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2DBase::Image::premultiply() +{ + PixFormat pixf(renBuf); + pixf.premultiply(); +} + +//------------------------------------------------------------------------ +AGG2D_TEMPLATE void Agg2DBase::Image::demultiply() +{ + PixFormat pixf(renBuf); + pixf.demultiply(); +} + + +// +////======================== +////testing stufff +// +//int width = 256; +//int height = 384; +// +//Agg2D m_graphics; +// +//void AGGDraw(unsigned char * buffer) +// { +// m_graphics.attach(buffer, +// 256, +// 384, +// 512); +// +// m_graphics.clearAll(255, 255, 255); +// //m_graphics.clearAll(0, 0, 0); +// +// //m_graphics.blendMode(TAGG2D::BlendSub); +// //m_graphics.blendMode(TAGG2D::BlendAdd); +// +// m_graphics.antiAliasGamma(1.4); +// +// // Set flipText(true) if you have the Y axis upside down. +// //m_graphics.flipText(true); +// +// +// // ClipBox. +// //m_graphics.clipBox(50, 50, rbuf_window().width() - 50, rbuf_window().height() - 50); +// +// // Transfornations - Rotate around (300,300) to 5 degree +// //m_graphics.translate(-300, -300); +// //m_graphics.rotate(TAGG2D::deg2Rad(5.0)); +// //m_graphics.translate(300, 300); +// +// // Viewport - set 0,0,600,600 to the actual window size +// // preserving aspect ratio and placing the viewport in the center. +// // To ignore aspect ratio use TAGG2D::Anisotropic +// // Note that the viewport just adds transformations to the current +// // affine matrix. So that, set the viewport *after* all transformations! +// m_graphics.viewport(0, 0, 600, 600, +// 0, 0, width, height, +// //TAGG2D::Anisotropic); +// TAGG2D::XMidYMid); +// +// +// // Rounded Rect +// m_graphics.lineColor(0, 0, 0); +// m_graphics.noFill(); +// m_graphics.roundedRect(0.5, 0.5, 600-0.5, 600-0.5, 20.0); +///* +// +// // Reglar Text +// m_graphics.font("Times New Roman", 14.0, false, false); +// m_graphics.fillColor(0, 0, 0); +// m_graphics.noLine(); +// m_graphics.text(100, 20, "Regular Raster Text -- Fast, but can't be rotated"); +// +// // Outlined Text +// m_graphics.font("Times New Roman", 50.0, false, false, TAGG2D::VectorFontCache); +// m_graphics.lineColor(50, 0, 0); +// m_graphics.fillColor(180, 200, 100); +// m_graphics.lineWidth(1.0); +// m_graphics.text(100.5, 50.5, "Outlined Text"); +// +// // Text Alignment +// m_graphics.line(250.5-150, 150.5, 250.5+150, 150.5); +// m_graphics.line(250.5, 150.5-20, 250.5, 150.5+20); +// m_graphics.line(250.5-150, 200.5, 250.5+150, 200.5); +// m_graphics.line(250.5, 200.5-20, 250.5, 200.5+20); +// m_graphics.line(250.5-150, 250.5, 250.5+150, 250.5); +// m_graphics.line(250.5, 250.5-20, 250.5, 250.5+20); +// m_graphics.line(250.5-150, 300.5, 250.5+150, 300.5); +// m_graphics.line(250.5, 300.5-20, 250.5, 300.5+20); +// m_graphics.line(250.5-150, 350.5, 250.5+150, 350.5); +// m_graphics.line(250.5, 350.5-20, 250.5, 350.5+20); +// m_graphics.line(250.5-150, 400.5, 250.5+150, 400.5); +// m_graphics.line(250.5, 400.5-20, 250.5, 400.5+20); +// m_graphics.line(250.5-150, 450.5, 250.5+150, 450.5); +// m_graphics.line(250.5, 450.5-20, 250.5, 450.5+20); +// m_graphics.line(250.5-150, 500.5, 250.5+150, 500.5); +// m_graphics.line(250.5, 500.5-20, 250.5, 500.5+20); +// m_graphics.line(250.5-150, 550.5, 250.5+150, 550.5); +// m_graphics.line(250.5, 550.5-20, 250.5, 550.5+20); +//*/ +///* +// m_graphics.fillColor(100, 50, 50); +// m_graphics.noLine(); +// //m_graphics.textHints(false); +// m_graphics.font("Times New Roman", 40.0, false, false, TAGG2D::VectorFontCache); +// +// m_graphics.textAlignment(TAGG2D::AlignLeft, TAGG2D::AlignBottom); +// m_graphics.text(250.0, 150.0, "Left-Bottom", true, 0, 0); +// +// m_graphics.textAlignment(TAGG2D::AlignCenter, TAGG2D::AlignBottom); +// m_graphics.text(250.0, 200.0, "Center-Bottom", true, 0, 0); +// +// m_graphics.textAlignment(TAGG2D::AlignRight, TAGG2D::AlignBottom); +// m_graphics.text(250.0, 250.0, "Right-Bottom", true, 0, 0); +// +// m_graphics.textAlignment(TAGG2D::AlignLeft, TAGG2D::AlignCenter); +// m_graphics.text(250.0, 300.0, "Left-Center", true, 0, 0); +// +// m_graphics.textAlignment(TAGG2D::AlignCenter, TAGG2D::AlignCenter); +// m_graphics.text(250.0, 350.0, "Center-Center", true, 0, 0); +// +// m_graphics.textAlignment(TAGG2D::AlignRight, TAGG2D::AlignCenter); +// m_graphics.text(250.0, 400.0, "Right-Center", true, 0, 0); +// +// m_graphics.textAlignment(TAGG2D::AlignLeft, TAGG2D::AlignTop); +// m_graphics.text(250.0, 450.0, "Left-Top", true, 0, 0); +// +// m_graphics.textAlignment(TAGG2D::AlignCenter, TAGG2D::AlignTop); +// m_graphics.text(250.0, 500.0, "Center-Top", true, 0, 0); +// +// m_graphics.textAlignment(TAGG2D::AlignRight, TAGG2D::AlignTop); +// m_graphics.text(250.0, 550.0, "Right-Top", true, 0, 0); +// +//*/ +// // Gradients (Aqua Buttons) +// //======================================= +// m_graphics.font("Verdana", 20.0, false, false, TAGG2D::VectorFontCache); +// double xb1 = 400; +// double yb1 = 80; +// double xb2 = xb1 + 150; +// double yb2 = yb1 + 36; +// +// m_graphics.fillColor(TAGG2D::Color(0,50,180,180)); +// m_graphics.lineColor(TAGG2D::Color(0,0,80, 255)); +// m_graphics.lineWidth(1.0); +// m_graphics.roundedRect(xb1, yb1, xb2, yb2, 12, 18); +// +// m_graphics.lineColor(TAGG2D::Color(0,0,0,0)); +// m_graphics.fillLinearGradient(xb1, yb1, xb1, yb1+30, +// TAGG2D::Color(100,200,255,255), +// TAGG2D::Color(255,255,255,0)); +// m_graphics.roundedRect(xb1+3, yb1+2.5, xb2-3, yb1+30, 9, 18, 1, 1); +// +// m_graphics.fillColor(TAGG2D::Color(0,0,50, 200)); +// m_graphics.noLine(); +///* m_graphics.textAlignment(TAGG2D::AlignCenter, TAGG2D::AlignCenter); +// m_graphics.text((xb1 + xb2) / 2.0, (yb1 + yb2) / 2.0, "Aqua Button", true, 0.0, 0.0); +//*/ +// m_graphics.fillLinearGradient(xb1, yb2-20, xb1, yb2-3, +// TAGG2D::Color(0, 0, 255,0), +// TAGG2D::Color(100,255,255,255)); +// m_graphics.roundedRect(xb1+3, yb2-20, xb2-3, yb2-2, 1, 1, 9, 18); +// +// +// // Aqua Button Pressed +// xb1 = 400; +// yb1 = 30; +// xb2 = xb1 + 150; +// yb2 = yb1 + 36; +// +// m_graphics.fillColor(TAGG2D::Color(0,50,180,180)); +// m_graphics.lineColor(TAGG2D::Color(0,0,0, 255)); +// m_graphics.lineWidth(2.0); +// m_graphics.roundedRect(xb1, yb1, xb2, yb2, 12, 18); +// +// m_graphics.lineColor(TAGG2D::Color(0,0,0,0)); +// m_graphics.fillLinearGradient(xb1, yb1+2, xb1, yb1+25, +// TAGG2D::Color(60, 160,255,255), +// TAGG2D::Color(100,255,255,0)); +// m_graphics.roundedRect(xb1+3, yb1+2.5, xb2-3, yb1+30, 9, 18, 1, 1); +// +// m_graphics.fillColor(TAGG2D::Color(0,0,50, 255)); +// m_graphics.noLine(); +///* m_graphics.textAlignment(TAGG2D::AlignCenter, TAGG2D::AlignCenter); +// m_graphics.text((xb1 + xb2) / 2.0, (yb1 + yb2) / 2.0, "Aqua Pressed", 0.0, 0.0); +//*/ +// m_graphics.fillLinearGradient(xb1, yb2-25, xb1, yb2-5, +// TAGG2D::Color(0, 180,255,0), +// TAGG2D::Color(0, 200,255,255)); +// m_graphics.roundedRect(xb1+3, yb2-25, xb2-3, yb2-2, 1, 1, 9, 18); +// +// +// +// +// // Basic Shapes -- Ellipse +// //=========================================== +// m_graphics.lineWidth(3.5); +// m_graphics.lineColor(20, 80, 80); +// m_graphics.fillColor(200, 255, 80, 200); +// m_graphics.ellipse(450, 200, 50, 90); +// +// +// // Paths +// //=========================================== +// m_graphics.resetPath(); +// m_graphics.fillColor(255, 0, 0, 100); +// m_graphics.lineColor(0, 0, 255, 100); +// m_graphics.lineWidth(2); +// m_graphics.moveTo(300/2, 200/2); +// m_graphics.horLineRel(-150/2); +// m_graphics.arcRel(150/2, 150/2, 0, 1, 0, 150/2, -150/2); +// m_graphics.closePolygon(); +// m_graphics.drawPath(); +// +// m_graphics.resetPath(); +// m_graphics.fillColor(255, 255, 0, 100); +// m_graphics.lineColor(0, 0, 255, 100); +// m_graphics.lineWidth(2); +// m_graphics.moveTo(275/2, 175/2); +// m_graphics.verLineRel(-150/2); +// m_graphics.arcRel(150/2, 150/2, 0, 0, 0, -150/2, 150/2); +// m_graphics.closePolygon(); +// m_graphics.drawPath(); +// +// +// m_graphics.resetPath(); +// m_graphics.noFill(); +// m_graphics.lineColor(127, 0, 0); +// m_graphics.lineWidth(5); +// m_graphics.moveTo(600/2, 350/2); +// m_graphics.lineRel(50/2, -25/2); +// m_graphics.arcRel(25/2, 25/2, TAGG2D::deg2Rad(-30), 0, 1, 50/2, -25/2); +// m_graphics.lineRel(50/2, -25/2); +// m_graphics.arcRel(25/2, 50/2, TAGG2D::deg2Rad(-30), 0, 1, 50/2, -25/2); +// m_graphics.lineRel(50/2, -25/2); +// m_graphics.arcRel(25/2, 75/2, TAGG2D::deg2Rad(-30), 0, 1, 50/2, -25/2); +// m_graphics.lineRel(50, -25); +// m_graphics.arcRel(25/2, 100/2, TAGG2D::deg2Rad(-30), 0, 1, 50/2, -25/2); +// m_graphics.lineRel(50/2, -25/2); +// m_graphics.drawPath(); +// +// +// // Master Alpha. From now on everything will be translucent +// //=========================================== +// m_graphics.masterAlpha(0.85); +// +// +// // Image Transformations +// //=========================================== +///* TAGG2D::Image img(rbuf_img(0).buf(), +// rbuf_img(0).width(), +// rbuf_img(0).height(), +// rbuf_img(0).stride()); +// m_graphics.imageFilter(TAGG2D::Bilinear); +// +// //m_graphics.imageResample(TAGG2D::NoResample); +// //m_graphics.imageResample(TAGG2D::ResampleAlways); +// m_graphics.imageResample(TAGG2D::ResampleOnZoomOut); +// +// // Set the initial image blending operation as BlendDst, that actually +// // does nothing. +// //----------------- +// m_graphics.imageBlendMode(TAGG2D::BlendDst); +// +// +// // Transform the whole image to the destination rectangle +// //----------------- +// //m_graphics.transformImage(img, 450, 200, 595, 350); +// +// // Transform the rectangular part of the image to the destination rectangle +// //----------------- +// //m_graphics.transformImage(img, 60, 60, img.width()-60, img.height()-60, +// // 450, 200, 595, 350); +// +// // Transform the whole image to the destination parallelogram +// //----------------- +// //double parl[6] = { 450, 200, 595, 220, 575, 350 }; +// //m_graphics.transformImage(img, parl); +// +// // Transform the rectangular part of the image to the destination parallelogram +// //----------------- +// //double parl[6] = { 450, 200, 595, 220, 575, 350 }; +// //m_graphics.transformImage(img, 60, 60, img.width()-60, img.height()-60, parl); +// +// // Transform image to the destination path. The scale is determined by a rectangle +// //----------------- +// //m_graphics.resetPath(); +// //m_graphics.moveTo(450, 200); +// //m_graphics.cubicCurveTo(595, 220, 575, 350, 595, 350); +// //m_graphics.lineTo(470, 340); +// //m_graphics.transformImagePath(img, 450, 200, 595, 350); +// +// +// // Transform image to the destination path. +// // The scale is determined by a rectangle +// //----------------- +// m_graphics.resetPath(); +// m_graphics.moveTo(450, 200); +// m_graphics.cubicCurveTo(595, 220, 575, 350, 595, 350); +// m_graphics.lineTo(470, 340); +// m_graphics.transformImagePath(img, 60, 60, img.width()-60, img.height()-60, +// 450, 200, 595, 350); +// +// // Transform image to the destination path. +// // The transformation is determined by a parallelogram +// //m_graphics.resetPath(); +// //m_graphics.moveTo(450, 200); +// //m_graphics.cubicCurveTo(595, 220, 575, 350, 595, 350); +// //m_graphics.lineTo(470, 340); +// //double parl[6] = { 450, 200, 595, 220, 575, 350 }; +// //m_graphics.transformImagePath(img, parl); +// +// // Transform the rectangular part of the image to the destination path. +// // The transformation is determined by a parallelogram +// //m_graphics.resetPath(); +// //m_graphics.moveTo(450, 200); +// //m_graphics.cubicCurveTo(595, 220, 575, 350, 595, 350); +// //m_graphics.lineTo(470, 340); +// //double parl[6] = { 450, 200, 595, 220, 575, 350 }; +// //m_graphics.transformImagePath(img, 60, 60, img.width()-60, img.height()-60, parl); +//*/ +// +// // Add/Sub/Contrast Blending Modes +// m_graphics.noLine(); +// m_graphics.fillColor(70, 70, 0); +// m_graphics.blendMode(TAGG2D::BlendAdd); +// m_graphics.ellipse(500, 280, 20, 40); +// +// m_graphics.fillColor(255, 255, 255); +// m_graphics.blendMode(TAGG2D::BlendContrast); +// m_graphics.ellipse(500+40, 280, 20, 40); +// +// +// +// // Radial gradient. +// m_graphics.blendMode(TAGG2D::BlendAlpha); +// m_graphics.fillRadialGradient(400, 500, 40, +// TAGG2D::Color(255, 255, 0, 0), +// TAGG2D::Color(0, 0, 127), +// TAGG2D::Color(0, 255, 0, 0)); +// m_graphics.ellipse(400, 500, 40, 40); +// +// } +// \ No newline at end of file diff --git a/desmume/src/aggdraw.cpp b/desmume/src/aggdraw.cpp index dfbdf0c6c..23cad4929 100644 --- a/desmume/src/aggdraw.cpp +++ b/desmume/src/aggdraw.cpp @@ -66,62 +66,6 @@ typedef std::map TAgg_Font_Table; static TAgg_Font_Table font_table; -const agg::int8u* AggDrawTarget::lookupFont(const std::string& name) -{ - TAgg_Font_Table::iterator it(font_table.find(name)); - if(it == font_table.end()) return NULL; - else return it->second; -} - -void Agg_init_fonts() -{ - struct font_type - { - const agg::int8u* font; - const char* name; - } - fonts[] = - { - { agg::gse4x6, "gse4x6" }, - { agg::gse4x8, "gse4x8" }, - { agg::gse5x7, "gse5x7" }, - { agg::gse5x9, "gse5x9" }, - { agg::gse6x9, "gse6x9" }, - { agg::gse6x12, "gse6x12" }, - { agg::gse7x11, "gse7x11" }, - { agg::gse7x11_bold, "gse7x11_bold" }, - { agg::gse7x15, "gse7x15" }, - { agg::gse7x15_bold, "gse7x15_bold" }, - { agg::gse8x16, "gse8x16" }, - { agg::gse8x16_bold, "gse8x16_bold" }, - { agg::mcs11_prop, "mcs11_prop" }, - { agg::mcs11_prop_condensed, "mcs11_prop_condensed" }, - { agg::mcs12_prop, "mcs12_prop" }, - { agg::mcs13_prop, "mcs13_prop" }, - { agg::mcs5x10_mono, "mcs5x10_mono" }, - { agg::mcs5x11_mono, "mcs5x11_mono" }, - { agg::mcs6x10_mono, "mcs6x10_mono" }, - { agg::mcs6x11_mono, "mcs6x11_mono" }, - { agg::mcs7x12_mono_high, "mcs7x12_mono_high" }, - { agg::mcs7x12_mono_low, "mcs7x12_mono_low" }, - { agg::verdana12, "verdana12" }, - { agg::verdana12_bold, "verdana12_bold" }, - { agg::verdana13, "verdana13" }, - { agg::verdana13_bold, "verdana13_bold" }, - { agg::verdana14, "verdana14" }, - { agg::verdana14_bold, "verdana14_bold" }, - { agg::verdana16, "verdana16" }, - { agg::verdana16_bold, "verdana16_bold" }, - { agg::verdana17, "verdana17" }, - { agg::verdana17_bold, "verdana17_bold" }, - { agg::verdana18, "verdana18" }, - { agg::verdana18_bold, "verdana18_bold" }, - }; - - for(int i=0;i T_AGG_RGB555; @@ -139,7 +83,7 @@ static AggDrawTarget* targets[] = { void Agg_init() { - Agg_init_fonts(); + //Agg_init_fonts(); aggDraw.target = targets[0]; } @@ -155,9 +99,10 @@ void AggDraw_Desmume::composite(void* dest) agg::rendering_buffer rBuf; rBuf.attach((u8*)dest, 256, 384, 1024); + typedef agg::image_accessor_clip img_source_type; - img_source_type img_src(agg_targetLua.pixf, T_AGG_RGBA::pixfmt::color_type(0,255,0,0)); + img_source_type img_src(agg_targetLua.pixFormat(), T_AGG_RGBA::pixfmt::color_type(0,255,0,0)); agg::trans_affine img_mtx; typedef agg::span_interpolator_linear<> interpolator_type; @@ -188,174 +133,42 @@ void AggDraw_Desmume::composite(void* dest) agg::render_scanlines_bin(ras, sl, rbase, sa, sg); } - -static int ctr=0; - -//temporary, just for testing the lib +// +//static int ctr=0; +// +////temporary, just for testing the lib void AGGDraw() { - +// aggDraw.setTarget(AggTarget_Lua); +// +// aggDraw.target->clear(); +// +// ctr++; +// - aggDraw.target->clear(); - - ctr++; - - aggDraw.target->set_color(0, 255, 0, 128); - int add = (int)(40*cos((double)ctr/20.0f)); - aggDraw.target->solid_rectangle(100 +add , 100, 200 + add, 200); - - aggDraw.target->set_gamma(99999); - aggDraw.target->set_color(255, 64, 64, 128); - aggDraw.target->solid_triangle(0, 60, 200, 170, 100, 310); - - aggDraw.target->set_color(255, 0, 0, 128); - aggDraw.target->solid_ellipse(70, 80, 50, 50); - aggDraw.target->set_font("verdana18_bold"); - aggDraw.target->set_color(255, 0, 255, 255); - aggDraw.target->render_text(60,60, "testing testing testing"); - aggDraw.target->line(60, 90, 100, 100, 4); - - aggDraw.target->marker(200, 200, 40, 4); - aggDraw.target->marker(100, 300, 40, 3); - // - //agg_draw_line_pattern(64, 19, 14, 126, 118, 266, 19, 265, .76, 4.69, "C:\\7.bmp"); + aggDraw.target->lineColor(0, 255, 0, 128); + aggDraw.target->noFill(); +// int add = (int)(40*cos((double)ctr/20.0f)); + aggDraw.target->roundedRect(0.5, 0.5, 600-0.5, 600-0.5, 20.0); +// +// aggDraw.target->set_gamma(99999); +// aggDraw.target->set_color(255, 64, 64, 128); +// aggDraw.target->solid_triangle(0, 60, 200, 170, 100, 310); +// +// aggDraw.target->set_color(255, 0, 0, 128); +// aggDraw.target->solid_ellipse(70, 80, 50, 50); +// +// aggDraw.target->set_font("verdana18_bold"); +// aggDraw.target->set_color(255, 0, 255, 255); +// aggDraw.target->render_text(60,60, "testing testing testing"); +// +// aggDraw.target->line(60, 90, 100, 100, 4); +// +// aggDraw.target->marker(200, 200, 40, 4); +// aggDraw.target->marker(100, 300, 40, 3); +// // +// //agg_draw_line_pattern(64, 19, 14, 126, 118, 266, 19, 265, .76, 4.69, "C:\\7.bmp"); } -//static agg::int8u brightness_to_alpha[256 * 3] = -//{ -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -// 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253, -// 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252, -// 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251, -// 251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 249, 249, 249, 249, -// 249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 247, 247, 247, 247, 247, 246, -// 246, 246, 246, 246, 246, 245, 245, 245, 245, 245, 244, 244, 244, 244, 243, 243, -// 243, 243, 243, 242, 242, 242, 242, 241, 241, 241, 241, 240, 240, 240, 239, 239, -// 239, 239, 238, 238, 238, 238, 237, 237, 237, 236, 236, 236, 235, 235, 235, 234, -// 234, 234, 233, 233, 233, 232, 232, 232, 231, 231, 230, 230, 230, 229, 229, 229, -// 228, 228, 227, 227, 227, 226, 226, 225, 225, 224, 224, 224, 223, 223, 222, 222, -// 221, 221, 220, 220, 219, 219, 219, 218, 218, 217, 217, 216, 216, 215, 214, 214, -// 213, 213, 212, 212, 211, 211, 210, 210, 209, 209, 208, 207, 207, 206, 206, 205, -// 204, 204, 203, 203, 202, 201, 201, 200, 200, 199, 198, 198, 197, 196, 196, 195, -// 194, 194, 193, 192, 192, 191, 190, 190, 189, 188, 188, 187, 186, 186, 185, 184, -// 183, 183, 182, 181, 180, 180, 179, 178, 177, 177, 176, 175, 174, 174, 173, 172, -// 171, 171, 170, 169, 168, 167, 166, 166, 165, 164, 163, 162, 162, 161, 160, 159, -// 158, 157, 156, 156, 155, 154, 153, 152, 151, 150, 149, 148, 148, 147, 146, 145, -// 144, 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, -// 128, 128, 127, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, -// 112, 111, 110, 109, 108, 107, 106, 105, 104, 102, 101, 100, 99, 98, 97, 96, -// 95, 94, 93, 91, 90, 89, 88, 87, 86, 85, 84, 82, 81, 80, 79, 78, -// 77, 75, 74, 73, 72, 71, 70, 69, 67, 66, 65, 64, 63, 61, 60, 59, -// 58, 57, 56, 54, 53, 52, 51, 50, 48, 47, 46, 45, 44, 42, 41, 40, -// 39, 37, 36, 35, 34, 33, 31, 30, 29, 28, 27, 25, 24, 23, 22, 20, -// 19, 18, 17, 15, 14, 13, 12, 11, 9, 8, 7, 6, 4, 3, 2, 1 -//}; -// -//template -//void draw_curve(Pattern& patt,Rasterizer& ras,Renderer& ren,PatternSource& src,VertexSource& vs, double scale, double start) -//{ -// patt.create(src); -// ren.scale_x(scale); -// ren.start_x(start); -// ras.add_path(vs); -//} -// -//class pattern_src_brightness_to_alpha_rgba8 -//{ -//public: -// pattern_src_brightness_to_alpha_rgba8(agg::rendering_buffer& rb) : -// m_rb(&rb), m_pf(*m_rb) {} -// -// unsigned width() const { return m_pf.width(); } -// unsigned height() const { return m_pf.height(); } -// agg::rgba8 pixel(int x, int y) const -// { -// agg::rgba8 c = m_pf.pixel(x, y); -// c.a = brightness_to_alpha[c.r + c.g + c.b]; -// return c; -// } -// -//private: -// agg::rendering_buffer* m_rb; -// pixfmt m_pf; -//}; -// -// void agg_draw_line_pattern(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, double scale, double start, char* filename){ -// -// int flipy = 0; -// -// agg::platform_support platsup(agg::pix_format_rgb555, flipy); -// -// platsup.load_img(0, filename); -// -// agg::bezier_ctrl m_curve1; -// -// typedef agg::rasterizer_scanline_aa<> rasterizer_scanline; -// typedef agg::scanline_p8 scanline; -// -// m_curve1.curve(x1, y1, x2, y2, x3, y3, x4, y4); -// m_curve1.no_transform(); -// -// rBuf.attach(GPU_tempScreen, width, height, stride); -// -// pixfmt pixf(rBuf); -// RendererBase ren_base(pixf); -// RendererSolid ren(ren_base); -// -// rasterizer_scanline ras; -// scanline sl; -// -// // Pattern source. Must have an interface: -// // width() const -// // height() const -// // pixel(int x, int y) const -// // Any agg::renderer_base<> or derived -// // is good for the use as a source. -// //----------------------------------- -// pattern_src_brightness_to_alpha_rgba8 p1(platsup.rbuf_img(0)); -// -// agg::pattern_filter_bilinear_rgba8 fltr; // Filtering functor -// -// // agg::line_image_pattern is the main container for the patterns. It creates -// // a copy of the patterns extended according to the needs of the filter. -// // agg::line_image_pattern can operate with arbitrary image width, but if the -// // width of the pattern is power of 2, it's better to use the modified -// // version agg::line_image_pattern_pow2 because it works about 15-25 percent -// // faster than agg::line_image_pattern (because of using simple masking instead -// // of expensive '%' operation). -// typedef agg::line_image_pattern pattern_type; -// typedef agg::renderer_base base_ren_type; -// typedef agg::renderer_outline_image renderer_type; -// typedef agg::rasterizer_outline_aa rasterizer_type; -// -// //-- Create uninitialized and set the source -// pattern_type patt(fltr); -// renderer_type ren_img(ren_base, patt); -// rasterizer_type ras_img(ren_img); -// -// draw_curve(patt, ras_img, ren_img, p1, m_curve1.curve(), scale, start); -// } diff --git a/desmume/src/aggdraw.h b/desmume/src/aggdraw.h index 0687a8581..e2c0648bb 100644 --- a/desmume/src/aggdraw.h +++ b/desmume/src/aggdraw.h @@ -39,172 +39,47 @@ #include "agg_renderer_outline_aa.h" #include "agg_renderer_markers.h" +#include "agg2d.h" + class AggDrawTarget { public: - virtual void set_color(int r, int g, int b, int a) = 0; - virtual void set_gamma(int gamma) = 0; - virtual void set_font(const std::string& name) = 0; - - virtual void set_pixel(int x, int y) = 0; - virtual void clear() = 0; - - virtual void render_text(int x, int y, const std::string& str) = 0; - virtual void solid_ellipse(int x, int y, int rx, int ry) = 0; - virtual void solid_rectangle(int x1, int y1, int x2, int y2) = 0; - virtual void solid_triangle(int x1, int y1, int x2, int y2, int x3, int y3) = 0; - virtual void line(int x1, int y1, int x2, int y2, double w) = 0; - virtual void marker(int x, int y, int size, int type) = 0; - - static const agg::int8u* lookupFont(const std::string& name); + virtual void lineColor(unsigned r, unsigned g, unsigned b, unsigned a) = 0; + virtual void noFill() = 0; + virtual void roundedRect(double x1, double y1, double x2, double y2,double rx_bottom, double ry_bottom,double rx_top, double ry_top) = 0; + virtual void roundedRect(double x1, double y1, double x2, double y2, double r) = 0; + virtual void roundedRect(double x1, double y1, double x2, double y2, double rx, double ry) = 0; }; + template -class AggDrawTargetImplementation : public AggDrawTarget +class AggDrawTargetImplementation : public AggDrawTarget, public Agg2D { -public: +public: typedef PIXFMT pixfmt; - - // The AGG base - typedef agg::renderer_base RendererBase; - - // The AGG primitives renderer - typedef agg::renderer_primitives RendererPrimitives; - - // The AGG solid renderer - typedef agg::renderer_scanline_aa_solid RendererSolid; - - - //the order of declaration matters in order to make these variables get setup correctly - agg::rendering_buffer rBuf; - pixfmt pixf; - RendererBase rbase; - RendererPrimitives rprim; - - AggDrawTargetImplementation(agg::int8u* buf, int width, int height, int stride) - : rBuf(buf,width,height,stride) - , pixf(rBuf) - , rbase(pixf) - , rprim(rbase) - { - } - typedef typename pixfmt::color_type color_type; - - struct TRenderState - { - TRenderState() - : color(0,0,0,255) - , gamma(99999) - , font(NULL) - {} - color_type color; - int gamma; - const agg::int8u* font; - } renderState; - virtual void set_color(int r, int g, int b, int a) { renderState.color = color_type(r,g,b,a); } - virtual void set_gamma(int gamma) { renderState.gamma = gamma; } - virtual void set_font(const std::string& name) { renderState.font = lookupFont(name); } - - virtual void set_pixel(int x, int y) + typedef Agg2D BASE; + AggDrawTargetImplementation(agg::int8u* buf, int width, int height, int stride) { - pixf.copy_pixel(x, y, renderState.color); + attach(buf,width,height,stride); + + BASE::viewport(0, 0, 600, 600, + 0, 0, width, height, + //TAGG2D::Anisotropic); + XMidYMid); } - virtual void clear() + virtual void lineColor(unsigned r, unsigned g, unsigned b, unsigned a) { BASE::lineColor(r,g,b,a); } + virtual void noFill() { BASE::noFill(); } + virtual void roundedRect(double x1, double y1, double x2, double y2,double rx_bottom, double ry_bottom,double rx_top,double ry_top) { - static color_type transparentBlack(0,0,0,0); - rbase.clear(transparentBlack); + BASE::roundedRect(x1,y1,x2,y2,rx_bottom,ry_bottom,rx_top,ry_top); } - - virtual void render_text(int x, int y, const std::string& str) - { - typedef agg::renderer_base ren_base; - typedef agg::glyph_raster_bin glyph_gen; - glyph_gen glyph(0); - - ren_base rb(pixf); - agg::renderer_raster_htext_solid rt(rb, glyph); - rt.color(renderState.color); - - glyph.font(renderState.font); - rt.render_text(x, y, str.c_str(), true); //flipy - } - - virtual void solid_ellipse(int x, int y, int rx, int ry) - { - rprim.fill_color(renderState.color); - rprim.solid_ellipse(x, y, rx, ry); - } - - virtual void solid_rectangle(int x1, int y1, int x2, int y2) - { - rprim.fill_color(renderState.color); - rprim.solid_rectangle(x1, y1, x2, y2); - } - - virtual void solid_triangle(int x1, int y1, int x2, int y2, int x3, int y3) - { - RendererSolid ren_aa(rbase); - agg::rasterizer_scanline_aa<> m_ras; - agg::scanline_p8 m_sl_p8; - - agg::path_storage path; - - path.move_to(x1, y1); - path.line_to(x2, y2); - path.line_to(x3, y3); - path.close_polygon(); - - ren_aa.color(renderState.color); - - m_ras.gamma(agg::gamma_power(renderState.gamma * 2.0)); - m_ras.add_path(path); - agg::render_scanlines(m_ras, m_sl_p8, ren_aa); - } - - virtual void line(int x1, int y1, int x2, int y2, double w) - { - - agg::line_profile_aa profile; - profile.width(w); - - typedef agg::renderer_mclip base_ren_type; - typedef agg::renderer_outline_aa renderer_type; - - base_ren_type r(pixf); - renderer_type ren(r, profile); - - agg::rasterizer_outline_aa ras(ren); - ras.round_cap(true); - - ren.color(renderState.color); - - ras.move_to_d(x1, y1); - ras.line_to_d(x2, y2); - ras.render(false); - } - - virtual void marker(int x, int y, int size, int type) - { - - typedef agg::renderer_mclip base_ren_type; - - base_ren_type r(pixf); - agg::renderer_scanline_aa_solid rs(r); - - agg::renderer_markers m(r); - - m.line_color(renderState.color); - m.fill_color(renderState.color); - - m.marker(x, y, size, agg::marker_e(type % agg::end_of_markers)); - } - + virtual void roundedRect(double x1, double y1, double x2, double y2, double r) { BASE::roundedRect(x1,y1,x2,y2,r); } + virtual void roundedRect(double x1, double y1, double x2, double y2, double rx, double ry) { BASE::roundedRect(x1,y1,x2,y2,rx,ry); } }; - class AggDraw { public: diff --git a/desmume/src/agg/agg-2.5.lib b/desmume/src/windows/agg/agg-2.5.lib similarity index 100% rename from desmume/src/agg/agg-2.5.lib rename to desmume/src/windows/agg/agg-2.5.lib diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index ed2ca02d7..bc0a3dbbc 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -86,6 +86,7 @@ #include "directx/ddraw.h" #include "aggdraw.h" +#include "agg2d.h" using namespace std; @@ -776,8 +777,8 @@ void Display() ddsd.dwFlags=DDSD_ALL; res = lpBackSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL); - extern void AGGDraw(); - AGGDraw(); + //extern void AGGDraw(); AGGDraw(); + if (res == DD_OK) { @@ -893,6 +894,9 @@ void Display() break; } + //extern void AGGDraw(unsigned char * buffer); AGGDraw((unsigned char*) ddsd.lpSurface); + + lpBackSurface->Unlock((LPRECT)ddsd.lpSurface); // Main screen