From 2a178393c00d0d234c4b59c190cc26fb6eee5cd7 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 15 Oct 2014 10:35:38 -0400 Subject: [PATCH 1/9] Upgrade Agg to SVN r103 --- extern/agg24/include/agg_alpha_mask_u8.h | 76 +- extern/agg24/include/agg_basics.h | 114 +- extern/agg24/include/agg_blur.h | 231 +- extern/agg24/include/agg_color_gray.h | 963 +++++- extern/agg24/include/agg_color_rgba.h | 1110 +++++-- extern/agg24/include/agg_config.h | 2 +- extern/agg24/include/agg_conv_curve.h | 108 +- extern/agg24/include/agg_conv_transform.h | 6 +- .../agg24/include/agg_font_cache_manager2.h | 311 ++ extern/agg24/include/agg_gamma_functions.h | 9 + extern/agg24/include/agg_gamma_lut.h | 184 ++ extern/agg24/include/agg_gsv_text.h | 2 +- extern/agg24/include/agg_image_accessors.h | 22 +- extern/agg24/include/agg_path_storage.h | 6 +- .../agg24/include/agg_pattern_filters_rgba.h | 11 +- .../agg24/include/agg_pixfmt_amask_adaptor.h | 6 +- extern/agg24/include/agg_pixfmt_base.h | 97 + extern/agg24/include/agg_pixfmt_gray.h | 476 +-- extern/agg24/include/agg_pixfmt_rgb.h | 687 ++-- extern/agg24/include/agg_pixfmt_rgb_packed.h | 9 +- extern/agg24/include/agg_pixfmt_rgba.h | 2871 ++++++++--------- .../agg24/include/agg_rasterizer_cells_aa.h | 124 +- .../include/agg_rasterizer_compound_aa.h | 43 +- .../include/agg_rasterizer_scanline_aa.h | 31 +- .../agg_rasterizer_scanline_aa_nogamma.h | 482 +++ extern/agg24/include/agg_renderer_base.h | 13 + .../agg24/include/agg_renderer_outline_aa.h | 38 +- .../include/agg_renderer_outline_image.h | 57 +- extern/agg24/include/agg_rendering_buffer.h | 22 +- .../agg24/include/agg_scanline_storage_aa.h | 12 +- .../agg24/include/agg_scanline_storage_bin.h | 20 +- extern/agg24/include/agg_scanline_u.h | 96 +- extern/agg24/include/agg_span_gradient.h | 29 +- .../agg24/include/agg_span_gradient_alpha.h | 8 +- .../agg24/include/agg_span_gradient_contour.h | 362 +++ .../agg24/include/agg_span_gradient_image.h | 188 ++ extern/agg24/include/agg_span_image_filter.h | 10 +- .../include/agg_span_image_filter_gray.h | 105 +- .../agg24/include/agg_span_image_filter_rgb.h | 151 +- .../include/agg_span_image_filter_rgba.h | 118 +- .../include/agg_span_interpolator_adaptor.h | 14 +- .../include/agg_span_interpolator_linear.h | 14 +- .../include/agg_span_interpolator_trans.h | 6 +- extern/agg24/include/agg_trans_affine.h | 4 +- extern/agg24/include/agg_trans_perspective.h | 8 +- .../include/platform/agg_platform_support.h | 17 +- extern/agg24/include/util/agg_color_conv.h | 44 + .../agg24/include/util/agg_color_conv_rgb8.h | 25 +- extern/agg24/src/agg_color_rgba.cpp | 17 + extern/agg24/src/agg_curves.cpp | 106 +- .../src/platform/X11/agg_platform_support.cpp | 384 ++- .../platform/win32/agg_platform_support.cpp | 272 +- .../src/platform/win32/agg_win32_bmp.cpp | 6 + src/_backend_agg.h | 2 +- src/_path.h | 16 +- src/_path_wrapper.cpp | 6 +- 56 files changed, 6915 insertions(+), 3236 deletions(-) create mode 100644 extern/agg24/include/agg_font_cache_manager2.h create mode 100644 extern/agg24/include/agg_pixfmt_base.h create mode 100644 extern/agg24/include/agg_rasterizer_scanline_aa_nogamma.h create mode 100644 extern/agg24/include/agg_span_gradient_contour.h create mode 100644 extern/agg24/include/agg_span_gradient_image.h create mode 100644 extern/agg24/src/agg_color_rgba.cpp diff --git a/extern/agg24/include/agg_alpha_mask_u8.h b/extern/agg24/include/agg_alpha_mask_u8.h index 0f1fc37ea43e..e301c100880d 100644 --- a/extern/agg24/include/agg_alpha_mask_u8.h +++ b/extern/agg24/include/agg_alpha_mask_u8.h @@ -2,8 +2,8 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-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. +// 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. // @@ -30,15 +30,15 @@ namespace agg { static unsigned calculate(const int8u* p) { return *p; } }; - + //=====================================================rgb_to_gray_mask_u8 template struct rgb_to_gray_mask_u8 { - static unsigned calculate(const int8u* p) - { - return (p[R]*77 + p[G]*150 + p[B]*29) >> 8; + static unsigned calculate(const int8u* p) + { + return (p[R]*77 + p[G]*150 + p[B]*29) >> 8; } }; @@ -50,7 +50,7 @@ namespace agg typedef int8u cover_type; typedef alpha_mask_u8 self_type; enum cover_scale_e - { + { cover_shift = 8, cover_none = 0, cover_full = 255 @@ -64,12 +64,12 @@ namespace agg MaskF& mask_function() { return m_mask_function; } const MaskF& mask_function() const { return m_mask_function; } - + //-------------------------------------------------------------------- cover_type pixel(int x, int y) const { - if(x >= 0 && y >= 0 && - x < (int)m_rbuf->width() && + if(x >= 0 && y >= 0 && + x < (int)m_rbuf->width() && y < (int)m_rbuf->height()) { return (cover_type)m_mask_function.calculate( @@ -81,13 +81,13 @@ namespace agg //-------------------------------------------------------------------- cover_type combine_pixel(int x, int y, cover_type val) const { - if(x >= 0 && y >= 0 && - x < (int)m_rbuf->width() && + if(x >= 0 && y >= 0 && + x < (int)m_rbuf->width() && y < (int)m_rbuf->height()) { - return (cover_type)((cover_full + val * + return (cover_type)((cover_full + val * m_mask_function.calculate( - m_rbuf->row_ptr(y) + x * Step + Offset)) >> + m_rbuf->row_ptr(y) + x * Step + Offset)) >> cover_shift); } return 0; @@ -112,7 +112,7 @@ namespace agg if(x < 0) { count += x; - if(count <= 0) + if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; @@ -126,7 +126,7 @@ namespace agg { int rest = x + count - xmax - 1; count -= rest; - if(count <= 0) + if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; @@ -162,7 +162,7 @@ namespace agg if(x < 0) { count += x; - if(count <= 0) + if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; @@ -176,7 +176,7 @@ namespace agg { int rest = x + count - xmax - 1; count -= rest; - if(count <= 0) + if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; @@ -187,8 +187,8 @@ namespace agg const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; do { - *covers = (cover_type)((cover_full + (*covers) * - m_mask_function.calculate(mask)) >> + *covers = (cover_type)((cover_full + (*covers) * + m_mask_function.calculate(mask)) >> cover_shift); ++covers; mask += Step; @@ -214,7 +214,7 @@ namespace agg if(y < 0) { count += y; - if(count <= 0) + if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; @@ -228,7 +228,7 @@ namespace agg { int rest = y + count - ymax - 1; count -= rest; - if(count <= 0) + if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; @@ -263,7 +263,7 @@ namespace agg if(y < 0) { count += y; - if(count <= 0) + if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; @@ -277,7 +277,7 @@ namespace agg { int rest = y + count - ymax - 1; count -= rest; - if(count <= 0) + if(count <= 0) { memset(dst, 0, num_pix * sizeof(cover_type)); return; @@ -288,8 +288,8 @@ namespace agg const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; do { - *covers = (cover_type)((cover_full + (*covers) * - m_mask_function.calculate(mask)) >> + *covers = (cover_type)((cover_full + (*covers) * + m_mask_function.calculate(mask)) >> cover_shift); ++covers; mask += m_rbuf->stride(); @@ -302,10 +302,10 @@ namespace agg alpha_mask_u8(const self_type&); const self_type& operator = (const self_type&); - agg::rendering_buffer* m_rbuf; + rendering_buffer* m_rbuf; MaskF m_mask_function; }; - + typedef alpha_mask_u8<1, 0> alpha_mask_gray8; //----alpha_mask_gray8 @@ -354,7 +354,7 @@ namespace agg typedef int8u cover_type; typedef amask_no_clip_u8 self_type; enum cover_scale_e - { + { cover_shift = 8, cover_none = 0, cover_full = 255 @@ -376,13 +376,13 @@ namespace agg m_rbuf->row_ptr(y) + x * Step + Offset); } - + //-------------------------------------------------------------------- cover_type combine_pixel(int x, int y, cover_type val) const { - return (cover_type)((cover_full + val * + return (cover_type)((cover_full + val * m_mask_function.calculate( - m_rbuf->row_ptr(y) + x * Step + Offset)) >> + m_rbuf->row_ptr(y) + x * Step + Offset)) >> cover_shift); } @@ -407,8 +407,8 @@ namespace agg const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; do { - *dst = (cover_type)((cover_full + (*dst) * - m_mask_function.calculate(mask)) >> + *dst = (cover_type)((cover_full + (*dst) * + m_mask_function.calculate(mask)) >> cover_shift); ++dst; mask += Step; @@ -436,8 +436,8 @@ namespace agg const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; do { - *dst = (cover_type)((cover_full + (*dst) * - m_mask_function.calculate(mask)) >> + *dst = (cover_type)((cover_full + (*dst) * + m_mask_function.calculate(mask)) >> cover_shift); ++dst; mask += m_rbuf->stride(); @@ -449,10 +449,10 @@ namespace agg amask_no_clip_u8(const self_type&); const self_type& operator = (const self_type&); - agg::rendering_buffer* m_rbuf; + rendering_buffer* m_rbuf; MaskF m_mask_function; }; - + typedef amask_no_clip_u8<1, 0> amask_no_clip_gray8; //----amask_no_clip_gray8 diff --git a/extern/agg24/include/agg_basics.h b/extern/agg24/include/agg_basics.h index b97e137821ef..112bb3524c94 100644 --- a/extern/agg24/include/agg_basics.h +++ b/extern/agg24/include/agg_basics.h @@ -2,8 +2,8 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-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. +// 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. // @@ -25,12 +25,12 @@ #else namespace agg { - // The policy of all AGG containers and memory allocation strategy + // The policy of all AGG containers and memory allocation strategy // in general is that no allocated data requires explicit construction. // It means that the allocator can be really simple; you can even - // replace new/delete to malloc/free. The constructors and destructors - // won't be called in this case, however everything will remain working. - // The second argument of deallocate() is the size of the allocated + // replace new/delete to malloc/free. The constructors and destructors + // won't be called in this case, however everything will remain working. + // The second argument of deallocate() is the size of the allocated // block. You can use this information if you wish. //------------------------------------------------------------pod_allocator template struct pod_allocator @@ -40,8 +40,8 @@ namespace agg }; // Single object allocator. It's also can be replaced with your custom - // allocator. The difference is that it can only allocate a single - // object and the constructor and destructor must be called. + // allocator. The difference is that it can only allocate a single + // object and the constructor and destructor must be called. // In AGG there is no need to allocate an array of objects with // calling their constructors (only single ones). So that, if you // replace these new/delete to malloc/free make sure that the in-place @@ -143,10 +143,18 @@ namespace agg __asm mov eax, dword ptr [t] } #pragma warning(pop) + AGG_INLINE int ifloor(double v) + { + return int(floor(v)); + } AGG_INLINE unsigned ufloor(double v) //-------ufloor { return unsigned(floor(v)); } + AGG_INLINE int iceil(double v) + { + return int(ceil(v)); + } AGG_INLINE unsigned uceil(double v) //--------uceil { return unsigned(ceil(v)); @@ -160,10 +168,18 @@ namespace agg { return unsigned(v); } + AGG_INLINE int ifloor(double v) + { + return int(floor(v)); + } AGG_INLINE unsigned ufloor(double v) { return unsigned(floor(v)); } + AGG_INLINE int iceil(double v) + { + return int(ceil(v)); + } AGG_INLINE unsigned uceil(double v) { return unsigned(ceil(v)); @@ -177,10 +193,19 @@ namespace agg { return unsigned(v + 0.5); } + AGG_INLINE int ifloor(double v) + { + int i = int(v); + return i - (i > v); + } AGG_INLINE unsigned ufloor(double v) { return unsigned(v); } + AGG_INLINE int iceil(double v) + { + return int(ceil(v)); + } AGG_INLINE unsigned uceil(double v) { return unsigned(ceil(v)); @@ -213,23 +238,23 @@ namespace agg enum cover_scale_e { cover_shift = 8, //----cover_shift - cover_size = 1 << cover_shift, //----cover_size - cover_mask = cover_size - 1, //----cover_mask - cover_none = 0, //----cover_none - cover_full = cover_mask //----cover_full + cover_size = 1 << cover_shift, //----cover_size + cover_mask = cover_size - 1, //----cover_mask + cover_none = 0, //----cover_none + cover_full = cover_mask //----cover_full }; //----------------------------------------------------poly_subpixel_scale_e - // These constants determine the subpixel accuracy, to be more precise, - // the number of bits of the fractional part of the coordinates. + // These constants determine the subpixel accuracy, to be more precise, + // the number of bits of the fractional part of the coordinates. // The possible coordinate capacity in bits can be calculated by formula: // sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and // 8-bits fractional part the capacity is 24 bits. enum poly_subpixel_scale_e { poly_subpixel_shift = 8, //----poly_subpixel_shift - poly_subpixel_scale = 1< struct rect_base { @@ -265,9 +290,9 @@ namespace agg rect_base(T x1_, T y1_, T x2_, T y2_) : x1(x1_), y1(y1_), x2(x2_), y2(y2_) {} - void init(T x1_, T y1_, T x2_, T y2_) + void init(T x1_, T y1_, T x2_, T y2_) { - x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_; + x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_; } const self_type& normalize() @@ -296,20 +321,26 @@ namespace agg { return (x >= x1 && x <= x2 && y >= y1 && y <= y2); } + + bool overlaps(const self_type& r) const + { + return !(r.x1 > x2 || r.x2 < x1 + || r.y1 > y2 || r.y2 < y1); + } }; //-----------------------------------------------------intersect_rectangles - template + template inline Rect intersect_rectangles(const Rect& r1, const Rect& r2) { Rect r = r1; - // First process x2,y2 because the other order - // results in Internal Compiler Error under - // Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in + // First process x2,y2 because the other order + // results in Internal Compiler Error under + // Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in // case of "Maximize Speed" optimization option. //----------------- - if(r.x2 > r2.x2) r.x2 = r2.x2; + if(r.x2 > r2.x2) r.x2 = r2.x2; if(r.y2 > r2.y2) r.y2 = r2.y2; if(r.x1 < r2.x1) r.x1 = r2.x1; if(r.y1 < r2.y1) r.y1 = r2.y1; @@ -318,7 +349,7 @@ namespace agg //---------------------------------------------------------unite_rectangles - template + template inline Rect unite_rectangles(const Rect& r1, const Rect& r2) { Rect r = r1; @@ -336,26 +367,26 @@ namespace agg //---------------------------------------------------------path_commands_e enum path_commands_e { - path_cmd_stop = 0, //----path_cmd_stop - path_cmd_move_to = 1, //----path_cmd_move_to - path_cmd_line_to = 2, //----path_cmd_line_to - path_cmd_curve3 = 3, //----path_cmd_curve3 - path_cmd_curve4 = 4, //----path_cmd_curve4 + path_cmd_stop = 0, //----path_cmd_stop + path_cmd_move_to = 1, //----path_cmd_move_to + path_cmd_line_to = 2, //----path_cmd_line_to + path_cmd_curve3 = 3, //----path_cmd_curve3 + path_cmd_curve4 = 4, //----path_cmd_curve4 path_cmd_curveN = 5, //----path_cmd_curveN path_cmd_catrom = 6, //----path_cmd_catrom path_cmd_ubspline = 7, //----path_cmd_ubspline path_cmd_end_poly = 0x0F, //----path_cmd_end_poly - path_cmd_mask = 0x0F //----path_cmd_mask + path_cmd_mask = 0x0F //----path_cmd_mask }; //------------------------------------------------------------path_flags_e enum path_flags_e { - path_flags_none = 0, //----path_flags_none - path_flags_ccw = 0x10, //----path_flags_ccw - path_flags_cw = 0x20, //----path_flags_cw + path_flags_none = 0, //----path_flags_none + path_flags_ccw = 0x10, //----path_flags_ccw + path_flags_cw = 0x20, //----path_flags_cw path_flags_close = 0x40, //----path_flags_close - path_flags_mask = 0xF0 //----path_flags_mask + path_flags_mask = 0xF0 //----path_flags_mask }; //---------------------------------------------------------------is_vertex @@ -372,7 +403,7 @@ namespace agg //-----------------------------------------------------------------is_stop inline bool is_stop(unsigned c) - { + { return c == path_cmd_stop; } @@ -416,7 +447,7 @@ namespace agg inline bool is_close(unsigned c) { return (c & ~(path_flags_cw | path_flags_ccw)) == - (path_cmd_end_poly | path_flags_close); + (path_cmd_end_poly | path_flags_close); } //------------------------------------------------------------is_next_poly @@ -440,19 +471,19 @@ namespace agg //-------------------------------------------------------------is_oriented inline bool is_oriented(unsigned c) { - return (c & (path_flags_cw | path_flags_ccw)) != 0; + return (c & (path_flags_cw | path_flags_ccw)) != 0; } //---------------------------------------------------------------is_closed inline bool is_closed(unsigned c) { - return (c & path_flags_close) != 0; + return (c & path_flags_close) != 0; } //----------------------------------------------------------get_close_flag inline unsigned get_close_flag(unsigned c) { - return c & path_flags_close; + return c & path_flags_close; } //-------------------------------------------------------clear_orientation @@ -513,7 +544,7 @@ namespace agg int x1, x2; const T* ptr; const_row_info() {} - const_row_info(int x1_, int x2_, const T* ptr_) : + const_row_info(int x1_, int x2_, const T* ptr_) : x1(x1_), x2(x2_), ptr(ptr_) {} }; @@ -522,7 +553,6 @@ namespace agg { return fabs(v1 - v2) <= double(epsilon); } - } diff --git a/extern/agg24/include/agg_blur.h b/extern/agg24/include/agg_blur.h index 0860f52e1957..cd5713f314f9 100644 --- a/extern/agg24/include/agg_blur.h +++ b/extern/agg24/include/agg_blur.h @@ -28,6 +28,7 @@ #define AGG_BLUR_INCLUDED #include "agg_array.h" +#include "agg_pixfmt_base.h" #include "agg_pixfmt_transposer.h" namespace agg @@ -399,7 +400,7 @@ namespace agg } for(i = 1; i <= rx; i++) { - if(i <= wm) src_pix_ptr += Img::pix_step; + if(i <= wm) src_pix_ptr += Img::pix_width; pix = *src_pix_ptr; stack[i + rx] = pix; sum += pix * (rx + 1 - i); @@ -414,7 +415,7 @@ namespace agg for(x = 0; x < w; x++) { *dst_pix_ptr = (sum * mul_sum) >> shr_sum; - dst_pix_ptr += Img::pix_step; + dst_pix_ptr += Img::pix_width; sum -= sum_out; @@ -424,7 +425,7 @@ namespace agg if(xp < wm) { - src_pix_ptr += Img::pix_step; + src_pix_ptr += Img::pix_width; pix = *src_pix_ptr; ++xp; } @@ -1203,10 +1204,10 @@ namespace agg AGG_INLINE void to_pix(ColorT& c) const { typedef typename ColorT::value_type cv_type; - c.r = (cv_type)uround(r); - c.g = (cv_type)uround(g); - c.b = (cv_type)uround(b); - c.a = (cv_type)uround(a); + c.r = cv_type(r); + c.g = cv_type(g); + c.b = cv_type(b); + c.a = cv_type(a); } }; @@ -1245,9 +1246,9 @@ namespace agg AGG_INLINE void to_pix(ColorT& c) const { typedef typename ColorT::value_type cv_type; - c.r = (cv_type)uround(r); - c.g = (cv_type)uround(g); - c.b = (cv_type)uround(b); + c.r = cv_type(r); + c.g = cv_type(g); + c.b = cv_type(b); } }; @@ -1282,10 +1283,218 @@ namespace agg AGG_INLINE void to_pix(ColorT& c) const { typedef typename ColorT::value_type cv_type; - c.v = (cv_type)uround(v); + c.v = cv_type(v); + } + }; + + //================================================slight_blur + // Special-purpose filter for applying a Gaussian blur with a radius small enough + // that the blur only affects adjacent pixels. A Gaussian curve with a standard + // deviation of r/2 is used, as per the HTML/CSS spec. At 3 standard deviations, + // the contribution drops to less than 0.005, i.e. less than half a percent, + // therefore the radius can be at least 1.33 before errors become significant. + // This filter is useful for smoothing artifacts caused by detail rendered + // at the pixel scale, e.g. single-pixel lines. Note that the filter should + // only be used with premultiplied pixel formats (or those without alpha). + // See the "line_thickness" example for a demonstration. + template + class slight_blur + { + public: + typedef typename PixFmt::pixel_type pixel_type; + typedef typename PixFmt::value_type value_type; + typedef typename PixFmt::order_type order_type; + + slight_blur(double r = 1.33) + { + radius(r); + } + + void radius(double r) + { + if (r > 0) + { + // Sample the gaussian curve at 0 and r/2 standard deviations. + // At 3 standard deviations, the response is < 0.005. + double pi = 3.14159; + double n = 2 / r; + m_g0 = 1 / sqrt(2 * pi); + m_g1 = m_g0 * exp(-n * n); + + // Normalize. + double sum = m_g0 + 2 * m_g1; + m_g0 /= sum; + m_g1 /= sum; + } + else + { + m_g0 = 1; + m_g1 = 0; + } + } + + void blur(PixFmt& img, rect_i bounds) + { + // Make sure we stay within the image area. + bounds.clip(rect_i(0, 0, img.width() - 1, img.height() - 1)); + + int w = bounds.x2 - bounds.x1 + 1; + int h = bounds.y2 - bounds.y1 + 1; + + if (w < 3 || h < 3) return; + + // Allocate 3 rows of buffer space. + m_buf.allocate(w * 3); + + // Set up row pointers + pixel_type * begin = &m_buf[0]; + pixel_type * r0 = begin; + pixel_type * r1 = r0 + w; + pixel_type * r2 = r1 + w; + pixel_type * end = r2 + w; + + // Horizontally blur the first two input rows. + calc_row(img, bounds.x1, bounds.y1, w, r0); + memcpy(r1, r0, w * sizeof(pixel_type)); + + for (int y = 0; ; ) + { + // Get pointer to first pixel. + pixel_type* p = img.pix_value_ptr(bounds.x1, bounds.y1 + y, bounds.x1 + w); + + // Horizontally blur the row below. + if (y + 1 < h) + { + calc_row(img, bounds.x1, bounds.y1 + y + 1, w, r2); + } + else + { + memcpy(r2, r1, w * sizeof(pixel_type)); // duplicate bottom row + } + + // Combine blurred rows into destination. + for (int x = 0; x < w; ++x) + { + calc_pixel(*r0++, *r1++, *r2++, *p++); + } + + if (++y >= h) break; + + // Wrap bottom row pointer around to top of buffer. + if (r2 == end) r2 = begin; + else if (r1 == end) r1 = begin; + else if (r0 == end) r0 = begin; + } + } + + private: + void calc_row(PixFmt& img, int x, int y, int w, pixel_type* row) + { + const int wm = w - 1; + + pixel_type* p = img.pix_value_ptr(x, y, w); + + pixel_type c[3]; + pixel_type* p0 = c; + pixel_type* p1 = c + 1; + pixel_type* p2 = c + 2; + pixel_type* end = c + 3; + *p0 = *p1 = *p; + + for (int x = 0; x < wm; ++x) + { + *p2 = *(p = p->next()); + + calc_pixel(*p0++, *p1++, *p2++, *row++); + + if (p0 == end) p0 = c; + else if (p1 == end) p1 = c; + else if (p2 == end) p2 = c; + } + + calc_pixel(*p0, *p1, *p1, *row); + } + + void calc_pixel( + pixel_type const & c1, + pixel_type const & c2, + pixel_type const & c3, + pixel_type & x) + { + calc_pixel(c1, c2, c3, x, PixFmt::pixfmt_category()); + } + + void calc_pixel( + pixel_type const & c1, + pixel_type const & c2, + pixel_type const & c3, + pixel_type & x, + pixfmt_gray_tag) + { + x.c[0] = calc_value(c1.c[0], c2.c[0], c3.c[0]); + } + + void calc_pixel( + pixel_type const & c1, + pixel_type const & c2, + pixel_type const & c3, + pixel_type & x, + pixfmt_rgb_tag) + { + enum { R = order_type::R, G = order_type::G, B = order_type::B }; + x.c[R] = calc_value(c1.c[R], c2.c[R], c3.c[R]); + x.c[G] = calc_value(c1.c[G], c2.c[G], c3.c[G]); + x.c[B] = calc_value(c1.c[B], c2.c[B], c3.c[B]); } + + void calc_pixel( + pixel_type const & c1, + pixel_type const & c2, + pixel_type const & c3, + pixel_type & x, + pixfmt_rgba_tag) + { + enum { R = order_type::R, G = order_type::G, B = order_type::B, A = order_type::A }; + x.c[R] = calc_value(c1.c[R], c2.c[R], c3.c[R]); + x.c[G] = calc_value(c1.c[G], c2.c[G], c3.c[G]); + x.c[B] = calc_value(c1.c[B], c2.c[B], c3.c[B]); + x.c[A] = calc_value(c1.c[A], c2.c[A], c3.c[A]); + } + + value_type calc_value(value_type v1, value_type v2, value_type v3) + { + return value_type(m_g1 * v1 + m_g0 * v2 + m_g1 * v3); + } + + double m_g0, m_g1; + pod_vector m_buf; }; + // Helper functions for applying blur to a surface without having to create an intermediate object. + + template + void apply_slight_blur(PixFmt& img, const rect_i& bounds, double r = 1) + { + if (r > 0) slight_blur(r).blur(img, bounds); + } + + template + void apply_slight_blur(PixFmt& img, double r = 1) + { + if (r > 0) slight_blur(r).blur(img, rect_i(0, 0, img.width() - 1, img.height() - 1)); + } + + template + void apply_slight_blur(renderer_base& img, const rect_i& bounds, double r = 1) + { + if (r > 0) slight_blur(r).blur(img.ren(), bounds); + } + + template + void apply_slight_blur(renderer_base& img, double r = 1) + { + if (r > 0) slight_blur(r).blur(img.ren(), img.clip_box()); + } } diff --git a/extern/agg24/include/agg_color_gray.h b/extern/agg24/include/agg_color_gray.h index 8e782ef2c954..4ddee04edd45 100644 --- a/extern/agg24/include/agg_color_gray.h +++ b/extern/agg24/include/agg_color_gray.h @@ -35,7 +35,8 @@ namespace agg { //===================================================================gray8 - struct gray8 + template + struct gray8T { typedef int8u value_type; typedef int32u calc_type; @@ -44,111 +45,329 @@ namespace agg { base_shift = 8, base_scale = 1 << base_shift, - base_mask = base_scale - 1 + base_mask = base_scale - 1, + base_MSB = 1 << (base_shift - 1) }; - typedef gray8 self_type; + typedef gray8T self_type; value_type v; value_type a; + static value_type luminance(const rgba& c) + { + // Calculate grayscale value as per ITU-R BT.709. + return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask)); + } + + static value_type luminance(const rgba8& c) + { + // Calculate grayscale value as per ITU-R BT.709. + return value_type((55u * c.r + 184u * c.g + 18u * c.b) >> 8); + } + + static void convert(gray8T& dst, const gray8T& src) + { + dst.v = sRGB_conv::rgb_from_sRGB(src.v); + dst.a = src.a; + } + + static void convert(gray8T& dst, const gray8T& src) + { + dst.v = sRGB_conv::rgb_to_sRGB(src.v); + dst.a = src.a; + } + + static void convert(gray8T& dst, const rgba8& src) + { + dst.v = luminance(src); + dst.a = src.a; + } + + static void convert(gray8T& dst, const srgba8& src) + { + // The RGB weights are only valid for linear values. + convert(dst, rgba8(src)); + } + + static void convert(gray8T& dst, const rgba8& src) + { + dst.v = sRGB_conv::rgb_to_sRGB(luminance(src)); + dst.a = src.a; + } + + static void convert(gray8T& dst, const srgba8& src) + { + // The RGB weights are only valid for linear values. + convert(dst, rgba8(src)); + } + //-------------------------------------------------------------------- - gray8() {} + gray8T() {} //-------------------------------------------------------------------- - gray8(unsigned v_, unsigned a_=base_mask) : + explicit gray8T(unsigned v_, unsigned a_ = base_mask) : v(int8u(v_)), a(int8u(a_)) {} //-------------------------------------------------------------------- - gray8(const self_type& c, unsigned a_) : + gray8T(const self_type& c, unsigned a_) : v(c.v), a(value_type(a_)) {} //-------------------------------------------------------------------- - gray8(const rgba& c) : - v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))), - a((value_type)uround(c.a * double(base_mask))) {} + gray8T(const rgba& c) : + v(luminance(c)), + a(value_type(uround(c.a * base_mask))) {} //-------------------------------------------------------------------- - gray8(const rgba& c, double a_) : - v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))), - a((value_type)uround(a_ * double(base_mask))) {} + template + gray8T(const gray8T& c) + { + convert(*this, c); + } //-------------------------------------------------------------------- - gray8(const rgba8& c) : - v((c.r*77 + c.g*150 + c.b*29) >> 8), - a(c.a) {} + template + gray8T(const rgba8T& c) + { + convert(*this, c); + } //-------------------------------------------------------------------- - gray8(const rgba8& c, unsigned a_) : - v((c.r*77 + c.g*150 + c.b*29) >> 8), - a(a_) {} + template + T convert_from_sRGB() const + { + typename T::value_type y = sRGB_conv::rgb_from_sRGB(v); + return T(y, y, y, sRGB_conv::alpha_from_sRGB(a)); + } + + template + T convert_to_sRGB() const + { + typename T::value_type y = sRGB_conv::rgb_to_sRGB(v); + return T(y, y, y, sRGB_conv::alpha_to_sRGB(a)); + } //-------------------------------------------------------------------- - void clear() + rgba8 make_rgba8(const linear&) const { - v = a = 0; + return rgba8(v, v, v, a); + } + + rgba8 make_rgba8(const sRGB&) const + { + return convert_from_sRGB(); + } + + operator rgba8() const + { + return make_rgba8(Colorspace()); } //-------------------------------------------------------------------- - const self_type& transparent() + srgba8 make_srgba8(const linear&) const { - a = 0; - return *this; + return convert_to_sRGB(); + } + + srgba8 make_srgba8(const sRGB&) const + { + return srgba8(v, v, v, a); + } + + operator srgba8() const + { + return make_rgba8(Colorspace()); + } + + //-------------------------------------------------------------------- + rgba16 make_rgba16(const linear&) const + { + rgba16::value_type rgb = (v << 8) | v; + return rgba16(rgb, rgb, rgb, (a << 8) | a); + } + + rgba16 make_rgba16(const sRGB&) const + { + return convert_from_sRGB(); + } + + operator rgba16() const + { + return make_rgba16(Colorspace()); + } + + //-------------------------------------------------------------------- + rgba32 make_rgba32(const linear&) const + { + rgba32::value_type v32 = v / 255.0f; + return rgba32(v32, v32, v32, a / 255.0f); + } + + rgba32 make_rgba32(const sRGB&) const + { + return convert_from_sRGB(); + } + + operator rgba32() const + { + return make_rgba32(Colorspace()); } //-------------------------------------------------------------------- - void opacity(double a_) + static AGG_INLINE double to_double(value_type a) { - if(a_ < 0.0) a_ = 0.0; - if(a_ > 1.0) a_ = 1.0; - a = (value_type)uround(a_ * double(base_mask)); + return double(a) / base_mask; } //-------------------------------------------------------------------- - double opacity() const + static AGG_INLINE value_type from_double(double a) { - return double(a) / double(base_mask); + return value_type(uround(a * base_mask)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return base_mask; } + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a == 0; + } //-------------------------------------------------------------------- - const self_type& premultiply() + AGG_INLINE bool is_opaque() const { - if(a == base_mask) return *this; - if(a == 0) + return a == base_mask; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int8u. + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + calc_type t = a * b + base_MSB; + return value_type(((t >> base_shift) + t) >> base_shift); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + if (a * b == 0) + { + return 0; + } + else if (a >= b) { - v = 0; - return *this; + return base_mask; } - v = value_type((calc_type(v) * a) >> base_shift); + else return value_type((a * base_mask + (b >> 1)) / b); + } + + //-------------------------------------------------------------------- + template + static AGG_INLINE T downscale(T a) + { + return a >> base_shift; + } + + //-------------------------------------------------------------------- + template + static AGG_INLINE T downshift(T a, unsigned n) + { + return a >> n; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int8u. + // Specifically for multiplying a color component by a cover. + static AGG_INLINE value_type mult_cover(value_type a, value_type b) + { + return multiply(a, b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return multiply(b, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return p + q - multiply(p, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + int t = (q - p) * a + base_MSB - (p > q); + return value_type(p + (((t >> base_shift) + t) >> base_shift)); + } + + //-------------------------------------------------------------------- + self_type& clear() + { + v = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; return *this; } //-------------------------------------------------------------------- - const self_type& premultiply(unsigned a_) + self_type& opacity(double a_) + { + if (a_ < 0) a_ = 0; + else if (a_ > 1) a_ = 1; + else a = (value_type)uround(a_ * double(base_mask)); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return double(a) / double(base_mask); + } + + //-------------------------------------------------------------------- + self_type& premultiply() { - if(a == base_mask && a_ >= base_mask) return *this; - if(a == 0 || a_ == 0) + if (a < base_mask) { - v = a = 0; - return *this; + if (a == 0) v = 0; + else v = multiply(v, a); } - calc_type v_ = (calc_type(v) * a_) / a; - v = value_type((v_ > a_) ? a_ : v_); - a = value_type(a_); return *this; } //-------------------------------------------------------------------- - const self_type& demultiply() + self_type& demultiply() { - if(a == base_mask) return *this; - if(a == 0) + if (a < base_mask) { - v = 0; - return *this; + if (a == 0) + { + v = 0; + } + else + { + calc_type v_ = (calc_type(v) * base_mask) / a; + v = value_type((v_ > base_mask) ? (value_type)base_mask : v_); + } } - calc_type v_ = (calc_type(v) * base_mask) / a; - v = value_type((v_ > base_mask) ? (value_type)base_mask : v_); return *this; } @@ -157,8 +376,8 @@ namespace agg { self_type ret; calc_type ik = uround(k * base_scale); - ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift)); - ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift)); + ret.v = lerp(v, c.v, ik); + ret.a = lerp(a, c.a, ik); return ret; } @@ -166,59 +385,34 @@ namespace agg AGG_INLINE void add(const self_type& c, unsigned cover) { calc_type cv, ca; - if(cover == cover_mask) + if (cover == cover_mask) { - if(c.a == base_mask) + if (c.a == base_mask) { *this = c; + return; } else { - cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv; - ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; + cv = v + c.v; + ca = a + c.a; } } else { - cv = v + ((c.v * cover + cover_mask/2) >> cover_shift); - ca = a + ((c.a * cover + cover_mask/2) >> cover_shift); - v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv; - a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; + cv = v + mult_cover(c.v, cover); + ca = a + mult_cover(c.a, cover); } + v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv); + a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); } //-------------------------------------------------------------------- static self_type no_color() { return self_type(0,0); } }; - - //-------------------------------------------------------------gray8_pre - inline gray8 gray8_pre(unsigned v, unsigned a = gray8::base_mask) - { - return gray8(v,a).premultiply(); - } - inline gray8 gray8_pre(const gray8& c, unsigned a) - { - return gray8(c,a).premultiply(); - } - inline gray8 gray8_pre(const rgba& c) - { - return gray8(c).premultiply(); - } - inline gray8 gray8_pre(const rgba& c, double a) - { - return gray8(c,a).premultiply(); - } - inline gray8 gray8_pre(const rgba8& c) - { - return gray8(c).premultiply(); - } - inline gray8 gray8_pre(const rgba8& c, unsigned a) - { - return gray8(c,a).premultiply(); - } - - + typedef gray8T gray8; + typedef gray8T sgray8; //==================================================================gray16 @@ -231,18 +425,46 @@ namespace agg { base_shift = 16, base_scale = 1 << base_shift, - base_mask = base_scale - 1 + base_mask = base_scale - 1, + base_MSB = 1 << (base_shift - 1) }; typedef gray16 self_type; value_type v; value_type a; + static value_type luminance(const rgba& c) + { + // Calculate grayscale value as per ITU-R BT.709. + return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask)); + } + + static value_type luminance(const rgba16& c) + { + // Calculate grayscale value as per ITU-R BT.709. + return value_type((13933u * c.r + 46872u * c.g + 4732u * c.b) >> 16); + } + + static value_type luminance(const rgba8& c) + { + return luminance(rgba16(c)); + } + + static value_type luminance(const srgba8& c) + { + return luminance(rgba16(c)); + } + + static value_type luminance(const rgba32& c) + { + return luminance(rgba(c)); + } + //-------------------------------------------------------------------- gray16() {} //-------------------------------------------------------------------- - gray16(unsigned v_, unsigned a_=base_mask) : + explicit gray16(unsigned v_, unsigned a_ = base_mask) : v(int16u(v_)), a(int16u(a_)) {} //-------------------------------------------------------------------- @@ -251,91 +473,231 @@ namespace agg //-------------------------------------------------------------------- gray16(const rgba& c) : - v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))), + v(luminance(c)), a((value_type)uround(c.a * double(base_mask))) {} //-------------------------------------------------------------------- - gray16(const rgba& c, double a_) : - v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))), - a((value_type)uround(a_ * double(base_mask))) {} + gray16(const rgba8& c) : + v(luminance(c)), + a((value_type(c.a) << 8) | c.a) {} //-------------------------------------------------------------------- - gray16(const rgba8& c) : - v(c.r*77 + c.g*150 + c.b*29), + gray16(const srgba8& c) : + v(luminance(c)), a((value_type(c.a) << 8) | c.a) {} //-------------------------------------------------------------------- - gray16(const rgba8& c, unsigned a_) : - v(c.r*77 + c.g*150 + c.b*29), - a((value_type(a_) << 8) | c.a) {} + gray16(const rgba16& c) : + v(luminance(c)), + a(c.a) {} + + //-------------------------------------------------------------------- + gray16(const gray8& c) : + v((value_type(c.v) << 8) | c.v), + a((value_type(c.a) << 8) | c.a) {} //-------------------------------------------------------------------- - void clear() + gray16(const sgray8& c) : + v(sRGB_conv::rgb_from_sRGB(c.v)), + a(sRGB_conv::alpha_from_sRGB(c.a)) {} + + //-------------------------------------------------------------------- + operator rgba8() const { - v = a = 0; + return rgba8(v >> 8, v >> 8, v >> 8, a >> 8); } //-------------------------------------------------------------------- - const self_type& transparent() + operator srgba8() const { - a = 0; - return *this; + value_type y = sRGB_conv::rgb_to_sRGB(v); + return srgba8(y, y, y, sRGB_conv::alpha_to_sRGB(a)); } //-------------------------------------------------------------------- - void opacity(double a_) + operator rgba16() const { - if(a_ < 0.0) a_ = 0.0; - if(a_ > 1.0) a_ = 1.0; - a = (value_type)uround(a_ * double(base_mask)); + return rgba16(v, v, v, a); + } + + //-------------------------------------------------------------------- + operator rgba32() const + { + rgba32::value_type v32 = v / 65535.0f; + return rgba32(v32, v32, v32, a / 65535.0f); + } + + //-------------------------------------------------------------------- + operator gray8() const + { + return gray8(v >> 8, a >> 8); } //-------------------------------------------------------------------- - double opacity() const + operator sgray8() const { - return double(a) / double(base_mask); + return sgray8( + sRGB_conv::rgb_to_sRGB(v), + sRGB_conv::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return double(a) / base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(uround(a * base_mask)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return base_mask; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a == 0; } + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a == base_mask; + } //-------------------------------------------------------------------- - const self_type& premultiply() + // Fixed-point multiply, exact over int16u. + static AGG_INLINE value_type multiply(value_type a, value_type b) { - if(a == base_mask) return *this; - if(a == 0) + calc_type t = a * b + base_MSB; + return value_type(((t >> base_shift) + t) >> base_shift); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + if (a * b == 0) + { + return 0; + } + else if (a >= b) { - v = 0; - return *this; + return base_mask; } - v = value_type((calc_type(v) * a) >> base_shift); + else return value_type((a * base_mask + (b >> 1)) / b); + } + + //-------------------------------------------------------------------- + template + static AGG_INLINE T downscale(T a) + { + return a >> base_shift; + } + + //-------------------------------------------------------------------- + template + static AGG_INLINE T downshift(T a, unsigned n) + { + return a >> n; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, almost exact over int16u. + // Specifically for multiplying a color component by a cover. + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return multiply(a, b << 8 | b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return mult_cover(b, a) >> 8; + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return p + q - multiply(p, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + int t = (q - p) * a + base_MSB - (p > q); + return value_type(p + (((t >> base_shift) + t) >> base_shift)); + } + + //-------------------------------------------------------------------- + self_type& clear() + { + v = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; return *this; } //-------------------------------------------------------------------- - const self_type& premultiply(unsigned a_) + self_type& opacity(double a_) { - if(a == base_mask && a_ >= base_mask) return *this; - if(a == 0 || a_ == 0) + if (a_ < 0) a_ = 0; + else if(a_ > 1) a_ = 1; + else a = (value_type)uround(a_ * double(base_mask)); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return double(a) / double(base_mask); + } + + + //-------------------------------------------------------------------- + self_type& premultiply() + { + if (a < base_mask) { - v = a = 0; - return *this; + if(a == 0) v = 0; + else v = multiply(v, a); } - calc_type v_ = (calc_type(v) * a_) / a; - v = value_type((v_ > a_) ? a_ : v_); - a = value_type(a_); return *this; } //-------------------------------------------------------------------- - const self_type& demultiply() + self_type& demultiply() { - if(a == base_mask) return *this; - if(a == 0) + if (a < base_mask) { - v = 0; - return *this; + if (a == 0) + { + v = 0; + } + else + { + calc_type v_ = (calc_type(v) * base_mask) / a; + v = value_type((v_ > base_mask) ? base_mask : v_); + } } - calc_type v_ = (calc_type(v) * base_mask) / a; - v = value_type((v_ > base_mask) ? base_mask : v_); return *this; } @@ -344,8 +706,8 @@ namespace agg { self_type ret; calc_type ik = uround(k * base_scale); - ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift)); - ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift)); + ret.v = lerp(v, c.v, ik); + ret.a = lerp(a, c.a, ik); return ret; } @@ -353,25 +715,26 @@ namespace agg AGG_INLINE void add(const self_type& c, unsigned cover) { calc_type cv, ca; - if(cover == cover_mask) + if (cover == cover_mask) { - if(c.a == base_mask) + if (c.a == base_mask) { *this = c; + return; } else { - cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv; - ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; + cv = v + c.v; + ca = a + c.a; } } else { - cv = v + ((c.v * cover + cover_mask/2) >> cover_shift); - ca = a + ((c.a * cover + cover_mask/2) >> cover_shift); - v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv; - a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; + cv = v + mult_cover(c.v, cover); + ca = a + mult_cover(c.a, cover); } + v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv); + a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); } //-------------------------------------------------------------------- @@ -379,33 +742,303 @@ namespace agg }; - //------------------------------------------------------------gray16_pre - inline gray16 gray16_pre(unsigned v, unsigned a = gray16::base_mask) - { - return gray16(v,a).premultiply(); - } - inline gray16 gray16_pre(const gray16& c, unsigned a) - { - return gray16(c,a).premultiply(); - } - inline gray16 gray16_pre(const rgba& c) - { - return gray16(c).premultiply(); - } - inline gray16 gray16_pre(const rgba& c, double a) + //===================================================================gray32 + struct gray32 { - return gray16(c,a).premultiply(); - } - inline gray16 gray16_pre(const rgba8& c) - { - return gray16(c).premultiply(); - } - inline gray16 gray16_pre(const rgba8& c, unsigned a) - { - return gray16(c,a).premultiply(); - } + typedef float value_type; + typedef double calc_type; + typedef double long_type; + typedef gray32 self_type; + + value_type v; + value_type a; + + // Calculate grayscale value as per ITU-R BT.709. + static value_type luminance(double r, double g, double b) + { + return value_type(0.2126 * r + 0.7152 * g + 0.0722 * b); + } + + static value_type luminance(const rgba& c) + { + return luminance(c.r, c.g, c.b); + } + + static value_type luminance(const rgba32& c) + { + return luminance(c.r, c.g, c.b); + } + + static value_type luminance(const rgba8& c) + { + return luminance(c.r / 255.0, c.g / 255.0, c.g / 255.0); + } + + static value_type luminance(const rgba16& c) + { + return luminance(c.r / 65535.0, c.g / 65535.0, c.g / 65535.0); + } + + //-------------------------------------------------------------------- + gray32() {} + + //-------------------------------------------------------------------- + explicit gray32(value_type v_, value_type a_ = 1) : + v(v_), a(a_) {} + + //-------------------------------------------------------------------- + gray32(const self_type& c, value_type a_) : + v(c.v), a(a_) {} + + //-------------------------------------------------------------------- + gray32(const rgba& c) : + v(luminance(c)), + a(value_type(c.a)) {} + + //-------------------------------------------------------------------- + gray32(const rgba8& c) : + v(luminance(c)), + a(value_type(c.a / 255.0)) {} + + //-------------------------------------------------------------------- + gray32(const srgba8& c) : + v(luminance(rgba32(c))), + a(value_type(c.a / 255.0)) {} + + //-------------------------------------------------------------------- + gray32(const rgba16& c) : + v(luminance(c)), + a(value_type(c.a / 65535.0)) {} + + //-------------------------------------------------------------------- + gray32(const rgba32& c) : + v(luminance(c)), + a(value_type(c.a)) {} + + //-------------------------------------------------------------------- + gray32(const gray8& c) : + v(value_type(c.v / 255.0)), + a(value_type(c.a / 255.0)) {} + + //-------------------------------------------------------------------- + gray32(const sgray8& c) : + v(sRGB_conv::rgb_from_sRGB(c.v)), + a(sRGB_conv::alpha_from_sRGB(c.a)) {} + + //-------------------------------------------------------------------- + gray32(const gray16& c) : + v(value_type(c.v / 65535.0)), + a(value_type(c.a / 65535.0)) {} + + //-------------------------------------------------------------------- + operator rgba() const + { + return rgba(v, v, v, a); + } + + //-------------------------------------------------------------------- + operator gray8() const + { + return gray8(uround(v * 255.0), uround(a * 255.0)); + } + + //-------------------------------------------------------------------- + operator sgray8() const + { + // Return (non-premultiplied) sRGB values. + return sgray8( + sRGB_conv::rgb_to_sRGB(v), + sRGB_conv::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + operator gray16() const + { + return gray16(uround(v * 65535.0), uround(a * 65535.0)); + } + //-------------------------------------------------------------------- + operator rgba8() const + { + rgba8::value_type y = uround(v * 255.0); + return rgba8(y, y, y, uround(a * 255.0)); + } + + //-------------------------------------------------------------------- + operator srgba8() const + { + srgba8::value_type y = sRGB_conv::rgb_to_sRGB(v); + return srgba8(y, y, y, sRGB_conv::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + operator rgba16() const + { + rgba16::value_type y = uround(v * 65535.0); + return rgba16(y, y, y, uround(a * 65535.0)); + } + + //-------------------------------------------------------------------- + operator rgba32() const + { + return rgba32(v, v, v, a); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(a); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return 1; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a <= 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a >= 1; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type invert(value_type x) + { + return 1 - x; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + return value_type(a * b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + return (b == 0) ? 0 : value_type(a / b); + } + + //-------------------------------------------------------------------- + template + static AGG_INLINE T downscale(T a) + { + return a; + } + + //-------------------------------------------------------------------- + template + static AGG_INLINE T downshift(T a, unsigned n) + { + return n > 0 ? a / (1 << n) : a; + } + //-------------------------------------------------------------------- + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return value_type(a * b / cover_mask); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return cover_type(uround(a * b)); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return (1 - a) * p + q; // more accurate than "p + q - p * a" + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + // The form "p + a * (q - p)" avoids a multiplication, but may produce an + // inaccurate result. For example, "p + (q - p)" may not be exactly equal + // to q. Therefore, stick to the basic expression, which at least produces + // the correct result at either extreme. + return (1 - a) * p + a * q; + } + + //-------------------------------------------------------------------- + self_type& clear() + { + v = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; + else a = value_type(a_); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return a; + } + + + //-------------------------------------------------------------------- + self_type& premultiply() + { + if (a < 0) v = 0; + else if(a < 1) v *= a; + return *this; + } + + //-------------------------------------------------------------------- + self_type& demultiply() + { + if (a < 0) v = 0; + else if (a < 1) v /= a; + return *this; + } + + //-------------------------------------------------------------------- + self_type gradient(self_type c, double k) const + { + return self_type( + value_type(v + (c.v - v) * k), + value_type(a + (c.a - a) * k)); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0); } + }; } diff --git a/extern/agg24/include/agg_color_rgba.h b/extern/agg24/include/agg_color_rgba.h index 7c088c695dcf..d8ef69a74fd9 100644 --- a/extern/agg24/include/agg_color_rgba.h +++ b/extern/agg24/include/agg_color_rgba.h @@ -26,17 +26,22 @@ #include #include "agg_basics.h" +#include "agg_gamma_lut.h" namespace agg { - // Supported byte orders for RGB and RGBA pixel formats + // Supported component orders for RGB and RGBA pixel formats //======================================================================= - struct order_rgb { enum rgb_e { R=0, G=1, B=2, rgb_tag }; }; //----order_rgb - struct order_bgr { enum bgr_e { B=0, G=1, R=2, rgb_tag }; }; //----order_bgr - struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, rgba_tag }; }; //----order_rgba - struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, rgba_tag }; }; //----order_argb - struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, rgba_tag }; }; //----order_abgr - struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, rgba_tag }; }; //----order_bgra + struct order_rgb { enum rgb_e { R=0, G=1, B=2, N=3 }; }; + struct order_bgr { enum bgr_e { B=0, G=1, R=2, N=3 }; }; + struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, N=4 }; }; + struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, N=4 }; }; + struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, N=4 }; }; + struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, N=4 }; }; + + // Colorspace tag types. + struct linear {}; + struct sRGB {}; //====================================================================rgba struct rgba @@ -59,24 +64,25 @@ namespace agg rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {} //-------------------------------------------------------------------- - void clear() + rgba& clear() { r = g = b = a = 0; + return *this; } //-------------------------------------------------------------------- - const rgba& transparent() + rgba& transparent() { - a = 0.0; + a = 0; return *this; } //-------------------------------------------------------------------- - const rgba& opacity(double a_) + rgba& opacity(double a_) { - if(a_ < 0.0) a_ = 0.0; - if(a_ > 1.0) a_ = 1.0; - a = a_; + if (a_ < 0) a_ = 0; + else if (a_ > 1) a_ = 1; + else a = a_; return *this; } @@ -87,7 +93,7 @@ namespace agg } //-------------------------------------------------------------------- - const rgba& premultiply() + rgba& premultiply() { r *= a; g *= a; @@ -96,33 +102,37 @@ namespace agg } //-------------------------------------------------------------------- - const rgba& premultiply(double a_) + rgba& premultiply(double a_) { - if(a <= 0.0 || a_ <= 0.0) + if (a <= 0 || a_ <= 0) + { + r = g = b = a = 0; + } + else { - r = g = b = a = 0.0; - return *this; + a_ /= a; + r *= a_; + g *= a_; + b *= a_; + a = a_; } - a_ /= a; - r *= a_; - g *= a_; - b *= a_; - a = a_; return *this; } //-------------------------------------------------------------------- - const rgba& demultiply() + rgba& demultiply() { - if(a == 0) + if (a == 0) { r = g = b = 0; - return *this; } - double a_ = 1.0 / a; - r *= a_; - g *= a_; - b *= a_; + else + { + double a_ = 1.0 / a; + r *= a_; + g *= a_; + b *= a_; + } return *this; } @@ -138,12 +148,30 @@ namespace agg return ret; } + rgba& operator+=(const rgba& c) + { + r += c.r; + g += c.g; + b += c.b; + a += c.a; + return *this; + } + + rgba& operator*=(double k) + { + r *= k; + g *= k; + b *= k; + a *= k; + return *this; + } + //-------------------------------------------------------------------- static rgba no_color() { return rgba(0,0,0,0); } //-------------------------------------------------------------------- static rgba from_wavelength(double wl, double gamma = 1.0); - + //-------------------------------------------------------------------- explicit rgba(double wavelen, double gamma=1.0) { @@ -152,18 +180,14 @@ namespace agg }; - //----------------------------------------------------------------rgba_pre - inline rgba rgba_pre(double r, double g, double b, double a=1.0) - { - return rgba(r, g, b, a).premultiply(); - } - inline rgba rgba_pre(const rgba& c) + inline rgba operator+(const rgba& a, const rgba& b) { - return rgba(c).premultiply(); + return rgba(a) += b; } - inline rgba rgba_pre(const rgba& c, double a) + + inline rgba operator*(const rgba& a, double b) { - return rgba(c, a).premultiply(); + return rgba(a) *= b; } //------------------------------------------------------------------------ @@ -171,44 +195,39 @@ namespace agg { rgba t(0.0, 0.0, 0.0); - if(wl >= 380.0 && wl <= 440.0) + if (wl >= 380.0 && wl <= 440.0) { t.r = -1.0 * (wl - 440.0) / (440.0 - 380.0); t.b = 1.0; } - else - if(wl >= 440.0 && wl <= 490.0) + else if (wl >= 440.0 && wl <= 490.0) { t.g = (wl - 440.0) / (490.0 - 440.0); t.b = 1.0; } - else - if(wl >= 490.0 && wl <= 510.0) + else if (wl >= 490.0 && wl <= 510.0) { t.g = 1.0; t.b = -1.0 * (wl - 510.0) / (510.0 - 490.0); } - else - if(wl >= 510.0 && wl <= 580.0) + else if (wl >= 510.0 && wl <= 580.0) { t.r = (wl - 510.0) / (580.0 - 510.0); t.g = 1.0; } - else - if(wl >= 580.0 && wl <= 645.0) + else if (wl >= 580.0 && wl <= 645.0) { t.r = 1.0; t.g = -1.0 * (wl - 645.0) / (645.0 - 580.0); } - else - if(wl >= 645.0 && wl <= 780.0) + else if (wl >= 645.0 && wl <= 780.0) { t.r = 1.0; } double s = 1.0; - if(wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0); - else if(wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0); + if (wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0); + else if (wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0); t.r = pow(t.r * s, gamma); t.g = pow(t.g * s, gamma); @@ -216,11 +235,15 @@ namespace agg return t; } - + inline rgba rgba_pre(double r, double g, double b, double a) + { + return rgba(r, g, b, a).premultiply(); + } //===================================================================rgba8 - struct rgba8 + template + struct rgba8T { typedef int8u value_type; typedef int32u calc_type; @@ -229,9 +252,10 @@ namespace agg { base_shift = 8, base_scale = 1 << base_shift, - base_mask = base_scale - 1 + base_mask = base_scale - 1, + base_MSB = 1 << (base_shift - 1) }; - typedef rgba8 self_type; + typedef rgba8T self_type; value_type r; @@ -239,53 +263,218 @@ namespace agg value_type b; value_type a; + static void convert(rgba8T& dst, const rgba8T& src) + { + dst.r = sRGB_conv::rgb_from_sRGB(src.r); + dst.g = sRGB_conv::rgb_from_sRGB(src.g); + dst.b = sRGB_conv::rgb_from_sRGB(src.b); + dst.a = src.a; + } + + static void convert(rgba8T& dst, const rgba8T& src) + { + dst.r = sRGB_conv::rgb_to_sRGB(src.r); + dst.g = sRGB_conv::rgb_to_sRGB(src.g); + dst.b = sRGB_conv::rgb_to_sRGB(src.b); + dst.a = src.a; + } + + static void convert(rgba8T& dst, const rgba& src) + { + dst.r = value_type(uround(src.r * base_mask)); + dst.g = value_type(uround(src.g * base_mask)); + dst.b = value_type(uround(src.b * base_mask)); + dst.a = value_type(uround(src.a * base_mask)); + } + + static void convert(rgba8T& dst, const rgba& src) + { + // Use the "float" table. + dst.r = sRGB_conv::rgb_to_sRGB(float(src.r)); + dst.g = sRGB_conv::rgb_to_sRGB(float(src.g)); + dst.b = sRGB_conv::rgb_to_sRGB(float(src.b)); + dst.a = sRGB_conv::alpha_to_sRGB(float(src.a)); + } + + static void convert(rgba& dst, const rgba8T& src) + { + dst.r = src.r / 255.0; + dst.g = src.g / 255.0; + dst.b = src.b / 255.0; + dst.a = src.a / 255.0; + } + + static void convert(rgba& dst, const rgba8T& src) + { + // Use the "float" table. + dst.r = sRGB_conv::rgb_from_sRGB(src.r); + dst.g = sRGB_conv::rgb_from_sRGB(src.g); + dst.b = sRGB_conv::rgb_from_sRGB(src.b); + dst.a = sRGB_conv::alpha_from_sRGB(src.a); + } + //-------------------------------------------------------------------- - rgba8() {} + rgba8T() {} //-------------------------------------------------------------------- - rgba8(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) : + rgba8T(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask) : r(value_type(r_)), g(value_type(g_)), b(value_type(b_)), a(value_type(a_)) {} //-------------------------------------------------------------------- - rgba8(const rgba& c, double a_) : - r((value_type)uround(c.r * double(base_mask))), - g((value_type)uround(c.g * double(base_mask))), - b((value_type)uround(c.b * double(base_mask))), - a((value_type)uround(a_ * double(base_mask))) {} + rgba8T(const rgba& c) + { + convert(*this, c); + } //-------------------------------------------------------------------- - rgba8(const self_type& c, unsigned a_) : + rgba8T(const self_type& c, unsigned a_) : r(c.r), g(c.g), b(c.b), a(value_type(a_)) {} //-------------------------------------------------------------------- - rgba8(const rgba& c) : - r((value_type)uround(c.r * double(base_mask))), - g((value_type)uround(c.g * double(base_mask))), - b((value_type)uround(c.b * double(base_mask))), - a((value_type)uround(c.a * double(base_mask))) {} + template + rgba8T(const rgba8T& c) + { + convert(*this, c); + } + + //-------------------------------------------------------------------- + operator rgba() const + { + rgba c; + convert(c, *this); + return c; + } //-------------------------------------------------------------------- - void clear() + static AGG_INLINE double to_double(value_type a) + { + return double(a) / base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(uround(a * base_mask)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return base_mask; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a == 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a == base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type invert(value_type x) + { + return base_mask - x; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int8u. + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + calc_type t = a * b + base_MSB; + return value_type(((t >> base_shift) + t) >> base_shift); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + if (a * b == 0) + { + return 0; + } + else if (a >= b) + { + return base_mask; + } + else return value_type((a * base_mask + (b >> 1)) / b); + } + + //-------------------------------------------------------------------- + template + static AGG_INLINE T downscale(T a) + { + return a >> base_shift; + } + + //-------------------------------------------------------------------- + template + static AGG_INLINE T downshift(T a, unsigned n) + { + return a >> n; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int8u. + // Specifically for multiplying a color component by a cover. + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return multiply(a, b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return multiply(b, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return p + q - multiply(p, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + int t = (q - p) * a + base_MSB - (p > q); + return value_type(p + (((t >> base_shift) + t) >> base_shift)); + } + + //-------------------------------------------------------------------- + self_type& clear() { r = g = b = a = 0; + return *this; } //-------------------------------------------------------------------- - const self_type& transparent() + self_type& transparent() { a = 0; return *this; } //-------------------------------------------------------------------- - const self_type& opacity(double a_) + self_type& opacity(double a_) { - if(a_ < 0.0) a_ = 0.0; - if(a_ > 1.0) a_ = 1.0; - a = (value_type)uround(a_ * double(base_mask)); + if (a_ < 0) a_ = 0; + else if (a_ > 1) a_ = 1; + else a = (value_type)uround(a_ * double(base_mask)); return *this; } @@ -296,54 +485,66 @@ namespace agg } //-------------------------------------------------------------------- - AGG_INLINE const self_type& premultiply() + AGG_INLINE self_type& premultiply() { - if(a == base_mask) return *this; - if(a == 0) + if (a != base_mask) { - r = g = b = 0; - return *this; + if (a == 0) + { + r = g = b = 0; + } + else + { + r = multiply(r, a); + g = multiply(g, a); + b = multiply(b, a); + } } - r = value_type((calc_type(r) * a) >> base_shift); - g = value_type((calc_type(g) * a) >> base_shift); - b = value_type((calc_type(b) * a) >> base_shift); return *this; } //-------------------------------------------------------------------- - AGG_INLINE const self_type& premultiply(unsigned a_) + AGG_INLINE self_type& premultiply(unsigned a_) { - if(a == base_mask && a_ >= base_mask) return *this; - if(a == 0 || a_ == 0) + if (a != base_mask || a_ < base_mask) { - r = g = b = a = 0; - return *this; + if (a == 0 || a_ == 0) + { + r = g = b = a = 0; + } + else + { + calc_type r_ = (calc_type(r) * a_) / a; + calc_type g_ = (calc_type(g) * a_) / a; + calc_type b_ = (calc_type(b) * a_) / a; + r = value_type((r_ > a_) ? a_ : r_); + g = value_type((g_ > a_) ? a_ : g_); + b = value_type((b_ > a_) ? a_ : b_); + a = value_type(a_); + } } - calc_type r_ = (calc_type(r) * a_) / a; - calc_type g_ = (calc_type(g) * a_) / a; - calc_type b_ = (calc_type(b) * a_) / a; - r = value_type((r_ > a_) ? a_ : r_); - g = value_type((g_ > a_) ? a_ : g_); - b = value_type((b_ > a_) ? a_ : b_); - a = value_type(a_); return *this; } //-------------------------------------------------------------------- - AGG_INLINE const self_type& demultiply() + AGG_INLINE self_type& demultiply() { - if(a == base_mask) return *this; - if(a == 0) + if (a < base_mask) { - r = g = b = 0; - return *this; + if (a == 0) + { + r = g = b = 0; + } + else + { + calc_type r_ = (calc_type(r) * base_mask) / a; + calc_type g_ = (calc_type(g) * base_mask) / a; + calc_type b_ = (calc_type(b) * base_mask) / a; + r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_); + g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_); + b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_); + } } - calc_type r_ = (calc_type(r) * base_mask) / a; - calc_type g_ = (calc_type(g) * base_mask) / a; - calc_type b_ = (calc_type(b) * base_mask) / a; - r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_); - g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_); - b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_); return *this; } @@ -351,11 +552,11 @@ namespace agg AGG_INLINE self_type gradient(const self_type& c, double k) const { self_type ret; - calc_type ik = uround(k * base_scale); - ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift)); - ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift)); - ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift)); - ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift)); + calc_type ik = uround(k * base_mask); + ret.r = lerp(r, c.r, ik); + ret.g = lerp(g, c.g, ik); + ret.b = lerp(b, c.b, ik); + ret.a = lerp(a, c.a, ik); return ret; } @@ -363,31 +564,32 @@ namespace agg AGG_INLINE void add(const self_type& c, unsigned cover) { calc_type cr, cg, cb, ca; - if(cover == cover_mask) + if (cover == cover_mask) { - if(c.a == base_mask) + if (c.a == base_mask) { *this = c; + return; } else { - cr = r + c.r; r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr; - cg = g + c.g; g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg; - cb = b + c.b; b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb; - ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; + cr = r + c.r; + cg = g + c.g; + cb = b + c.b; + ca = a + c.a; } } else { - cr = r + ((c.r * cover + cover_mask/2) >> cover_shift); - cg = g + ((c.g * cover + cover_mask/2) >> cover_shift); - cb = b + ((c.b * cover + cover_mask/2) >> cover_shift); - ca = a + ((c.a * cover + cover_mask/2) >> cover_shift); - r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr; - g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg; - b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb; - a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; + cr = r + mult_cover(c.r, cover); + cg = g + mult_cover(c.g, cover); + cb = b + mult_cover(c.b, cover); + ca = a + mult_cover(c.a, cover); } + r = (value_type)((cr > calc_type(base_mask)) ? calc_type(base_mask) : cr); + g = (value_type)((cg > calc_type(base_mask)) ? calc_type(base_mask) : cg); + b = (value_type)((cb > calc_type(base_mask)) ? calc_type(base_mask) : cb); + a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); } //-------------------------------------------------------------------- @@ -418,29 +620,8 @@ namespace agg } }; - - //-------------------------------------------------------------rgba8_pre - inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b, - unsigned a = rgba8::base_mask) - { - return rgba8(r,g,b,a).premultiply(); - } - inline rgba8 rgba8_pre(const rgba8& c) - { - return rgba8(c).premultiply(); - } - inline rgba8 rgba8_pre(const rgba8& c, unsigned a) - { - return rgba8(c,a).premultiply(); - } - inline rgba8 rgba8_pre(const rgba& c) - { - return rgba8(c).premultiply(); - } - inline rgba8 rgba8_pre(const rgba& c, double a) - { - return rgba8(c,a).premultiply(); - } + typedef rgba8T rgba8; + typedef rgba8T srgba8; //-------------------------------------------------------------rgb8_packed @@ -477,8 +658,6 @@ namespace agg - - //==================================================================rgba16 struct rgba16 { @@ -489,7 +668,8 @@ namespace agg { base_shift = 16, base_scale = 1 << base_shift, - base_mask = base_scale - 1 + base_mask = base_scale - 1, + base_MSB = 1 << (base_shift - 1) }; typedef rgba16 self_type; @@ -519,13 +699,6 @@ namespace agg b((value_type)uround(c.b * double(base_mask))), a((value_type)uround(c.a * double(base_mask))) {} - //-------------------------------------------------------------------- - rgba16(const rgba& c, double a_) : - r((value_type)uround(c.r * double(base_mask))), - g((value_type)uround(c.g * double(base_mask))), - b((value_type)uround(c.b * double(base_mask))), - a((value_type)uround(a_ * double(base_mask))) {} - //-------------------------------------------------------------------- rgba16(const rgba8& c) : r(value_type((value_type(c.r) << 8) | c.r)), @@ -534,31 +707,166 @@ namespace agg a(value_type((value_type(c.a) << 8) | c.a)) {} //-------------------------------------------------------------------- - rgba16(const rgba8& c, unsigned a_) : - r(value_type((value_type(c.r) << 8) | c.r)), - g(value_type((value_type(c.g) << 8) | c.g)), - b(value_type((value_type(c.b) << 8) | c.b)), - a(value_type(( a_ << 8) | c.a)) {} + rgba16(const srgba8& c) : + r(sRGB_conv::rgb_from_sRGB(c.r)), + g(sRGB_conv::rgb_from_sRGB(c.g)), + b(sRGB_conv::rgb_from_sRGB(c.b)), + a(sRGB_conv::alpha_from_sRGB(c.a)) {} + + //-------------------------------------------------------------------- + operator rgba() const + { + return rgba( + r / 65535.0, + g / 65535.0, + b / 65535.0, + a / 65535.0); + } + + //-------------------------------------------------------------------- + operator rgba8() const + { + return rgba8(r >> 8, g >> 8, b >> 8, a >> 8); + } + + //-------------------------------------------------------------------- + operator srgba8() const + { + // Return (non-premultiplied) sRGB values. + return srgba8( + sRGB_conv::rgb_to_sRGB(r), + sRGB_conv::rgb_to_sRGB(g), + sRGB_conv::rgb_to_sRGB(b), + sRGB_conv::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return double(a) / base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(uround(a * base_mask)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return base_mask; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a == 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a == base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type invert(value_type x) + { + return base_mask - x; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int16u. + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + calc_type t = a * b + base_MSB; + return value_type(((t >> base_shift) + t) >> base_shift); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + if (a * b == 0) + { + return 0; + } + else if (a >= b) + { + return base_mask; + } + else return value_type((a * base_mask + (b >> 1)) / b); + } //-------------------------------------------------------------------- - void clear() + template + static AGG_INLINE T downscale(T a) + { + return a >> base_shift; + } + + //-------------------------------------------------------------------- + template + static AGG_INLINE T downshift(T a, unsigned n) + { + return a >> n; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, almost exact over int16u. + // Specifically for multiplying a color component by a cover. + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return multiply(a, (b << 8) | b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return multiply((a << 8) | a, b) >> 8; + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return p + q - multiply(p, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + int t = (q - p) * a + base_MSB - (p > q); + return value_type(p + (((t >> base_shift) + t) >> base_shift)); + } + + //-------------------------------------------------------------------- + self_type& clear() { r = g = b = a = 0; + return *this; } //-------------------------------------------------------------------- - const self_type& transparent() + self_type& transparent() { a = 0; return *this; } //-------------------------------------------------------------------- - AGG_INLINE const self_type& opacity(double a_) + AGG_INLINE self_type& opacity(double a_) { - if(a_ < 0.0) a_ = 0.0; - if(a_ > 1.0) a_ = 1.0; - a = (value_type)uround(a_ * double(base_mask)); + if (a_ < 0) a_ = 0; + if (a_ > 1) a_ = 1; + a = value_type(uround(a_ * double(base_mask))); return *this; } @@ -569,54 +877,66 @@ namespace agg } //-------------------------------------------------------------------- - AGG_INLINE const self_type& premultiply() + AGG_INLINE self_type& premultiply() { - if(a == base_mask) return *this; - if(a == 0) + if (a != base_mask) { - r = g = b = 0; - return *this; + if (a == 0) + { + r = g = b = 0; + } + else + { + r = multiply(r, a); + g = multiply(g, a); + b = multiply(b, a); + } } - r = value_type((calc_type(r) * a) >> base_shift); - g = value_type((calc_type(g) * a) >> base_shift); - b = value_type((calc_type(b) * a) >> base_shift); return *this; } //-------------------------------------------------------------------- - AGG_INLINE const self_type& premultiply(unsigned a_) + AGG_INLINE self_type& premultiply(unsigned a_) { - if(a == base_mask && a_ >= base_mask) return *this; - if(a == 0 || a_ == 0) + if (a < base_mask || a_ < base_mask) { - r = g = b = a = 0; - return *this; + if (a == 0 || a_ == 0) + { + r = g = b = a = 0; + } + else + { + calc_type r_ = (calc_type(r) * a_) / a; + calc_type g_ = (calc_type(g) * a_) / a; + calc_type b_ = (calc_type(b) * a_) / a; + r = value_type((r_ > a_) ? a_ : r_); + g = value_type((g_ > a_) ? a_ : g_); + b = value_type((b_ > a_) ? a_ : b_); + a = value_type(a_); + } } - calc_type r_ = (calc_type(r) * a_) / a; - calc_type g_ = (calc_type(g) * a_) / a; - calc_type b_ = (calc_type(b) * a_) / a; - r = value_type((r_ > a_) ? a_ : r_); - g = value_type((g_ > a_) ? a_ : g_); - b = value_type((b_ > a_) ? a_ : b_); - a = value_type(a_); return *this; } //-------------------------------------------------------------------- - AGG_INLINE const self_type& demultiply() + AGG_INLINE self_type& demultiply() { - if(a == base_mask) return *this; - if(a == 0) + if (a < base_mask) { - r = g = b = 0; - return *this; + if (a == 0) + { + r = g = b = 0; + } + else + { + calc_type r_ = (calc_type(r) * base_mask) / a; + calc_type g_ = (calc_type(g) * base_mask) / a; + calc_type b_ = (calc_type(b) * base_mask) / a; + r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_); + g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_); + b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_); + } } - calc_type r_ = (calc_type(r) * base_mask) / a; - calc_type g_ = (calc_type(g) * base_mask) / a; - calc_type b_ = (calc_type(b) * base_mask) / a; - r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_); - g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_); - b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_); return *this; } @@ -624,11 +944,11 @@ namespace agg AGG_INLINE self_type gradient(const self_type& c, double k) const { self_type ret; - calc_type ik = uround(k * base_scale); - ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift)); - ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift)); - ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift)); - ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift)); + calc_type ik = uround(k * base_mask); + ret.r = lerp(r, c.r, ik); + ret.g = lerp(g, c.g, ik); + ret.b = lerp(b, c.b, ik); + ret.a = lerp(a, c.a, ik); return ret; } @@ -636,31 +956,32 @@ namespace agg AGG_INLINE void add(const self_type& c, unsigned cover) { calc_type cr, cg, cb, ca; - if(cover == cover_mask) + if (cover == cover_mask) { - if(c.a == base_mask) + if (c.a == base_mask) { *this = c; + return; } else { - cr = r + c.r; r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr; - cg = g + c.g; g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg; - cb = b + c.b; b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb; - ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; + cr = r + c.r; + cg = g + c.g; + cb = b + c.b; + ca = a + c.a; } } else { - cr = r + ((c.r * cover + cover_mask) >> cover_shift); - cg = g + ((c.g * cover + cover_mask) >> cover_shift); - cb = b + ((c.b * cover + cover_mask) >> cover_shift); - ca = a + ((c.a * cover + cover_mask) >> cover_shift); - r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr; - g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg; - b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb; - a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca; + cr = r + mult_cover(c.r, cover); + cg = g + mult_cover(c.g, cover); + cb = b + mult_cover(c.b, cover); + ca = a + mult_cover(c.a, cover); } + r = (value_type)((cr > calc_type(base_mask)) ? calc_type(base_mask) : cr); + g = (value_type)((cg > calc_type(base_mask)) ? calc_type(base_mask) : cg); + b = (value_type)((cb > calc_type(base_mask)) ? calc_type(base_mask) : cb); + a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); } //-------------------------------------------------------------------- @@ -692,35 +1013,6 @@ namespace agg }; - - //--------------------------------------------------------------rgba16_pre - inline rgba16 rgba16_pre(unsigned r, unsigned g, unsigned b, - unsigned a = rgba16::base_mask) - { - return rgba16(r,g,b,a).premultiply(); - } - inline rgba16 rgba16_pre(const rgba16& c, unsigned a) - { - return rgba16(c,a).premultiply(); - } - inline rgba16 rgba16_pre(const rgba& c) - { - return rgba16(c).premultiply(); - } - inline rgba16 rgba16_pre(const rgba& c, double a) - { - return rgba16(c,a).premultiply(); - } - inline rgba16 rgba16_pre(const rgba8& c) - { - return rgba16(c).premultiply(); - } - inline rgba16 rgba16_pre(const rgba8& c, unsigned a) - { - return rgba16(c,a).premultiply(); - } - - //------------------------------------------------------rgba16_gamma_dir template rgba16 rgba16_gamma_dir(rgba16 c, const GammaLUT& gamma) @@ -735,7 +1027,325 @@ namespace agg return rgba16(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a); } + //====================================================================rgba32 + struct rgba32 + { + typedef float value_type; + typedef double calc_type; + typedef double long_type; + typedef rgba32 self_type; + + value_type r; + value_type g; + value_type b; + value_type a; + + //-------------------------------------------------------------------- + rgba32() {} + + //-------------------------------------------------------------------- + rgba32(value_type r_, value_type g_, value_type b_, value_type a_= 1) : + r(r_), g(g_), b(b_), a(a_) {} + + //-------------------------------------------------------------------- + rgba32(const self_type& c, float a_) : + r(c.r), g(c.g), b(c.b), a(a_) {} + + //-------------------------------------------------------------------- + rgba32(const rgba& c) : + r(value_type(c.r)), g(value_type(c.g)), b(value_type(c.b)), a(value_type(c.a)) {} + + //-------------------------------------------------------------------- + rgba32(const rgba8& c) : + r(value_type(c.r / 255.0)), + g(value_type(c.g / 255.0)), + b(value_type(c.b / 255.0)), + a(value_type(c.a / 255.0)) {} + + //-------------------------------------------------------------------- + rgba32(const srgba8& c) : + r(sRGB_conv::rgb_from_sRGB(c.r)), + g(sRGB_conv::rgb_from_sRGB(c.g)), + b(sRGB_conv::rgb_from_sRGB(c.b)), + a(sRGB_conv::alpha_from_sRGB(c.a)) {} + + //-------------------------------------------------------------------- + rgba32(const rgba16& c) : + r(value_type(c.r / 65535.0)), + g(value_type(c.g / 65535.0)), + b(value_type(c.b / 65535.0)), + a(value_type(c.a / 65535.0)) {} + + //-------------------------------------------------------------------- + operator rgba() const + { + return rgba(r, g, b, a); + } + + //-------------------------------------------------------------------- + operator rgba8() const + { + return rgba8( + uround(r * 255.0), + uround(g * 255.0), + uround(b * 255.0), + uround(a * 255.0)); + } + + //-------------------------------------------------------------------- + operator srgba8() const + { + return srgba8( + sRGB_conv::rgb_to_sRGB(r), + sRGB_conv::rgb_to_sRGB(g), + sRGB_conv::rgb_to_sRGB(b), + sRGB_conv::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + operator rgba16() const + { + return rgba8( + uround(r * 65535.0), + uround(g * 65535.0), + uround(b * 65535.0), + uround(a * 65535.0)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(a); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return 1; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a <= 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a >= 1; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type invert(value_type x) + { + return 1 - x; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + return value_type(a * b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + return (b == 0) ? 0 : value_type(a / b); + } + + //-------------------------------------------------------------------- + template + static AGG_INLINE T downscale(T a) + { + return a; + } + + //-------------------------------------------------------------------- + template + static AGG_INLINE T downshift(T a, unsigned n) + { + return n > 0 ? a / (1 << n) : a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return value_type(a * b / cover_mask); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return cover_type(uround(a * b)); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return (1 - a) * p + q; // more accurate than "p + q - p * a" + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + // The form "p + a * (q - p)" avoids a multiplication, but may produce an + // inaccurate result. For example, "p + (q - p)" may not be exactly equal + // to q. Therefore, stick to the basic expression, which at least produces + // the correct result at either extreme. + return (1 - a) * p + a * q; + } + + //-------------------------------------------------------------------- + self_type& clear() + { + r = g = b = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& opacity(double a_) + { + if (a_ < 0) a_ = 0; + else if (a_ > 1) a_ = 1; + else a = value_type(a_); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return a; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& premultiply() + { + if (a < 1) + { + if (a <= 0) + { + r = g = b = 0; + } + else + { + r *= a; + g *= a; + b *= a; + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& demultiply() + { + if (a < 1) + { + if (a <= 0) + { + r = g = b = 0; + } + else + { + r /= a; + g /= a; + b /= a; + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type gradient(const self_type& c, double k) const + { + self_type ret; + ret.r = value_type(r + (c.r - r) * k); + ret.g = value_type(g + (c.g - g) * k); + ret.b = value_type(b + (c.b - b) * k); + ret.a = value_type(a + (c.a - a) * k); + return ret; + } + + //-------------------------------------------------------------------- + AGG_INLINE void add(const self_type& c, unsigned cover) + { + if (cover == cover_mask) + { + if (c.is_opaque()) + { + *this = c; + return; + } + else + { + r += c.r; + g += c.g; + b += c.b; + a += c.a; + } + } + else + { + r += mult_cover(c.r, cover); + g += mult_cover(c.g, cover); + b += mult_cover(c.b, cover); + a += mult_cover(c.a, cover); + } + if (a > 1) a = 1; + if (r > a) r = a; + if (g > a) g = a; + if (b > a) b = a; + } + + //-------------------------------------------------------------------- + template + AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) + { + r = gamma.dir(r); + g = gamma.dir(g); + b = gamma.dir(b); + } + //-------------------------------------------------------------------- + template + AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma) + { + r = gamma.inv(r); + g = gamma.inv(g); + b = gamma.inv(b); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0,0,0); } + + //-------------------------------------------------------------------- + static self_type from_wavelength(double wl, double gamma = 1) + { + return self_type(rgba::from_wavelength(wl, gamma)); + } + }; } diff --git a/extern/agg24/include/agg_config.h b/extern/agg24/include/agg_config.h index 81c75f124a21..fa1dae2ba7b8 100644 --- a/extern/agg24/include/agg_config.h +++ b/extern/agg24/include/agg_config.h @@ -37,7 +37,7 @@ // Provides cheaper creation and destruction (no mem allocs): // #define AGG_RENDERING_BUFFER row_accessor // -// You can still use both of them simultaneouslyin your applications +// You can still use both of them simultaneously in your applications // This #define is used only for default rendering_buffer type, // in short hand typedefs like pixfmt_rgba32. diff --git a/extern/agg24/include/agg_conv_curve.h b/extern/agg24/include/agg_conv_curve.h index aeb4fdaa5274..d5b475de7a12 100644 --- a/extern/agg24/include/agg_conv_curve.h +++ b/extern/agg24/include/agg_conv_curve.h @@ -2,8 +2,8 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-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. +// 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. // @@ -28,31 +28,31 @@ namespace agg //---------------------------------------------------------------conv_curve - // Curve converter class. Any path storage can have Bezier curves defined - // by their control points. There're two types of curves supported: curve3 + // Curve converter class. Any path storage can have Bezier curves defined + // by their control points. There're two types of curves supported: curve3 // and curve4. Curve3 is a conic Bezier curve with 2 endpoints and 1 control // point. Curve4 has 2 control points (4 points in total) and can be used - // to interpolate more complicated curves. Curve4, unlike curve3 can be used - // to approximate arcs, both circular and elliptical. Curves are approximated - // with straight lines and one of the approaches is just to store the whole - // sequence of vertices that approximate our curve. It takes additional - // memory, and at the same time the consecutive vertices can be calculated - // on demand. + // to interpolate more complicated curves. Curve4, unlike curve3 can be used + // to approximate arcs, both circular and elliptical. Curves are approximated + // with straight lines and one of the approaches is just to store the whole + // sequence of vertices that approximate our curve. It takes additional + // memory, and at the same time the consecutive vertices can be calculated + // on demand. // // Initially, path storages are not suppose to keep all the vertices of the // curves (although, nothing prevents us from doing so). Instead, path_storage // keeps only vertices, needed to calculate a curve on demand. Those vertices - // are marked with special commands. So, if the path_storage contains curves - // (which are not real curves yet), and we render this storage directly, - // all we will see is only 2 or 3 straight line segments (for curve3 and - // curve4 respectively). If we need to see real curves drawn we need to - // include this class into the conversion pipeline. + // are marked with special commands. So, if the path_storage contains curves + // (which are not real curves yet), and we render this storage directly, + // all we will see is only 2 or 3 straight line segments (for curve3 and + // curve4 respectively). If we need to see real curves drawn we need to + // include this class into the conversion pipeline. // - // Class conv_curve recognizes commands path_cmd_curve3 and path_cmd_curve4 - // and converts these vertices into a move_to/line_to sequence. + // Class conv_curve recognizes commands path_cmd_curve3 and path_cmd_curve4 + // and converts these vertices into a move_to/line_to sequence. //----------------------------------------------------------------------- - template class conv_curve { public: @@ -64,51 +64,51 @@ namespace agg m_source(&source), m_last_x(0.0), m_last_y(0.0) {} void attach(VertexSource& source) { m_source = &source; } - void approximation_method(curve_approximation_method_e v) - { + void approximation_method(curve_approximation_method_e v) + { m_curve3.approximation_method(v); m_curve4.approximation_method(v); } - curve_approximation_method_e approximation_method() const - { + curve_approximation_method_e approximation_method() const + { return m_curve4.approximation_method(); } - void approximation_scale(double s) - { - m_curve3.approximation_scale(s); - m_curve4.approximation_scale(s); + void approximation_scale(double s) + { + m_curve3.approximation_scale(s); + m_curve4.approximation_scale(s); } - double approximation_scale() const - { - return m_curve4.approximation_scale(); + double approximation_scale() const + { + return m_curve4.approximation_scale(); } - void angle_tolerance(double v) - { - m_curve3.angle_tolerance(v); - m_curve4.angle_tolerance(v); + void angle_tolerance(double v) + { + m_curve3.angle_tolerance(v); + m_curve4.angle_tolerance(v); } - double angle_tolerance() const - { - return m_curve4.angle_tolerance(); + double angle_tolerance() const + { + return m_curve4.angle_tolerance(); } - void cusp_limit(double v) - { - m_curve3.cusp_limit(v); - m_curve4.cusp_limit(v); + void cusp_limit(double v) + { + m_curve3.cusp_limit(v); + m_curve4.cusp_limit(v); } - double cusp_limit() const - { - return m_curve4.cusp_limit(); + double cusp_limit() const + { + return m_curve4.cusp_limit(); } - void rewind(unsigned path_id); + void rewind(unsigned path_id); unsigned vertex(double* x, double* y); private: @@ -154,10 +154,10 @@ namespace agg return path_cmd_line_to; } - double ct2_x = 0.0; - double ct2_y = 0.0; - double end_x = 0.0; - double end_y = 0.0; + double ct2_x; + double ct2_y; + double end_x; + double end_y; unsigned cmd = m_source->vertex(x, y); switch(cmd) @@ -165,8 +165,8 @@ namespace agg case path_cmd_curve3: m_source->vertex(&end_x, &end_y); - m_curve3.init(m_last_x, m_last_y, - *x, *y, + m_curve3.init(m_last_x, m_last_y, + *x, *y, end_x, end_y); m_curve3.vertex(x, y); // First call returns path_cmd_move_to @@ -178,9 +178,9 @@ namespace agg m_source->vertex(&ct2_x, &ct2_y); m_source->vertex(&end_x, &end_y); - m_curve4.init(m_last_x, m_last_y, - *x, *y, - ct2_x, ct2_y, + m_curve4.init(m_last_x, m_last_y, + *x, *y, + ct2_x, ct2_y, end_x, end_y); m_curve4.vertex(x, y); // First call returns path_cmd_move_to diff --git a/extern/agg24/include/agg_conv_transform.h b/extern/agg24/include/agg_conv_transform.h index 1710877481d4..0c88a245bda6 100644 --- a/extern/agg24/include/agg_conv_transform.h +++ b/extern/agg24/include/agg_conv_transform.h @@ -29,7 +29,7 @@ namespace agg template class conv_transform { public: - conv_transform(VertexSource& source, const Transformer& tr) : + conv_transform(VertexSource& source, Transformer& tr) : m_source(&source), m_trans(&tr) {} void attach(VertexSource& source) { m_source = &source; } @@ -48,7 +48,7 @@ namespace agg return cmd; } - void transformer(const Transformer& tr) + void transformer(Transformer& tr) { m_trans = &tr; } @@ -59,7 +59,7 @@ namespace agg operator = (const conv_transform&); VertexSource* m_source; - const Transformer* m_trans; + Transformer* m_trans; }; diff --git a/extern/agg24/include/agg_font_cache_manager2.h b/extern/agg24/include/agg_font_cache_manager2.h new file mode 100644 index 000000000000..75d311eff791 --- /dev/null +++ b/extern/agg24/include/agg_font_cache_manager2.h @@ -0,0 +1,311 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_FONT_CACHE_MANAGER2_INCLUDED +#define AGG_FONT_CACHE_MANAGER2_INCLUDED + +#include +#include +#include +#include "agg_array.h" + +namespace agg { + +namespace fman { + //---------------------------------------------------------glyph_data_type + enum glyph_data_type + { + glyph_data_invalid = 0, + glyph_data_mono = 1, + glyph_data_gray8 = 2, + glyph_data_outline = 3 + }; + + + //-------------------------------------------------------------cached_glyph + struct cached_glyph + { + void * cached_font; + unsigned glyph_code; + unsigned glyph_index; + int8u* data; + unsigned data_size; + glyph_data_type data_type; + rect_i bounds; + double advance_x; + double advance_y; + }; + + + //--------------------------------------------------------------cached_glyphs + class cached_glyphs + { + public: + enum block_size_e { block_size = 16384-16 }; + + //-------------------------------------------------------------------- + cached_glyphs() + : m_allocator(block_size) + { memset(m_glyphs, 0, sizeof(m_glyphs)); } + + //-------------------------------------------------------------------- + const cached_glyph* find_glyph(unsigned glyph_code) const + { + unsigned msb = (glyph_code >> 8) & 0xFF; + if(m_glyphs[msb]) + { + return m_glyphs[msb][glyph_code & 0xFF]; + } + return 0; + } + + //-------------------------------------------------------------------- + cached_glyph* cache_glyph( + void * cached_font, + unsigned glyph_code, + unsigned glyph_index, + unsigned data_size, + glyph_data_type data_type, + const rect_i& bounds, + double advance_x, + double advance_y) + { + unsigned msb = (glyph_code >> 8) & 0xFF; + if(m_glyphs[msb] == 0) + { + m_glyphs[msb] = + (cached_glyph**)m_allocator.allocate(sizeof(cached_glyph*) * 256, + sizeof(cached_glyph*)); + memset(m_glyphs[msb], 0, sizeof(cached_glyph*) * 256); + } + + unsigned lsb = glyph_code & 0xFF; + if(m_glyphs[msb][lsb]) return 0; // Already exists, do not overwrite + + cached_glyph* glyph = + (cached_glyph*)m_allocator.allocate(sizeof(cached_glyph), + sizeof(double)); + + glyph->cached_font = cached_font; + glyph->glyph_code = glyph_code; + glyph->glyph_index = glyph_index; + glyph->data = m_allocator.allocate(data_size); + glyph->data_size = data_size; + glyph->data_type = data_type; + glyph->bounds = bounds; + glyph->advance_x = advance_x; + glyph->advance_y = advance_y; + return m_glyphs[msb][lsb] = glyph; + } + + private: + block_allocator m_allocator; + cached_glyph** m_glyphs[256]; + }; + + + + //------------------------------------------------------------------------ + enum glyph_rendering + { + glyph_ren_native_mono, + glyph_ren_native_gray8, + glyph_ren_outline, + glyph_ren_agg_mono, + glyph_ren_agg_gray8 + }; + + + + + //------------------------------------------------------font_cache_manager + template class font_cache_manager + { + public: + typedef FontEngine font_engine_type; + typedef font_cache_manager self_type; + typedef typename font_engine_type::path_adaptor_type path_adaptor_type; + typedef typename font_engine_type::gray8_adaptor_type gray8_adaptor_type; + typedef typename gray8_adaptor_type::embedded_scanline gray8_scanline_type; + typedef typename font_engine_type::mono_adaptor_type mono_adaptor_type; + typedef typename mono_adaptor_type::embedded_scanline mono_scanline_type; + + struct cached_font + { + cached_font( + font_engine_type& engine, + typename FontEngine::loaded_face *face, + double height, + double width, + bool hinting, + glyph_rendering rendering ) + : m_engine( engine ) + , m_face( face ) + , m_height( height ) + , m_width( width ) + , m_hinting( hinting ) + , m_rendering( rendering ) + { + select_face(); + m_face_height=m_face->height(); + m_face_width=m_face->width(); + m_face_ascent=m_face->ascent(); + m_face_descent=m_face->descent(); + m_face_ascent_b=m_face->ascent_b(); + m_face_descent_b=m_face->descent_b(); + } + + double height() const + { + return m_face_height; + } + + double width() const + { + return m_face_width; + } + + double ascent() const + { + return m_face_ascent; + } + + double descent() const + { + return m_face_descent; + } + + double ascent_b() const + { + return m_face_ascent_b; + } + + double descent_b() const + { + return m_face_descent_b; + } + + bool add_kerning( const cached_glyph *first, const cached_glyph *second, double* x, double* y) + { + if( !first || !second ) + return false; + select_face(); + return m_face->add_kerning( + first->glyph_index, second->glyph_index, x, y ); + } + + void select_face() + { + m_face->select_instance( m_height, m_width, m_hinting, m_rendering ); + } + + const cached_glyph *get_glyph(unsigned cp) + { + const cached_glyph *glyph=m_glyphs.find_glyph(cp); + if( glyph==0 ) + { + typename FontEngine::prepared_glyph prepared; + select_face(); + bool success=m_face->prepare_glyph(cp, &prepared); + if( success ) + { + glyph=m_glyphs.cache_glyph( + this, + prepared.glyph_code, + prepared.glyph_index, + prepared.data_size, + prepared.data_type, + prepared.bounds, + prepared.advance_x, + prepared.advance_y ); + assert( glyph!=0 ); + m_face->write_glyph_to(&prepared,glyph->data); + } + } + return glyph; + } + + font_engine_type& m_engine; + typename FontEngine::loaded_face *m_face; + double m_height; + double m_width; + bool m_hinting; + glyph_rendering m_rendering; + double m_face_height; + double m_face_width; + double m_face_ascent; + double m_face_descent; + double m_face_ascent_b; + double m_face_descent_b; + cached_glyphs m_glyphs; + }; + + //-------------------------------------------------------------------- + font_cache_manager(font_engine_type& engine, unsigned max_fonts=32) + :m_engine(engine) + { } + + //-------------------------------------------------------------------- + void init_embedded_adaptors(const cached_glyph* gl, + double x, double y, + double scale=1.0) + { + if(gl) + { + switch(gl->data_type) + { + default: return; + case glyph_data_mono: + m_mono_adaptor.init(gl->data, gl->data_size, x, y); + break; + + case glyph_data_gray8: + m_gray8_adaptor.init(gl->data, gl->data_size, x, y); + break; + + case glyph_data_outline: + m_path_adaptor.init(gl->data, gl->data_size, x, y, scale); + break; + } + } + } + + + //-------------------------------------------------------------------- + path_adaptor_type& path_adaptor() { return m_path_adaptor; } + gray8_adaptor_type& gray8_adaptor() { return m_gray8_adaptor; } + gray8_scanline_type& gray8_scanline() { return m_gray8_scanline; } + mono_adaptor_type& mono_adaptor() { return m_mono_adaptor; } + mono_scanline_type& mono_scanline() { return m_mono_scanline; } + + + private: + //-------------------------------------------------------------------- + font_cache_manager(const self_type&); + const self_type& operator = (const self_type&); + + font_engine_type& m_engine; + path_adaptor_type m_path_adaptor; + gray8_adaptor_type m_gray8_adaptor; + gray8_scanline_type m_gray8_scanline; + mono_adaptor_type m_mono_adaptor; + mono_scanline_type m_mono_scanline; + }; + +} +} + +#endif + diff --git a/extern/agg24/include/agg_gamma_functions.h b/extern/agg24/include/agg_gamma_functions.h index 45facac00c2a..5d720daa9a71 100644 --- a/extern/agg24/include/agg_gamma_functions.h +++ b/extern/agg24/include/agg_gamma_functions.h @@ -115,6 +115,15 @@ namespace agg double m_mul; }; + inline double sRGB_to_linear(double x) + { + return (x <= 0.04045) ? (x / 12.92) : pow((x + 0.055) / (1.055), 2.4); + } + + inline double linear_to_sRGB(double x) + { + return (x <= 0.0031308) ? (x * 12.92) : (1.055 * pow(x, 1 / 2.4) - 0.055); + } } #endif diff --git a/extern/agg24/include/agg_gamma_lut.h b/extern/agg24/include/agg_gamma_lut.h index c3e8dfc13903..ef1e38d80926 100644 --- a/extern/agg24/include/agg_gamma_lut.h +++ b/extern/agg24/include/agg_gamma_lut.h @@ -18,6 +18,7 @@ #include #include "agg_basics.h" +#include "agg_gamma_functions.h" namespace agg { @@ -116,6 +117,189 @@ namespace agg HiResT* m_dir_gamma; LoResT* m_inv_gamma; }; + + // + // sRGB support classes + // + + // Optimized sRGB lookup table. The direct conversion (sRGB to linear) + // is a straightforward lookup. The inverse conversion (linear to sRGB) + // is implemented using binary search. + template + class sRGB_lut_base + { + public: + LinearType dir(int8u v) const + { + return m_dir_table[v]; + } + + int8u inv(LinearType v) const + { + // Unrolled binary search. + int8u x = 0; + if (v > m_inv_table[128]) x = 128; + if (v > m_inv_table[x + 64]) x += 64; + if (v > m_inv_table[x + 32]) x += 32; + if (v > m_inv_table[x + 16]) x += 16; + if (v > m_inv_table[x + 8]) x += 8; + if (v > m_inv_table[x + 4]) x += 4; + if (v > m_inv_table[x + 2]) x += 2; + if (v > m_inv_table[x + 1]) x += 1; + return x; + } + + protected: + LinearType m_dir_table[256]; + LinearType m_inv_table[256]; + + // Only derived classes may instantiate. + sRGB_lut_base() + { + } + }; + + // sRGB_lut - implements sRGB conversion for the various types. + // Base template is undefined, specializations are provided below. + template + class sRGB_lut; + + template<> + class sRGB_lut : public sRGB_lut_base + { + public: + sRGB_lut() + { + // Generate lookup tables. + m_dir_table[0] = 0; + m_inv_table[0] = 0; + for (unsigned i = 1; i <= 255; ++i) + { + // Floating-point RGB is in range [0,1]. + m_dir_table[i] = float(sRGB_to_linear(i / 255.0)); + m_inv_table[i] = float(sRGB_to_linear((i - 0.5) / 255.0)); + } + } + }; + + template<> + class sRGB_lut : public sRGB_lut_base + { + public: + sRGB_lut() + { + // Generate lookup tables. + m_dir_table[0] = 0; + m_inv_table[0] = 0; + for (unsigned i = 1; i <= 255; ++i) + { + // 16-bit RGB is in range [0,65535]. + m_dir_table[i] = uround(65535.0 * sRGB_to_linear(i / 255.0)); + m_inv_table[i] = uround(65535.0 * sRGB_to_linear((i - 0.5) / 255.0)); + } + } + }; + + template<> + class sRGB_lut : public sRGB_lut_base + { + public: + sRGB_lut() + { + // Generate lookup tables. + m_dir_table[0] = 0; + m_inv_table[0] = 0; + for (unsigned i = 1; i <= 255; ++i) + { + // 8-bit RGB is handled with simple bidirectional lookup tables. + m_dir_table[i] = uround(255.0 * sRGB_to_linear(i / 255.0)); + m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 255.0)); + } + } + + int8u inv(int8u v) const + { + // In this case, the inverse transform is a simple lookup. + return m_inv_table[v]; + } + }; + + // Common base class for sRGB_conv objects. Defines an internal + // sRGB_lut object so that users don't have to. + template + class sRGB_conv_base + { + public: + static T rgb_from_sRGB(int8u x) + { + return lut.dir(x); + } + + static int8u rgb_to_sRGB(T x) + { + return lut.inv(x); + } + + private: + static sRGB_lut lut; + }; + + // Definition of sRGB_conv_base::lut. Due to the fact that this a template, + // we don't need to place the definition in a cpp file. Hurrah. + template + sRGB_lut sRGB_conv_base::lut; + + // Wrapper for sRGB-linear conversion. + // Base template is undefined, specializations are provided below. + template + class sRGB_conv; + + template<> + class sRGB_conv : public sRGB_conv_base + { + public: + static float alpha_from_sRGB(int8u x) + { + return float(x / 255.0); + } + + static int8u alpha_to_sRGB(float x) + { + if (x <= 0) return 0; + else if (x >= 1) return 255; + else return int8u(0.5 + x * 255); + } + }; + + template<> + class sRGB_conv : public sRGB_conv_base + { + public: + static int16u alpha_from_sRGB(int8u x) + { + return (x << 8) | x; + } + + static int8u alpha_to_sRGB(int16u x) + { + return x >> 8; + } + }; + + template<> + class sRGB_conv : public sRGB_conv_base + { + public: + static int8u alpha_from_sRGB(int8u x) + { + return x; + } + + static int8u alpha_to_sRGB(int8u x) + { + return x; + } + }; } #endif diff --git a/extern/agg24/include/agg_gsv_text.h b/extern/agg24/include/agg_gsv_text.h index 73e4ec888889..16b3aeb33d87 100644 --- a/extern/agg24/include/agg_gsv_text.h +++ b/extern/agg24/include/agg_gsv_text.h @@ -112,7 +112,7 @@ namespace agg template class gsv_text_outline { public: - gsv_text_outline(gsv_text& text, const Transformer& trans) : + gsv_text_outline(gsv_text& text, Transformer& trans) : m_polyline(text), m_trans(m_polyline, trans) { diff --git a/extern/agg24/include/agg_image_accessors.h b/extern/agg24/include/agg_image_accessors.h index baaef9c5baa7..7c3902824437 100644 --- a/extern/agg24/include/agg_image_accessors.h +++ b/extern/agg24/include/agg_image_accessors.h @@ -32,14 +32,14 @@ namespace agg enum pix_width_e { pix_width = pixfmt_type::pix_width }; image_accessor_clip() {} - explicit image_accessor_clip(const pixfmt_type& pixf, + explicit image_accessor_clip(pixfmt_type& pixf, const color_type& bk) : m_pixf(&pixf) { pixfmt_type::make_pix(m_bk_buf, bk); } - void attach(const pixfmt_type& pixf) + void attach(pixfmt_type& pixf) { m_pixf = &pixf; } @@ -96,7 +96,7 @@ namespace agg private: const pixfmt_type* m_pixf; - int8u m_bk_buf[4]; + int8u m_bk_buf[pix_width]; int m_x, m_x0, m_y; const int8u* m_pix_ptr; }; @@ -115,11 +115,11 @@ namespace agg enum pix_width_e { pix_width = pixfmt_type::pix_width }; image_accessor_no_clip() {} - explicit image_accessor_no_clip(const pixfmt_type& pixf) : + explicit image_accessor_no_clip(pixfmt_type& pixf) : m_pixf(&pixf) {} - void attach(const pixfmt_type& pixf) + void attach(pixfmt_type& pixf) { m_pixf = &pixf; } @@ -162,11 +162,11 @@ namespace agg enum pix_width_e { pix_width = pixfmt_type::pix_width }; image_accessor_clone() {} - explicit image_accessor_clone(const pixfmt_type& pixf) : + explicit image_accessor_clone(pixfmt_type& pixf) : m_pixf(&pixf) {} - void attach(const pixfmt_type& pixf) + void attach(pixfmt_type& pixf) { m_pixf = &pixf; } @@ -238,13 +238,13 @@ namespace agg enum pix_width_e { pix_width = pixfmt_type::pix_width }; image_accessor_wrap() {} - explicit image_accessor_wrap(const pixfmt_type& pixf) : + explicit image_accessor_wrap(pixfmt_type& pixf) : m_pixf(&pixf), m_wrap_x(pixf.width()), m_wrap_y(pixf.height()) {} - void attach(const pixfmt_type& pixf) + void attach(pixfmt_type& pixf) { m_pixf = &pixf; } @@ -252,7 +252,7 @@ namespace agg AGG_INLINE const int8u* span(int x, int y, unsigned) { m_x = x; - m_row_ptr = m_pixf->row_ptr(m_wrap_y(y)); + m_row_ptr = m_pixf->pix_ptr(0, m_wrap_y(y)); return m_row_ptr + m_wrap_x(x) * pix_width; } @@ -264,7 +264,7 @@ namespace agg AGG_INLINE const int8u* next_y() { - m_row_ptr = m_pixf->row_ptr(++m_wrap_y); + m_row_ptr = m_pixf->pix_ptr(0, ++m_wrap_y); return m_row_ptr + m_wrap_x(m_x) * pix_width; } diff --git a/extern/agg24/include/agg_path_storage.h b/extern/agg24/include/agg_path_storage.h index f4f754746999..c01b867f26c4 100644 --- a/extern/agg24/include/agg_path_storage.h +++ b/extern/agg24/include/agg_path_storage.h @@ -490,14 +490,14 @@ namespace agg m_stop(false) {} - poly_container_reverse_adaptor(const Container& data, bool closed) : + poly_container_reverse_adaptor(Container& data, bool closed) : m_container(&data), m_index(-1), m_closed(closed), m_stop(false) {} - void init(const Container& data, bool closed) + void init(Container& data, bool closed) { m_container = &data; m_index = m_container->size() - 1; @@ -531,7 +531,7 @@ namespace agg } private: - const Container* m_container; + Container* m_container; int m_index; bool m_closed; bool m_stop; diff --git a/extern/agg24/include/agg_pattern_filters_rgba.h b/extern/agg24/include/agg_pattern_filters_rgba.h index 9fb8afa6cf92..c1d174cacbf7 100644 --- a/extern/agg24/include/agg_pattern_filters_rgba.h +++ b/extern/agg24/include/agg_pattern_filters_rgba.h @@ -67,7 +67,7 @@ namespace agg color_type* p, int x, int y) { calc_type r, g, b, a; - r = g = b = a = line_subpixel_scale * line_subpixel_scale / 2; + r = g = b = a = 0; calc_type weight; int x_lr = x >> line_subpixel_shift; @@ -108,15 +108,16 @@ namespace agg b += weight * ptr->b; a += weight * ptr->a; - p->r = (value_type)(r >> line_subpixel_shift * 2); - p->g = (value_type)(g >> line_subpixel_shift * 2); - p->b = (value_type)(b >> line_subpixel_shift * 2); - p->a = (value_type)(a >> line_subpixel_shift * 2); + p->r = (value_type)color_type::downshift(r, line_subpixel_shift * 2); + p->g = (value_type)color_type::downshift(g, line_subpixel_shift * 2); + p->b = (value_type)color_type::downshift(b, line_subpixel_shift * 2); + p->a = (value_type)color_type::downshift(a, line_subpixel_shift * 2); } }; typedef pattern_filter_bilinear_rgba pattern_filter_bilinear_rgba8; typedef pattern_filter_bilinear_rgba pattern_filter_bilinear_rgba16; + typedef pattern_filter_bilinear_rgba pattern_filter_bilinear_rgba32; } #endif diff --git a/extern/agg24/include/agg_pixfmt_amask_adaptor.h b/extern/agg24/include/agg_pixfmt_amask_adaptor.h index b30014fc4dfd..cf39c54ad55e 100644 --- a/extern/agg24/include/agg_pixfmt_amask_adaptor.h +++ b/extern/agg24/include/agg_pixfmt_amask_adaptor.h @@ -59,12 +59,12 @@ namespace agg public: - pixfmt_amask_adaptor(pixfmt_type& pixf, const amask_type& mask) : + pixfmt_amask_adaptor(pixfmt_type& pixf, amask_type& mask) : m_pixf(&pixf), m_mask(&mask), m_span() {} - void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; } - void attach_alpha_mask(const amask_type& mask) { m_mask = &mask; } + void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; } + void attach_alpha_mask(amask_type& mask) { m_mask = &mask; } //-------------------------------------------------------------------- template diff --git a/extern/agg24/include/agg_pixfmt_base.h b/extern/agg24/include/agg_pixfmt_base.h new file mode 100644 index 000000000000..57ae19cfe046 --- /dev/null +++ b/extern/agg24/include/agg_pixfmt_base.h @@ -0,0 +1,97 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_PIXFMT_BASE_INCLUDED +#define AGG_PIXFMT_BASE_INCLUDED + +#include "agg_basics.h" +#include "agg_color_gray.h" +#include "agg_color_rgba.h" + +namespace agg +{ + struct pixfmt_gray_tag + { + }; + + struct pixfmt_rgb_tag + { + }; + + struct pixfmt_rgba_tag + { + }; + + //--------------------------------------------------------------blender_base + template + struct blender_base + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + + static rgba get(value_type r, value_type g, value_type b, value_type a, cover_type cover = cover_full) + { + if (cover > cover_none) + { + rgba c( + color_type::to_double(r), + color_type::to_double(g), + color_type::to_double(b), + color_type::to_double(a)); + + if (cover < cover_full) + { + double x = double(cover) / cover_full; + c.r *= x; + c.g *= x; + c.b *= x; + c.a *= x; + } + + return c; + } + else return rgba::no_color(); + } + + static rgba get(const value_type* p, cover_type cover = cover_full) + { + return get( + p[order_type::R], + p[order_type::G], + p[order_type::B], + p[order_type::A], + cover); + } + + static void set(value_type* p, value_type r, value_type g, value_type b, value_type a) + { + p[order_type::R] = r; + p[order_type::G] = g; + p[order_type::B] = b; + p[order_type::A] = a; + } + + static void set(value_type* p, const rgba& c) + { + p[order_type::R] = color_type::from_double(c.r); + p[order_type::G] = color_type::from_double(c.g); + p[order_type::B] = color_type::from_double(c.b); + p[order_type::A] = color_type::from_double(c.a); + } + }; +} + +#endif diff --git a/extern/agg24/include/agg_pixfmt_gray.h b/extern/agg24/include/agg_pixfmt_gray.h index dd4f2469dffc..d03dc8650170 100644 --- a/extern/agg24/include/agg_pixfmt_gray.h +++ b/extern/agg24/include/agg_pixfmt_gray.h @@ -25,8 +25,7 @@ #define AGG_PIXFMT_GRAY_INCLUDED #include -#include "agg_basics.h" -#include "agg_color_gray.h" +#include "agg_pixfmt_base.h" #include "agg_rendering_buffer.h" namespace agg @@ -38,12 +37,22 @@ namespace agg typedef ColorT color_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e { base_shift = color_type::base_shift }; + typedef typename color_type::long_type long_type; - static AGG_INLINE void blend_pix(value_type* p, unsigned cv, - unsigned alpha, unsigned cover=0) + // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's + // compositing function. Since the render buffer is opaque we skip the + // initial premultiply and final demultiply. + + static AGG_INLINE void blend_pix(value_type* p, + value_type cv, value_type alpha, cover_type cover) + { + blend_pix(p, cv, color_type::mult_cover(alpha, cover)); + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type cv, value_type alpha) { - *p = (value_type)((((cv - calc_type(*p)) * alpha) + (calc_type(*p) << base_shift)) >> base_shift); + *p = color_type::lerp(*p, cv, alpha); } }; @@ -54,20 +63,21 @@ namespace agg typedef ColorT color_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e { base_shift = color_type::base_shift }; + typedef typename color_type::long_type long_type; + + // Blend pixels using the premultiplied form of Alvy-Ray Smith's + // compositing function. - static AGG_INLINE void blend_pix(value_type* p, unsigned cv, - unsigned alpha, unsigned cover) + static AGG_INLINE void blend_pix(value_type* p, + value_type cv, value_type alpha, cover_type cover) { - alpha = color_type::base_mask - alpha; - cover = (cover + 1) << (base_shift - 8); - *p = (value_type)((*p * alpha + cv * cover) >> base_shift); + blend_pix(p, color_type::mult_cover(cv, cover), color_type::mult_cover(alpha, cover)); } - static AGG_INLINE void blend_pix(value_type* p, unsigned cv, - unsigned alpha) + static AGG_INLINE void blend_pix(value_type* p, + value_type cv, value_type alpha) { - *p = (value_type)(((*p * (color_type::base_mask - alpha)) >> base_shift) + cv); + *p = color_type::prelerp(*p, cv, alpha); } }; @@ -112,10 +122,11 @@ namespace agg //=================================================pixfmt_alpha_blend_gray - template + template class pixfmt_alpha_blend_gray { public: + typedef pixfmt_gray_tag pixfmt_category; typedef RenBuf rbuf_type; typedef typename rbuf_type::row_data row_data; typedef Blender blender_type; @@ -123,54 +134,117 @@ namespace agg typedef int order_type; // A fake one typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_scale = color_type::base_scale, - base_mask = color_type::base_mask, - pix_width = sizeof(value_type), - pix_step = Step, - pix_offset = Offset + enum + { + num_components = 1, + pix_width = sizeof(value_type) * Step, + pix_step = Step, + pix_offset = Offset, + }; + struct pixel_type + { + value_type c[num_components]; + + void set(value_type v) + { + c[0] = v; + } + + void set(const color_type& color) + { + set(color.v); + } + + void get(value_type& v) const + { + v = c[0]; + } + + color_type get() const + { + return color_type(c[0]); + } + + pixel_type* next() + { + return (pixel_type*)(c + pix_step); + } + + const pixel_type* next() const + { + return (const pixel_type*)(c + pix_step); + } + + pixel_type* advance(int n) + { + return (pixel_type*)(c + n * pix_step); + } + + const pixel_type* advance(int n) const + { + return (const pixel_type*)(c + n * pix_step); + } }; private: //-------------------------------------------------------------------- - static AGG_INLINE void copy_or_blend_pix(value_type* p, - const color_type& c, - unsigned cover) + AGG_INLINE void blend_pix(pixel_type* p, + value_type v, value_type a, + unsigned cover) + { + blender_type::blend_pix(p->c, v, a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, value_type v, value_type a) + { + blender_type::blend_pix(p->c, v, a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + blender_type::blend_pix(p->c, c.v, c.a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c) + { + blender_type::blend_pix(p->c, c.v, c.a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover) { - if (c.a) + if (!c.is_transparent()) { - calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; - if(alpha == base_mask) + if (c.is_opaque() && cover == cover_mask) { - *p = c.v; + p->set(c); } else { - Blender::blend_pix(p, c.v, alpha, cover); + blend_pix(p, c, cover); } } } - - static AGG_INLINE void copy_or_blend_pix(value_type* p, - const color_type& c) + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c) { - if (c.a) + if (!c.is_transparent()) { - if(c.a == base_mask) + if (c.is_opaque()) { - *p = c.v; + p->set(c); } else { - Blender::blend_pix(p, c.v, c.a); + blend_pix(p, c); } } } - public: //-------------------------------------------------------------------- explicit pixfmt_alpha_blend_gray(rbuf_type& rb) : @@ -183,7 +257,7 @@ namespace agg bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) { rect_i r(x1, y1, x2, y2); - if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) + if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) { int stride = pixf.stride(); m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), @@ -201,61 +275,98 @@ namespace agg AGG_INLINE int stride() const { return m_rbuf->stride(); } //-------------------------------------------------------------------- - int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } + int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } row_data row(int y) const { return m_rbuf->row(y); } - const int8u* pix_ptr(int x, int y) const + //-------------------------------------------------------------------- + AGG_INLINE int8u* pix_ptr(int x, int y) + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset); + } + + AGG_INLINE const int8u* pix_ptr(int x, int y) const + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset); + } + + // Return pointer to pixel value, forcing row to be allocated. + AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) + { + return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset)); + } + + // Return pointer to pixel value, or null if row not allocated. + AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const + { + int8u* p = m_rbuf->row_ptr(y); + return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static pixel_type* pix_value_ptr(void* p) + { + return (pixel_type*)((value_type*)p + pix_offset); + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) + { + return (const pixel_type*)((const value_type*)p + pix_offset); + } + + //-------------------------------------------------------------------- + AGG_INLINE static void write_plain_color(void* p, color_type c) { - return m_rbuf->row_ptr(y) + x * Step + Offset; + // Grayscale formats are implicitly premultiplied. + c.premultiply(); + pix_value_ptr(p)->set(c); } - int8u* pix_ptr(int x, int y) + //-------------------------------------------------------------------- + AGG_INLINE static color_type read_plain_color(const void* p) { - return m_rbuf->row_ptr(y) + x * Step + Offset; + return pix_value_ptr(p)->get(); } //-------------------------------------------------------------------- AGG_INLINE static void make_pix(int8u* p, const color_type& c) { - *(value_type*)p = c.v; + ((pixel_type*)p)->set(c); } //-------------------------------------------------------------------- AGG_INLINE color_type pixel(int x, int y) const { - value_type* p = (value_type*)m_rbuf->row_ptr(y) + x * Step + Offset; - return color_type(*p); + if (const pixel_type* p = pix_value_ptr(x, y)) + { + return p->get(); + } + return color_type::no_color(); } //-------------------------------------------------------------------- AGG_INLINE void copy_pixel(int x, int y, const color_type& c) { - *((value_type*)m_rbuf->row_ptr(x, y, 1) + x * Step + Offset) = c.v; + pix_value_ptr(x, y, 1)->set(c); } //-------------------------------------------------------------------- AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) { - copy_or_blend_pix((value_type*) - m_rbuf->row_ptr(x, y, 1) + x * Step + Offset, - c, - cover); + copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover); } - //-------------------------------------------------------------------- AGG_INLINE void copy_hline(int x, int y, unsigned len, const color_type& c) { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y, len) + x * Step + Offset; - + pixel_type* p = pix_value_ptr(x, y, len); do { - *p = c.v; - p += Step; + p->set(c); + p = p->next(); } while(--len); } @@ -268,12 +379,9 @@ namespace agg { do { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset; - - *p = c.v; + pix_value_ptr(x, y++, 1)->set(c); } - while(--len); + while (--len); } @@ -283,29 +391,27 @@ namespace agg const color_type& c, int8u cover) { - if (c.a) + if (!c.is_transparent()) { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y, len) + x * Step + Offset; + pixel_type* p = pix_value_ptr(x, y, len); - calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; - if(alpha == base_mask) + if (c.is_opaque() && cover == cover_mask) { do { - *p = c.v; - p += Step; + p->set(c); + p = p->next(); } - while(--len); + while (--len); } else { do { - Blender::blend_pix(p, c.v, alpha, cover); - p += Step; + blend_pix(p, c, cover); + p = p->next(); } - while(--len); + while (--len); } } } @@ -317,31 +423,23 @@ namespace agg const color_type& c, int8u cover) { - if (c.a) + if (!c.is_transparent()) { - value_type* p; - calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; - if(alpha == base_mask) + if (c.is_opaque() && cover == cover_mask) { do { - p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset; - - *p = c.v; + pix_value_ptr(x, y++, 1)->set(c); } - while(--len); + while (--len); } else { do { - p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset; - - Blender::blend_pix(p, c.v, alpha, cover); + blend_pix(pix_value_ptr(x, y++, 1), c, cover); } - while(--len); + while (--len); } } } @@ -353,26 +451,24 @@ namespace agg const color_type& c, const int8u* covers) { - if (c.a) + if (!c.is_transparent()) { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y, len) + x * Step + Offset; + pixel_type* p = pix_value_ptr(x, y, len); do { - calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8; - if(alpha == base_mask) + if (c.is_opaque() && *covers == cover_mask) { - *p = c.v; + p->set(c); } else { - Blender::blend_pix(p, c.v, alpha, *covers); + blend_pix(p, c, *covers); } - p += Step; + p = p->next(); ++covers; } - while(--len); + while (--len); } } @@ -383,26 +479,23 @@ namespace agg const color_type& c, const int8u* covers) { - if (c.a) + if (!c.is_transparent()) { do { - calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8; + pixel_type* p = pix_value_ptr(x, y++, 1); - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset; - - if(alpha == base_mask) + if (c.is_opaque() && *covers == cover_mask) { - *p = c.v; + p->set(c); } else { - Blender::blend_pix(p, c.v, alpha, *covers); + blend_pix(p, c, *covers); } ++covers; } - while(--len); + while (--len); } } @@ -412,16 +505,14 @@ namespace agg unsigned len, const color_type* colors) { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y, len) + x * Step + Offset; + pixel_type* p = pix_value_ptr(x, y, len); do { - *p = colors->v; - p += Step; - ++colors; + p->set(*colors++); + p = p->next(); } - while(--len); + while (--len); } @@ -432,12 +523,9 @@ namespace agg { do { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset; - *p = colors->v; - ++colors; + pix_value_ptr(x, y++, 1)->set(*colors++); } - while(--len); + while (--len); } @@ -448,50 +536,40 @@ namespace agg const int8u* covers, int8u cover) { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y, len) + x * Step + Offset; + pixel_type* p = pix_value_ptr(x, y, len); - if(covers) + if (covers) { do { copy_or_blend_pix(p, *colors++, *covers++); - p += Step; + p = p->next(); } - while(--len); + while (--len); } else { - if(cover == 255) + if (cover == cover_mask) { do { - if(colors->a == base_mask) - { - *p = colors->v; - } - else - { - copy_or_blend_pix(p, *colors); - } - p += Step; - ++colors; + copy_or_blend_pix(p, *colors++); + p = p->next(); } - while(--len); + while (--len); } else { do { copy_or_blend_pix(p, *colors++, cover); - p += Step; + p = p->next(); } - while(--len); + while (--len); } } } - - + //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, @@ -500,49 +578,31 @@ namespace agg const int8u* covers, int8u cover) { - value_type* p; - if(covers) + if (covers) { do { - p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset; - - copy_or_blend_pix(p, *colors++, *covers++); + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++); } - while(--len); + while (--len); } else { - if(cover == 255) + if (cover == cover_mask) { do { - p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset; - - if(colors->a == base_mask) - { - *p = colors->v; - } - else - { - copy_or_blend_pix(p, *colors); - } - ++colors; + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++); } - while(--len); + while (--len); } else { do { - p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset; - - copy_or_blend_pix(p, *colors++, cover); + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover); } - while(--len); + while (--len); } } } @@ -551,22 +611,19 @@ namespace agg template void for_each_pixel(Function f) { unsigned y; - for(y = 0; y < height(); ++y) + for (y = 0; y < height(); ++y) { row_data r = m_rbuf->row(y); - if(r.ptr) + if (r.ptr) { unsigned len = r.x2 - r.x1 + 1; - - value_type* p = (value_type*) - m_rbuf->row_ptr(r.x1, y, len) + r.x1 * Step + Offset; - + pixel_type* p = pix_value_ptr(r.x1, y, len); do { - f(p); - p += Step; + f(p->c); + p = p->next(); } - while(--len); + while (--len); } } } @@ -590,8 +647,7 @@ namespace agg int xsrc, int ysrc, unsigned len) { - const int8u* p = from.row_ptr(ysrc); - if(p) + if (const int8u* p = from.row_ptr(ysrc)) { memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, p + xsrc * pix_width, @@ -600,6 +656,7 @@ namespace agg } //-------------------------------------------------------------------- + // Blend from single color, using grayscale surface as alpha channel. template void blend_from_color(const SrcPixelFormatRenderer& from, const color_type& color, @@ -608,25 +665,26 @@ namespace agg unsigned len, int8u cover) { - typedef typename SrcPixelFormatRenderer::value_type src_value_type; - const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); - if(psrc) + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) { - value_type* pdst = - (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst; + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + do { - copy_or_blend_pix(pdst, - color, - (*psrc * cover + base_mask) >> base_shift); - ++psrc; - ++pdst; + copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0])); + psrc = psrc->next(); + pdst = pdst->next(); } - while(--len); + while (--len); } } //-------------------------------------------------------------------- + // Blend from color table, using grayscale surface as indexes into table. + // Obviously, this only works for integer value types. template void blend_from_lut(const SrcPixelFormatRenderer& from, const color_type* color_lut, @@ -635,19 +693,19 @@ namespace agg unsigned len, int8u cover) { - typedef typename SrcPixelFormatRenderer::value_type src_value_type; - const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); - if(psrc) + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) { - value_type* pdst = - (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst; + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + do { - copy_or_blend_pix(pdst, color_lut[*psrc], cover); - ++psrc; - ++pdst; + copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover); + psrc = psrc->next(); + pdst = pdst->next(); } - while(--len); + while (--len); } } @@ -655,15 +713,25 @@ namespace agg rbuf_type* m_rbuf; }; - typedef blender_gray blender_gray8; - typedef blender_gray_pre blender_gray8_pre; - typedef blender_gray blender_gray16; + typedef blender_gray blender_gray8; + typedef blender_gray blender_sgray8; + typedef blender_gray blender_gray16; + typedef blender_gray blender_gray32; + + typedef blender_gray_pre blender_gray8_pre; + typedef blender_gray_pre blender_sgray8_pre; typedef blender_gray_pre blender_gray16_pre; + typedef blender_gray_pre blender_gray32_pre; + + typedef pixfmt_alpha_blend_gray pixfmt_gray8; + typedef pixfmt_alpha_blend_gray pixfmt_sgray8; + typedef pixfmt_alpha_blend_gray pixfmt_gray16; + typedef pixfmt_alpha_blend_gray pixfmt_gray32; - typedef pixfmt_alpha_blend_gray pixfmt_gray8; //----pixfmt_gray8 - typedef pixfmt_alpha_blend_gray pixfmt_gray8_pre; //----pixfmt_gray8_pre - typedef pixfmt_alpha_blend_gray pixfmt_gray16; //----pixfmt_gray16 - typedef pixfmt_alpha_blend_gray pixfmt_gray16_pre; //----pixfmt_gray16_pre + typedef pixfmt_alpha_blend_gray pixfmt_gray8_pre; + typedef pixfmt_alpha_blend_gray pixfmt_sgray8_pre; + typedef pixfmt_alpha_blend_gray pixfmt_gray16_pre; + typedef pixfmt_alpha_blend_gray pixfmt_gray32_pre; } #endif diff --git a/extern/agg24/include/agg_pixfmt_rgb.h b/extern/agg24/include/agg_pixfmt_rgb.h index 4025fa5ab3e5..6fa8772ce061 100644 --- a/extern/agg24/include/agg_pixfmt_rgb.h +++ b/extern/agg24/include/agg_pixfmt_rgb.h @@ -25,8 +25,7 @@ #define AGG_PIXFMT_RGB_INCLUDED #include -#include "agg_basics.h" -#include "agg_color_rgba.h" +#include "agg_pixfmt_base.h" #include "agg_rendering_buffer.h" namespace agg @@ -74,66 +73,73 @@ namespace agg //=========================================================blender_rgb - template struct blender_rgb + template + struct blender_rgb { typedef ColorT color_type; typedef Order order_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e { base_shift = color_type::base_shift }; + typedef typename color_type::long_type long_type; + + // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's + // compositing function. Since the render buffer is opaque we skip the + // initial premultiply and final demultiply. //-------------------------------------------------------------------- static AGG_INLINE void blend_pix(value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned alpha, - unsigned cover=0) + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) { - p[Order::R] += (value_type)(((cr - p[Order::R]) * alpha) >> base_shift); - p[Order::G] += (value_type)(((cg - p[Order::G]) * alpha) >> base_shift); - p[Order::B] += (value_type)(((cb - p[Order::B]) * alpha) >> base_shift); + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + p[Order::R] = color_type::lerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::lerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::lerp(p[Order::B], cb, alpha); } }; - //======================================================blender_rgb_pre - template struct blender_rgb_pre + template + struct blender_rgb_pre { typedef ColorT color_type; typedef Order order_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e { base_shift = color_type::base_shift }; + typedef typename color_type::long_type long_type; + + // Blend pixels using the premultiplied form of Alvy-Ray Smith's + // compositing function. //-------------------------------------------------------------------- static AGG_INLINE void blend_pix(value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned alpha, - unsigned cover) + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) { - alpha = color_type::base_mask - alpha; - cover = (cover + 1) << (base_shift - 8); - p[Order::R] = (value_type)((p[Order::R] * alpha + cr * cover) >> base_shift); - p[Order::G] = (value_type)((p[Order::G] * alpha + cg * cover) >> base_shift); - p[Order::B] = (value_type)((p[Order::B] * alpha + cb * cover) >> base_shift); + blend_pix(p, + color_type::mult_cover(cr, cover), + color_type::mult_cover(cg, cover), + color_type::mult_cover(cb, cover), + color_type::mult_cover(alpha, cover)); } //-------------------------------------------------------------------- static AGG_INLINE void blend_pix(value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned alpha) + value_type cr, value_type cg, value_type cb, value_type alpha) { - alpha = color_type::base_mask - alpha; - p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr); - p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg); - p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb); + p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha); } - }; - - //===================================================blender_rgb_gamma - template class blender_rgb_gamma + template + class blender_rgb_gamma : public blender_base { public: typedef ColorT color_type; @@ -141,7 +147,7 @@ namespace agg typedef Gamma gamma_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e { base_shift = color_type::base_shift }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- blender_rgb_gamma() : m_gamma(0) {} @@ -149,29 +155,34 @@ namespace agg //-------------------------------------------------------------------- AGG_INLINE void blend_pix(value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned alpha, - unsigned cover=0) + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) { calc_type r = m_gamma->dir(p[Order::R]); calc_type g = m_gamma->dir(p[Order::G]); calc_type b = m_gamma->dir(p[Order::B]); - p[Order::R] = m_gamma->inv((((m_gamma->dir(cr) - r) * alpha) >> base_shift) + r); - p[Order::G] = m_gamma->inv((((m_gamma->dir(cg) - g) * alpha) >> base_shift) + g); - p[Order::B] = m_gamma->inv((((m_gamma->dir(cb) - b) * alpha) >> base_shift) + b); + p[Order::R] = m_gamma->inv(color_type::downscale((m_gamma->dir(cr) - r) * alpha) + r); + p[Order::G] = m_gamma->inv(color_type::downscale((m_gamma->dir(cg) - g) * alpha) + g); + p[Order::B] = m_gamma->inv(color_type::downscale((m_gamma->dir(cb) - b) * alpha) + b); } - + private: const gamma_type* m_gamma; }; - - //==================================================pixfmt_alpha_blend_rgb - template class pixfmt_alpha_blend_rgb + template + class pixfmt_alpha_blend_rgb { public: + typedef pixfmt_rgb_tag pixfmt_category; typedef RenBuf rbuf_type; typedef Blender blender_type; typedef typename rbuf_type::row_data row_data; @@ -179,56 +190,125 @@ namespace agg typedef typename blender_type::order_type order_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e + enum { - base_shift = color_type::base_shift, - base_scale = color_type::base_scale, - base_mask = color_type::base_mask, - pix_width = sizeof(value_type) * 3 + num_components = 3, + pix_step = Step, + pix_offset = Offset, + pix_width = sizeof(value_type) * pix_step + }; + struct pixel_type + { + value_type c[num_components]; + + void set(value_type r, value_type g, value_type b) + { + c[order_type::R] = r; + c[order_type::G] = g; + c[order_type::B] = b; + } + + void set(const color_type& color) + { + set(color.r, color.g, color.b); + } + + void get(value_type& r, value_type& g, value_type& b) const + { + r = c[order_type::R]; + g = c[order_type::G]; + b = c[order_type::B]; + } + + color_type get() const + { + return color_type( + c[order_type::R], + c[order_type::G], + c[order_type::B]); + } + + pixel_type* next() + { + return (pixel_type*)(c + pix_step); + } + + const pixel_type* next() const + { + return (const pixel_type*)(c + pix_step); + } + + pixel_type* advance(int n) + { + return (pixel_type*)(c + n * pix_step); + } + + const pixel_type* advance(int n) const + { + return (const pixel_type*)(c + n * pix_step); + } }; private: //-------------------------------------------------------------------- - AGG_INLINE void copy_or_blend_pix(value_type* p, - const color_type& c, - unsigned cover) + AGG_INLINE void blend_pix(pixel_type* p, + value_type r, value_type g, value_type b, value_type a, + unsigned cover) + { + m_blender.blend_pix(p->c, r, g, b, a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, + value_type r, value_type g, value_type b, value_type a) + { + m_blender.blend_pix(p->c, r, g, b, a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover) { - if (c.a) + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c) + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + if (!c.is_transparent()) { - calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; - if(alpha == base_mask) + if (c.is_opaque() && cover == cover_mask) { - p[order_type::R] = c.r; - p[order_type::G] = c.g; - p[order_type::B] = c.b; + p->set(c); } else { - m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); + blend_pix(p, c, cover); } } } //-------------------------------------------------------------------- - AGG_INLINE void copy_or_blend_pix(value_type* p, - const color_type& c) + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c) { - if (c.a) + if (!c.is_transparent()) { - if(c.a == base_mask) + if (c.is_opaque()) { - p[order_type::R] = c.r; - p[order_type::G] = c.g; - p[order_type::B] = c.b; + p->set(c); } else { - m_blender.blend_pix(p, c.r, c.g, c.b, c.a); + blend_pix(p, c); } } } - public: //-------------------------------------------------------------------- explicit pixfmt_alpha_blend_rgb(rbuf_type& rb) : @@ -241,7 +321,7 @@ namespace agg bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) { rect_i r(x1, y1, x2, y2); - if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) + if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) { int stride = pixf.stride(); m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), @@ -269,59 +349,91 @@ namespace agg //-------------------------------------------------------------------- AGG_INLINE int8u* pix_ptr(int x, int y) { - return m_rbuf->row_ptr(y) + x * pix_width; + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset); } AGG_INLINE const int8u* pix_ptr(int x, int y) const { - return m_rbuf->row_ptr(y) + x * pix_width; + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset); + } + + // Return pointer to pixel value, forcing row to be allocated. + AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) + { + return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset)); + } + + // Return pointer to pixel value, or null if row not allocated. + AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const + { + int8u* p = m_rbuf->row_ptr(y); + return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static pixel_type* pix_value_ptr(void* p) + { + return (pixel_type*)((value_type*)p + pix_offset); + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) + { + return (const pixel_type*)((const value_type*)p + pix_offset); + } + + //-------------------------------------------------------------------- + AGG_INLINE static void write_plain_color(void* p, color_type c) + { + // RGB formats are implicitly premultiplied. + c.premultiply(); + pix_value_ptr(p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE static color_type read_plain_color(const void* p) + { + return pix_value_ptr(p)->get(); } //-------------------------------------------------------------------- AGG_INLINE static void make_pix(int8u* p, const color_type& c) { - ((value_type*)p)[order_type::R] = c.r; - ((value_type*)p)[order_type::G] = c.g; - ((value_type*)p)[order_type::B] = c.b; + ((pixel_type*)p)->set(c); } //-------------------------------------------------------------------- AGG_INLINE color_type pixel(int x, int y) const { - value_type* p = (value_type*)m_rbuf->row_ptr(y) + x + x + x; - return color_type(p[order_type::R], - p[order_type::G], - p[order_type::B]); + if (const pixel_type* p = pix_value_ptr(x, y)) + { + return p->get(); + } + return color_type::no_color(); } //-------------------------------------------------------------------- AGG_INLINE void copy_pixel(int x, int y, const color_type& c) { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x; - p[order_type::R] = c.r; - p[order_type::G] = c.g; - p[order_type::B] = c.b; + pix_value_ptr(x, y, 1)->set(c); } //-------------------------------------------------------------------- AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) { - copy_or_blend_pix((value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x, c, cover); + copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover); } - //-------------------------------------------------------------------- AGG_INLINE void copy_hline(int x, int y, unsigned len, const color_type& c) { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + x + x + x; + pixel_type* p = pix_value_ptr(x, y, len); do { - p[order_type::R] = c.r; - p[order_type::G] = c.g; - p[order_type::B] = c.b; - p += 3; + p->set(c); + p = p->next(); } while(--len); } @@ -334,47 +446,38 @@ namespace agg { do { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x + x + x; - p[order_type::R] = c.r; - p[order_type::G] = c.g; - p[order_type::B] = c.b; + pix_value_ptr(x, y++, 1)->set(c); } - while(--len); + while (--len); } - //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { - if (c.a) + if (!c.is_transparent()) { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y, len) + x + x + x; + pixel_type* p = pix_value_ptr(x, y, len); - calc_type alpha = (calc_type(c.a) * (calc_type(cover) + 1)) >> 8; - if(alpha == base_mask) + if (c.is_opaque() && cover == cover_mask) { do { - p[order_type::R] = c.r; - p[order_type::G] = c.g; - p[order_type::B] = c.b; - p += 3; + p->set(c); + p = p->next(); } - while(--len); + while (--len); } else { do { - m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); - p += 3; + blend_pix(p, c, cover); + p = p->next(); } - while(--len); + while (--len); } } } @@ -386,66 +489,51 @@ namespace agg const color_type& c, int8u cover) { - if (c.a) + if (!c.is_transparent()) { - value_type* p; - calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; - if(alpha == base_mask) + if (c.is_opaque() && cover == cover_mask) { do { - p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x + x + x; - - p[order_type::R] = c.r; - p[order_type::G] = c.g; - p[order_type::B] = c.b; + pix_value_ptr(x, y++, 1)->set(c); } - while(--len); + while (--len); } else { do { - p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x + x + x; - - m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); + blend_pix(pix_value_ptr(x, y++, 1), c, cover); } - while(--len); + while (--len); } } } - //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { - if (c.a) + if (!c.is_transparent()) { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y, len) + x + x + x; + pixel_type* p = pix_value_ptr(x, y, len); do { - calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8; - if(alpha == base_mask) + if (c.is_opaque() && *covers == cover_mask) { - p[order_type::R] = c.r; - p[order_type::G] = c.g; - p[order_type::B] = c.b; + p->set(c); } else { - m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers); + blend_pix(p, c, *covers); } - p += 3; + p = p->next(); ++covers; } - while(--len); + while (--len); } } @@ -456,48 +544,39 @@ namespace agg const color_type& c, const int8u* covers) { - if (c.a) + if (!c.is_transparent()) { do { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x + x + x; + pixel_type* p = pix_value_ptr(x, y++, 1); - calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8; - if(alpha == base_mask) + if (c.is_opaque() && *covers == cover_mask) { - p[order_type::R] = c.r; - p[order_type::G] = c.g; - p[order_type::B] = c.b; + p->set(c); } else { - m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers); + blend_pix(p, c, *covers); } ++covers; } - while(--len); + while (--len); } } - //-------------------------------------------------------------------- void copy_color_hspan(int x, int y, unsigned len, const color_type* colors) { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y, len) + x + x + x; + pixel_type* p = pix_value_ptr(x, y, len); do { - p[order_type::R] = colors->r; - p[order_type::G] = colors->g; - p[order_type::B] = colors->b; - ++colors; - p += 3; + p->set(*colors++); + p = p->next(); } - while(--len); + while (--len); } @@ -508,17 +587,11 @@ namespace agg { do { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x + x + x; - p[order_type::R] = colors->r; - p[order_type::G] = colors->g; - p[order_type::B] = colors->b; - ++colors; + pix_value_ptr(x, y++, 1)->set(*colors++); } - while(--len); + while (--len); } - //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, @@ -526,43 +599,40 @@ namespace agg const int8u* covers, int8u cover) { - value_type* p = (value_type*) - m_rbuf->row_ptr(x, y, len) + x + x + x; + pixel_type* p = pix_value_ptr(x, y, len); - if(covers) + if (covers) { do { copy_or_blend_pix(p, *colors++, *covers++); - p += 3; + p = p->next(); } - while(--len); + while (--len); } else { - if(cover == 255) + if (cover == cover_mask) { do { copy_or_blend_pix(p, *colors++); - p += 3; + p = p->next(); } - while(--len); + while (--len); } else { do { copy_or_blend_pix(p, *colors++, cover); - p += 3; + p = p->next(); } - while(--len); + while (--len); } } } - - //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, @@ -570,41 +640,31 @@ namespace agg const int8u* covers, int8u cover) { - value_type* p; - if(covers) + if (covers) { do { - p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x + x + x; - - copy_or_blend_pix(p, *colors++, *covers++); + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++); } - while(--len); + while (--len); } else { - if(cover == 255) + if (cover == cover_mask) { do { - p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x + x + x; - - copy_or_blend_pix(p, *colors++); + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++); } - while(--len); + while (--len); } else { do { - p = (value_type*) - m_rbuf->row_ptr(x, y++, 1) + x + x + x; - - copy_or_blend_pix(p, *colors++, cover); + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover); } - while(--len); + while (--len); } } } @@ -612,21 +672,19 @@ namespace agg //-------------------------------------------------------------------- template void for_each_pixel(Function f) { - unsigned y; - for(y = 0; y < height(); ++y) + for (unsigned y = 0; y < height(); ++y) { row_data r = m_rbuf->row(y); - if(r.ptr) + if (r.ptr) { unsigned len = r.x2 - r.x1 + 1; - value_type* p = (value_type*) - m_rbuf->row_ptr(r.x1, y, len) + r.x1 * 3; + pixel_type* p = pix_value_ptr(r.x1, y, len); do { - f(p); - p += 3; + f(p->c); + p = p->next(); } - while(--len); + while (--len); } } } @@ -650,8 +708,7 @@ namespace agg int xsrc, int ysrc, unsigned len) { - const int8u* p = from.row_ptr(ysrc); - if(p) + if (const int8u* p = from.row_ptr(ysrc)) { memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, p + xsrc * pix_width, @@ -659,8 +716,8 @@ namespace agg } } - //-------------------------------------------------------------------- + // Blend from an RGBA surface. template void blend_from(const SrcPixelFormatRenderer& from, int xdst, int ydst, @@ -668,61 +725,55 @@ namespace agg unsigned len, int8u cover) { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; typedef typename SrcPixelFormatRenderer::order_type src_order; - const value_type* psrc = (const value_type*)from.row_ptr(ysrc); - if(psrc) + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) { - psrc += xsrc * 4; - value_type* pdst = - (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3; + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); - if(cover == 255) + if (cover == cover_mask) { do { - value_type alpha = psrc[src_order::A]; - if(alpha) + value_type alpha = psrc->c[src_order::A]; + if (alpha <= color_type::empty_value()) { - if(alpha == base_mask) + if (alpha >= color_type::full_value()) { - pdst[order_type::R] = psrc[src_order::R]; - pdst[order_type::G] = psrc[src_order::G]; - pdst[order_type::B] = psrc[src_order::B]; + pdst->c[order_type::R] = psrc->c[src_order::R]; + pdst->c[order_type::G] = psrc->c[src_order::G]; + pdst->c[order_type::B] = psrc->c[src_order::B]; } else { - m_blender.blend_pix(pdst, - psrc[src_order::R], - psrc[src_order::G], - psrc[src_order::B], - alpha); + blend_pix(pdst, + psrc->c[src_order::R], + psrc->c[src_order::G], + psrc->c[src_order::B], + alpha); } } - psrc += 4; - pdst += 3; + psrc = psrc->next(); + pdst = pdst->next(); } while(--len); } else { - color_type color; do { - color.r = psrc[src_order::R]; - color.g = psrc[src_order::G]; - color.b = psrc[src_order::B]; - color.a = psrc[src_order::A]; - copy_or_blend_pix(pdst, color, cover); - psrc += 4; - pdst += 3; + copy_or_blend_pix(pdst, psrc->get(), cover); + psrc = psrc->next(); + pdst = pdst->next(); } - while(--len); + while (--len); } } } //-------------------------------------------------------------------- + // Blend from single color, using grayscale surface as alpha channel. template void blend_from_color(const SrcPixelFormatRenderer& from, const color_type& color, @@ -731,25 +782,26 @@ namespace agg unsigned len, int8u cover) { - typedef typename SrcPixelFormatRenderer::value_type src_value_type; - const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); - if(psrc) + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) { - value_type* pdst = - (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3; + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + do { - copy_or_blend_pix(pdst, - color, - (*psrc * cover + base_mask) >> base_shift); - ++psrc; - pdst += 3; + copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0])); + psrc = psrc->next(); + pdst = pdst->next(); } - while(--len); + while (--len); } } //-------------------------------------------------------------------- + // Blend from color table, using grayscale surface as indexes into table. + // Obviously, this only works for integer value types. template void blend_from_lut(const SrcPixelFormatRenderer& from, const color_type* color_lut, @@ -758,22 +810,20 @@ namespace agg unsigned len, int8u cover) { - typedef typename SrcPixelFormatRenderer::value_type src_value_type; - const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); - if(psrc) + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) { - value_type* pdst = - (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3; + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); - if(cover == 255) + if (cover == cover_mask) { do { - const color_type& color = color_lut[*psrc]; - m_blender.blend_pix(pdst, - color.r, color.g, color.b, color.a); - ++psrc; - pdst += 3; + const color_type& color = color_lut[psrc->c[0]]; + blend_pix(pdst, color); + psrc = psrc->next(); + pdst = pdst->next(); } while(--len); } @@ -781,9 +831,9 @@ namespace agg { do { - copy_or_blend_pix(pdst, color_lut[*psrc], cover); - ++psrc; - pdst += 3; + copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover); + psrc = psrc->next(); + pdst = pdst->next(); } while(--len); } @@ -794,24 +844,98 @@ namespace agg rbuf_type* m_rbuf; Blender m_blender; }; - - typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_rgb24; //----pixfmt_rgb24 - typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_bgr24; //----pixfmt_bgr24 - typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_rgb48; //----pixfmt_rgb48 - typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_bgr48; //----pixfmt_bgr48 - - typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_rgb24_pre; //----pixfmt_rgb24_pre - typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_bgr24_pre; //----pixfmt_bgr24_pre - typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_rgb48_pre; //----pixfmt_rgb48_pre - typedef pixfmt_alpha_blend_rgb, rendering_buffer> pixfmt_bgr48_pre; //----pixfmt_bgr48_pre + + //----------------------------------------------------------------------- + typedef blender_rgb blender_rgb24; + typedef blender_rgb blender_bgr24; + typedef blender_rgb blender_srgb24; + typedef blender_rgb blender_sbgr24; + typedef blender_rgb blender_rgb48; + typedef blender_rgb blender_bgr48; + typedef blender_rgb blender_rgb96; + typedef blender_rgb blender_bgr96; + + typedef blender_rgb_pre blender_rgb24_pre; + typedef blender_rgb_pre blender_bgr24_pre; + typedef blender_rgb_pre blender_srgb24_pre; + typedef blender_rgb_pre blender_sbgr24_pre; + typedef blender_rgb_pre blender_rgb48_pre; + typedef blender_rgb_pre blender_bgr48_pre; + typedef blender_rgb_pre blender_rgb96_pre; + typedef blender_rgb_pre blender_bgr96_pre; + + typedef pixfmt_alpha_blend_rgb pixfmt_rgb24; + typedef pixfmt_alpha_blend_rgb pixfmt_bgr24; + typedef pixfmt_alpha_blend_rgb pixfmt_srgb24; + typedef pixfmt_alpha_blend_rgb pixfmt_sbgr24; + typedef pixfmt_alpha_blend_rgb pixfmt_rgb48; + typedef pixfmt_alpha_blend_rgb pixfmt_bgr48; + typedef pixfmt_alpha_blend_rgb pixfmt_rgb96; + typedef pixfmt_alpha_blend_rgb pixfmt_bgr96; + + typedef pixfmt_alpha_blend_rgb pixfmt_rgb24_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_bgr24_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_srgb24_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_sbgr24_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_rgb48_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_bgr48_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_rgb96_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_bgr96_pre; + + typedef pixfmt_alpha_blend_rgb pixfmt_rgbx32; + typedef pixfmt_alpha_blend_rgb pixfmt_xrgb32; + typedef pixfmt_alpha_blend_rgb pixfmt_xbgr32; + typedef pixfmt_alpha_blend_rgb pixfmt_bgrx32; + typedef pixfmt_alpha_blend_rgb pixfmt_srgbx32; + typedef pixfmt_alpha_blend_rgb pixfmt_sxrgb32; + typedef pixfmt_alpha_blend_rgb pixfmt_sxbgr32; + typedef pixfmt_alpha_blend_rgb pixfmt_sbgrx32; + typedef pixfmt_alpha_blend_rgb pixfmt_rgbx64; + typedef pixfmt_alpha_blend_rgb pixfmt_xrgb64; + typedef pixfmt_alpha_blend_rgb pixfmt_xbgr64; + typedef pixfmt_alpha_blend_rgb pixfmt_bgrx64; + typedef pixfmt_alpha_blend_rgb pixfmt_rgbx128; + typedef pixfmt_alpha_blend_rgb pixfmt_xrgb128; + typedef pixfmt_alpha_blend_rgb pixfmt_xbgr128; + typedef pixfmt_alpha_blend_rgb pixfmt_bgrx128; + + typedef pixfmt_alpha_blend_rgb pixfmt_rgbx32_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_xrgb32_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_xbgr32_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_bgrx32_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_srgbx32_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_sxrgb32_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_sxbgr32_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_sbgrx32_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_rgbx64_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_xrgb64_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_xbgr64_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_bgrx64_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_rgbx128_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_xrgb128_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_xbgr128_pre; + typedef pixfmt_alpha_blend_rgb pixfmt_bgrx128_pre; + //-----------------------------------------------------pixfmt_rgb24_gamma template class pixfmt_rgb24_gamma : - public pixfmt_alpha_blend_rgb, rendering_buffer> + public pixfmt_alpha_blend_rgb, rendering_buffer, 3> { public: pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) : - pixfmt_alpha_blend_rgb, rendering_buffer>(rb) + pixfmt_alpha_blend_rgb, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_srgb24_gamma + template class pixfmt_srgb24_gamma : + public pixfmt_alpha_blend_rgb, rendering_buffer, 3> + { + public: + pixfmt_srgb24_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb, rendering_buffer, 3>(rb) { this->blender().gamma(g); } @@ -819,11 +943,23 @@ namespace agg //-----------------------------------------------------pixfmt_bgr24_gamma template class pixfmt_bgr24_gamma : - public pixfmt_alpha_blend_rgb, rendering_buffer> + public pixfmt_alpha_blend_rgb, rendering_buffer, 3> { public: pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) : - pixfmt_alpha_blend_rgb, rendering_buffer>(rb) + pixfmt_alpha_blend_rgb, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_sbgr24_gamma + template class pixfmt_sbgr24_gamma : + public pixfmt_alpha_blend_rgb, rendering_buffer, 3> + { + public: + pixfmt_sbgr24_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb, rendering_buffer, 3>(rb) { this->blender().gamma(g); } @@ -831,11 +967,11 @@ namespace agg //-----------------------------------------------------pixfmt_rgb48_gamma template class pixfmt_rgb48_gamma : - public pixfmt_alpha_blend_rgb, rendering_buffer> + public pixfmt_alpha_blend_rgb, rendering_buffer, 3> { public: pixfmt_rgb48_gamma(rendering_buffer& rb, const Gamma& g) : - pixfmt_alpha_blend_rgb, rendering_buffer>(rb) + pixfmt_alpha_blend_rgb, rendering_buffer, 3>(rb) { this->blender().gamma(g); } @@ -843,17 +979,16 @@ namespace agg //-----------------------------------------------------pixfmt_bgr48_gamma template class pixfmt_bgr48_gamma : - public pixfmt_alpha_blend_rgb, rendering_buffer> + public pixfmt_alpha_blend_rgb, rendering_buffer, 3> { public: pixfmt_bgr48_gamma(rendering_buffer& rb, const Gamma& g) : - pixfmt_alpha_blend_rgb, rendering_buffer>(rb) + pixfmt_alpha_blend_rgb, rendering_buffer, 3>(rb) { this->blender().gamma(g); } }; - - + } #endif diff --git a/extern/agg24/include/agg_pixfmt_rgb_packed.h b/extern/agg24/include/agg_pixfmt_rgb_packed.h index 4bb11cf19676..d879517de6e2 100644 --- a/extern/agg24/include/agg_pixfmt_rgb_packed.h +++ b/extern/agg24/include/agg_pixfmt_rgb_packed.h @@ -805,7 +805,7 @@ namespace agg base_shift = color_type::base_shift, base_scale = color_type::base_scale, base_mask = color_type::base_mask, - pix_width = sizeof(pixel_type) + pix_width = sizeof(pixel_type), }; private: @@ -1144,9 +1144,11 @@ namespace agg int8u cover) { typedef typename SrcPixelFormatRenderer::value_type src_value_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); if(psrc) { + psrc += xsrc * SrcPixelFormatRenderer::pix_step + SrcPixelFormatRenderer::pix_offset; pixel_type* pdst = (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst; @@ -1155,7 +1157,7 @@ namespace agg m_blender.blend_pix(pdst, color.r, color.g, color.b, color.a, cover); - ++psrc; + psrc += SrcPixelFormatRenderer::pix_step; ++pdst; } while(--len); @@ -1175,6 +1177,7 @@ namespace agg const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); if(psrc) { + psrc += xsrc * SrcPixelFormatRenderer::pix_step + SrcPixelFormatRenderer::pix_offset; pixel_type* pdst = (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst; @@ -1184,7 +1187,7 @@ namespace agg m_blender.blend_pix(pdst, color.r, color.g, color.b, color.a, cover); - ++psrc; + psrc += SrcPixelFormatRenderer::pix_step; ++pdst; } while(--len); diff --git a/extern/agg24/include/agg_pixfmt_rgba.h b/extern/agg24/include/agg_pixfmt_rgba.h index 7d89b4905b58..701ccad6ef6a 100644 --- a/extern/agg24/include/agg_pixfmt_rgba.h +++ b/extern/agg24/include/agg_pixfmt_rgba.h @@ -26,63 +26,57 @@ #include #include -#include "agg_basics.h" -#include "agg_color_rgba.h" +#include "agg_pixfmt_base.h" #include "agg_rendering_buffer.h" namespace agg { + template inline T sd_min(T a, T b) { return (a < b) ? a : b; } + template inline T sd_max(T a, T b) { return (a > b) ? a : b; } + + inline rgba & clip(rgba & c) + { + if (c.a > 1) c.a = 1; else if (c.a < 0) c.a = 0; + if (c.r > c.a) c.r = c.a; else if (c.r < 0) c.r = 0; + if (c.g > c.a) c.g = c.a; else if (c.g < 0) c.g = 0; + if (c.b > c.a) c.b = c.a; else if (c.b < 0) c.b = 0; + return c; + } //=========================================================multiplier_rgba - template struct multiplier_rgba + template + struct multiplier_rgba { - typedef typename ColorT::value_type value_type; - typedef typename ColorT::calc_type calc_type; + typedef ColorT color_type; + typedef typename color_type::value_type value_type; //-------------------------------------------------------------------- static AGG_INLINE void premultiply(value_type* p) { - calc_type a = p[Order::A]; - if(a < ColorT::base_mask) - { - if(a == 0) - { - p[Order::R] = p[Order::G] = p[Order::B] = 0; - return; - } - p[Order::R] = value_type((p[Order::R] * a + ColorT::base_mask) >> ColorT::base_shift); - p[Order::G] = value_type((p[Order::G] * a + ColorT::base_mask) >> ColorT::base_shift); - p[Order::B] = value_type((p[Order::B] * a + ColorT::base_mask) >> ColorT::base_shift); - } + value_type a = p[Order::A]; + p[Order::R] = color_type::multiply(p[Order::R], a); + p[Order::G] = color_type::multiply(p[Order::G], a); + p[Order::B] = color_type::multiply(p[Order::B], a); } //-------------------------------------------------------------------- static AGG_INLINE void demultiply(value_type* p) { - calc_type a = p[Order::A]; - if(a < ColorT::base_mask) - { - if(a == 0) - { - p[Order::R] = p[Order::G] = p[Order::B] = 0; - return; - } - calc_type r = (calc_type(p[Order::R]) * ColorT::base_mask) / a; - calc_type g = (calc_type(p[Order::G]) * ColorT::base_mask) / a; - calc_type b = (calc_type(p[Order::B]) * ColorT::base_mask) / a; - p[Order::R] = value_type((r > ColorT::base_mask) ? ColorT::base_mask : r); - p[Order::G] = value_type((g > ColorT::base_mask) ? ColorT::base_mask : g); - p[Order::B] = value_type((b > ColorT::base_mask) ? ColorT::base_mask : b); - } + value_type a = p[Order::A]; + p[Order::R] = color_type::demultiply(p[Order::R], a); + p[Order::G] = color_type::demultiply(p[Order::G], a); + p[Order::B] = color_type::demultiply(p[Order::B], a); } }; //=====================================================apply_gamma_dir_rgba - template class apply_gamma_dir_rgba + template + class apply_gamma_dir_rgba { public: - typedef typename ColorT::value_type value_type; + typedef ColorT color_type; + typedef typename color_type::value_type value_type; apply_gamma_dir_rgba(const GammaLut& gamma) : m_gamma(gamma) {} @@ -101,7 +95,8 @@ namespace agg template class apply_gamma_inv_rgba { public: - typedef typename ColorT::value_type value_type; + typedef ColorT color_type; + typedef typename color_type::value_type value_type; apply_gamma_inv_rgba(const GammaLut& gamma) : m_gamma(gamma) {} @@ -117,964 +112,789 @@ namespace agg }; - - + template + struct conv_rgba_pre + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + //-------------------------------------------------------------------- + static AGG_INLINE void set_plain_color(value_type* p, color_type c) + { + c.premultiply(); + p[Order::R] = c.r; + p[Order::G] = c.g; + p[Order::B] = c.b; + p[Order::A] = c.a; + } + //-------------------------------------------------------------------- + static AGG_INLINE color_type get_plain_color(const value_type* p) + { + return color_type( + p[Order::R], + p[Order::G], + p[Order::B], + p[Order::A]).demultiply(); + } + }; + template + struct conv_rgba_plain + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + //-------------------------------------------------------------------- + static AGG_INLINE void set_plain_color(value_type* p, color_type c) + { + p[Order::R] = c.r; + p[Order::G] = c.g; + p[Order::B] = c.b; + p[Order::A] = c.a; + } + //-------------------------------------------------------------------- + static AGG_INLINE color_type get_plain_color(const value_type* p) + { + return color_type( + p[Order::R], + p[Order::G], + p[Order::B], + p[Order::A]); + } + }; //=============================================================blender_rgba - template struct blender_rgba + // Blends "plain" (i.e. non-premultiplied) colors into a premultiplied buffer. + template + struct blender_rgba : conv_rgba_pre { typedef ColorT color_type; typedef Order order_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; + + // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's + // compositing function. Since the render buffer is in fact premultiplied + // we omit the initial premultiplication and final demultiplication. //-------------------------------------------------------------------- static AGG_INLINE void blend_pix(value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned alpha, - unsigned cover=0) - { - calc_type r = p[Order::R]; - calc_type g = p[Order::G]; - calc_type b = p[Order::B]; - calc_type a = p[Order::A]; - p[Order::R] = (value_type)(((cr - r) * alpha + (r << base_shift)) >> base_shift); - p[Order::G] = (value_type)(((cg - g) * alpha + (g << base_shift)) >> base_shift); - p[Order::B] = (value_type)(((cb - b) * alpha + (b << base_shift)) >> base_shift); - p[Order::A] = (value_type)((alpha + a) - ((alpha * a + base_mask) >> base_shift)); + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + p[Order::R] = color_type::lerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::lerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::lerp(p[Order::B], cb, alpha); + p[Order::A] = color_type::prelerp(p[Order::A], alpha, alpha); } }; - //=========================================================blender_rgba_pre - template struct blender_rgba_pre + + //========================================================blender_rgba_pre + // Blends premultiplied colors into a premultiplied buffer. + template + struct blender_rgba_pre : conv_rgba_pre { typedef ColorT color_type; typedef Order order_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; + + // Blend pixels using the premultiplied form of Alvy-Ray Smith's + // compositing function. //-------------------------------------------------------------------- static AGG_INLINE void blend_pix(value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned alpha, - unsigned cover) + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) { - alpha = color_type::base_mask - alpha; - cover = (cover + 1) << (base_shift - 8); - p[Order::R] = (value_type)((p[Order::R] * alpha + cr * cover) >> base_shift); - p[Order::G] = (value_type)((p[Order::G] * alpha + cg * cover) >> base_shift); - p[Order::B] = (value_type)((p[Order::B] * alpha + cb * cover) >> base_shift); - p[Order::A] = (value_type)(base_mask - ((alpha * (base_mask - p[Order::A])) >> base_shift)); + blend_pix(p, + color_type::mult_cover(cr, cover), + color_type::mult_cover(cg, cover), + color_type::mult_cover(cb, cover), + color_type::mult_cover(alpha, cover)); } - + //-------------------------------------------------------------------- static AGG_INLINE void blend_pix(value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned alpha) + value_type cr, value_type cg, value_type cb, value_type alpha) { - alpha = color_type::base_mask - alpha; - p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr); - p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg); - p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb); - p[Order::A] = (value_type)(base_mask - ((alpha * (base_mask - p[Order::A])) >> base_shift)); + p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha); + p[Order::A] = color_type::prelerp(p[Order::A], alpha, alpha); } }; //======================================================blender_rgba_plain - template struct blender_rgba_plain + // Blends "plain" (non-premultiplied) colors into a plain (non-premultiplied) buffer. + template + struct blender_rgba_plain : conv_rgba_plain { typedef ColorT color_type; typedef Order order_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e { base_shift = color_type::base_shift }; + typedef typename color_type::long_type long_type; + // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's + // compositing function. + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + //-------------------------------------------------------------------- static AGG_INLINE void blend_pix(value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned alpha, - unsigned cover=0) - { - if(alpha == 0) return; - calc_type a = p[Order::A]; - calc_type r = p[Order::R] * a; - calc_type g = p[Order::G] * a; - calc_type b = p[Order::B] * a; - a = ((alpha + a) << base_shift) - alpha * a; - p[Order::A] = (value_type)(a >> base_shift); - p[Order::R] = (value_type)((((cr << base_shift) - r) * alpha + (r << base_shift)) / a); - p[Order::G] = (value_type)((((cg << base_shift) - g) * alpha + (g << base_shift)) / a); - p[Order::B] = (value_type)((((cb << base_shift) - b) * alpha + (b << base_shift)) / a); + value_type cr, value_type cg, value_type cb, value_type alpha) + { + if (alpha > color_type::empty_value()) + { + calc_type a = p[Order::A]; + calc_type r = color_type::multiply(p[Order::R], a); + calc_type g = color_type::multiply(p[Order::G], a); + calc_type b = color_type::multiply(p[Order::B], a); + p[Order::R] = color_type::lerp(r, cr, alpha); + p[Order::G] = color_type::lerp(g, cg, alpha); + p[Order::B] = color_type::lerp(b, cb, alpha); + p[Order::A] = color_type::prelerp(a, alpha, alpha); + multiplier_rgba::demultiply(p); + } } }; - - - - - - - - - + // SVG compositing operations. + // For specifications, see http://www.w3.org/TR/SVGCompositing/ //=========================================================comp_op_rgba_clear - template struct comp_op_rgba_clear + template + struct comp_op_rgba_clear : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; + // Dca' = 0 + // Da' = 0 static AGG_INLINE void blend_pix(value_type* p, - unsigned, unsigned, unsigned, unsigned, - unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) + if (cover >= cover_full) { - cover = 255 - cover; - p[Order::R] = (value_type)((p[Order::R] * cover + 255) >> 8); - p[Order::G] = (value_type)((p[Order::G] * cover + 255) >> 8); - p[Order::B] = (value_type)((p[Order::B] * cover + 255) >> 8); - p[Order::A] = (value_type)((p[Order::A] * cover + 255) >> 8); + p[0] = p[1] = p[2] = p[3] = color_type::empty_value(); } - else + else if (cover > cover_none) { - p[0] = p[1] = p[2] = p[3] = 0; + set(p, get(p, cover_full - cover)); } } }; //===========================================================comp_op_rgba_src - template struct comp_op_rgba_src + template + struct comp_op_rgba_src : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; + using blender_base::get; + using blender_base::set; + // Dca' = Sca + // Da' = Sa static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) + if (cover >= cover_full) { - unsigned alpha = 255 - cover; - p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((sr * cover + 255) >> 8)); - p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((sg * cover + 255) >> 8)); - p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((sb * cover + 255) >> 8)); - p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((sa * cover + 255) >> 8)); + set(p, r, g, b, a); } else { - p[Order::R] = sr; - p[Order::G] = sg; - p[Order::B] = sb; - p[Order::A] = sa; + rgba s = get(r, g, b, a, cover); + rgba d = get(p, cover_full - cover); + d.r += s.r; + d.g += s.g; + d.b += s.b; + d.a += s.a; + set(p, d); } } }; //===========================================================comp_op_rgba_dst - template struct comp_op_rgba_dst + template + struct comp_op_rgba_dst : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - static AGG_INLINE void blend_pix(value_type*, - unsigned, unsigned, unsigned, - unsigned, unsigned) + // Dca' = Dca.Sa + Dca.(1 - Sa) = Dca + // Da' = Da.Sa + Da.(1 - Sa) = Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) { + // Well, that was easy! } }; //======================================================comp_op_rgba_src_over - template struct comp_op_rgba_src_over + template + struct comp_op_rgba_src_over : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; - // Dca' = Sca + Dca.(1 - Sa) - // Da' = Sa + Da - Sa.Da + // Dca' = Sca + Dca.(1 - Sa) = Dca + Sca - Dca.Sa + // Da' = Sa + Da - Sa.Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) - { - if(cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - calc_type s1a = base_mask - sa; - p[Order::R] = (value_type)(sr + ((p[Order::R] * s1a + base_mask) >> base_shift)); - p[Order::G] = (value_type)(sg + ((p[Order::G] * s1a + base_mask) >> base_shift)); - p[Order::B] = (value_type)(sb + ((p[Order::B] * s1a + base_mask) >> base_shift)); - p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { +#if 1 + blender_rgba_pre::blend_pix(p, r, g, b, a, cover); +#else + rgba s = get(r, g, b, a, cover); + rgba d = get(p); + d.r += s.r - d.r * s.a; + d.g += s.g - d.g * s.a; + d.b += s.b - d.b * s.a; + d.a += s.a - d.a * s.a; + set(p, d); +#endif } }; //======================================================comp_op_rgba_dst_over - template struct comp_op_rgba_dst_over + template + struct comp_op_rgba_dst_over : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Dca + Sca.(1 - Da) - // Da' = Sa + Da - Sa.Da + // Da' = Sa + Da - Sa.Da = Da + Sa.(1 - Da) static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - calc_type d1a = base_mask - p[Order::A]; - p[Order::R] = (value_type)(p[Order::R] + ((sr * d1a + base_mask) >> base_shift)); - p[Order::G] = (value_type)(p[Order::G] + ((sg * d1a + base_mask) >> base_shift)); - p[Order::B] = (value_type)(p[Order::B] + ((sb * d1a + base_mask) >> base_shift)); - p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + rgba s = get(r, g, b, a, cover); + rgba d = get(p); + double d1a = 1 - d.a; + d.r += s.r * d1a; + d.g += s.g * d1a; + d.b += s.b * d1a; + d.a += s.a * d1a; + set(p, d); } }; //======================================================comp_op_rgba_src_in - template struct comp_op_rgba_src_in + template + struct comp_op_rgba_src_in : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Sca.Da // Da' = Sa.Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - calc_type da = p[Order::A]; - if(cover < 255) + double da = ColorT::to_double(p[Order::A]); + if (da > 0) { - unsigned alpha = 255 - cover; - p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((((sr * da + base_mask) >> base_shift) * cover + 255) >> 8)); - p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((((sg * da + base_mask) >> base_shift) * cover + 255) >> 8)); - p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((((sb * da + base_mask) >> base_shift) * cover + 255) >> 8)); - p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((((sa * da + base_mask) >> base_shift) * cover + 255) >> 8)); - } - else - { - p[Order::R] = (value_type)((sr * da + base_mask) >> base_shift); - p[Order::G] = (value_type)((sg * da + base_mask) >> base_shift); - p[Order::B] = (value_type)((sb * da + base_mask) >> base_shift); - p[Order::A] = (value_type)((sa * da + base_mask) >> base_shift); + rgba s = get(r, g, b, a, cover); + rgba d = get(p, cover_full - cover); + d.r += s.r * da; + d.g += s.g * da; + d.b += s.b * da; + d.a += s.a * da; + set(p, d); } } }; //======================================================comp_op_rgba_dst_in - template struct comp_op_rgba_dst_in + template + struct comp_op_rgba_dst_in : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Dca.Sa // Da' = Sa.Da static AGG_INLINE void blend_pix(value_type* p, - unsigned, unsigned, unsigned, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) - { - sa = base_mask - ((cover * (base_mask - sa) + 255) >> 8); - } - p[Order::R] = (value_type)((p[Order::R] * sa + base_mask) >> base_shift); - p[Order::G] = (value_type)((p[Order::G] * sa + base_mask) >> base_shift); - p[Order::B] = (value_type)((p[Order::B] * sa + base_mask) >> base_shift); - p[Order::A] = (value_type)((p[Order::A] * sa + base_mask) >> base_shift); + double sa = ColorT::to_double(a); + rgba d = get(p, cover_full - cover); + rgba d2 = get(p, cover); + d.r += d2.r * sa; + d.g += d2.g * sa; + d.b += d2.b * sa; + d.a += d2.a * sa; + set(p, d); } }; //======================================================comp_op_rgba_src_out - template struct comp_op_rgba_src_out + template + struct comp_op_rgba_src_out : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Sca.(1 - Da) // Da' = Sa.(1 - Da) static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - calc_type da = base_mask - p[Order::A]; - if(cover < 255) - { - unsigned alpha = 255 - cover; - p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((((sr * da + base_mask) >> base_shift) * cover + 255) >> 8)); - p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((((sg * da + base_mask) >> base_shift) * cover + 255) >> 8)); - p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((((sb * da + base_mask) >> base_shift) * cover + 255) >> 8)); - p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((((sa * da + base_mask) >> base_shift) * cover + 255) >> 8)); - } - else - { - p[Order::R] = (value_type)((sr * da + base_mask) >> base_shift); - p[Order::G] = (value_type)((sg * da + base_mask) >> base_shift); - p[Order::B] = (value_type)((sb * da + base_mask) >> base_shift); - p[Order::A] = (value_type)((sa * da + base_mask) >> base_shift); - } + rgba s = get(r, g, b, a, cover); + rgba d = get(p, cover_full - cover); + double d1a = 1 - ColorT::to_double(p[Order::A]); + d.r += s.r * d1a; + d.g += s.g * d1a; + d.b += s.b * d1a; + d.a += s.a * d1a; + set(p, d); } }; //======================================================comp_op_rgba_dst_out - template struct comp_op_rgba_dst_out + template + struct comp_op_rgba_dst_out : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Dca.(1 - Sa) // Da' = Da.(1 - Sa) static AGG_INLINE void blend_pix(value_type* p, - unsigned, unsigned, unsigned, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) - { - sa = (sa * cover + 255) >> 8; - } - sa = base_mask - sa; - p[Order::R] = (value_type)((p[Order::R] * sa + base_shift) >> base_shift); - p[Order::G] = (value_type)((p[Order::G] * sa + base_shift) >> base_shift); - p[Order::B] = (value_type)((p[Order::B] * sa + base_shift) >> base_shift); - p[Order::A] = (value_type)((p[Order::A] * sa + base_shift) >> base_shift); + rgba d = get(p, cover_full - cover); + rgba dc = get(p, cover); + double s1a = 1 - ColorT::to_double(a); + d.r += dc.r * s1a; + d.g += dc.g * s1a; + d.b += dc.b * s1a; + d.a += dc.a * s1a; + set(p, d); } }; //=====================================================comp_op_rgba_src_atop - template struct comp_op_rgba_src_atop + template + struct comp_op_rgba_src_atop : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Sca.Da + Dca.(1 - Sa) // Da' = Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - calc_type da = p[Order::A]; - sa = base_mask - sa; - p[Order::R] = (value_type)((sr * da + p[Order::R] * sa + base_mask) >> base_shift); - p[Order::G] = (value_type)((sg * da + p[Order::G] * sa + base_mask) >> base_shift); - p[Order::B] = (value_type)((sb * da + p[Order::B] * sa + base_mask) >> base_shift); + rgba s = get(r, g, b, a, cover); + rgba d = get(p); + double s1a = 1 - s.a; + d.r = s.r * d.a + d.r * s1a; + d.g = s.g * d.a + d.g * s1a; + d.b = s.b * d.a + d.g * s1a; + set(p, d); } }; //=====================================================comp_op_rgba_dst_atop - template struct comp_op_rgba_dst_atop + template + struct comp_op_rgba_dst_atop : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Dca.Sa + Sca.(1 - Da) // Da' = Sa static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) - { - calc_type da = base_mask - p[Order::A]; - if(cover < 255) - { - unsigned alpha = 255 - cover; - sr = (p[Order::R] * sa + sr * da + base_mask) >> base_shift; - sg = (p[Order::G] * sa + sg * da + base_mask) >> base_shift; - sb = (p[Order::B] * sa + sb * da + base_mask) >> base_shift; - p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((sr * cover + 255) >> 8)); - p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((sg * cover + 255) >> 8)); - p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((sb * cover + 255) >> 8)); - p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((sa * cover + 255) >> 8)); - - } - else - { - p[Order::R] = (value_type)((p[Order::R] * sa + sr * da + base_mask) >> base_shift); - p[Order::G] = (value_type)((p[Order::G] * sa + sg * da + base_mask) >> base_shift); - p[Order::B] = (value_type)((p[Order::B] * sa + sb * da + base_mask) >> base_shift); - p[Order::A] = (value_type)sa; - } + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba sc = get(r, g, b, a, cover); + rgba dc = get(p, cover); + rgba d = get(p, cover_full - cover); + double sa = ColorT::to_double(a); + double d1a = 1 - ColorT::to_double(p[Order::A]); + d.r += dc.r * sa + sc.r * d1a; + d.g += dc.g * sa + sc.g * d1a; + d.b += dc.b * sa + sc.b * d1a; + d.a += sc.a; + set(p, d); } }; //=========================================================comp_op_rgba_xor - template struct comp_op_rgba_xor + template + struct comp_op_rgba_xor : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Sca.(1 - Da) + Dca.(1 - Sa) // Da' = Sa + Da - 2.Sa.Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) - { - if(cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) - { - calc_type s1a = base_mask - sa; - calc_type d1a = base_mask - p[Order::A]; - p[Order::R] = (value_type)((p[Order::R] * s1a + sr * d1a + base_mask) >> base_shift); - p[Order::G] = (value_type)((p[Order::G] * s1a + sg * d1a + base_mask) >> base_shift); - p[Order::B] = (value_type)((p[Order::B] * s1a + sb * d1a + base_mask) >> base_shift); - p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask/2) >> (base_shift - 1))); - } + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p); + double s1a = 1 - s.a; + double d1a = 1 - ColorT::to_double(p[Order::A]); + d.r = s.r * d1a + d.r * s1a; + d.g = s.g * d1a + d.g * s1a; + d.b = s.b * d1a + d.b * s1a; + d.a = s.a + d.a - 2 * s.a * d.a; + set(p, d); } }; //=========================================================comp_op_rgba_plus - template struct comp_op_rgba_plus + template + struct comp_op_rgba_plus : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Sca + Dca // Da' = Sa + Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) + rgba s = get(r, g, b, a, cover); + if (s.a > 0) { - calc_type dr = p[Order::R] + sr; - calc_type dg = p[Order::G] + sg; - calc_type db = p[Order::B] + sb; - calc_type da = p[Order::A] + sa; - p[Order::R] = (dr > base_mask) ? (value_type)base_mask : dr; - p[Order::G] = (dg > base_mask) ? (value_type)base_mask : dg; - p[Order::B] = (db > base_mask) ? (value_type)base_mask : db; - p[Order::A] = (da > base_mask) ? (value_type)base_mask : da; + rgba d = get(p); + d.a = sd_min(d.a + s.a, 1.0); + d.r = sd_min(d.r + s.r, d.a); + d.g = sd_min(d.g + s.g, d.a); + d.b = sd_min(d.b + s.b, d.a); + set(p, clip(d)); } } }; //========================================================comp_op_rgba_minus - template struct comp_op_rgba_minus + // Note: not included in SVG spec. + template + struct comp_op_rgba_minus : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Dca - Sca - // Da' = 1 - (1 - Sa).(1 - Da) + // Da' = 1 - (1 - Sa).(1 - Da) = Da + Sa - Sa.Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) + rgba s = get(r, g, b, a, cover); + if (s.a > 0) { - calc_type dr = p[Order::R] - sr; - calc_type dg = p[Order::G] - sg; - calc_type db = p[Order::B] - sb; - p[Order::R] = (dr > base_mask) ? 0 : dr; - p[Order::G] = (dg > base_mask) ? 0 : dg; - p[Order::B] = (db > base_mask) ? 0 : db; - p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); - //p[Order::A] = (value_type)(base_mask - (((base_mask - sa) * (base_mask - p[Order::A]) + base_mask) >> base_shift)); + rgba d = get(p); + d.a += s.a - s.a * d.a; + d.r = sd_max(d.r - s.r, 0.0); + d.g = sd_max(d.g - s.g, 0.0); + d.b = sd_max(d.b - s.b, 0.0); + set(p, clip(d)); } } }; //=====================================================comp_op_rgba_multiply - template struct comp_op_rgba_multiply + template + struct comp_op_rgba_multiply : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) // Da' = Sa + Da - Sa.Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) + rgba s = get(r, g, b, a, cover); + if (s.a > 0) { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) - { - calc_type s1a = base_mask - sa; - calc_type d1a = base_mask - p[Order::A]; - calc_type dr = p[Order::R]; - calc_type dg = p[Order::G]; - calc_type db = p[Order::B]; - p[Order::R] = (value_type)((sr * dr + sr * d1a + dr * s1a + base_mask) >> base_shift); - p[Order::G] = (value_type)((sg * dg + sg * d1a + dg * s1a + base_mask) >> base_shift); - p[Order::B] = (value_type)((sb * db + sb * d1a + db * s1a + base_mask) >> base_shift); - p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + rgba d = get(p); + double s1a = 1 - s.a; + double d1a = 1 - d.a; + d.r = s.r * d.r + s.r * d1a + d.r * s1a; + d.g = s.g * d.g + s.g * d1a + d.g * s1a; + d.b = s.b * d.b + s.b * d1a + d.b * s1a; + d.a += s.a - s.a * d.a; + set(p, clip(d)); } } }; //=====================================================comp_op_rgba_screen - template struct comp_op_rgba_screen + template + struct comp_op_rgba_screen : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Sca + Dca - Sca.Dca // Da' = Sa + Da - Sa.Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) + rgba s = get(r, g, b, a, cover); + if (s.a > 0) { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) - { - calc_type dr = p[Order::R]; - calc_type dg = p[Order::G]; - calc_type db = p[Order::B]; - calc_type da = p[Order::A]; - p[Order::R] = (value_type)(sr + dr - ((sr * dr + base_mask) >> base_shift)); - p[Order::G] = (value_type)(sg + dg - ((sg * dg + base_mask) >> base_shift)); - p[Order::B] = (value_type)(sb + db - ((sb * db + base_mask) >> base_shift)); - p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + rgba d = get(p); + d.r += s.r - s.r * d.r; + d.g += s.g - s.g * d.g; + d.b += s.b - s.b * d.b; + d.a += s.a - s.a * d.a; + set(p, clip(d)); } } }; //=====================================================comp_op_rgba_overlay - template struct comp_op_rgba_overlay + template + struct comp_op_rgba_overlay : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; - // if 2.Dca < Da + // if 2.Dca <= Da // Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) // otherwise // Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa) // // Da' = Sa + Da - Sa.Da + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + return (2 * dca <= da) ? + 2 * sca * dca + sca * d1a + dca * s1a : + sada - 2 * (da - dca) * (sa - sca) + sca * d1a + dca * s1a; + } + static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) + rgba s = get(r, g, b, a, cover); + if (s.a > 0) { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) - { - calc_type d1a = base_mask - p[Order::A]; - calc_type s1a = base_mask - sa; - calc_type dr = p[Order::R]; - calc_type dg = p[Order::G]; - calc_type db = p[Order::B]; - calc_type da = p[Order::A]; - calc_type sada = sa * p[Order::A]; - - p[Order::R] = (value_type)(((2*dr < da) ? - 2*sr*dr + sr*d1a + dr*s1a : - sada - 2*(da - dr)*(sa - sr) + sr*d1a + dr*s1a + base_mask) >> base_shift); - - p[Order::G] = (value_type)(((2*dg < da) ? - 2*sg*dg + sg*d1a + dg*s1a : - sada - 2*(da - dg)*(sa - sg) + sg*d1a + dg*s1a + base_mask) >> base_shift); - - p[Order::B] = (value_type)(((2*db < da) ? - 2*sb*db + sb*d1a + db*s1a : - sada - 2*(da - db)*(sa - sb) + sb*d1a + db*s1a + base_mask) >> base_shift); - - p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + double sada = s.a * d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - s.a * d.a; + set(p, clip(d)); } } }; - - template inline T sd_min(T a, T b) { return (a < b) ? a : b; } - template inline T sd_max(T a, T b) { return (a > b) ? a : b; } - //=====================================================comp_op_rgba_darken - template struct comp_op_rgba_darken + template + struct comp_op_rgba_darken : blender_base { - typedef ColorT color_type; - typedef Order order_type; - typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base::get; + using blender_base::set; // Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) // Da' = Sa + Da - Sa.Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) + rgba s = get(r, g, b, a, cover); + if (s.a > 0) { - calc_type d1a = base_mask - p[Order::A]; - calc_type s1a = base_mask - sa; - calc_type dr = p[Order::R]; - calc_type dg = p[Order::G]; - calc_type db = p[Order::B]; - calc_type da = p[Order::A]; - - p[Order::R] = (value_type)((sd_min(sr * da, dr * sa) + sr * d1a + dr * s1a + base_mask) >> base_shift); - p[Order::G] = (value_type)((sd_min(sg * da, dg * sa) + sg * d1a + dg * s1a + base_mask) >> base_shift); - p[Order::B] = (value_type)((sd_min(sb * da, db * sa) + sb * d1a + db * s1a + base_mask) >> base_shift); - p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + d.r = sd_min(s.r * d.a, d.r * s.a) + s.r * d1a + d.r * s1a; + d.g = sd_min(s.g * d.a, d.g * s.a) + s.g * d1a + d.g * s1a; + d.b = sd_min(s.b * d.a, d.b * s.a) + s.b * d1a + d.b * s1a; + d.a += s.a - s.a * d.a; + set(p, clip(d)); } } }; //=====================================================comp_op_rgba_lighten - template struct comp_op_rgba_lighten + template + struct comp_op_rgba_lighten : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) // Da' = Sa + Da - Sa.Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) + rgba s = get(r, g, b, a, cover); + if (s.a > 0) { - calc_type d1a = base_mask - p[Order::A]; - calc_type s1a = base_mask - sa; - calc_type dr = p[Order::R]; - calc_type dg = p[Order::G]; - calc_type db = p[Order::B]; - calc_type da = p[Order::A]; - - p[Order::R] = (value_type)((sd_max(sr * da, dr * sa) + sr * d1a + dr * s1a + base_mask) >> base_shift); - p[Order::G] = (value_type)((sd_max(sg * da, dg * sa) + sg * d1a + dg * s1a + base_mask) >> base_shift); - p[Order::B] = (value_type)((sd_max(sb * da, db * sa) + sb * d1a + db * s1a + base_mask) >> base_shift); - p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + d.r = sd_max(s.r * d.a, d.r * s.a) + s.r * d1a + d.r * s1a; + d.g = sd_max(s.g * d.a, d.g * s.a) + s.g * d1a + d.g * s1a; + d.b = sd_max(s.b * d.a, d.b * s.a) + s.b * d1a + d.b * s1a; + d.a += s.a - s.a * d.a; + set(p, clip(d)); } } }; //=====================================================comp_op_rgba_color_dodge - template struct comp_op_rgba_color_dodge + template + struct comp_op_rgba_color_dodge : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - typedef typename color_type::long_type long_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; - - // if Sca.Da + Dca.Sa >= Sa.Da - // Dca' = Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa) - // otherwise - // Dca' = Dca.Sa/(1-Sca/Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + using blender_base::get; + using blender_base::set; + + // if Sca == Sa and Dca == 0 + // Dca' = Sca.(1 - Da) + Dca.(1 - Sa) = Sca.(1 - Da) + // otherwise if Sca == Sa + // Dca' = Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise if Sca < Sa + // Dca' = Sa.Da.min(1, Dca/Da.Sa/(Sa - Sca)) + Sca.(1 - Da) + Dca.(1 - Sa) // - // Da' = Sa + Da - Sa.Da + // Da' = Sa + Da - Sa.Da + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + if (sca < sa) return sada * sd_min(1.0, (dca / da) * sa / (sa - sca)) + sca * d1a + dca * s1a; + if (dca > 0) return sada + sca * d1a + dca * s1a; + return sca * d1a; + } + static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) + rgba s = get(r, g, b, a, cover); + if (s.a > 0) { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) - { - calc_type d1a = base_mask - p[Order::A]; - calc_type s1a = base_mask - sa; - calc_type dr = p[Order::R]; - calc_type dg = p[Order::G]; - calc_type db = p[Order::B]; - calc_type da = p[Order::A]; - long_type drsa = dr * sa; - long_type dgsa = dg * sa; - long_type dbsa = db * sa; - long_type srda = sr * da; - long_type sgda = sg * da; - long_type sbda = sb * da; - long_type sada = sa * da; - - p[Order::R] = (value_type)((srda + drsa >= sada) ? - (sada + sr * d1a + dr * s1a + base_mask) >> base_shift : - drsa / (base_mask - (sr << base_shift) / sa) + ((sr * d1a + dr * s1a + base_mask) >> base_shift)); - - p[Order::G] = (value_type)((sgda + dgsa >= sada) ? - (sada + sg * d1a + dg * s1a + base_mask) >> base_shift : - dgsa / (base_mask - (sg << base_shift) / sa) + ((sg * d1a + dg * s1a + base_mask) >> base_shift)); - - p[Order::B] = (value_type)((sbda + dbsa >= sada) ? - (sada + sb * d1a + db * s1a + base_mask) >> base_shift : - dbsa / (base_mask - (sb << base_shift) / sa) + ((sb * d1a + db * s1a + base_mask) >> base_shift)); - - p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + rgba d = get(p); + if (d.a > 0) + { + double sada = s.a * d.a; + double s1a = 1 - s.a; + double d1a = 1 - d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + else set(p, s); } } }; //=====================================================comp_op_rgba_color_burn - template struct comp_op_rgba_color_burn + template + struct comp_op_rgba_color_burn : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - typedef typename color_type::long_type long_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; + + // if Sca == 0 and Dca == Da + // Dca' = Sa.Da + Dca.(1 - Sa) + // otherwise if Sca == 0 + // Dca' = Dca.(1 - Sa) + // otherwise if Sca > 0 + // Dca' = Sa.Da.(1 - min(1, (1 - Dca/Da).Sa/Sca)) + Sca.(1 - Da) + Dca.(1 - Sa) + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + if (sca > 0) return sada * (1 - sd_min(1.0, (1 - dca / da) * sa / sca)) + sca * d1a + dca * s1a; + if (dca > da) return sada + dca * s1a; + return dca * s1a; + } - // if Sca.Da + Dca.Sa <= Sa.Da - // Dca' = Sca.(1 - Da) + Dca.(1 - Sa) - // otherwise - // Dca' = Sa.(Sca.Da + Dca.Sa - Sa.Da)/Sca + Sca.(1 - Da) + Dca.(1 - Sa) - // - // Da' = Sa + Da - Sa.Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) + rgba s = get(r, g, b, a, cover); + if (s.a > 0) { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) - { - calc_type d1a = base_mask - p[Order::A]; - calc_type s1a = base_mask - sa; - calc_type dr = p[Order::R]; - calc_type dg = p[Order::G]; - calc_type db = p[Order::B]; - calc_type da = p[Order::A]; - long_type drsa = dr * sa; - long_type dgsa = dg * sa; - long_type dbsa = db * sa; - long_type srda = sr * da; - long_type sgda = sg * da; - long_type sbda = sb * da; - long_type sada = sa * da; - - p[Order::R] = (value_type)(((srda + drsa <= sada) ? - sr * d1a + dr * s1a : - sa * (srda + drsa - sada) / sr + sr * d1a + dr * s1a + base_mask) >> base_shift); - - p[Order::G] = (value_type)(((sgda + dgsa <= sada) ? - sg * d1a + dg * s1a : - sa * (sgda + dgsa - sada) / sg + sg * d1a + dg * s1a + base_mask) >> base_shift); - - p[Order::B] = (value_type)(((sbda + dbsa <= sada) ? - sb * d1a + db * s1a : - sa * (sbda + dbsa - sada) / sb + sb * d1a + db * s1a + base_mask) >> base_shift); - - p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + rgba d = get(p); + if (d.a > 0) + { + double sada = s.a * d.a; + double s1a = 1 - s.a; + double d1a = 1 - d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - sada; + set(p, clip(d)); + } + else set(p, s); } } }; //=====================================================comp_op_rgba_hard_light - template struct comp_op_rgba_hard_light + template + struct comp_op_rgba_hard_light : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - typedef typename color_type::long_type long_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // if 2.Sca < Sa // Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) @@ -1082,191 +902,137 @@ namespace agg // Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa) // // Da' = Sa + Da - Sa.Da + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + return (2 * sca < sa) ? + 2 * sca * dca + sca * d1a + dca * s1a : + sada - 2 * (da - dca) * (sa - sca) + sca * d1a + dca * s1a; + } + static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) + rgba s = get(r, g, b, a, cover); + if (s.a > 0) { - calc_type d1a = base_mask - p[Order::A]; - calc_type s1a = base_mask - sa; - calc_type dr = p[Order::R]; - calc_type dg = p[Order::G]; - calc_type db = p[Order::B]; - calc_type da = p[Order::A]; - calc_type sada = sa * da; - - p[Order::R] = (value_type)(((2*sr < sa) ? - 2*sr*dr + sr*d1a + dr*s1a : - sada - 2*(da - dr)*(sa - sr) + sr*d1a + dr*s1a + base_mask) >> base_shift); - - p[Order::G] = (value_type)(((2*sg < sa) ? - 2*sg*dg + sg*d1a + dg*s1a : - sada - 2*(da - dg)*(sa - sg) + sg*d1a + dg*s1a + base_mask) >> base_shift); - - p[Order::B] = (value_type)(((2*sb < sa) ? - 2*sb*db + sb*d1a + db*s1a : - sada - 2*(da - db)*(sa - sb) + sb*d1a + db*s1a + base_mask) >> base_shift); - - p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + double sada = s.a * d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - sada; + set(p, clip(d)); } } }; //=====================================================comp_op_rgba_soft_light - template struct comp_op_rgba_soft_light + template + struct comp_op_rgba_soft_light : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - typedef typename color_type::long_type long_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; - - // if 2.Sca < Sa - // Dca' = Dca.(Sa + (1 - Dca/Da).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa) - // otherwise if 8.Dca <= Da - // Dca' = Dca.(Sa + (1 - Dca/Da).(2.Sca - Sa).(3 - 8.Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa) - // otherwise - // Dca' = (Dca.Sa + ((Dca/Da)^(0.5).Da - Dca).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa) + using blender_base::get; + using blender_base::set; + + // if 2.Sca <= Sa + // Dca' = Dca.Sa - (Sa.Da - 2.Sca.Da).Dca.Sa.(Sa.Da - Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise if 2.Sca > Sa and 4.Dca <= Da + // Dca' = Dca.Sa + (2.Sca.Da - Sa.Da).((((16.Dsa.Sa - 12).Dsa.Sa + 4).Dsa.Da) - Dsa.Da) + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise if 2.Sca > Sa and 4.Dca > Da + // Dca' = Dca.Sa + (2.Sca.Da - Sa.Da).((Dca.Sa)^0.5 - Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) // // Da' = Sa + Da - Sa.Da + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + double dcasa = dca * sa; + if (2 * sca <= sa) return dcasa - (sada - 2 * sca * da) * dcasa * (sada - dcasa) + sca * d1a + dca * s1a; + if (4 * dca <= da) return dcasa + (2 * sca * da - sada) * ((((16 * dcasa - 12) * dcasa + 4) * dca * da) - dca * da) + sca * d1a + dca * s1a; + return dcasa + (2 * sca * da - sada) * (sqrt(dcasa) - dcasa) + sca * d1a + dca * s1a; + } static AGG_INLINE void blend_pix(value_type* p, - unsigned r, unsigned g, unsigned b, - unsigned a, unsigned cover) - { - double sr = double(r * cover) / (base_mask * 255); - double sg = double(g * cover) / (base_mask * 255); - double sb = double(b * cover) / (base_mask * 255); - double sa = double(a * cover) / (base_mask * 255); - if(sa > 0) - { - double dr = double(p[Order::R]) / base_mask; - double dg = double(p[Order::G]) / base_mask; - double db = double(p[Order::B]) / base_mask; - double da = double(p[Order::A] ? p[Order::A] : 1) / base_mask; - if(cover < 255) + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + if (d.a > 0) { - a = (a * cover + 255) >> 8; + double sada = s.a * d.a; + double s1a = 1 - s.a; + double d1a = 1 - d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - sada; + set(p, clip(d)); } - - if(2*sr < sa) dr = dr*(sa + (1 - dr/da)*(2*sr - sa)) + sr*(1 - da) + dr*(1 - sa); - else if(8*dr <= da) dr = dr*(sa + (1 - dr/da)*(2*sr - sa)*(3 - 8*dr/da)) + sr*(1 - da) + dr*(1 - sa); - else dr = (dr*sa + (sqrt(dr/da)*da - dr)*(2*sr - sa)) + sr*(1 - da) + dr*(1 - sa); - - if(2*sg < sa) dg = dg*(sa + (1 - dg/da)*(2*sg - sa)) + sg*(1 - da) + dg*(1 - sa); - else if(8*dg <= da) dg = dg*(sa + (1 - dg/da)*(2*sg - sa)*(3 - 8*dg/da)) + sg*(1 - da) + dg*(1 - sa); - else dg = (dg*sa + (sqrt(dg/da)*da - dg)*(2*sg - sa)) + sg*(1 - da) + dg*(1 - sa); - - if(2*sb < sa) db = db*(sa + (1 - db/da)*(2*sb - sa)) + sb*(1 - da) + db*(1 - sa); - else if(8*db <= da) db = db*(sa + (1 - db/da)*(2*sb - sa)*(3 - 8*db/da)) + sb*(1 - da) + db*(1 - sa); - else db = (db*sa + (sqrt(db/da)*da - db)*(2*sb - sa)) + sb*(1 - da) + db*(1 - sa); - - p[Order::R] = (value_type)uround(dr * base_mask); - p[Order::G] = (value_type)uround(dg * base_mask); - p[Order::B] = (value_type)uround(db * base_mask); - p[Order::A] = (value_type)(a + p[Order::A] - ((a * p[Order::A] + base_mask) >> base_shift)); + else set(p, s); } } }; //=====================================================comp_op_rgba_difference - template struct comp_op_rgba_difference + template + struct comp_op_rgba_difference : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - typedef typename color_type::long_type long_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_scale = color_type::base_scale, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = Sca + Dca - 2.min(Sca.Da, Dca.Sa) // Da' = Sa + Da - Sa.Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) + rgba s = get(r, g, b, a, cover); + if (s.a > 0) { - calc_type dr = p[Order::R]; - calc_type dg = p[Order::G]; - calc_type db = p[Order::B]; - calc_type da = p[Order::A]; - p[Order::R] = (value_type)(sr + dr - ((2 * sd_min(sr*da, dr*sa) + base_mask) >> base_shift)); - p[Order::G] = (value_type)(sg + dg - ((2 * sd_min(sg*da, dg*sa) + base_mask) >> base_shift)); - p[Order::B] = (value_type)(sb + db - ((2 * sd_min(sb*da, db*sa) + base_mask) >> base_shift)); - p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + rgba d = get(p); + d.r += s.r - 2 * sd_min(s.r * d.a, d.r * s.a); + d.g += s.g - 2 * sd_min(s.g * d.a, d.g * s.a); + d.b += s.b - 2 * sd_min(s.b * d.a, d.b * s.a); + d.a += s.a - s.a * d.a; + set(p, clip(d)); } } }; //=====================================================comp_op_rgba_exclusion - template struct comp_op_rgba_exclusion + template + struct comp_op_rgba_exclusion : blender_base { typedef ColorT color_type; - typedef Order order_type; typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - typedef typename color_type::long_type long_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + using blender_base::get; + using blender_base::set; // Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa) // Da' = Sa + Da - Sa.Da static AGG_INLINE void blend_pix(value_type* p, - unsigned sr, unsigned sg, unsigned sb, - unsigned sa, unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - if(cover < 255) - { - sr = (sr * cover + 255) >> 8; - sg = (sg * cover + 255) >> 8; - sb = (sb * cover + 255) >> 8; - sa = (sa * cover + 255) >> 8; - } - if(sa) + rgba s = get(r, g, b, a, cover); + if (s.a > 0) { - calc_type d1a = base_mask - p[Order::A]; - calc_type s1a = base_mask - sa; - calc_type dr = p[Order::R]; - calc_type dg = p[Order::G]; - calc_type db = p[Order::B]; - calc_type da = p[Order::A]; - p[Order::R] = (value_type)((sr*da + dr*sa - 2*sr*dr + sr*d1a + dr*s1a + base_mask) >> base_shift); - p[Order::G] = (value_type)((sg*da + dg*sa - 2*sg*dg + sg*d1a + dg*s1a + base_mask) >> base_shift); - p[Order::B] = (value_type)((sb*da + db*sa - 2*sb*db + sb*d1a + db*s1a + base_mask) >> base_shift); - p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + d.r = (s.r * d.a + d.r * s.a - 2 * s.r * d.r) + s.r * d1a + d.r * s1a; + d.g = (s.g * d.a + d.g * s.a - 2 * s.g * d.g) + s.g * d1a + d.g * s1a; + d.b = (s.b * d.a + d.b * s.a - 2 * s.b * d.b) + s.b * d1a + d.b * s1a; + d.a += s.a - s.a * d.a; + set(p, clip(d)); } } }; +#if 0 //=====================================================comp_op_rgba_contrast template struct comp_op_rgba_contrast { @@ -1286,7 +1052,7 @@ namespace agg unsigned sr, unsigned sg, unsigned sb, unsigned sa, unsigned cover) { - if(cover < 255) + if (cover < 255) { sr = (sr * cover + 255) >> 8; sg = (sg * cover + 255) >> 8; @@ -1335,7 +1101,7 @@ namespace agg unsigned sa, unsigned cover) { sa = (sa * cover + 255) >> 8; - if(sa) + if (sa) { calc_type da = p[Order::A]; calc_type dr = ((da - p[Order::R]) * sa + base_mask) >> base_shift; @@ -1370,14 +1136,14 @@ namespace agg unsigned sr, unsigned sg, unsigned sb, unsigned sa, unsigned cover) { - if(cover < 255) + if (cover < 255) { sr = (sr * cover + 255) >> 8; sg = (sg * cover + 255) >> 8; sb = (sb * cover + 255) >> 8; sa = (sa * cover + 255) >> 8; } - if(sa) + if (sa) { calc_type da = p[Order::A]; calc_type dr = ((da - p[Order::R]) * sr + base_mask) >> base_shift; @@ -1391,21 +1157,20 @@ namespace agg } } }; - - - +#endif //======================================================comp_op_table_rgba template struct comp_op_table_rgba { typedef typename ColorT::value_type value_type; + typedef typename ColorT::calc_type calc_type; typedef void (*comp_op_func_type)(value_type* p, - unsigned cr, - unsigned cg, - unsigned cb, - unsigned ca, - unsigned cover); + value_type cr, + value_type cg, + value_type cb, + value_type ca, + cover_type cover); static comp_op_func_type g_comp_op_func[]; }; @@ -1427,7 +1192,7 @@ namespace agg comp_op_rgba_dst_atop ::blend_pix, comp_op_rgba_xor ::blend_pix, comp_op_rgba_plus ::blend_pix, - comp_op_rgba_minus ::blend_pix, + //comp_op_rgba_minus ::blend_pix, comp_op_rgba_multiply ::blend_pix, comp_op_rgba_screen ::blend_pix, comp_op_rgba_overlay ::blend_pix, @@ -1439,9 +1204,9 @@ namespace agg comp_op_rgba_soft_light ::blend_pix, comp_op_rgba_difference ::blend_pix, comp_op_rgba_exclusion ::blend_pix, - comp_op_rgba_contrast ::blend_pix, - comp_op_rgba_invert ::blend_pix, - comp_op_rgba_invert_rgb ::blend_pix, + //comp_op_rgba_contrast ::blend_pix, + //comp_op_rgba_invert ::blend_pix, + //comp_op_rgba_invert_rgb ::blend_pix, 0 }; @@ -1462,7 +1227,7 @@ namespace agg comp_op_dst_atop, //----comp_op_dst_atop comp_op_xor, //----comp_op_xor comp_op_plus, //----comp_op_plus - comp_op_minus, //----comp_op_minus + //comp_op_minus, //----comp_op_minus comp_op_multiply, //----comp_op_multiply comp_op_screen, //----comp_op_screen comp_op_overlay, //----comp_op_overlay @@ -1474,9 +1239,9 @@ namespace agg comp_op_soft_light, //----comp_op_soft_light comp_op_difference, //----comp_op_difference comp_op_exclusion, //----comp_op_exclusion - comp_op_contrast, //----comp_op_contrast - comp_op_invert, //----comp_op_invert - comp_op_invert_rgb, //----comp_op_invert_rgb + //comp_op_contrast, //----comp_op_contrast + //comp_op_invert, //----comp_op_invert + //comp_op_invert_rgb, //----comp_op_invert_rgb end_of_comp_op_e }; @@ -1488,288 +1253,373 @@ namespace agg //====================================================comp_op_adaptor_rgba - template struct comp_op_adaptor_rgba + template + struct comp_op_adaptor_rgba { - typedef Order order_type; typedef ColorT color_type; + typedef Order order_type; typedef typename color_type::value_type value_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; static AGG_INLINE void blend_pix(unsigned op, value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned ca, - unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - comp_op_table_rgba::g_comp_op_func[op] - (p, (cr * ca + base_mask) >> base_shift, - (cg * ca + base_mask) >> base_shift, - (cb * ca + base_mask) >> base_shift, - ca, cover); + comp_op_table_rgba::g_comp_op_func[op](p, + color_type::multiply(r, a), + color_type::multiply(g, a), + color_type::multiply(b, a), + a, cover); } }; //=========================================comp_op_adaptor_clip_to_dst_rgba - template struct comp_op_adaptor_clip_to_dst_rgba + template + struct comp_op_adaptor_clip_to_dst_rgba { - typedef Order order_type; typedef ColorT color_type; + typedef Order order_type; typedef typename color_type::value_type value_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; static AGG_INLINE void blend_pix(unsigned op, value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned ca, - unsigned cover) - { - cr = (cr * ca + base_mask) >> base_shift; - cg = (cg * ca + base_mask) >> base_shift; - cb = (cb * ca + base_mask) >> base_shift; - unsigned da = p[Order::A]; - comp_op_table_rgba::g_comp_op_func[op] - (p, (cr * da + base_mask) >> base_shift, - (cg * da + base_mask) >> base_shift, - (cb * da + base_mask) >> base_shift, - (ca * da + base_mask) >> base_shift, - cover); + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + r = color_type::multiply(r, a); + g = color_type::multiply(g, a); + b = color_type::multiply(b, a); + value_type da = p[Order::A]; + comp_op_table_rgba::g_comp_op_func[op](p, + color_type::multiply(r, da), + color_type::multiply(g, da), + color_type::multiply(b, da), + color_type::multiply(a, da), cover); } }; //================================================comp_op_adaptor_rgba_pre - template struct comp_op_adaptor_rgba_pre + template + struct comp_op_adaptor_rgba_pre { - typedef Order order_type; typedef ColorT color_type; + typedef Order order_type; typedef typename color_type::value_type value_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + comp_op_table_rgba::g_comp_op_func[op](p, r, g, b, a, cover); + } + }; + + //=====================================comp_op_adaptor_clip_to_dst_rgba_pre + template + struct comp_op_adaptor_clip_to_dst_rgba_pre + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + value_type da = p[Order::A]; + comp_op_table_rgba::g_comp_op_func[op](p, + color_type::multiply(r, da), + color_type::multiply(g, da), + color_type::multiply(b, da), + color_type::multiply(a, da), cover); + } + }; + + //====================================================comp_op_adaptor_rgba_plain + template + struct comp_op_adaptor_rgba_plain + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + multiplier_rgba::premultiply(p); + comp_op_adaptor_rgba::blend_pix(op, p, r, g, b, a, cover); + multiplier_rgba::demultiply(p); + } + }; + + //=========================================comp_op_adaptor_clip_to_dst_rgba_plain + template + struct comp_op_adaptor_clip_to_dst_rgba_plain + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + multiplier_rgba::premultiply(p); + comp_op_adaptor_clip_to_dst_rgba::blend_pix(op, p, r, g, b, a, cover); + multiplier_rgba::demultiply(p); + } + }; + + //=======================================================comp_adaptor_rgba + template + struct comp_adaptor_rgba + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + BlenderPre::blend_pix(p, + color_type::multiply(r, a), + color_type::multiply(g, a), + color_type::multiply(b, a), + a, cover); + } + }; + + //==========================================comp_adaptor_clip_to_dst_rgba + template + struct comp_adaptor_clip_to_dst_rgba + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; static AGG_INLINE void blend_pix(unsigned op, value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned ca, - unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - comp_op_table_rgba::g_comp_op_func[op](p, cr, cg, cb, ca, cover); + r = color_type::multiply(r, a); + g = color_type::multiply(g, a); + b = color_type::multiply(b, a); + value_type da = p[order_type::A]; + BlenderPre::blend_pix(p, + color_type::multiply(r, da), + color_type::multiply(g, da), + color_type::multiply(b, da), + color_type::multiply(a, da), cover); } }; - //=====================================comp_op_adaptor_clip_to_dst_rgba_pre - template struct comp_op_adaptor_clip_to_dst_rgba_pre + //=======================================================comp_adaptor_rgba_pre + template + struct comp_adaptor_rgba_pre { - typedef Order order_type; - typedef ColorT color_type; + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; typedef typename color_type::value_type value_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; static AGG_INLINE void blend_pix(unsigned op, value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned ca, - unsigned cover) - { - unsigned da = p[Order::A]; - comp_op_table_rgba::g_comp_op_func[op] - (p, (cr * da + base_mask) >> base_shift, - (cg * da + base_mask) >> base_shift, - (cb * da + base_mask) >> base_shift, - (ca * da + base_mask) >> base_shift, - cover); + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + BlenderPre::blend_pix(p, r, g, b, a, cover); } }; - //=======================================================comp_adaptor_rgba - template struct comp_adaptor_rgba + //======================================comp_adaptor_clip_to_dst_rgba_pre + template + struct comp_adaptor_clip_to_dst_rgba_pre { - typedef typename BlenderPre::order_type order_type; typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; typedef typename color_type::value_type value_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; static AGG_INLINE void blend_pix(unsigned op, value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned ca, - unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { + unsigned da = p[order_type::A]; BlenderPre::blend_pix(p, - (cr * ca + base_mask) >> base_shift, - (cg * ca + base_mask) >> base_shift, - (cb * ca + base_mask) >> base_shift, - ca, cover); + color_type::multiply(r, da), + color_type::multiply(g, da), + color_type::multiply(b, da), + color_type::multiply(a, da), + cover); } }; - //==========================================comp_adaptor_clip_to_dst_rgba - template struct comp_adaptor_clip_to_dst_rgba + //=======================================================comp_adaptor_rgba_plain + template + struct comp_adaptor_rgba_plain { - typedef typename BlenderPre::order_type order_type; typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; typedef typename color_type::value_type value_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; static AGG_INLINE void blend_pix(unsigned op, value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned ca, - unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - cr = (cr * ca + base_mask) >> base_shift; - cg = (cg * ca + base_mask) >> base_shift; - cb = (cb * ca + base_mask) >> base_shift; - unsigned da = p[order_type::A]; - BlenderPre::blend_pix(p, - (cr * da + base_mask) >> base_shift, - (cg * da + base_mask) >> base_shift, - (cb * da + base_mask) >> base_shift, - (ca * da + base_mask) >> base_shift, - cover); + multiplier_rgba::premultiply(p); + comp_adaptor_rgba::blend_pix(op, p, r, g, b, a, cover); + multiplier_rgba::demultiply(p); } }; - //======================================comp_adaptor_clip_to_dst_rgba_pre - template struct comp_adaptor_clip_to_dst_rgba_pre + //==========================================comp_adaptor_clip_to_dst_rgba_plain + template + struct comp_adaptor_clip_to_dst_rgba_plain { - typedef typename BlenderPre::order_type order_type; typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; typedef typename color_type::value_type value_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; static AGG_INLINE void blend_pix(unsigned op, value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned ca, - unsigned cover) + value_type r, value_type g, value_type b, value_type a, cover_type cover) { - unsigned da = p[order_type::A]; - BlenderPre::blend_pix(p, - (cr * da + base_mask) >> base_shift, - (cg * da + base_mask) >> base_shift, - (cb * da + base_mask) >> base_shift, - (ca * da + base_mask) >> base_shift, - cover); + multiplier_rgba::premultiply(p); + comp_adaptor_clip_to_dst_rgba::blend_pix(op, p, r, g, b, a, cover); + multiplier_rgba::demultiply(p); } }; - - - - - //===============================================copy_or_blend_rgba_wrapper - template struct copy_or_blend_rgba_wrapper + //=================================================pixfmt_alpha_blend_rgba + template + class pixfmt_alpha_blend_rgba { - typedef typename Blender::color_type color_type; - typedef typename Blender::order_type order_type; + public: + typedef pixfmt_rgba_tag pixfmt_category; + typedef RenBuf rbuf_type; + typedef typename rbuf_type::row_data row_data; + typedef Blender blender_type; + typedef typename blender_type::color_type color_type; + typedef typename blender_type::order_type order_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e + enum { - base_shift = color_type::base_shift, - base_scale = color_type::base_scale, - base_mask = color_type::base_mask + num_components = 4, + pix_step = 4, + pix_width = sizeof(value_type) * pix_step, + }; + struct pixel_type + { + value_type c[num_components]; + + void set(value_type r, value_type g, value_type b, value_type a) + { + c[order_type::R] = r; + c[order_type::G] = g; + c[order_type::B] = b; + c[order_type::A] = a; + } + + void set(const color_type& color) + { + set(color.r, color.g, color.b, color.a); + } + + void get(value_type& r, value_type& g, value_type& b, value_type& a) const + { + r = c[order_type::R]; + g = c[order_type::G]; + b = c[order_type::B]; + a = c[order_type::A]; + } + + color_type get() const + { + return color_type( + c[order_type::R], + c[order_type::G], + c[order_type::B], + c[order_type::A]); + } + + pixel_type* next() + { + return (pixel_type*)(c + pix_step); + } + + const pixel_type* next() const + { + return (const pixel_type*)(c + pix_step); + } + + pixel_type* advance(int n) + { + return (pixel_type*)(c + n * pix_step); + } + + const pixel_type* advance(int n) const + { + return (const pixel_type*)(c + n * pix_step); + } }; + private: + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c) + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a); + } + //-------------------------------------------------------------------- - static AGG_INLINE void copy_or_blend_pix(value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned alpha) + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover) { - if(alpha) + if (!c.is_transparent()) { - if(alpha == base_mask) + if (c.is_opaque() && cover == cover_mask) { - p[order_type::R] = cr; - p[order_type::G] = cg; - p[order_type::B] = cb; - p[order_type::A] = base_mask; + p->set(c.r, c.g, c.b, c.a); } else { - Blender::blend_pix(p, cr, cg, cb, alpha); + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover); } } } //-------------------------------------------------------------------- - static AGG_INLINE void copy_or_blend_pix(value_type* p, - unsigned cr, unsigned cg, unsigned cb, - unsigned alpha, - unsigned cover) + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c) { - if(cover == 255) + if (!c.is_transparent()) { - copy_or_blend_pix(p, cr, cg, cb, alpha); - } - else - { - if(alpha) + if (c.is_opaque()) { - alpha = (alpha * (cover + 1)) >> 8; - if(alpha == base_mask) - { - p[order_type::R] = cr; - p[order_type::G] = cg; - p[order_type::B] = cb; - p[order_type::A] = base_mask; - } - else - { - Blender::blend_pix(p, cr, cg, cb, alpha, cover); - } + p->set(c.r, c.g, c.b, c.a); + } + else + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a); } } } - }; - - - - - - //=================================================pixfmt_alpha_blend_rgba - template - class pixfmt_alpha_blend_rgba - { public: - typedef RenBuf rbuf_type; - typedef typename rbuf_type::row_data row_data; - typedef PixelT pixel_type; - typedef Blender blender_type; - typedef typename blender_type::color_type color_type; - typedef typename blender_type::order_type order_type; - typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - typedef copy_or_blend_rgba_wrapper cob_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_scale = color_type::base_scale, - base_mask = color_type::base_mask, - pix_width = sizeof(pixel_type) - }; - //-------------------------------------------------------------------- pixfmt_alpha_blend_rgba() : m_rbuf(0) {} explicit pixfmt_alpha_blend_rgba(rbuf_type& rb) : m_rbuf(&rb) {} @@ -1780,7 +1630,7 @@ namespace agg bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) { rect_i r(x1, y1, x2, y2); - if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) + if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) { int stride = pixf.stride(); m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), @@ -1803,37 +1653,65 @@ namespace agg AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); } //-------------------------------------------------------------------- - AGG_INLINE int8u* pix_ptr(int x, int y) + AGG_INLINE int8u* pix_ptr(int x, int y) + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step); + } + + AGG_INLINE const int8u* pix_ptr(int x, int y) const + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step); + } + + // Return pointer to pixel value, forcing row to be allocated. + AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) + { + return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step)); + } + + // Return pointer to pixel value, or null if row not allocated. + AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const { - return m_rbuf->row_ptr(y) + x * pix_width; + int8u* p = m_rbuf->row_ptr(y); + return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step)) : 0; } - AGG_INLINE const int8u* pix_ptr(int x, int y) const + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static pixel_type* pix_value_ptr(void* p) { - return m_rbuf->row_ptr(y) + x * pix_width; + return (pixel_type*)p; } + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) + { + return (const pixel_type*)p; + } + + //-------------------------------------------------------------------- + AGG_INLINE static void write_plain_color(void* p, color_type c) + { + blender_type::set_plain_color(pix_value_ptr(p)->c, c); + } + + //-------------------------------------------------------------------- + AGG_INLINE static color_type read_plain_color(const void* p) + { + return blender_type::get_plain_color(pix_value_ptr(p)->c); + } //-------------------------------------------------------------------- AGG_INLINE static void make_pix(int8u* p, const color_type& c) { - ((value_type*)p)[order_type::R] = c.r; - ((value_type*)p)[order_type::G] = c.g; - ((value_type*)p)[order_type::B] = c.b; - ((value_type*)p)[order_type::A] = c.a; + ((pixel_type*)p)->set(c); } //-------------------------------------------------------------------- AGG_INLINE color_type pixel(int x, int y) const { - const value_type* p = (const value_type*)m_rbuf->row_ptr(y); - if(p) + if (const pixel_type* p = pix_value_ptr(x, y)) { - p += x << 2; - return color_type(p[order_type::R], - p[order_type::G], - p[order_type::B], - p[order_type::A]); + return p->get(); } return color_type::no_color(); } @@ -1841,40 +1719,29 @@ namespace agg //-------------------------------------------------------------------- AGG_INLINE void copy_pixel(int x, int y, const color_type& c) { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2); - p[order_type::R] = c.r; - p[order_type::G] = c.g; - p[order_type::B] = c.b; - p[order_type::A] = c.a; + pix_value_ptr(x, y, 1)->set(c); } //-------------------------------------------------------------------- AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) { - cob_type::copy_or_blend_pix( - (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2), - c.r, c.g, c.b, c.a, - cover); + copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover); } - //-------------------------------------------------------------------- AGG_INLINE void copy_hline(int x, int y, unsigned len, const color_type& c) { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2); pixel_type v; - ((value_type*)&v)[order_type::R] = c.r; - ((value_type*)&v)[order_type::G] = c.g; - ((value_type*)&v)[order_type::B] = c.b; - ((value_type*)&v)[order_type::A] = c.a; + v.set(c); + pixel_type* p = pix_value_ptr(x, y, len); do { - *(pixel_type*)p = v; - p += 4; + *p = v; + p = p->next(); } - while(--len); + while (--len); } @@ -1884,62 +1751,53 @@ namespace agg const color_type& c) { pixel_type v; - ((value_type*)&v)[order_type::R] = c.r; - ((value_type*)&v)[order_type::G] = c.g; - ((value_type*)&v)[order_type::B] = c.b; - ((value_type*)&v)[order_type::A] = c.a; + v.set(c); do { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); - *(pixel_type*)p = v; + *pix_value_ptr(x, y++, 1) = v; } - while(--len); + while (--len); } - //-------------------------------------------------------------------- void blend_hline(int x, int y, unsigned len, const color_type& c, int8u cover) { - if (c.a) + if (!c.is_transparent()) { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2); - calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; - if(alpha == base_mask) + pixel_type* p = pix_value_ptr(x, y, len); + if (c.is_opaque() && cover == cover_mask) { pixel_type v; - ((value_type*)&v)[order_type::R] = c.r; - ((value_type*)&v)[order_type::G] = c.g; - ((value_type*)&v)[order_type::B] = c.b; - ((value_type*)&v)[order_type::A] = c.a; + v.set(c); do { - *(pixel_type*)p = v; - p += 4; + *p = v; + p = p->next(); } - while(--len); + while (--len); } else { - if(cover == 255) + if (cover == cover_mask) { do { - blender_type::blend_pix(p, c.r, c.g, c.b, alpha); - p += 4; + blend_pix(p, c); + p = p->next(); } - while(--len); + while (--len); } else { do { - blender_type::blend_pix(p, c.r, c.g, c.b, alpha, cover); - p += 4; + blend_pix(p, c, cover); + p = p->next(); } - while(--len); + while (--len); } } } @@ -1952,43 +1810,35 @@ namespace agg const color_type& c, int8u cover) { - if (c.a) + if (!c.is_transparent()) { - value_type* p; - calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; - if(alpha == base_mask) + if (c.is_opaque() && cover == cover_mask) { pixel_type v; - ((value_type*)&v)[order_type::R] = c.r; - ((value_type*)&v)[order_type::G] = c.g; - ((value_type*)&v)[order_type::B] = c.b; - ((value_type*)&v)[order_type::A] = c.a; + v.set(c); do { - p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); - *(pixel_type*)p = v; + *pix_value_ptr(x, y++, 1) = v; } - while(--len); + while (--len); } else { - if(cover == 255) + if (cover == cover_mask) { do { - p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); - blender_type::blend_pix(p, c.r, c.g, c.b, alpha); + blend_pix(pix_value_ptr(x, y++, 1), c, c.a); } - while(--len); + while (--len); } else { do { - p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); - blender_type::blend_pix(p, c.r, c.g, c.b, alpha, cover); + blend_pix(pix_value_ptr(x, y++, 1), c, cover); } - while(--len); + while (--len); } } } @@ -2001,27 +1851,23 @@ namespace agg const color_type& c, const int8u* covers) { - if (c.a) + if (!c.is_transparent()) { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2); + pixel_type* p = pix_value_ptr(x, y, len); do { - calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8; - if(alpha == base_mask) + if (c.is_opaque() && *covers == cover_mask) { - p[order_type::R] = c.r; - p[order_type::G] = c.g; - p[order_type::B] = c.b; - p[order_type::A] = base_mask; + p->set(c); } else { - blender_type::blend_pix(p, c.r, c.g, c.b, alpha, *covers); + blend_pix(p, c, *covers); } - p += 4; + p = p->next(); ++covers; } - while(--len); + while (--len); } } @@ -2032,46 +1878,37 @@ namespace agg const color_type& c, const int8u* covers) { - if (c.a) + if (!c.is_transparent()) { do { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); - calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8; - if(alpha == base_mask) + pixel_type* p = pix_value_ptr(x, y++, 1); + if (c.is_opaque() && *covers == cover_mask) { - p[order_type::R] = c.r; - p[order_type::G] = c.g; - p[order_type::B] = c.b; - p[order_type::A] = base_mask; + p->set(c); } else { - blender_type::blend_pix(p, c.r, c.g, c.b, alpha, *covers); + blend_pix(p, c, *covers); } ++covers; } - while(--len); + while (--len); } } - //-------------------------------------------------------------------- void copy_color_hspan(int x, int y, unsigned len, const color_type* colors) { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2); + pixel_type* p = pix_value_ptr(x, y, len); do { - p[order_type::R] = colors->r; - p[order_type::G] = colors->g; - p[order_type::B] = colors->b; - p[order_type::A] = colors->a; - ++colors; - p += 4; + p->set(*colors++); + p = p->next(); } - while(--len); + while (--len); } @@ -2082,17 +1919,11 @@ namespace agg { do { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); - p[order_type::R] = colors->r; - p[order_type::G] = colors->g; - p[order_type::B] = colors->b; - p[order_type::A] = colors->a; - ++colors; + pix_value_ptr(x, y++, 1)->set(*colors++); } - while(--len); + while (--len); } - //-------------------------------------------------------------------- void blend_color_hspan(int x, int y, unsigned len, @@ -2100,58 +1931,39 @@ namespace agg const int8u* covers, int8u cover) { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2); - if(covers) + pixel_type* p = pix_value_ptr(x, y, len); + if (covers) { do { - cob_type::copy_or_blend_pix(p, - colors->r, - colors->g, - colors->b, - colors->a, - *covers++); - p += 4; - ++colors; + copy_or_blend_pix(p, *colors++, *covers++); + p = p->next(); } - while(--len); + while (--len); } else { - if(cover == 255) + if (cover == cover_mask) { do { - cob_type::copy_or_blend_pix(p, - colors->r, - colors->g, - colors->b, - colors->a); - p += 4; - ++colors; + copy_or_blend_pix(p, *colors++); + p = p->next(); } - while(--len); + while (--len); } else { do { - cob_type::copy_or_blend_pix(p, - colors->r, - colors->g, - colors->b, - colors->a, - cover); - p += 4; - ++colors; + copy_or_blend_pix(p, *colors++, cover); + p = p->next(); } - while(--len); + while (--len); } } } - - //-------------------------------------------------------------------- void blend_color_vspan(int x, int y, unsigned len, @@ -2159,52 +1971,31 @@ namespace agg const int8u* covers, int8u cover) { - value_type* p; - if(covers) + if (covers) { do { - p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); - cob_type::copy_or_blend_pix(p, - colors->r, - colors->g, - colors->b, - colors->a, - *covers++); - ++colors; + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++); } - while(--len); + while (--len); } else { - if(cover == 255) + if (cover == cover_mask) { do { - p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); - cob_type::copy_or_blend_pix(p, - colors->r, - colors->g, - colors->b, - colors->a); - ++colors; + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++); } - while(--len); + while (--len); } else { do { - p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); - cob_type::copy_or_blend_pix(p, - colors->r, - colors->g, - colors->b, - colors->a, - cover); - ++colors; + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover); } - while(--len); + while (--len); } } } @@ -2212,21 +2003,19 @@ namespace agg //-------------------------------------------------------------------- template void for_each_pixel(Function f) { - unsigned y; - for(y = 0; y < height(); ++y) + for (unsigned y = 0; y < height(); ++y) { row_data r = m_rbuf->row(y); - if(r.ptr) + if (r.ptr) { unsigned len = r.x2 - r.x1 + 1; - value_type* p = - (value_type*)m_rbuf->row_ptr(r.x1, y, len) + (r.x1 << 2); + pixel_type* p = pix_value_ptr(r.x1, y, len); do { - f(p); - p += 4; + f(p->c); + p = p->next(); } - while(--len); + while (--len); } } } @@ -2261,8 +2050,7 @@ namespace agg int xsrc, int ysrc, unsigned len) { - const int8u* p = from.row_ptr(ysrc); - if(p) + if (const int8u* p = from.row_ptr(ysrc)) { memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, p + xsrc * pix_width, @@ -2271,6 +2059,7 @@ namespace agg } //-------------------------------------------------------------------- + // Blend from another RGBA surface. template void blend_from(const SrcPixelFormatRenderer& from, int xdst, int ydst, @@ -2278,54 +2067,47 @@ namespace agg unsigned len, int8u cover) { - typedef typename SrcPixelFormatRenderer::order_type src_order; - const value_type* psrc = (value_type*)from.row_ptr(ysrc); - if(psrc) + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) { - psrc += xsrc << 2; - value_type* pdst = - (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2); - int incp = 4; - if(xdst > xsrc) + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + int srcinc = 1; + int dstinc = 1; + + if (xdst > xsrc) { - psrc += (len-1) << 2; - pdst += (len-1) << 2; - incp = -4; + psrc = psrc->advance(len - 1); + pdst = pdst->advance(len - 1); + srcinc = -1; + dstinc = -1; } - if(cover == 255) + if (cover == cover_mask) { do { - cob_type::copy_or_blend_pix(pdst, - psrc[src_order::R], - psrc[src_order::G], - psrc[src_order::B], - psrc[src_order::A]); - psrc += incp; - pdst += incp; + copy_or_blend_pix(pdst, psrc->get()); + psrc = psrc->advance(srcinc); + pdst = pdst->advance(dstinc); } - while(--len); + while (--len); } else { do { - cob_type::copy_or_blend_pix(pdst, - psrc[src_order::R], - psrc[src_order::G], - psrc[src_order::B], - psrc[src_order::A], - cover); - psrc += incp; - pdst += incp; + copy_or_blend_pix(pdst, psrc->get(), cover); + psrc = psrc->advance(srcinc); + pdst = pdst->advance(dstinc); } - while(--len); + while (--len); } } } //-------------------------------------------------------------------- + // Combine single color with grayscale surface and blend. template void blend_from_color(const SrcPixelFormatRenderer& from, const color_type& color, @@ -2334,25 +2116,27 @@ namespace agg unsigned len, int8u cover) { - typedef typename SrcPixelFormatRenderer::value_type src_value_type; - const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); - if(psrc) + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) { - value_type* pdst = - (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2); + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + do { - cob_type::copy_or_blend_pix(pdst, - color.r, color.g, color.b, color.a, - (*psrc * cover + base_mask) >> base_shift); - ++psrc; - pdst += 4; + copy_or_blend_pix(pdst, color, + src_color_type::scale_cover(cover, psrc->c[0])); + psrc = psrc->next(); + pdst = pdst->next(); } - while(--len); + while (--len); } } //-------------------------------------------------------------------- + // Blend from color table, using grayscale surface as indexes into table. + // Obviously, this only works for integer value types. template void blend_from_lut(const SrcPixelFormatRenderer& from, const color_type* color_lut, @@ -2361,52 +2145,45 @@ namespace agg unsigned len, int8u cover) { - typedef typename SrcPixelFormatRenderer::value_type src_value_type; - const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); - if(psrc) + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) { - value_type* pdst = - (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2); + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); - if(cover == 255) + if (cover == cover_mask) { do { - const color_type& color = color_lut[*psrc]; - cob_type::copy_or_blend_pix(pdst, - color.r, color.g, color.b, color.a); - ++psrc; - pdst += 4; + copy_or_blend_pix(pdst, color_lut[psrc->c[0]]); + psrc = psrc->next(); + pdst = pdst->next(); } - while(--len); + while (--len); } else { do { - const color_type& color = color_lut[*psrc]; - cob_type::copy_or_blend_pix(pdst, - color.r, color.g, color.b, color.a, - cover); - ++psrc; - pdst += 4; + copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover); + psrc = psrc->next(); + pdst = pdst->next(); } - while(--len); + while (--len); } } } private: rbuf_type* m_rbuf; + Blender m_blender; }; - - - //================================================pixfmt_custom_blend_rgba template class pixfmt_custom_blend_rgba { public: + typedef pixfmt_rgba_tag pixfmt_category; typedef RenBuf rbuf_type; typedef typename rbuf_type::row_data row_data; typedef Blender blender_type; @@ -2414,15 +2191,92 @@ namespace agg typedef typename blender_type::order_type order_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e + enum { - base_shift = color_type::base_shift, - base_scale = color_type::base_scale, - base_mask = color_type::base_mask, - pix_width = sizeof(value_type) * 4 + num_components = 4, + pix_step = 4, + pix_width = sizeof(value_type) * pix_step, + }; + struct pixel_type + { + value_type c[num_components]; + + void set(value_type r, value_type g, value_type b, value_type a) + { + c[order_type::R] = r; + c[order_type::G] = g; + c[order_type::B] = b; + c[order_type::A] = a; + } + + void set(const color_type& color) + { + set(color.r, color.g, color.b, color.a); + } + + void get(value_type& r, value_type& g, value_type& b, value_type& a) const + { + r = c[order_type::R]; + g = c[order_type::G]; + b = c[order_type::B]; + a = c[order_type::A]; + } + + color_type get() const + { + return color_type( + c[order_type::R], + c[order_type::G], + c[order_type::B], + c[order_type::A]); + } + + pixel_type* next() + { + return (pixel_type*)(c + pix_step); + } + + const pixel_type* next() const + { + return (const pixel_type*)(c + pix_step); + } + + pixel_type* advance(int n) + { + return (pixel_type*)(c + n * pix_step); + } + + const pixel_type* advance(int n) const + { + return (const pixel_type*)(c + n * pix_step); + } }; + private: + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover = cover_full) + { + m_blender.blend_pix(m_comp_op, p->c, c.r, c.g, c.b, c.a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover = cover_full) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + p->set(c.r, c.g, c.b, c.a); + } + else + { + blend_pix(p, c, cover); + } + } + } + + public: //-------------------------------------------------------------------- pixfmt_custom_blend_rgba() : m_rbuf(0), m_comp_op(3) {} explicit pixfmt_custom_blend_rgba(rbuf_type& rb, unsigned comp_op=3) : @@ -2436,7 +2290,7 @@ namespace agg bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) { rect_i r(x1, y1, x2, y2); - if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) + if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) { int stride = pixf.stride(); m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), @@ -2448,6 +2302,10 @@ namespace agg return false; } + //-------------------------------------------------------------------- + void comp_op(unsigned op) { m_comp_op = op; } + unsigned comp_op() const { return m_comp_op; } + //-------------------------------------------------------------------- AGG_INLINE unsigned width() const { return m_rbuf->width(); } AGG_INLINE unsigned height() const { return m_rbuf->height(); } @@ -2459,81 +2317,98 @@ namespace agg AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); } //-------------------------------------------------------------------- - AGG_INLINE int8u* pix_ptr(int x, int y) + AGG_INLINE int8u* pix_ptr(int x, int y) + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step); + } + + AGG_INLINE const int8u* pix_ptr(int x, int y) const + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step); + } + + // Return pointer to pixel value, forcing row to be allocated. + AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) { - return m_rbuf->row_ptr(y) + x * pix_width; + return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step)); } - AGG_INLINE const int8u* pix_ptr(int x, int y) const + // Return pointer to pixel value, or null if row not allocated. + AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const { - return m_rbuf->row_ptr(y) + x * pix_width; + int8u* p = m_rbuf->row_ptr(y); + return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step)) : 0; } - //-------------------------------------------------------------------- - void comp_op(unsigned op) { m_comp_op = op; } - unsigned comp_op() const { return m_comp_op; } + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static pixel_type* pix_value_ptr(void* p) + { + return (pixel_type*)p; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) + { + return (const pixel_type*)p; + } //-------------------------------------------------------------------- AGG_INLINE static void make_pix(int8u* p, const color_type& c) { - ((value_type*)p)[order_type::R] = c.r; - ((value_type*)p)[order_type::G] = c.g; - ((value_type*)p)[order_type::B] = c.b; - ((value_type*)p)[order_type::A] = c.a; + ((pixel_type*)p)->set(c); } //-------------------------------------------------------------------- - color_type pixel(int x, int y) const + AGG_INLINE color_type pixel(int x, int y) const { - const value_type* p = (value_type*)m_rbuf->row_ptr(y) + (x << 2); - return color_type(p[order_type::R], - p[order_type::G], - p[order_type::B], - p[order_type::A]); + if (const pixel_type* p = pix_value_ptr(x, y)) + { + return p->get(); + } + return color_type::no_color(); } //-------------------------------------------------------------------- - void copy_pixel(int x, int y, const color_type& c) + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) { - blender_type::blend_pix( - m_comp_op, - (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2), - c.r, c.g, c.b, c.a, 255); + make_pix(pix_value_ptr(x, y, 1), c); } //-------------------------------------------------------------------- - void blend_pixel(int x, int y, const color_type& c, int8u cover) + AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) { - blender_type::blend_pix( - m_comp_op, - (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2), - c.r, c.g, c.b, c.a, - cover); + blend_pix(pix_value_ptr(x, y, 1), c, cover); } //-------------------------------------------------------------------- - void copy_hline(int x, int y, unsigned len, const color_type& c) + AGG_INLINE void copy_hline(int x, int y, + unsigned len, + const color_type& c) { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);; + pixel_type v; + v.set(c); + pixel_type* p = pix_value_ptr(x, y, len); do { - blender_type::blend_pix(m_comp_op, p, c.r, c.g, c.b, c.a, 255); - p += 4; + *p = v; + p = p->next(); } - while(--len); + while (--len); } + //-------------------------------------------------------------------- - void copy_vline(int x, int y, unsigned len, const color_type& c) + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) { + pixel_type v; + v.set(c); do { - blender_type::blend_pix( - m_comp_op, - (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2), - c.r, c.g, c.b, c.a, 255); + *pix_value_ptr(x, y++, 1) = v; } - while(--len); + while (--len); } //-------------------------------------------------------------------- @@ -2541,44 +2416,38 @@ namespace agg const color_type& c, int8u cover) { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2); + pixel_type* p = pix_value_ptr(x, y, len); do { - blender_type::blend_pix(m_comp_op, p, c.r, c.g, c.b, c.a, cover); - p += 4; + blend_pix(p, c, cover); + p = p->next(); } - while(--len); + while (--len); } //-------------------------------------------------------------------- void blend_vline(int x, int y, unsigned len, const color_type& c, int8u cover) { - do { - blender_type::blend_pix( - m_comp_op, - (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2), - c.r, c.g, c.b, c.a, - cover); + blend_pix(pix_value_ptr(x, y++, 1), c, cover); } - while(--len); + while (--len); } //-------------------------------------------------------------------- void blend_solid_hspan(int x, int y, unsigned len, const color_type& c, const int8u* covers) { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2); + pixel_type* p = pix_value_ptr(x, y, len); + do { - blender_type::blend_pix(m_comp_op, - p, c.r, c.g, c.b, c.a, - *covers++); - p += 4; + blend_pix(p, c, *covers++); + p = p->next(); } - while(--len); + while (--len); } //-------------------------------------------------------------------- @@ -2587,13 +2456,9 @@ namespace agg { do { - blender_type::blend_pix( - m_comp_op, - (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2), - c.r, c.g, c.b, c.a, - *covers++); + blend_pix(pix_value_ptr(x, y++, 1), c, *covers++); } - while(--len); + while (--len); } //-------------------------------------------------------------------- @@ -2601,18 +2466,14 @@ namespace agg unsigned len, const color_type* colors) { + pixel_type* p = pix_value_ptr(x, y, len); - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2); do { - p[order_type::R] = colors->r; - p[order_type::G] = colors->g; - p[order_type::B] = colors->b; - p[order_type::A] = colors->a; - ++colors; - p += 4; + p->set(*colors++); + p = p->next(); } - while(--len); + while (--len); } //-------------------------------------------------------------------- @@ -2622,14 +2483,9 @@ namespace agg { do { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2); - p[order_type::R] = colors->r; - p[order_type::G] = colors->g; - p[order_type::B] = colors->b; - p[order_type::A] = colors->a; - ++colors; + pix_value_ptr(x, y++, 1)->set(*colors++); } - while(--len); + while (--len); } //-------------------------------------------------------------------- @@ -2638,20 +2494,14 @@ namespace agg const int8u* covers, int8u cover) { - value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2); + pixel_type* p = pix_value_ptr(x, y, len); + do { - blender_type::blend_pix(m_comp_op, - p, - colors->r, - colors->g, - colors->b, - colors->a, - covers ? *covers++ : cover); - p += 4; - ++colors; + blend_pix(p, *colors++, covers ? *covers++ : cover); + p = p->next(); } - while(--len); + while (--len); } //-------------------------------------------------------------------- @@ -2662,17 +2512,9 @@ namespace agg { do { - blender_type::blend_pix( - m_comp_op, - (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2), - colors->r, - colors->g, - colors->b, - colors->a, - covers ? *covers++ : cover); - ++colors; + blend_pix(pix_value_ptr(x, y++, 1), *colors++, covers ? *covers++ : cover); } - while(--len); + while (--len); } @@ -2680,20 +2522,19 @@ namespace agg template void for_each_pixel(Function f) { unsigned y; - for(y = 0; y < height(); ++y) + for (y = 0; y < height(); ++y) { row_data r = m_rbuf->row(y); - if(r.ptr) + if (r.ptr) { unsigned len = r.x2 - r.x1 + 1; - value_type* p = - (value_type*)m_rbuf->row_ptr(r.x1, y, len) + (r.x1 << 2); + pixel_type* p = pix_value_ptr(r.x1, y, len); do { - f(p); - p += 4; + f(p->c); + p = p->next(); } - while(--len); + while (--len); } } } @@ -2728,8 +2569,7 @@ namespace agg int xsrc, int ysrc, unsigned len) { - const int8u* p = from.row_ptr(ysrc); - if(p) + if (const int8u* p = from.row_ptr(ysrc)) { memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, p + xsrc * pix_width, @@ -2738,6 +2578,7 @@ namespace agg } //-------------------------------------------------------------------- + // Blend from another RGBA surface. template void blend_from(const SrcPixelFormatRenderer& from, int xdst, int ydst, @@ -2745,39 +2586,34 @@ namespace agg unsigned len, int8u cover) { - typedef typename SrcPixelFormatRenderer::order_type src_order; - const value_type* psrc = (const value_type*)from.row_ptr(ysrc); - if(psrc) + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) { - psrc += xsrc << 2; - value_type* pdst = - (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2); + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + int srcinc = 1; + int dstinc = 1; - int incp = 4; - if(xdst > xsrc) + if (xdst > xsrc) { - psrc += (len-1) << 2; - pdst += (len-1) << 2; - incp = -4; + psrc = psrc->advance(len - 1); + pdst = pdst->advance(len - 1); + srcinc = -1; + dstinc = -1; } do { - blender_type::blend_pix(m_comp_op, - pdst, - psrc[src_order::R], - psrc[src_order::G], - psrc[src_order::B], - psrc[src_order::A], - cover); - psrc += incp; - pdst += incp; + blend_pix(pdst, psrc->get(), cover); + psrc = psrc->advance(srcinc); + pdst = pdst->advance(dstinc); } - while(--len); + while (--len); } } //-------------------------------------------------------------------- + // Blend from single color, using grayscale surface as alpha channel. template void blend_from_color(const SrcPixelFormatRenderer& from, const color_type& color, @@ -2786,26 +2622,27 @@ namespace agg unsigned len, int8u cover) { - typedef typename SrcPixelFormatRenderer::value_type src_value_type; - const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); - if(psrc) + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) { - value_type* pdst = - (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2); + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + do { - blender_type::blend_pix(m_comp_op, - pdst, - color.r, color.g, color.b, color.a, - (*psrc * cover + base_mask) >> base_shift); - ++psrc; - pdst += 4; + blend_pix(pdst, color, + src_color_type::scale_cover(cover, psrc->c[0])); + psrc = psrc->next(); + pdst = pdst->next(); } - while(--len); + while (--len); } } //-------------------------------------------------------------------- + // Blend from color table, using grayscale surface as indexes into table. + // Obviously, this only works for integer value types. template void blend_from_lut(const SrcPixelFormatRenderer& from, const color_type* color_lut, @@ -2814,88 +2651,152 @@ namespace agg unsigned len, int8u cover) { - typedef typename SrcPixelFormatRenderer::value_type src_value_type; - const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); - if(psrc) + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) { - value_type* pdst = - (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2); + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + do { - const color_type& color = color_lut[*psrc]; - blender_type::blend_pix(m_comp_op, - pdst, - color.r, color.g, color.b, color.a, - cover); - ++psrc; - pdst += 4; + blend_pix(pdst, color_lut[psrc->c[0]], cover); + psrc = psrc->next(); + pdst = pdst->next(); } - while(--len); + while (--len); } } private: rbuf_type* m_rbuf; + Blender m_blender; unsigned m_comp_op; }; - - //----------------------------------------------------------------------- - typedef blender_rgba blender_rgba32; //----blender_rgba32 - typedef blender_rgba blender_argb32; //----blender_argb32 - typedef blender_rgba blender_abgr32; //----blender_abgr32 - typedef blender_rgba blender_bgra32; //----blender_bgra32 - - typedef blender_rgba_pre blender_rgba32_pre; //----blender_rgba32_pre - typedef blender_rgba_pre blender_argb32_pre; //----blender_argb32_pre - typedef blender_rgba_pre blender_abgr32_pre; //----blender_abgr32_pre - typedef blender_rgba_pre blender_bgra32_pre; //----blender_bgra32_pre - - typedef blender_rgba_plain blender_rgba32_plain; //----blender_rgba32_plain - typedef blender_rgba_plain blender_argb32_plain; //----blender_argb32_plain - typedef blender_rgba_plain blender_abgr32_plain; //----blender_abgr32_plain - typedef blender_rgba_plain blender_bgra32_plain; //----blender_bgra32_plain - - typedef blender_rgba blender_rgba64; //----blender_rgba64 - typedef blender_rgba blender_argb64; //----blender_argb64 - typedef blender_rgba blender_abgr64; //----blender_abgr64 - typedef blender_rgba blender_bgra64; //----blender_bgra64 - - typedef blender_rgba_pre blender_rgba64_pre; //----blender_rgba64_pre - typedef blender_rgba_pre blender_argb64_pre; //----blender_argb64_pre - typedef blender_rgba_pre blender_abgr64_pre; //----blender_abgr64_pre - typedef blender_rgba_pre blender_bgra64_pre; //----blender_bgra64_pre + typedef blender_rgba blender_rgba32; + typedef blender_rgba blender_argb32; + typedef blender_rgba blender_abgr32; + typedef blender_rgba blender_bgra32; + + typedef blender_rgba blender_srgba32; + typedef blender_rgba blender_sargb32; + typedef blender_rgba blender_sabgr32; + typedef blender_rgba blender_sbgra32; + + typedef blender_rgba_pre blender_rgba32_pre; + typedef blender_rgba_pre blender_argb32_pre; + typedef blender_rgba_pre blender_abgr32_pre; + typedef blender_rgba_pre blender_bgra32_pre; + + typedef blender_rgba_pre blender_srgba32_pre; + typedef blender_rgba_pre blender_sargb32_pre; + typedef blender_rgba_pre blender_sabgr32_pre; + typedef blender_rgba_pre blender_sbgra32_pre; + + typedef blender_rgba_plain blender_rgba32_plain; + typedef blender_rgba_plain blender_argb32_plain; + typedef blender_rgba_plain blender_abgr32_plain; + typedef blender_rgba_plain blender_bgra32_plain; + + typedef blender_rgba_plain blender_srgba32_plain; + typedef blender_rgba_plain blender_sargb32_plain; + typedef blender_rgba_plain blender_sabgr32_plain; + typedef blender_rgba_plain blender_sbgra32_plain; + + typedef blender_rgba blender_rgba64; + typedef blender_rgba blender_argb64; + typedef blender_rgba blender_abgr64; + typedef blender_rgba blender_bgra64; + + typedef blender_rgba_pre blender_rgba64_pre; + typedef blender_rgba_pre blender_argb64_pre; + typedef blender_rgba_pre blender_abgr64_pre; + typedef blender_rgba_pre blender_bgra64_pre; + + typedef blender_rgba_plain blender_rgba64_plain; + typedef blender_rgba_plain blender_argb64_plain; + typedef blender_rgba_plain blender_abgr64_plain; + typedef blender_rgba_plain blender_bgra64_plain; + + typedef blender_rgba blender_rgba128; + typedef blender_rgba blender_argb128; + typedef blender_rgba blender_abgr128; + typedef blender_rgba blender_bgra128; + + typedef blender_rgba_pre blender_rgba128_pre; + typedef blender_rgba_pre blender_argb128_pre; + typedef blender_rgba_pre blender_abgr128_pre; + typedef blender_rgba_pre blender_bgra128_pre; + + typedef blender_rgba_plain blender_rgba128_plain; + typedef blender_rgba_plain blender_argb128_plain; + typedef blender_rgba_plain blender_abgr128_plain; + typedef blender_rgba_plain blender_bgra128_plain; //----------------------------------------------------------------------- - typedef int32u pixel32_type; - typedef pixfmt_alpha_blend_rgba pixfmt_rgba32; //----pixfmt_rgba32 - typedef pixfmt_alpha_blend_rgba pixfmt_argb32; //----pixfmt_argb32 - typedef pixfmt_alpha_blend_rgba pixfmt_abgr32; //----pixfmt_abgr32 - typedef pixfmt_alpha_blend_rgba pixfmt_bgra32; //----pixfmt_bgra32 - - typedef pixfmt_alpha_blend_rgba pixfmt_rgba32_pre; //----pixfmt_rgba32_pre - typedef pixfmt_alpha_blend_rgba pixfmt_argb32_pre; //----pixfmt_argb32_pre - typedef pixfmt_alpha_blend_rgba pixfmt_abgr32_pre; //----pixfmt_abgr32_pre - typedef pixfmt_alpha_blend_rgba pixfmt_bgra32_pre; //----pixfmt_bgra32_pre - - typedef pixfmt_alpha_blend_rgba pixfmt_rgba32_plain; //----pixfmt_rgba32_plain - typedef pixfmt_alpha_blend_rgba pixfmt_argb32_plain; //----pixfmt_argb32_plain - typedef pixfmt_alpha_blend_rgba pixfmt_abgr32_plain; //----pixfmt_abgr32_plain - typedef pixfmt_alpha_blend_rgba pixfmt_bgra32_plain; //----pixfmt_bgra32_plain - - struct pixel64_type { int16u c[4]; }; - typedef pixfmt_alpha_blend_rgba pixfmt_rgba64; //----pixfmt_rgba64 - typedef pixfmt_alpha_blend_rgba pixfmt_argb64; //----pixfmt_argb64 - typedef pixfmt_alpha_blend_rgba pixfmt_abgr64; //----pixfmt_abgr64 - typedef pixfmt_alpha_blend_rgba pixfmt_bgra64; //----pixfmt_bgra64 - - typedef pixfmt_alpha_blend_rgba pixfmt_rgba64_pre; //----pixfmt_rgba64_pre - typedef pixfmt_alpha_blend_rgba pixfmt_argb64_pre; //----pixfmt_argb64_pre - typedef pixfmt_alpha_blend_rgba pixfmt_abgr64_pre; //----pixfmt_abgr64_pre - typedef pixfmt_alpha_blend_rgba pixfmt_bgra64_pre; //----pixfmt_bgra64_pre + typedef pixfmt_alpha_blend_rgba pixfmt_rgba32; + typedef pixfmt_alpha_blend_rgba pixfmt_argb32; + typedef pixfmt_alpha_blend_rgba pixfmt_abgr32; + typedef pixfmt_alpha_blend_rgba pixfmt_bgra32; + + typedef pixfmt_alpha_blend_rgba pixfmt_srgba32; + typedef pixfmt_alpha_blend_rgba pixfmt_sargb32; + typedef pixfmt_alpha_blend_rgba pixfmt_sabgr32; + typedef pixfmt_alpha_blend_rgba pixfmt_sbgra32; + + typedef pixfmt_alpha_blend_rgba pixfmt_rgba32_pre; + typedef pixfmt_alpha_blend_rgba pixfmt_argb32_pre; + typedef pixfmt_alpha_blend_rgba pixfmt_abgr32_pre; + typedef pixfmt_alpha_blend_rgba pixfmt_bgra32_pre; + + typedef pixfmt_alpha_blend_rgba pixfmt_srgba32_pre; + typedef pixfmt_alpha_blend_rgba pixfmt_sargb32_pre; + typedef pixfmt_alpha_blend_rgba pixfmt_sabgr32_pre; + typedef pixfmt_alpha_blend_rgba pixfmt_sbgra32_pre; + + typedef pixfmt_alpha_blend_rgba pixfmt_rgba32_plain; + typedef pixfmt_alpha_blend_rgba pixfmt_argb32_plain; + typedef pixfmt_alpha_blend_rgba pixfmt_abgr32_plain; + typedef pixfmt_alpha_blend_rgba pixfmt_bgra32_plain; + + typedef pixfmt_alpha_blend_rgba pixfmt_srgba32_plain; + typedef pixfmt_alpha_blend_rgba pixfmt_sargb32_plain; + typedef pixfmt_alpha_blend_rgba pixfmt_sabgr32_plain; + typedef pixfmt_alpha_blend_rgba pixfmt_sbgra32_plain; + + typedef pixfmt_alpha_blend_rgba pixfmt_rgba64; + typedef pixfmt_alpha_blend_rgba pixfmt_argb64; + typedef pixfmt_alpha_blend_rgba pixfmt_abgr64; + typedef pixfmt_alpha_blend_rgba pixfmt_bgra64; + + typedef pixfmt_alpha_blend_rgba pixfmt_rgba64_pre; + typedef pixfmt_alpha_blend_rgba pixfmt_argb64_pre; + typedef pixfmt_alpha_blend_rgba pixfmt_abgr64_pre; + typedef pixfmt_alpha_blend_rgba pixfmt_bgra64_pre; + + typedef pixfmt_alpha_blend_rgba pixfmt_rgba64_plain; + typedef pixfmt_alpha_blend_rgba pixfmt_argb64_plain; + typedef pixfmt_alpha_blend_rgba pixfmt_abgr64_plain; + typedef pixfmt_alpha_blend_rgba pixfmt_bgra64_plain; + + typedef pixfmt_alpha_blend_rgba pixfmt_rgba128; + typedef pixfmt_alpha_blend_rgba pixfmt_argb128; + typedef pixfmt_alpha_blend_rgba pixfmt_abgr128; + typedef pixfmt_alpha_blend_rgba pixfmt_bgra128; + + typedef pixfmt_alpha_blend_rgba pixfmt_rgba128_pre; + typedef pixfmt_alpha_blend_rgba pixfmt_argb128_pre; + typedef pixfmt_alpha_blend_rgba pixfmt_abgr128_pre; + typedef pixfmt_alpha_blend_rgba pixfmt_bgra128_pre; + + typedef pixfmt_alpha_blend_rgba pixfmt_rgba128_plain; + typedef pixfmt_alpha_blend_rgba pixfmt_argb128_plain; + typedef pixfmt_alpha_blend_rgba pixfmt_abgr128_plain; + typedef pixfmt_alpha_blend_rgba pixfmt_bgra128_plain; + } #endif diff --git a/extern/agg24/include/agg_rasterizer_cells_aa.h b/extern/agg24/include/agg_rasterizer_cells_aa.h index 2be0efeca175..1d797bf90114 100755 --- a/extern/agg24/include/agg_rasterizer_cells_aa.h +++ b/extern/agg24/include/agg_rasterizer_cells_aa.h @@ -2,15 +2,15 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-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. +// 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. // //---------------------------------------------------------------------------- // -// The author gratefully acknowleges the support of David Turner, -// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType +// The author gratefully acknowleges the support of David Turner, +// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType // libray - in producing this work. See http://www.freetype.org for details. // //---------------------------------------------------------------------------- @@ -19,24 +19,25 @@ // http://www.antigrain.com //---------------------------------------------------------------------------- // -// Adaptation for 32-bit screen coordinates has been sponsored by +// Adaptation for 32-bit screen coordinates has been sponsored by // Liberty Technology Systems, Inc., visit http://lib-sys.com // // Liberty Technology Systems, Inc. is the provider of // PostScript and PDF technology for software developers. -// +// //---------------------------------------------------------------------------- #ifndef AGG_RASTERIZER_CELLS_AA_INCLUDED #define AGG_RASTERIZER_CELLS_AA_INCLUDED -#include #include #include #include "agg_math.h" #include "agg_array.h" + namespace agg { + //-----------------------------------------------------rasterizer_cells_aa // An internal class that implements the main rasterization algorithm. // Used in the rasterizer. Should not be used direcly. @@ -48,7 +49,7 @@ namespace agg cell_block_size = 1 << cell_block_shift, cell_block_mask = cell_block_size - 1, cell_block_pool = 256, - cell_block_limit = 4096 + cell_block_limit = 1024 }; struct sorted_y @@ -75,19 +76,19 @@ namespace agg void sort_cells(); - unsigned total_cells() const + unsigned total_cells() const { return m_num_cells; } - unsigned scanline_num_cells(unsigned y) const - { - return m_sorted_y[y - m_min_y].num; + unsigned scanline_num_cells(unsigned y) const + { + return m_sorted_y[y - m_min_y].num; } const cell_type* const* scanline_cells(unsigned y) const - { - return m_sorted_cells.data() + m_sorted_y[y - m_min_y].start; + { + return m_sorted_cells.data() + m_sorted_y[y - m_min_y].start; } bool sorted() const { return m_sorted; } @@ -100,7 +101,7 @@ namespace agg void add_curr_cell(); void render_hline(int ey, int x1, int y1, int x2, int y2); void allocate_block(); - + private: unsigned m_num_blocks; unsigned m_max_blocks; @@ -123,7 +124,7 @@ namespace agg //------------------------------------------------------------------------ - template + template rasterizer_cells_aa::~rasterizer_cells_aa() { if(m_num_blocks) @@ -139,7 +140,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template rasterizer_cells_aa::rasterizer_cells_aa() : m_num_blocks(0), m_max_blocks(0), @@ -160,10 +161,10 @@ namespace agg } //------------------------------------------------------------------------ - template + template void rasterizer_cells_aa::reset() { - m_num_cells = 0; + m_num_cells = 0; m_curr_block = 0; m_curr_cell.initial(); m_style_cell.initial(); @@ -175,17 +176,14 @@ namespace agg } //------------------------------------------------------------------------ - template + template AGG_INLINE void rasterizer_cells_aa::add_curr_cell() { if(m_curr_cell.area | m_curr_cell.cover) { if((m_num_cells & cell_block_mask) == 0) { - if (m_num_blocks >= cell_block_limit) - { - throw std::overflow_error("Allocated too many blocks"); - } + if(m_num_blocks >= cell_block_limit) return; allocate_block(); } *m_curr_cell_ptr++ = m_curr_cell; @@ -194,7 +192,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template AGG_INLINE void rasterizer_cells_aa::set_curr_cell(int x, int y) { if(m_curr_cell.not_equal(x, y, m_style_cell)) @@ -209,9 +207,9 @@ namespace agg } //------------------------------------------------------------------------ - template - AGG_INLINE void rasterizer_cells_aa::render_hline(int ey, - int x1, int y1, + template + AGG_INLINE void rasterizer_cells_aa::render_hline(int ey, + int x1, int y1, int x2, int y2) { int ex1 = x1 >> poly_subpixel_shift; @@ -307,14 +305,14 @@ namespace agg } //------------------------------------------------------------------------ - template + template AGG_INLINE void rasterizer_cells_aa::style(const cell_type& style_cell) - { - m_style_cell.style(style_cell); + { + m_style_cell.style(style_cell); } //------------------------------------------------------------------------ - template + template void rasterizer_cells_aa::line(int x1, int y1, int x2, int y2) { enum dx_limit_e { dx_limit = 16384 << poly_subpixel_shift }; @@ -360,7 +358,7 @@ namespace agg //Vertical line - we have to calculate start and end cells, //and then - the common values of the area and coverage for - //all cells of the line. We know exactly there's only one + //all cells of the line. We know exactly there's only one //cell, so, we don't have to call render_hline(). incr = 1; if(dx == 0) @@ -465,15 +463,15 @@ namespace agg } //------------------------------------------------------------------------ - template + template void rasterizer_cells_aa::allocate_block() { if(m_curr_block >= m_num_blocks) { if(m_num_blocks >= m_max_blocks) { - cell_type** new_cells = - pod_allocator::allocate(m_max_blocks + + cell_type** new_cells = + pod_allocator::allocate(m_max_blocks + cell_block_pool); if(m_cells) @@ -485,7 +483,7 @@ namespace agg m_max_blocks += cell_block_pool; } - m_cells[m_num_blocks++] = + m_cells[m_num_blocks++] = pod_allocator::allocate(cell_block_size); } @@ -515,7 +513,7 @@ namespace agg void qsort_cells(Cell** start, unsigned num) { Cell** stack[80]; - Cell*** top; + Cell*** top; Cell** limit; Cell** base; @@ -540,7 +538,7 @@ namespace agg i = base + 1; j = limit - 1; - // now ensure that *i <= *base <= *j + // now ensure that *i <= *base <= *j if((*j)->x < (*i)->x) { swap_cells(i, j); @@ -621,7 +619,7 @@ namespace agg //------------------------------------------------------------------------ - template + template void rasterizer_cells_aa::sort_cells() { if(m_sorted) return; //Perform sort only the first time. @@ -638,9 +636,9 @@ namespace agg //for(unsigned nc = 0; nc < m_num_cells; nc++) //{ // cell_type* cell = m_cells[nc >> cell_block_shift] + (nc & cell_block_mask); -// if(cell->x < m_min_x || -// cell->y < m_min_y || -// cell->x > m_max_x || +// if(cell->x < m_min_x || +// cell->y < m_min_y || +// cell->x > m_max_x || // cell->y > m_max_y) // { // cell = cell; // Breakpoint here @@ -656,29 +654,20 @@ namespace agg // Create the Y-histogram (count the numbers of cells for each Y) cell_type** block_ptr = m_cells; cell_type* cell_ptr; - unsigned nb = m_num_cells >> cell_block_shift; + unsigned nb = m_num_cells; unsigned i; - while(nb--) + while(nb) { cell_ptr = *block_ptr++; - i = cell_block_size; - while(i--) + i = (nb > cell_block_size) ? cell_block_size : nb; + nb -= i; + while(i--) { m_sorted_y[cell_ptr->y - m_min_y].start++; ++cell_ptr; } } - i = m_num_cells & cell_block_mask; - if (i) { - cell_ptr = *block_ptr++; - while(i--) - { - m_sorted_y[cell_ptr->y - m_min_y].start++; - ++cell_ptr; - } - } - // Convert the Y-histogram into the array of starting indexes unsigned start = 0; for(i = 0; i < m_sorted_y.size(); i++) @@ -690,11 +679,12 @@ namespace agg // Fill the cell pointer array sorted by Y block_ptr = m_cells; - nb = m_num_cells >> cell_block_shift; - while(nb--) + nb = m_num_cells; + while(nb) { cell_ptr = *block_ptr++; - i = cell_block_size; + i = (nb > cell_block_size) ? cell_block_size : nb; + nb -= i; while(i--) { sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y]; @@ -703,19 +693,7 @@ namespace agg ++cell_ptr; } } - - i = m_num_cells & cell_block_mask; - if (i) { - cell_ptr = *block_ptr++; - while(i--) - { - sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y]; - m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr; - ++curr_y.num; - ++cell_ptr; - } - } - + // Finally arrange the X-arrays for(i = 0; i < m_sorted_y.size(); i++) { diff --git a/extern/agg24/include/agg_rasterizer_compound_aa.h b/extern/agg24/include/agg_rasterizer_compound_aa.h index 15b88b5457a3..165806dae4e2 100755 --- a/extern/agg24/include/agg_rasterizer_compound_aa.h +++ b/extern/agg24/include/agg_rasterizer_compound_aa.h @@ -119,7 +119,6 @@ namespace agg m_asm(), // Active Style Mask m_cells(), m_cover_buf(), - m_master_alpha(), m_min_style(0x7FFFFFFF), m_max_style(-0x7FFFFFFF), m_start_x(0), @@ -135,7 +134,6 @@ namespace agg void clip_box(double x1, double y1, double x2, double y2); void filling_rule(filling_rule_e filling_rule); void layer_order(layer_order_e order); - void master_alpha(int style, double alpha); //-------------------------------------------------------------------- void styles(int left, int right); @@ -188,7 +186,7 @@ namespace agg bool hit_test(int tx, int ty); //-------------------------------------------------------------------- - AGG_INLINE unsigned calculate_alpha(int area, unsigned master_alpha) const + AGG_INLINE unsigned calculate_alpha(int area) const { int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift); if(cover < 0) cover = -cover; @@ -201,7 +199,7 @@ namespace agg } } if(cover > aa_mask) cover = aa_mask; - return (cover * master_alpha + aa_mask) >> aa_shift; + return cover; } //-------------------------------------------------------------------- @@ -214,8 +212,6 @@ namespace agg sl.reset_spans(); - unsigned master_alpha = aa_mask; - if(style_idx < 0) { style_idx = 0; @@ -223,7 +219,6 @@ namespace agg else { style_idx++; - master_alpha = m_master_alpha[m_ast[style_idx] + m_min_style - 1]; } const style_info& st = m_styles[m_ast[style_idx]]; @@ -244,16 +239,14 @@ namespace agg if(area) { - alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area, - master_alpha); + alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area); sl.add_cell(x, alpha); x++; } if(num_cells && cell->x > x) { - alpha = calculate_alpha(cover << (poly_subpixel_shift + 1), - master_alpha); + alpha = calculate_alpha(cover << (poly_subpixel_shift + 1)); if(alpha) { sl.add_span(x, cell->x - x, alpha); @@ -268,7 +261,6 @@ namespace agg private: void add_style(int style_id); - void allocate_master_alpha(); //-------------------------------------------------------------------- // Disable copying @@ -286,7 +278,6 @@ namespace agg pod_vector m_asm; // Active Style Mask pod_vector m_cells; pod_vector m_cover_buf; - pod_bvector m_master_alpha; int m_min_style; int m_max_style; @@ -466,7 +457,6 @@ namespace agg } m_scan_y = m_outline.min_y(); m_styles.allocate(m_max_style - m_min_style + 2, 128); - allocate_master_alpha(); return true; } @@ -634,7 +624,6 @@ namespace agg } m_scan_y = y; m_styles.allocate(m_max_style - m_min_style + 2, 128); - allocate_master_alpha(); return true; } @@ -666,30 +655,6 @@ namespace agg return &m_cover_buf[0]; } - //------------------------------------------------------------------------ - template - void rasterizer_compound_aa::allocate_master_alpha() - { - while((int)m_master_alpha.size() <= m_max_style) - { - m_master_alpha.add(aa_mask); - } - } - - //------------------------------------------------------------------------ - template - void rasterizer_compound_aa::master_alpha(int style, double alpha) - { - if(style >= 0) - { - while((int)m_master_alpha.size() <= style) - { - m_master_alpha.add(aa_mask); - } - m_master_alpha[style] = uround(alpha * aa_mask); - } - } - } diff --git a/extern/agg24/include/agg_rasterizer_scanline_aa.h b/extern/agg24/include/agg_rasterizer_scanline_aa.h index 77bc41bc7735..ffc2ddf941dc 100644 --- a/extern/agg24/include/agg_rasterizer_scanline_aa.h +++ b/extern/agg24/include/agg_rasterizer_scanline_aa.h @@ -31,41 +31,12 @@ #include "agg_rasterizer_cells_aa.h" #include "agg_rasterizer_sl_clip.h" +#include "agg_rasterizer_scanline_aa_nogamma.h" #include "agg_gamma_functions.h" namespace agg { - - - //-----------------------------------------------------------------cell_aa - // A pixel cell. There're no constructors defined and it was done - // intentionally in order to avoid extra overhead when allocating an - // array of cells. - struct cell_aa - { - int x; - int y; - int cover; - int area; - - void initial() - { - x = 0x7FFFFFFF; - y = 0x7FFFFFFF; - cover = 0; - area = 0; - } - - void style(const cell_aa&) {} - - int not_equal(int ex, int ey, const cell_aa&) const - { - return (ex - x) | (ey - y); - } - }; - - //==================================================rasterizer_scanline_aa // Polygon rasterizer that is used to render filled polygons with // high-quality Anti-Aliasing. Internally, by default, the class uses diff --git a/extern/agg24/include/agg_rasterizer_scanline_aa_nogamma.h b/extern/agg24/include/agg_rasterizer_scanline_aa_nogamma.h new file mode 100644 index 000000000000..354416cc267c --- /dev/null +++ b/extern/agg24/include/agg_rasterizer_scanline_aa_nogamma.h @@ -0,0 +1,482 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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. +// +//---------------------------------------------------------------------------- +// +// The author gratefully acknowleges the support of David Turner, +// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType +// libray - in producing this work. See http://www.freetype.org for details. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +#ifndef AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED +#define AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED + +#include "agg_rasterizer_cells_aa.h" +#include "agg_rasterizer_sl_clip.h" + + +namespace agg +{ + + + //-----------------------------------------------------------------cell_aa + // A pixel cell. There're no constructors defined and it was done + // intentionally in order to avoid extra overhead when allocating an + // array of cells. + struct cell_aa + { + int x; + int y; + int cover; + int area; + + void initial() + { + x = 0x7FFFFFFF; + y = 0x7FFFFFFF; + cover = 0; + area = 0; + } + + void style(const cell_aa&) {} + + int not_equal(int ex, int ey, const cell_aa&) const + { + return (ex - x) | (ey - y); + } + }; + + + //==================================================rasterizer_scanline_aa_nogamma + // Polygon rasterizer that is used to render filled polygons with + // high-quality Anti-Aliasing. Internally, by default, the class uses + // integer coordinates in format 24.8, i.e. 24 bits for integer part + // and 8 bits for fractional - see poly_subpixel_shift. This class can be + // used in the following way: + // + // 1. filling_rule(filling_rule_e ft) - optional. + // + // 2. gamma() - optional. + // + // 3. reset() + // + // 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create + // more than one contour, but each contour must consist of at least 3 + // vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3); + // is the absolute minimum of vertices that define a triangle. + // The algorithm does not check either the number of vertices nor + // coincidence of their coordinates, but in the worst case it just + // won't draw anything. + // The orger of the vertices (clockwise or counterclockwise) + // is important when using the non-zero filling rule (fill_non_zero). + // In this case the vertex order of all the contours must be the same + // if you want your intersecting polygons to be without "holes". + // You actually can use different vertices order. If the contours do not + // intersect each other the order is not important anyway. If they do, + // contours with the same vertex order will be rendered without "holes" + // while the intersecting contours with different orders will have "holes". + // + // filling_rule() and gamma() can be called anytime before "sweeping". + //------------------------------------------------------------------------ + template class rasterizer_scanline_aa_nogamma + { + enum status + { + status_initial, + status_move_to, + status_line_to, + status_closed + }; + + public: + typedef Clip clip_type; + typedef typename Clip::conv_type conv_type; + typedef typename Clip::coord_type coord_type; + + enum aa_scale_e + { + aa_shift = 8, + aa_scale = 1 << aa_shift, + aa_mask = aa_scale - 1, + aa_scale2 = aa_scale * 2, + aa_mask2 = aa_scale2 - 1 + }; + + //-------------------------------------------------------------------- + rasterizer_scanline_aa_nogamma() : + m_outline(), + m_clipper(), + m_filling_rule(fill_non_zero), + m_auto_close(true), + m_start_x(0), + m_start_y(0), + m_status(status_initial) + { + } + + //-------------------------------------------------------------------- + void reset(); + void reset_clipping(); + void clip_box(double x1, double y1, double x2, double y2); + void filling_rule(filling_rule_e filling_rule); + void auto_close(bool flag) { m_auto_close = flag; } + + //-------------------------------------------------------------------- + unsigned apply_gamma(unsigned cover) const + { + return cover; + } + + //-------------------------------------------------------------------- + void move_to(int x, int y); + void line_to(int x, int y); + void move_to_d(double x, double y); + void line_to_d(double x, double y); + void close_polygon(); + void add_vertex(double x, double y, unsigned cmd); + + void edge(int x1, int y1, int x2, int y2); + void edge_d(double x1, double y1, double x2, double y2); + + //------------------------------------------------------------------- + template + void add_path(VertexSource& vs, unsigned path_id=0) + { + double x; + double y; + + unsigned cmd; + vs.rewind(path_id); + if(m_outline.sorted()) reset(); + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + add_vertex(x, y, cmd); + } + } + + //-------------------------------------------------------------------- + int min_x() const { return m_outline.min_x(); } + int min_y() const { return m_outline.min_y(); } + int max_x() const { return m_outline.max_x(); } + int max_y() const { return m_outline.max_y(); } + + //-------------------------------------------------------------------- + void sort(); + bool rewind_scanlines(); + bool navigate_scanline(int y); + + //-------------------------------------------------------------------- + AGG_INLINE unsigned calculate_alpha(int area) const + { + int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift); + + if(cover < 0) cover = -cover; + if(m_filling_rule == fill_even_odd) + { + cover &= aa_mask2; + if(cover > aa_scale) + { + cover = aa_scale2 - cover; + } + } + if(cover > aa_mask) cover = aa_mask; + return cover; + } + + //-------------------------------------------------------------------- + template bool sweep_scanline(Scanline& sl) + { + for(;;) + { + if(m_scan_y > m_outline.max_y()) return false; + sl.reset_spans(); + unsigned num_cells = m_outline.scanline_num_cells(m_scan_y); + const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y); + int cover = 0; + + while(num_cells) + { + const cell_aa* cur_cell = *cells; + int x = cur_cell->x; + int area = cur_cell->area; + unsigned alpha; + + cover += cur_cell->cover; + + //accumulate all cells with the same X + while(--num_cells) + { + cur_cell = *++cells; + if(cur_cell->x != x) break; + area += cur_cell->area; + cover += cur_cell->cover; + } + + if(area) + { + alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area); + if(alpha) + { + sl.add_cell(x, alpha); + } + x++; + } + + if(num_cells && cur_cell->x > x) + { + alpha = calculate_alpha(cover << (poly_subpixel_shift + 1)); + if(alpha) + { + sl.add_span(x, cur_cell->x - x, alpha); + } + } + } + + if(sl.num_spans()) break; + ++m_scan_y; + } + + sl.finalize(m_scan_y); + ++m_scan_y; + return true; + } + + //-------------------------------------------------------------------- + bool hit_test(int tx, int ty); + + + private: + //-------------------------------------------------------------------- + // Disable copying + rasterizer_scanline_aa_nogamma(const rasterizer_scanline_aa_nogamma&); + const rasterizer_scanline_aa_nogamma& + operator = (const rasterizer_scanline_aa_nogamma&); + + private: + rasterizer_cells_aa m_outline; + clip_type m_clipper; + filling_rule_e m_filling_rule; + bool m_auto_close; + coord_type m_start_x; + coord_type m_start_y; + unsigned m_status; + int m_scan_y; + }; + + + + + + + + + + + + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::reset() + { + m_outline.reset(); + m_status = status_initial; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::filling_rule(filling_rule_e filling_rule) + { + m_filling_rule = filling_rule; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::clip_box(double x1, double y1, + double x2, double y2) + { + reset(); + m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1), + conv_type::upscale(x2), conv_type::upscale(y2)); + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::reset_clipping() + { + reset(); + m_clipper.reset_clipping(); + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::close_polygon() + { + if(m_status == status_line_to) + { + m_clipper.line_to(m_outline, m_start_x, m_start_y); + m_status = status_closed; + } + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::move_to(int x, int y) + { + if(m_outline.sorted()) reset(); + if(m_auto_close) close_polygon(); + m_clipper.move_to(m_start_x = conv_type::downscale(x), + m_start_y = conv_type::downscale(y)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::line_to(int x, int y) + { + m_clipper.line_to(m_outline, + conv_type::downscale(x), + conv_type::downscale(y)); + m_status = status_line_to; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::move_to_d(double x, double y) + { + if(m_outline.sorted()) reset(); + if(m_auto_close) close_polygon(); + m_clipper.move_to(m_start_x = conv_type::upscale(x), + m_start_y = conv_type::upscale(y)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::line_to_d(double x, double y) + { + m_clipper.line_to(m_outline, + conv_type::upscale(x), + conv_type::upscale(y)); + m_status = status_line_to; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::add_vertex(double x, double y, unsigned cmd) + { + if(is_move_to(cmd)) + { + move_to_d(x, y); + } + else + if(is_vertex(cmd)) + { + line_to_d(x, y); + } + else + if(is_close(cmd)) + { + close_polygon(); + } + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::edge(int x1, int y1, int x2, int y2) + { + if(m_outline.sorted()) reset(); + m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1)); + m_clipper.line_to(m_outline, + conv_type::downscale(x2), + conv_type::downscale(y2)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::edge_d(double x1, double y1, + double x2, double y2) + { + if(m_outline.sorted()) reset(); + m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1)); + m_clipper.line_to(m_outline, + conv_type::upscale(x2), + conv_type::upscale(y2)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template + void rasterizer_scanline_aa_nogamma::sort() + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + } + + //------------------------------------------------------------------------ + template + AGG_INLINE bool rasterizer_scanline_aa_nogamma::rewind_scanlines() + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0) + { + return false; + } + m_scan_y = m_outline.min_y(); + return true; + } + + + //------------------------------------------------------------------------ + template + AGG_INLINE bool rasterizer_scanline_aa_nogamma::navigate_scanline(int y) + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0 || + y < m_outline.min_y() || + y > m_outline.max_y()) + { + return false; + } + m_scan_y = y; + return true; + } + + //------------------------------------------------------------------------ + template + bool rasterizer_scanline_aa_nogamma::hit_test(int tx, int ty) + { + if(!navigate_scanline(ty)) return false; + scanline_hit_test sl(tx); + sweep_scanline(sl); + return sl.hit(); + } + + + +} + + + +#endif + diff --git a/extern/agg24/include/agg_renderer_base.h b/extern/agg24/include/agg_renderer_base.h index ad7915a2ae8a..527c62f78917 100644 --- a/extern/agg24/include/agg_renderer_base.h +++ b/extern/agg24/include/agg_renderer_base.h @@ -134,6 +134,19 @@ namespace agg } + //-------------------------------------------------------------------- + void fill(const color_type& c) + { + unsigned y; + if(width()) + { + for(y = 0; y < height(); y++) + { + m_ren->blend_hline(0, y, width(), c, cover_mask); + } + } + } + //-------------------------------------------------------------------- void copy_pixel(int x, int y, const color_type& c) { diff --git a/extern/agg24/include/agg_renderer_outline_aa.h b/extern/agg24/include/agg_renderer_outline_aa.h index e5e3b50fd18c..ee564f04d50c 100644 --- a/extern/agg24/include/agg_renderer_outline_aa.h +++ b/extern/agg24/include/agg_renderer_outline_aa.h @@ -474,7 +474,7 @@ namespace agg }; //--------------------------------------------------------------------- - line_interpolator_aa_base(renderer_type& ren, const line_parameters& lp) : + line_interpolator_aa_base(renderer_type& ren, line_parameters& lp) : m_lp(&lp), m_li(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) : line_dbl_hr(lp.y2 - lp.y1), @@ -550,7 +550,7 @@ namespace agg operator = (const line_interpolator_aa_base&); protected: - const line_parameters* m_lp; + line_parameters* m_lp; dda2_line_interpolator m_li; renderer_type& m_ren; int m_len; @@ -582,7 +582,7 @@ namespace agg typedef line_interpolator_aa_base base_type; //--------------------------------------------------------------------- - line_interpolator_aa0(renderer_type& ren, const line_parameters& lp) : + line_interpolator_aa0(renderer_type& ren, line_parameters& lp) : line_interpolator_aa_base(ren, lp), m_di(lp.x1, lp.y1, lp.x2, lp.y2, lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) @@ -676,7 +676,7 @@ namespace agg typedef line_interpolator_aa_base base_type; //--------------------------------------------------------------------- - line_interpolator_aa1(renderer_type& ren, const line_parameters& lp, + line_interpolator_aa1(renderer_type& ren, line_parameters& lp, int sx, int sy) : line_interpolator_aa_base(ren, lp), m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, @@ -887,7 +887,7 @@ namespace agg typedef line_interpolator_aa_base base_type; //--------------------------------------------------------------------- - line_interpolator_aa2(renderer_type& ren, const line_parameters& lp, + line_interpolator_aa2(renderer_type& ren, line_parameters& lp, int ex, int ey) : line_interpolator_aa_base(ren, lp), m_di(lp.x1, lp.y1, lp.x2, lp.y2, ex, ey, @@ -1036,7 +1036,7 @@ namespace agg typedef line_interpolator_aa_base base_type; //--------------------------------------------------------------------- - line_interpolator_aa3(renderer_type& ren, const line_parameters& lp, + line_interpolator_aa3(renderer_type& ren, line_parameters& lp, int sx, int sy, int ex, int ey) : line_interpolator_aa_base(ren, lp), m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, @@ -1350,7 +1350,7 @@ namespace agg typedef typename base_ren_type::color_type color_type; //--------------------------------------------------------------------- - renderer_outline_aa(base_ren_type& ren, const line_profile_aa& prof) : + renderer_outline_aa(base_ren_type& ren, line_profile_aa& prof) : m_ren(&ren), m_profile(&prof), m_clip_box(0,0,0,0), @@ -1363,9 +1363,9 @@ namespace agg const color_type& color() const { return m_color; } //--------------------------------------------------------------------- - void profile(const line_profile_aa& prof) { m_profile = &prof; } - const line_profile_aa& profile() const { return *m_profile; } - const line_profile_aa& profile() { return *m_profile; } + void profile(line_profile_aa& prof) { m_profile = &prof; } + line_profile_aa& profile() const { return *m_profile; } + line_profile_aa& profile() { return *m_profile; } //--------------------------------------------------------------------- int subpixel_width() const { return m_profile->subpixel_width(); } @@ -1546,7 +1546,7 @@ namespace agg } //------------------------------------------------------------------------- - void line0_no_clip(const line_parameters& lp) + void line0_no_clip(line_parameters& lp) { if(lp.len > line_max_length) { @@ -1572,7 +1572,7 @@ namespace agg } //------------------------------------------------------------------------- - void line0(const line_parameters& lp) + void line0(line_parameters& lp) { if(m_clipping) { @@ -1602,7 +1602,7 @@ namespace agg } //------------------------------------------------------------------------- - void line1_no_clip(const line_parameters& lp, int sx, int sy) + void line1_no_clip(line_parameters& lp, int sx, int sy) { if(lp.len > line_max_length) { @@ -1627,7 +1627,7 @@ namespace agg //------------------------------------------------------------------------- - void line1(const line_parameters& lp, int sx, int sy) + void line1(line_parameters& lp, int sx, int sy) { if(m_clipping) { @@ -1670,7 +1670,7 @@ namespace agg } //------------------------------------------------------------------------- - void line2_no_clip(const line_parameters& lp, int ex, int ey) + void line2_no_clip(line_parameters& lp, int ex, int ey) { if(lp.len > line_max_length) { @@ -1694,7 +1694,7 @@ namespace agg } //------------------------------------------------------------------------- - void line2(const line_parameters& lp, int ex, int ey) + void line2(line_parameters& lp, int ex, int ey) { if(m_clipping) { @@ -1737,7 +1737,7 @@ namespace agg } //------------------------------------------------------------------------- - void line3_no_clip(const line_parameters& lp, + void line3_no_clip(line_parameters& lp, int sx, int sy, int ex, int ey) { if(lp.len > line_max_length) @@ -1765,7 +1765,7 @@ namespace agg } //------------------------------------------------------------------------- - void line3(const line_parameters& lp, + void line3(line_parameters& lp, int sx, int sy, int ex, int ey) { if(m_clipping) @@ -1824,7 +1824,7 @@ namespace agg private: base_ren_type* m_ren; - const line_profile_aa* m_profile; + line_profile_aa* m_profile; color_type m_color; rect_i m_clip_box; bool m_clipping; diff --git a/extern/agg24/include/agg_renderer_outline_image.h b/extern/agg24/include/agg_renderer_outline_image.h index dd48450edbd4..8abb9fa0bddf 100644 --- a/extern/agg24/include/agg_renderer_outline_image.h +++ b/extern/agg24/include/agg_renderer_outline_image.h @@ -34,7 +34,8 @@ namespace agg line_image_scale(const Source& src, double height) : m_source(src), m_height(height), - m_scale(src.height() / height) + m_scale(src.height() / height), + m_scale_inv(height / src.height()) { } @@ -43,13 +44,34 @@ namespace agg color_type pixel(int x, int y) const { - double src_y = (y + 0.5) * m_scale - 0.5; - int h = m_source.height() - 1; - int y1 = ufloor(src_y); - int y2 = y1 + 1; - color_type pix1 = (y1 < 0) ? color_type::no_color() : m_source.pixel(x, y1); - color_type pix2 = (y2 > h) ? color_type::no_color() : m_source.pixel(x, y2); - return pix1.gradient(pix2, src_y - y1); + if (m_scale < 1.0) + { + // Interpolate between nearest source pixels. + double src_y = (y + 0.5) * m_scale - 0.5; + int h = m_source.height() - 1; + int y1 = ifloor(src_y); + int y2 = y1 + 1; + rgba pix1 = (y1 < 0) ? rgba::no_color() : m_source.pixel(x, y1); + rgba pix2 = (y2 > h) ? rgba::no_color() : m_source.pixel(x, y2); + return pix1.gradient(pix2, src_y - y1); + } + else + { + // Average source pixels between y and y+1. + double src_y1 = (y + 0.5) * m_scale - 0.5; + double src_y2 = src_y1 + m_scale; + int h = m_source.height() - 1; + int y1 = ifloor(src_y1); + int y2 = ifloor(src_y2); + rgba c = rgba::no_color(); + if (y1 >= 0) c += rgba(m_source.pixel(x, y1)) *= y1 + 1 - src_y1; + while (++y1 < y2) + { + if (y1 <= h) c += m_source.pixel(x, y1); + } + if (y2 <= h) c += rgba(m_source.pixel(x, y2)) *= src_y2 - y2; + return c *= m_scale_inv; + } } private: @@ -59,6 +81,7 @@ namespace agg const Source& m_source; double m_height; double m_scale; + double m_scale_inv; }; @@ -71,7 +94,7 @@ namespace agg typedef typename filter_type::color_type color_type; //-------------------------------------------------------------------- - line_image_pattern(const Filter& filter) : + line_image_pattern(Filter& filter) : m_filter(&filter), m_dilation(filter.dilation() + 1), m_dilation_hr(m_dilation << line_subpixel_shift), @@ -87,7 +110,7 @@ namespace agg // Create //-------------------------------------------------------------------- template - line_image_pattern(const Filter& filter, const Source& src) : + line_image_pattern(Filter& filter, const Source& src) : m_filter(&filter), m_dilation(filter.dilation() + 1), m_dilation_hr(m_dilation << line_subpixel_shift), @@ -210,14 +233,14 @@ namespace agg typedef Filter filter_type; typedef typename filter_type::color_type color_type; typedef line_image_pattern base_type; - + //-------------------------------------------------------------------- - line_image_pattern_pow2(const Filter& filter) : + line_image_pattern_pow2(Filter& filter) : line_image_pattern(filter), m_mask(line_subpixel_mask) {} //-------------------------------------------------------------------- template - line_image_pattern_pow2(const Filter& filter, const Source& src) : + line_image_pattern_pow2(Filter& filter, const Source& src) : line_image_pattern(filter), m_mask(line_subpixel_mask) { create(src); @@ -816,7 +839,7 @@ namespace agg //--------------------------------------------------------------------- - renderer_outline_image(base_ren_type& ren, const pattern_type& patt) : + renderer_outline_image(base_ren_type& ren, pattern_type& patt) : m_ren(&ren), m_pattern(&patt), m_start(0), @@ -827,8 +850,8 @@ namespace agg void attach(base_ren_type& ren) { m_ren = &ren; } //--------------------------------------------------------------------- - void pattern(const pattern_type& p) { m_pattern = &p; } - const pattern_type& pattern() const { return *m_pattern; } + void pattern(pattern_type& p) { m_pattern = &p; } + pattern_type& pattern() const { return *m_pattern; } //--------------------------------------------------------------------- void reset_clipping() { m_clipping = false; } @@ -995,7 +1018,7 @@ namespace agg private: base_ren_type* m_ren; - const pattern_type* m_pattern; + pattern_type* m_pattern; int m_start; double m_scale_x; rect_i m_clip_box; diff --git a/extern/agg24/include/agg_rendering_buffer.h b/extern/agg24/include/agg_rendering_buffer.h index 14d3e5397a61..0eff6ff27d3d 100644 --- a/extern/agg24/include/agg_rendering_buffer.h +++ b/extern/agg24/include/agg_rendering_buffer.h @@ -56,14 +56,14 @@ namespace agg //-------------------------------------------------------------------- void attach(T* buf, unsigned width, unsigned height, int stride) { - m_buf = m_start = buf; - m_width = width; - m_height = height; - m_stride = stride; - if(stride < 0) + m_buf = m_start = buf; + m_width = width; + m_height = height; + m_stride = stride; + if(stride < 0) { - m_start = m_buf - int(height - 1) * stride; - } + m_start = m_buf - int(height - 1) * stride; + } } //-------------------------------------------------------------------- @@ -78,13 +78,13 @@ namespace agg } //-------------------------------------------------------------------- - AGG_INLINE T* row_ptr(int, int y, unsigned) + AGG_INLINE T* row_ptr(int, int y, unsigned) { return m_start + y * m_stride; } - AGG_INLINE T* row_ptr(int y) { return m_start + y * m_stride; } - AGG_INLINE const T* row_ptr(int y) const { return m_start + y * m_stride; } - AGG_INLINE row_data row (int y) const + AGG_INLINE T* row_ptr(int y) { return m_start + y * m_stride; } + AGG_INLINE const T* row_ptr(int y) const { return m_start + y * m_stride; } + AGG_INLINE row_data row (int y) const { return row_data(0, m_width-1, row_ptr(y)); } diff --git a/extern/agg24/include/agg_scanline_storage_aa.h b/extern/agg24/include/agg_scanline_storage_aa.h index be452a88ffa8..7148c8992224 100644 --- a/extern/agg24/include/agg_scanline_storage_aa.h +++ b/extern/agg24/include/agg_scanline_storage_aa.h @@ -198,7 +198,7 @@ namespace agg }; const_iterator() : m_storage(0) {} - const_iterator(const embedded_scanline& sl) : + const_iterator(embedded_scanline& sl) : m_storage(sl.m_storage), m_span_idx(sl.m_scanline.start_span) { @@ -223,7 +223,7 @@ namespace agg m_span.covers = m_storage->covers_by_index(s.covers_id); } - const scanline_storage_aa* m_storage; + scanline_storage_aa* m_storage; unsigned m_span_idx; span m_span; }; @@ -557,9 +557,9 @@ namespace agg }; const_iterator() : m_ptr(0) {} - const_iterator(const embedded_scanline& sl) : - m_ptr(sl.m_ptr), - m_dx(sl.m_dx) + const_iterator(const embedded_scanline* sl) : + m_ptr(sl->m_ptr), + m_dx(sl->m_dx) { init_span(); } @@ -613,7 +613,7 @@ namespace agg void reset(int, int) {} unsigned num_spans() const { return m_num_spans; } int y() const { return m_y; } - const_iterator begin() const { return const_iterator(*this); } + const_iterator begin() const { return const_iterator(this); } private: diff --git a/extern/agg24/include/agg_scanline_storage_bin.h b/extern/agg24/include/agg_scanline_storage_bin.h index d76001697053..3ab1adca5168 100644 --- a/extern/agg24/include/agg_scanline_storage_bin.h +++ b/extern/agg24/include/agg_scanline_storage_bin.h @@ -64,9 +64,9 @@ namespace agg { public: const_iterator() : m_storage(0) {} - const_iterator(const embedded_scanline& sl) : - m_storage(sl.m_storage), - m_span_idx(sl.m_scanline.start_span) + const_iterator(const embedded_scanline* sl) : + m_storage(sl->m_storage), + m_span_idx(sl->m_scanline.start_span) { m_span = m_storage->span_by_index(m_span_idx); } @@ -90,7 +90,7 @@ namespace agg //----------------------------------------------------------- - embedded_scanline(const scanline_storage_bin& storage) : + embedded_scanline(scanline_storage_bin& storage) : m_storage(&storage) { setup(0); @@ -100,7 +100,7 @@ namespace agg void reset(int, int) {} unsigned num_spans() const { return m_scanline.num_spans; } int y() const { return m_scanline.y; } - const_iterator begin() const { return const_iterator(*this); } + const_iterator begin() const { return const_iterator(this); } //----------------------------------------------------------- void setup(unsigned scanline_idx) @@ -110,7 +110,7 @@ namespace agg } private: - const scanline_storage_bin* m_storage; + scanline_storage_bin* m_storage; scanline_data m_scanline; unsigned m_scanline_idx; }; @@ -362,9 +362,9 @@ namespace agg }; const_iterator() : m_ptr(0) {} - const_iterator(const embedded_scanline& sl) : - m_ptr(sl.m_ptr), - m_dx(sl.m_dx) + const_iterator(const embedded_scanline* sl) : + m_ptr(sl->m_ptr), + m_dx(sl->m_dx) { m_span.x = read_int32() + m_dx; m_span.len = read_int32(); @@ -405,7 +405,7 @@ namespace agg void reset(int, int) {} unsigned num_spans() const { return m_num_spans; } int y() const { return m_y; } - const_iterator begin() const { return const_iterator(*this); } + const_iterator begin() const { return const_iterator(this); } private: diff --git a/extern/agg24/include/agg_scanline_u.h b/extern/agg24/include/agg_scanline_u.h index 22e6274f89c0..630eb9deac3b 100644 --- a/extern/agg24/include/agg_scanline_u.h +++ b/extern/agg24/include/agg_scanline_u.h @@ -2,8 +2,8 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-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. +// 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. // @@ -13,12 +13,12 @@ // http://www.antigrain.com //---------------------------------------------------------------------------- // -// Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by +// Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by // Liberty Technology Systems, Inc., visit http://lib-sys.com // // Liberty Technology Systems, Inc. is the provider of // PostScript and PDF technology for software developers. -// +// //---------------------------------------------------------------------------- #ifndef AGG_SCANLINE_U_INCLUDED @@ -32,22 +32,22 @@ namespace agg // // Unpacked scanline container class // - // This class is used to transfer data from a scanline rasterizer - // to the rendering buffer. It's organized very simple. The class stores - // information of horizontal spans to render it into a pixel-map buffer. - // Each span has staring X, length, and an array of bytes that determine the - // cover-values for each pixel. - // Before using this class you should know the minimal and maximal pixel + // This class is used to transfer data from a scanline rasterizer + // to the rendering buffer. It's organized very simple. The class stores + // information of horizontal spans to render it into a pixel-map buffer. + // Each span has staring X, length, and an array of bytes that determine the + // cover-values for each pixel. + // Before using this class you should know the minimal and maximal pixel // coordinates of your scanline. The protocol of using is: // 1. reset(min_x, max_x) - // 2. add_cell() / add_span() - accumulate scanline. + // 2. add_cell() / add_span() - accumulate scanline. // When forming one scanline the next X coordinate must be always greater // than the last stored one, i.e. it works only with ordered coordinates. // 3. Call finalize(y) and render the scanline. // 3. Call reset_spans() to prepare for the new scanline. - // + // // 4. Rendering: - // + // // Scanline provides an iterator class that allows you to extract // the spans and the cover values for each pixel. Be aware that clipping // has not been done yet, so you should perform it yourself. @@ -61,10 +61,10 @@ namespace agg // ************************************ // // scanline_u8::const_iterator span = sl.begin(); - // - // unsigned char* row = m_rbuf->row(y); // The the address of the beginning + // + // unsigned char* row = m_rbuf->row(y); // The the address of the beginning // // of the current row - // + // // unsigned num_spans = sl.num_spans(); // Number of spans. It's guaranteed that // // num_spans is always greater than 0. // @@ -75,7 +75,7 @@ namespace agg // // int num_pix = span->len; // Number of pixels of the span. // // Always greater than 0, still it's - // // better to use "int" instead of + // // better to use "int" instead of // // "unsigned" because it's more // // convenient for clipping // int x = span->x; @@ -86,24 +86,24 @@ namespace agg // ************************************** // // unsigned char* dst = row + x; // Calculate the start address of the row. - // // In this case we assume a simple + // // In this case we assume a simple // // grayscale image 1-byte per pixel. // do // { - // *dst++ = *covers++; // Hypotetical rendering. + // *dst++ = *covers++; // Hypotetical rendering. // } // while(--num_pix); // // ++span; - // } + // } // while(--num_spans); // num_spans cannot be 0, so this loop is quite safe //------------------------------------------------------------------------ // // The question is: why should we accumulate the whole scanline when we // could render just separate spans when they're ready? - // That's because using the scanline is generally faster. When is consists + // That's because using the scanline is generally faster. When is consists // of more than one span the conditions for the processor cash system - // are better, because switching between two different areas of memory + // are better, because switching between two different areas of memory // (that can be very large) occurs less frequently. //------------------------------------------------------------------------ class scanline_u8 @@ -203,9 +203,9 @@ namespace agg } //-------------------------------------------------------------------- - void finalize(int y) - { - m_y = y; + void finalize(int y) + { + m_y = y; } //-------------------------------------------------------------------- @@ -238,11 +238,11 @@ namespace agg //==========================================================scanline_u8_am - // + // // The scanline container with alpha-masking - // + // //------------------------------------------------------------------------ - template + template class scanline_u8_am : public scanline_u8 { public: @@ -252,7 +252,7 @@ namespace agg typedef base_type::coord_type coord_type; scanline_u8_am() : base_type(), m_alpha_mask(0) {} - scanline_u8_am(const AlphaMask& am) : base_type(), m_alpha_mask(&am) {} + scanline_u8_am(AlphaMask& am) : base_type(), m_alpha_mask(&am) {} //-------------------------------------------------------------------- void finalize(int span_y) @@ -264,9 +264,9 @@ namespace agg unsigned count = base_type::num_spans(); do { - m_alpha_mask->combine_hspan(span->x, - base_type::y(), - span->covers, + m_alpha_mask->combine_hspan(span->x, + base_type::y(), + span->covers, span->len); ++span; } @@ -275,7 +275,7 @@ namespace agg } private: - const AlphaMask* m_alpha_mask; + AlphaMask* m_alpha_mask; }; @@ -390,8 +390,8 @@ namespace agg } else { - m_spans.add(span(coord_type(x + m_min_x), - coord_type(len), + m_spans.add(span(coord_type(x + m_min_x), + coord_type(len), &m_covers[x])); } m_last_x = x + len - 1; @@ -408,17 +408,17 @@ namespace agg } else { - m_spans.add(span(coord_type(x + m_min_x), - coord_type(len), + m_spans.add(span(coord_type(x + m_min_x), + coord_type(len), &m_covers[x])); } m_last_x = x + len - 1; } //-------------------------------------------------------------------- - void finalize(int y) - { - m_y = y; + void finalize(int y) + { + m_y = y; } //-------------------------------------------------------------------- @@ -450,11 +450,11 @@ namespace agg //========================================================scanline32_u8_am - // + // // The scanline container with alpha-masking - // + // //------------------------------------------------------------------------ - template + template class scanline32_u8_am : public scanline32_u8 { public: @@ -465,7 +465,7 @@ namespace agg scanline32_u8_am() : base_type(), m_alpha_mask(0) {} - scanline32_u8_am(const AlphaMask& am) : base_type(), m_alpha_mask(&am) {} + scanline32_u8_am(AlphaMask& am) : base_type(), m_alpha_mask(&am) {} //-------------------------------------------------------------------- void finalize(int span_y) @@ -477,9 +477,9 @@ namespace agg unsigned count = base_type::num_spans(); do { - m_alpha_mask->combine_hspan(span->x, - base_type::y(), - span->covers, + m_alpha_mask->combine_hspan(span->x, + base_type::y(), + span->covers, span->len); ++span; } @@ -488,7 +488,7 @@ namespace agg } private: - const AlphaMask* m_alpha_mask; + AlphaMask* m_alpha_mask; }; diff --git a/extern/agg24/include/agg_span_gradient.h b/extern/agg24/include/agg_span_gradient.h index e30d42b1a98b..58b506dcfe6e 100644 --- a/extern/agg24/include/agg_span_gradient.h +++ b/extern/agg24/include/agg_span_gradient.h @@ -58,8 +58,8 @@ namespace agg //-------------------------------------------------------------------- span_gradient(interpolator_type& inter, - const GradientF& gradient_function, - const ColorF& color_function, + GradientF& gradient_function, + ColorF& color_function, double d1, double d2) : m_interpolator(&inter), m_gradient_function(&gradient_function), @@ -77,8 +77,8 @@ namespace agg //-------------------------------------------------------------------- void interpolator(interpolator_type& i) { m_interpolator = &i; } - void gradient_function(const GradientF& gf) { m_gradient_function = &gf; } - void color_function(const ColorF& cf) { m_color_function = &cf; } + void gradient_function(GradientF& gf) { m_gradient_function = &gf; } + void color_function(ColorF& cf) { m_color_function = &cf; } void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); } void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); } @@ -107,8 +107,8 @@ namespace agg private: interpolator_type* m_interpolator; - const GradientF* m_gradient_function; - const ColorF* m_color_function; + GradientF* m_gradient_function; + ColorF* m_color_function; int m_d1; int m_d2; }; @@ -125,12 +125,19 @@ namespace agg gradient_linear_color() {} gradient_linear_color(const color_type& c1, const color_type& c2, unsigned size = 256) : - m_c1(c1), m_c2(c2), m_size(size) {} + m_c1(c1), m_c2(c2), m_size(size) + // VFALCO 4/28/09 + ,m_mult(1/(double(size)-1)) + // VFALCO + {} unsigned size() const { return m_size; } color_type operator [] (unsigned v) const { - return m_c1.gradient(m_c2, double(v) / double(m_size - 1)); + // VFALCO 4/28/09 + //return m_c1.gradient(m_c2, double(v) / double(m_size - 1)); + return m_c1.gradient(m_c2, double(v) * m_mult ); + // VFALCO } void colors(const color_type& c1, const color_type& c2, unsigned size = 256) @@ -138,11 +145,17 @@ namespace agg m_c1 = c1; m_c2 = c2; m_size = size; + // VFALCO 4/28/09 + m_mult=1/(double(size)-1); + // VFALCO } color_type m_c1; color_type m_c2; unsigned m_size; + // VFALCO 4/28/09 + double m_mult; + // VFALCO }; diff --git a/extern/agg24/include/agg_span_gradient_alpha.h b/extern/agg24/include/agg_span_gradient_alpha.h index e6ee216558ea..2ec040e3b93a 100644 --- a/extern/agg24/include/agg_span_gradient_alpha.h +++ b/extern/agg24/include/agg_span_gradient_alpha.h @@ -43,8 +43,8 @@ namespace agg //-------------------------------------------------------------------- span_gradient_alpha(interpolator_type& inter, - const GradientF& gradient_function, - const AlphaF& alpha_function, + GradientF& gradient_function, + AlphaF& alpha_function, double d1, double d2) : m_interpolator(&inter), m_gradient_function(&gradient_function), @@ -93,8 +93,8 @@ namespace agg private: interpolator_type* m_interpolator; - const GradientF* m_gradient_function; - const AlphaF* m_alpha_function; + GradientF* m_gradient_function; + AlphaF* m_alpha_function; int m_d1; int m_d2; }; diff --git a/extern/agg24/include/agg_span_gradient_contour.h b/extern/agg24/include/agg_span_gradient_contour.h new file mode 100644 index 000000000000..142c2e6d1a34 --- /dev/null +++ b/extern/agg24/include/agg_span_gradient_contour.h @@ -0,0 +1,362 @@ +//---------------------------------------------------------------------------- +// AGG Contribution Pack - Gradients 1 (AGG CP - Gradients 1) +// http://milan.marusinec.sk/aggcp +// +// For Anti-Grain Geometry - Version 2.4 +// http://www.antigrain.org +// +// Contribution Created By: +// Milan Marusinec alias Milano +// milan@marusinec.sk +// Copyright (c) 2007-2008 +// +// 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. +// +// [History] ----------------------------------------------------------------- +// +// 02.02.2008-Milano: Ported from Object Pascal code of AggPas +// +#ifndef AGG_SPAN_GRADIENT_CONTOUR_INCLUDED +#define AGG_SPAN_GRADIENT_CONTOUR_INCLUDED + +#include "agg_basics.h" +#include "agg_trans_affine.h" +#include "agg_path_storage.h" +#include "agg_pixfmt_gray.h" +#include "agg_conv_transform.h" +#include "agg_conv_curve.h" +#include "agg_bounding_rect.h" +#include "agg_renderer_base.h" +#include "agg_renderer_primitives.h" +#include "agg_rasterizer_outline.h" +#include "agg_span_gradient.h" + +#define infinity 1E20 + +namespace agg +{ + + //==========================================================gradient_contour + class gradient_contour + { + private: + int8u* m_buffer; + int m_width; + int m_height; + int m_frame; + + double m_d1; + double m_d2; + + public: + gradient_contour() : + m_buffer(NULL), + m_width(0), + m_height(0), + m_frame(10), + m_d1(0), + m_d2(100) + { + } + + gradient_contour(double d1, double d2) : + m_buffer(NULL), + m_width(0), + m_height(0), + m_frame(10), + m_d1(d1), + m_d2(d2) + { + } + + ~gradient_contour() + { + if (m_buffer) + { + delete [] m_buffer; + } + } + + int8u* contour_create(path_storage* ps ); + + int contour_width() { return m_width; } + int contour_height() { return m_height; } + + void d1(double d ) { m_d1 = d; } + void d2(double d ) { m_d2 = d; } + + void frame(int f ) { m_frame = f; } + int frame() { return m_frame; } + + int calculate(int x, int y, int d) const + { + if (m_buffer) + { + int px = x >> agg::gradient_subpixel_shift; + int py = y >> agg::gradient_subpixel_shift; + + px %= m_width; + + if (px < 0) + { + px += m_width; + } + + py %= m_height; + + if (py < 0 ) + { + py += m_height; + } + + return iround(m_buffer[py * m_width + px ] * (m_d2 / 256 ) + m_d1 ) << gradient_subpixel_shift; + + } + else + { + return 0; + } + } + + }; + + static AGG_INLINE int square(int x ) { return x * x; } + + // DT algorithm by: Pedro Felzenszwalb + void dt(float* spanf, float* spang, float* spanr, int* spann ,int length ) + { + int k = 0; + float s; + + spann[0 ] = 0; + spang[0 ] = float(-infinity ); + spang[1 ] = float(+infinity ); + + for (int q = 1; q <= length - 1; q++) + { + s = ((spanf[q ] + square(q ) ) - (spanf[spann[k ] ] + square(spann[k ] ) ) ) / (2 * q - 2 * spann[k ] ); + + while (s <= spang[k ]) + { + k--; + s = ((spanf[q ] + square(q ) ) - (spanf[spann[k ] ] + square(spann[k ] ) ) ) / (2 * q - 2 * spann[k ] ); + } + + k++; + spann[k ] = q; + spang[k ] = s; + spang[k + 1 ] = float(+infinity); + + } + + k = 0; + + for (int q = 0; q <= length - 1; q++) + { + while (spang[k + 1 ] < q ) + { + k++; + } + + spanr[q ] = square(q - spann[k ] ) + spanf[spann[k ] ]; + } + } + + // DT algorithm by: Pedro Felzenszwalb + int8u* gradient_contour::contour_create(path_storage* ps ) + { + int8u* result = NULL; + + if (ps) + { + // I. Render Black And White NonAA Stroke of the Path + // Path Bounding Box + Some Frame Space Around [configurable] + agg::conv_curve conv(*ps); + + double x1, y1, x2, y2; + + if (agg::bounding_rect_single(conv ,0 ,&x1 ,&y1 ,&x2 ,&y2 )) + { + // Create BW Rendering Surface + int width = int(ceil(x2 - x1 ) ) + m_frame * 2 + 1; + int height = int(ceil(y2 - y1 ) ) + m_frame * 2 + 1; + + int8u* buffer = new int8u[width * height]; + + if (buffer) + { + memset(buffer ,255 ,width * height ); + + // Setup VG Engine & Render + agg::rendering_buffer rb; + rb.attach(buffer ,width ,height ,width ); + + agg::pixfmt_gray8 pf(rb); + agg::renderer_base renb(pf ); + + agg::renderer_primitives > prim(renb ); + agg::rasterizer_outline > > ras(prim ); + + agg::trans_affine mtx; + mtx *= agg::trans_affine_translation(-x1 + m_frame, -y1 + m_frame ); + + agg::conv_transform > trans(conv ,mtx ); + + prim.line_color(agg::rgba8(0 ,0 ,0 ,255 ) ); + ras.add_path(trans ); + + // II. Distance Transform + // Create Float Buffer + 0 vs infinity (1e20) assignment + float* image = new float[width * height]; + + if (image) + { + for (int y = 0, l = 0; y < height; y++ ) + { + for (int x = 0; x < width; x++, l++ ) + { + if (buffer[l ] == 0) + { + image[l ] = 0.0; + } + else + { + image[l ] = float(infinity ); + } + } + + } + + // DT of 2d + // SubBuff max width,height + int length = width; + + if (height > length) + { + length = height; + } + + float* spanf = new float[length]; + float* spang = new float[length + 1]; + float* spanr = new float[length]; + int* spann = new int[length]; + + if ((spanf) && (spang) && (spanr) && (spann)) + { + // Transform along columns + for (int x = 0; x < width; x++ ) + { + for (int y = 0; y < height; y++ ) + { + spanf[y] = image[y * width + x]; + } + + // DT of 1d + dt(spanf ,spang ,spanr ,spann ,height ); + + for (int y = 0; y < height; y++ ) + { + image[y * width + x] = spanr[y]; + } + } + + // Transform along rows + for (int y = 0; y < height; y++ ) + { + for (int x = 0; x < width; x++ ) + { + spanf[x] = image[y * width + x]; + } + + // DT of 1d + dt(spanf ,spang ,spanr ,spann ,width ); + + for (int x = 0; x < width; x++ ) + { + image[y * width + x] = spanr[x]; + } + } + + // Take Square Roots, Min & Max + float min = sqrt(image[0] ); + float max = min; + + for (int y = 0, l = 0; y < height; y++ ) + { + for (int x = 0; x < width; x++, l++ ) + { + image[l] = sqrt(image[l]); + + if (min > image[l]) + { + min = image[l]; + } + + if (max < image[l]) + { + max = image[l]; + } + + } + } + + // III. Convert To Grayscale + if (min == max) + { + memset(buffer ,0 ,width * height ); + } + else + { + float scale = 255 / (max - min ); + + for (int y = 0, l = 0; y < height; y++ ) + { + for (int x = 0; x < width; x++ ,l++ ) + { + buffer[l] = int8u(int((image[l] - min ) * scale )); + } + } + } + + // OK + if (m_buffer) + { + delete [] m_buffer; + } + + m_buffer = buffer; + m_width = width; + m_height = height; + + buffer = NULL; + result = m_buffer; + + } + + if (spanf) { delete [] spanf; } + if (spang) { delete [] spang; } + if (spanr) { delete [] spanr; } + if (spann) { delete [] spann; } + + delete [] image; + + } + } + + if (buffer) + { + delete [] buffer; + } + + } + + } + return result; + } + +} + +#endif diff --git a/extern/agg24/include/agg_span_gradient_image.h b/extern/agg24/include/agg_span_gradient_image.h new file mode 100644 index 000000000000..c99eaca166bd --- /dev/null +++ b/extern/agg24/include/agg_span_gradient_image.h @@ -0,0 +1,188 @@ +//---------------------------------------------------------------------------- +// AGG Contribution Pack - Gradients 1 (AGG CP - Gradients 1) +// http://milan.marusinec.sk/aggcp +// +// For Anti-Grain Geometry - Version 2.4 +// http://www.antigrain.org +// +// Contribution Created By: +// Milan Marusinec alias Milano +// milan@marusinec.sk +// Copyright (c) 2007-2008 +// +// 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. +// +// [History] ----------------------------------------------------------------- +// +// 03.02.2008-Milano: Ported from Object Pascal code of AggPas +// +#ifndef AGG_SPAN_GRADIENT_IMAGE_INCLUDED +#define AGG_SPAN_GRADIENT_IMAGE_INCLUDED + +#include "agg_basics.h" +#include "agg_span_gradient.h" +#include "agg_color_rgba.h" +#include "agg_rendering_buffer.h" +#include "agg_pixfmt_rgba.h" + +namespace agg +{ + + //==========================================================one_color_function + template class one_color_function + { + public: + typedef ColorT color_type; + + color_type m_color; + + one_color_function() : + m_color() + { + } + + static unsigned size() { return 1; } + + const color_type& operator [] (unsigned i) const + { + return m_color; + } + + color_type* operator [] (unsigned i) + { + return &m_color; + } + }; + + //==========================================================gradient_image + template class gradient_image + { + private: + //------------ fields + typedef ColorT color_type; + typedef agg::pixfmt_rgba32 pixfmt_type; + + agg::rgba8* m_buffer; + + int m_alocdx; + int m_alocdy; + int m_width; + int m_height; + + color_type* m_color; + + one_color_function m_color_function; + + public: + gradient_image() : + m_color_function(), + m_buffer(NULL), + m_alocdx(0), + m_alocdy(0), + m_width(0), + m_height(0) + { + m_color = m_color_function[0 ]; + } + + ~gradient_image() + { + if (m_buffer) { delete [] m_buffer; } + } + + void* image_create(int width, int height ) + { + void* result = NULL; + + if (width > m_alocdx || height > m_alocdy) + { + if (m_buffer) { delete [] m_buffer; } + + m_buffer = NULL; + m_buffer = new agg::rgba8[width * height]; + + if (m_buffer) + { + m_alocdx = width; + m_alocdy = height; + } + else + { + m_alocdx = 0; + m_alocdy = 0; + }; + }; + + if (m_buffer) + { + m_width = width; + m_height = height; + + for (int rows = 0; rows < height; rows++) + { + agg::rgba8* row = &m_buffer[rows * m_alocdx ]; + memset(row ,0 ,m_width * 4 ); + }; + + result = m_buffer; + }; + return result; + } + + void* image_buffer() { return m_buffer; } + int image_width() { return m_width; } + int image_height() { return m_height; } + int image_stride() { return m_alocdx * 4; } + + int calculate(int x, int y, int d) const + { + if (m_buffer) + { + int px = x >> agg::gradient_subpixel_shift; + int py = y >> agg::gradient_subpixel_shift; + + px %= m_width; + + if (px < 0) + { + px += m_width; + } + + py %= m_height; + + if (py < 0 ) + { + py += m_height; + } + + rgba8* pixel = &m_buffer[py * m_alocdx + px ]; + + m_color->r = pixel->r; + m_color->g = pixel->g; + m_color->b = pixel->b; + m_color->a = pixel->a; + + } + else + { + m_color->r = 0; + m_color->g = 0; + m_color->b = 0; + m_color->a = 0; + } + return 0; + } + + const one_color_function& color_function() const + { + return m_color_function; + } + + }; + +} + +#endif diff --git a/extern/agg24/include/agg_span_image_filter.h b/extern/agg24/include/agg_span_image_filter.h index 47e2f44e3e34..2f613e5d86c3 100644 --- a/extern/agg24/include/agg_span_image_filter.h +++ b/extern/agg24/include/agg_span_image_filter.h @@ -37,7 +37,7 @@ namespace agg span_image_filter() {} span_image_filter(source_type& src, interpolator_type& interpolator, - const image_filter_lut* filter) : + image_filter_lut* filter) : m_src(&src), m_interpolator(&interpolator), m_filter(filter), @@ -59,7 +59,7 @@ namespace agg //-------------------------------------------------------------------- void interpolator(interpolator_type& v) { m_interpolator = &v; } - void filter(const image_filter_lut& v) { m_filter = &v; } + void filter(image_filter_lut& v) { m_filter = &v; } void filter_offset(double dx, double dy) { m_dx_dbl = dx; @@ -79,7 +79,7 @@ namespace agg private: source_type* m_src; interpolator_type* m_interpolator; - const image_filter_lut* m_filter; + image_filter_lut* m_filter; double m_dx_dbl; double m_dy_dbl; unsigned m_dx_int; @@ -109,7 +109,7 @@ namespace agg //-------------------------------------------------------------------- span_image_resample_affine(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, &filter), m_scale_limit(200.0), m_blur_x(1.0), @@ -195,7 +195,7 @@ namespace agg //-------------------------------------------------------------------- span_image_resample(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, &filter), m_scale_limit(20), m_blur_x(image_subpixel_scale), diff --git a/extern/agg24/include/agg_span_image_filter_gray.h b/extern/agg24/include/agg_span_image_filter_gray.h index 9f3ede78f23c..4bc9c00be666 100644 --- a/extern/agg24/include/agg_span_image_filter_gray.h +++ b/extern/agg24/include/agg_span_image_filter_gray.h @@ -43,11 +43,7 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_gray_nn() {} @@ -68,7 +64,7 @@ namespace agg base_type::source().span(x >> image_subpixel_shift, y >> image_subpixel_shift, 1); - span->a = base_mask; + span->a = color_type::full_value(); ++span; ++base_type::interpolator(); } while(--len); @@ -89,11 +85,7 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_gray_bilinear() {} @@ -108,7 +100,7 @@ namespace agg { base_type::interpolator().begin(x + base_type::filter_dx_dbl(), y + base_type::filter_dy_dbl(), len); - calc_type fg; + long_type fg; const value_type *fg_ptr; do { @@ -123,7 +115,7 @@ namespace agg int x_lr = x_hr >> image_subpixel_shift; int y_lr = y_hr >> image_subpixel_shift; - fg = image_subpixel_scale * image_subpixel_scale / 2; + fg = 0; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; @@ -140,8 +132,8 @@ namespace agg fg_ptr = (const value_type*)base_type::source().next_x(); fg += *fg_ptr * x_hr * y_hr; - span->v = value_type(fg >> (image_subpixel_shift * 2)); - span->a = base_mask; + span->v = color_type::downshift(fg, image_subpixel_shift * 2); + span->a = color_type::full_value(); ++span; ++base_type::interpolator(); @@ -162,11 +154,7 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_gray_bilinear_clip() {} @@ -184,8 +172,8 @@ namespace agg { base_type::interpolator().begin(x + base_type::filter_dx_dbl(), y + base_type::filter_dy_dbl(), len); - calc_type fg; - calc_type src_alpha; + long_type fg; + long_type src_alpha; value_type back_v = m_back_color.v; value_type back_a = m_back_color.a; @@ -210,7 +198,7 @@ namespace agg if(x_lr >= 0 && y_lr >= 0 && x_lr < maxx && y_lr < maxy) { - fg = image_subpixel_scale * image_subpixel_scale / 2; + fg = 0; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; @@ -225,8 +213,8 @@ namespace agg fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * y_hr; fg += *fg_ptr++ * x_hr * y_hr; - fg >>= image_subpixel_shift * 2; - src_alpha = base_mask; + fg = color_type::downshift(fg, image_subpixel_shift * 2); + src_alpha = color_type::full_value(); } else { @@ -239,8 +227,7 @@ namespace agg } else { - fg = - src_alpha = image_subpixel_scale * image_subpixel_scale / 2; + fg = src_alpha = 0; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; @@ -252,7 +239,7 @@ namespace agg { fg += weight * *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); - src_alpha += weight * base_mask; + src_alpha += weight * color_type::full_value(); } else { @@ -268,7 +255,7 @@ namespace agg { fg += weight * *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); - src_alpha += weight * base_mask; + src_alpha += weight * color_type::full_value(); } else { @@ -285,7 +272,7 @@ namespace agg { fg += weight * *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); - src_alpha += weight * base_mask; + src_alpha += weight * color_type::full_value(); } else { @@ -301,7 +288,7 @@ namespace agg { fg += weight * *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); - src_alpha += weight * base_mask; + src_alpha += weight * color_type::full_value(); } else { @@ -309,8 +296,8 @@ namespace agg src_alpha += back_a * weight; } - fg >>= image_subpixel_shift * 2; - src_alpha >>= image_subpixel_shift * 2; + fg = color_type::downshift(fg, image_subpixel_shift * 2); + src_alpha = color_type::downshift(src_alpha, image_subpixel_shift * 2); } } @@ -339,17 +326,13 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_gray_2x2() {} span_image_filter_gray_2x2(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, &filter) {} @@ -360,7 +343,7 @@ namespace agg base_type::interpolator().begin(x + base_type::filter_dx_dbl(), y + base_type::filter_dy_dbl(), len); - calc_type fg; + long_type fg; const value_type *fg_ptr; const int16* weight_array = base_type::filter().weight_array() + @@ -380,7 +363,7 @@ namespace agg int y_lr = y_hr >> image_subpixel_shift; unsigned weight; - fg = image_filter_scale / 2; + fg = 0; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; @@ -414,10 +397,10 @@ namespace agg fg += weight * *fg_ptr; fg >>= image_filter_shift; - if(fg > base_mask) fg = base_mask; + if(fg > color_type::full_value()) fg = color_type::full_value(); span->v = (value_type)fg; - span->a = base_mask; + span->a = color_type::full_value(); ++span; ++base_type::interpolator(); } while(--len); @@ -438,17 +421,13 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_gray() {} span_image_filter_gray(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, &filter) {} @@ -458,7 +437,7 @@ namespace agg base_type::interpolator().begin(x + base_type::filter_dx_dbl(), y + base_type::filter_dy_dbl(), len); - int fg; + long_type fg; const value_type *fg_ptr; unsigned diameter = base_type::filter().diameter(); @@ -481,7 +460,7 @@ namespace agg int x_lr = x_hr >> image_subpixel_shift; int y_lr = y_hr >> image_subpixel_shift; - fg = image_filter_scale / 2; + fg = 0; int x_fract = x_hr & image_subpixel_mask; unsigned y_count = diameter; @@ -513,9 +492,9 @@ namespace agg fg >>= image_filter_shift; if(fg < 0) fg = 0; - if(fg > base_mask) fg = base_mask; + if(fg > color_type::full_value()) fg = color_type::full_value(); span->v = (value_type)fg; - span->a = base_mask; + span->a = color_type::full_value(); ++span; ++base_type::interpolator(); @@ -540,8 +519,6 @@ namespace agg typedef typename color_type::long_type long_type; enum base_scale_e { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask, downscale_shift = image_filter_shift }; @@ -549,7 +526,7 @@ namespace agg span_image_resample_gray_affine() {} span_image_resample_gray_affine(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, filter) {} @@ -579,7 +556,7 @@ namespace agg x += base_type::filter_dx_int() - radius_x; y += base_type::filter_dy_int() - radius_y; - fg = image_filter_scale / 2; + fg = 0; int y_lr = y >> image_subpixel_shift; int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * @@ -617,10 +594,10 @@ namespace agg fg /= total_weight; if(fg < 0) fg = 0; - if(fg > base_mask) fg = base_mask; + if(fg > color_type::full_value()) fg = color_type::full_value(); span->v = (value_type)fg; - span->a = base_mask; + span->a = color_type::full_value(); ++span; ++base_type::interpolator(); @@ -644,8 +621,6 @@ namespace agg typedef typename color_type::long_type long_type; enum base_scale_e { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask, downscale_shift = image_filter_shift }; @@ -653,7 +628,7 @@ namespace agg span_image_resample_gray() {} span_image_resample_gray(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, filter) {} @@ -690,7 +665,7 @@ namespace agg x += base_type::filter_dx_int() - radius_x; y += base_type::filter_dy_int() - radius_y; - fg = image_filter_scale / 2; + fg = 0; int y_lr = y >> image_subpixel_shift; int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * @@ -727,10 +702,10 @@ namespace agg fg /= total_weight; if(fg < 0) fg = 0; - if(fg > base_mask) fg = base_mask; + if(fg > color_type::full_value()) fg = color_type::full_value(); span->v = (value_type)fg; - span->a = base_mask; + span->a = color_type::full_value(); ++span; ++base_type::interpolator(); diff --git a/extern/agg24/include/agg_span_image_filter_rgb.h b/extern/agg24/include/agg_span_image_filter_rgb.h index a72ffd2406e6..f78ae19c1b40 100644 --- a/extern/agg24/include/agg_span_image_filter_rgb.h +++ b/extern/agg24/include/agg_span_image_filter_rgb.h @@ -44,11 +44,7 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_rgb_nn() {} @@ -72,7 +68,7 @@ namespace agg span->r = fg_ptr[order_type::R]; span->g = fg_ptr[order_type::G]; span->b = fg_ptr[order_type::B]; - span->a = base_mask; + span->a = color_type::full_value(); ++span; ++base_type::interpolator(); @@ -95,11 +91,7 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_rgb_bilinear() {} @@ -114,7 +106,7 @@ namespace agg { base_type::interpolator().begin(x + base_type::filter_dx_dbl(), y + base_type::filter_dy_dbl(), len); - calc_type fg[3]; + long_type fg[3]; const value_type *fg_ptr; do { @@ -131,9 +123,7 @@ namespace agg unsigned weight; - fg[0] = - fg[1] = - fg[2] = image_subpixel_scale * image_subpixel_scale / 2; + fg[0] = fg[1] = fg[2] = 0; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; @@ -163,10 +153,10 @@ namespace agg fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr; - span->r = value_type(fg[order_type::R] >> (image_subpixel_shift * 2)); - span->g = value_type(fg[order_type::G] >> (image_subpixel_shift * 2)); - span->b = value_type(fg[order_type::B] >> (image_subpixel_shift * 2)); - span->a = base_mask; + span->r = color_type::downshift(fg[order_type::R], image_subpixel_shift * 2); + span->g = color_type::downshift(fg[order_type::G], image_subpixel_shift * 2); + span->b = color_type::downshift(fg[order_type::B], image_subpixel_shift * 2); + span->a = color_type::full_value(); ++span; ++base_type::interpolator(); @@ -190,11 +180,7 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_rgb_bilinear_clip() {} @@ -212,8 +198,8 @@ namespace agg { base_type::interpolator().begin(x + base_type::filter_dx_dbl(), y + base_type::filter_dy_dbl(), len); - calc_type fg[3]; - calc_type src_alpha; + long_type fg[3]; + long_type src_alpha; value_type back_r = m_back_color.r; value_type back_g = m_back_color.g; value_type back_b = m_back_color.b; @@ -241,9 +227,7 @@ namespace agg if(x_lr >= 0 && y_lr >= 0 && x_lr < maxx && y_lr < maxy) { - fg[0] = - fg[1] = - fg[2] = image_subpixel_scale * image_subpixel_scale / 2; + fg[0] = fg[1] = fg[2] = 0; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; @@ -276,10 +260,10 @@ namespace agg fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; - fg[0] >>= image_subpixel_shift * 2; - fg[1] >>= image_subpixel_shift * 2; - fg[2] >>= image_subpixel_shift * 2; - src_alpha = base_mask; + fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2); + fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2); + fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2); + src_alpha = color_type::full_value(); } else { @@ -293,10 +277,7 @@ namespace agg } else { - fg[0] = - fg[1] = - fg[2] = - src_alpha = image_subpixel_scale * image_subpixel_scale / 2; + fg[0] = fg[1] = fg[2] = src_alpha = 0; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; @@ -312,7 +293,7 @@ namespace agg fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; - src_alpha += weight * base_mask; + src_alpha += weight * color_type::full_value(); } else { @@ -334,7 +315,7 @@ namespace agg fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; - src_alpha += weight * base_mask; + src_alpha += weight * color_type::full_value(); } else { @@ -357,7 +338,7 @@ namespace agg fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; - src_alpha += weight * base_mask; + src_alpha += weight * color_type::full_value(); } else { @@ -379,7 +360,7 @@ namespace agg fg[0] += weight * *fg_ptr++; fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr++; - src_alpha += weight * base_mask; + src_alpha += weight * color_type::full_value(); } else { @@ -389,10 +370,10 @@ namespace agg src_alpha += back_a * weight; } - fg[0] >>= image_subpixel_shift * 2; - fg[1] >>= image_subpixel_shift * 2; - fg[2] >>= image_subpixel_shift * 2; - src_alpha >>= image_subpixel_shift * 2; + fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2); + fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2); + fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2); + src_alpha = color_type::downshift(src_alpha, image_subpixel_shift * 2); } } @@ -424,17 +405,13 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_rgb_2x2() {} span_image_filter_rgb_2x2(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, &filter) {} @@ -445,7 +422,7 @@ namespace agg base_type::interpolator().begin(x + base_type::filter_dx_dbl(), y + base_type::filter_dy_dbl(), len); - calc_type fg[3]; + long_type fg[3]; const value_type *fg_ptr; const int16* weight_array = base_type::filter().weight_array() + @@ -465,7 +442,7 @@ namespace agg int y_lr = y_hr >> image_subpixel_shift; unsigned weight; - fg[0] = fg[1] = fg[2] = image_filter_scale / 2; + fg[0] = fg[1] = fg[2] = 0; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; @@ -506,18 +483,18 @@ namespace agg fg[1] += weight * *fg_ptr++; fg[2] += weight * *fg_ptr; - fg[0] >>= image_filter_shift; - fg[1] >>= image_filter_shift; - fg[2] >>= image_filter_shift; + fg[0] = color_type::downshift(fg[0], image_filter_shift); + fg[1] = color_type::downshift(fg[1], image_filter_shift); + fg[2] = color_type::downshift(fg[2], image_filter_shift); - if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask; - if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask; - if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask; + if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value(); + if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value(); + if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value(); span->r = (value_type)fg[order_type::R]; span->g = (value_type)fg[order_type::G]; span->b = (value_type)fg[order_type::B]; - span->a = base_mask; + span->a = color_type::full_value(); ++span; ++base_type::interpolator(); @@ -541,17 +518,13 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_rgb() {} span_image_filter_rgb(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, &filter) {} @@ -561,7 +534,7 @@ namespace agg base_type::interpolator().begin(x + base_type::filter_dx_dbl(), y + base_type::filter_dy_dbl(), len); - int fg[3]; + long_type fg[3]; const value_type *fg_ptr; unsigned diameter = base_type::filter().diameter(); @@ -584,7 +557,7 @@ namespace agg int x_lr = x_hr >> image_subpixel_shift; int y_lr = y_hr >> image_subpixel_shift; - fg[0] = fg[1] = fg[2] = image_filter_scale / 2; + fg[0] = fg[1] = fg[2] = 0; int x_fract = x_hr & image_subpixel_mask; unsigned y_count = diameter; @@ -618,22 +591,22 @@ namespace agg fg_ptr = (const value_type*)base_type::source().next_y(); } - fg[0] >>= image_filter_shift; - fg[1] >>= image_filter_shift; - fg[2] >>= image_filter_shift; + fg[0] = color_type::downshift(fg[0], image_filter_shift); + fg[1] = color_type::downshift(fg[1], image_filter_shift); + fg[2] = color_type::downshift(fg[2], image_filter_shift); if(fg[0] < 0) fg[0] = 0; if(fg[1] < 0) fg[1] = 0; if(fg[2] < 0) fg[2] = 0; - if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask; - if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask; - if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask; + if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value(); + if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value(); + if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value(); span->r = (value_type)fg[order_type::R]; span->g = (value_type)fg[order_type::G]; span->b = (value_type)fg[order_type::B]; - span->a = base_mask; + span->a = color_type::full_value(); ++span; ++base_type::interpolator(); @@ -659,8 +632,6 @@ namespace agg typedef typename color_type::long_type long_type; enum base_scale_e { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask, downscale_shift = image_filter_shift }; @@ -668,7 +639,7 @@ namespace agg span_image_resample_rgb_affine() {} span_image_resample_rgb_affine(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, filter) {} @@ -698,7 +669,7 @@ namespace agg x += base_type::filter_dx_int() - radius_x; y += base_type::filter_dy_int() - radius_y; - fg[0] = fg[1] = fg[2] = image_filter_scale / 2; + fg[0] = fg[1] = fg[2] = 0; int y_lr = y >> image_subpixel_shift; int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * @@ -744,14 +715,14 @@ namespace agg if(fg[1] < 0) fg[1] = 0; if(fg[2] < 0) fg[2] = 0; - if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask; - if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask; - if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask; + if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value(); + if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value(); + if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value(); span->r = (value_type)fg[order_type::R]; span->g = (value_type)fg[order_type::G]; span->b = (value_type)fg[order_type::B]; - span->a = base_mask; + span->a = color_type::full_value(); ++span; ++base_type::interpolator(); @@ -776,8 +747,6 @@ namespace agg typedef typename color_type::long_type long_type; enum base_scale_e { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask, downscale_shift = image_filter_shift }; @@ -785,7 +754,7 @@ namespace agg span_image_resample_rgb() {} span_image_resample_rgb(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, filter) {} @@ -822,7 +791,7 @@ namespace agg x += base_type::filter_dx_int() - radius_x; y += base_type::filter_dy_int() - radius_y; - fg[0] = fg[1] = fg[2] = image_filter_scale / 2; + fg[0] = fg[1] = fg[2] = 0; int y_lr = y >> image_subpixel_shift; int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * @@ -867,14 +836,14 @@ namespace agg if(fg[1] < 0) fg[1] = 0; if(fg[2] < 0) fg[2] = 0; - if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask; - if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask; - if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask; + if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value(); + if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value(); + if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value(); span->r = (value_type)fg[order_type::R]; span->g = (value_type)fg[order_type::G]; span->b = (value_type)fg[order_type::B]; - span->a = base_mask; + span->a = color_type::full_value(); ++span; ++base_type::interpolator(); diff --git a/extern/agg24/include/agg_span_image_filter_rgba.h b/extern/agg24/include/agg_span_image_filter_rgba.h index 134a802550d7..af7a1a2ef0d2 100644 --- a/extern/agg24/include/agg_span_image_filter_rgba.h +++ b/extern/agg24/include/agg_span_image_filter_rgba.h @@ -44,11 +44,7 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_rgba_nn() {} @@ -85,7 +81,7 @@ namespace agg //=========================================span_image_filter_rgba_bilinear template class span_image_filter_rgba_bilinear : - public span_image_filter + public span_image_filter { public: typedef Source source_type; @@ -95,11 +91,7 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_rgba_bilinear() {} @@ -115,7 +107,7 @@ namespace agg base_type::interpolator().begin(x + base_type::filter_dx_dbl(), y + base_type::filter_dy_dbl(), len); - calc_type fg[4]; + long_type fg[4]; const value_type *fg_ptr; do @@ -170,10 +162,10 @@ namespace agg fg[2] += weight * *fg_ptr++; fg[3] += weight * *fg_ptr; - span->r = value_type(fg[order_type::R] >> (image_subpixel_shift * 2)); - span->g = value_type(fg[order_type::G] >> (image_subpixel_shift * 2)); - span->b = value_type(fg[order_type::B] >> (image_subpixel_shift * 2)); - span->a = value_type(fg[order_type::A] >> (image_subpixel_shift * 2)); + span->r = value_type(color_type::downshift(fg[order_type::R], image_subpixel_shift * 2)); + span->g = value_type(color_type::downshift(fg[order_type::G], image_subpixel_shift * 2)); + span->b = value_type(color_type::downshift(fg[order_type::B], image_subpixel_shift * 2)); + span->a = value_type(color_type::downshift(fg[order_type::A], image_subpixel_shift * 2)); ++span; ++base_type::interpolator(); @@ -196,11 +188,7 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_rgba_bilinear_clip() {} @@ -220,7 +208,7 @@ namespace agg base_type::interpolator().begin(x + base_type::filter_dx_dbl(), y + base_type::filter_dy_dbl(), len); - calc_type fg[4]; + long_type fg[4]; value_type back_r = m_back_color.r; value_type back_g = m_back_color.g; value_type back_b = m_back_color.b; @@ -248,10 +236,7 @@ namespace agg if(x_lr >= 0 && y_lr >= 0 && x_lr < maxx && y_lr < maxy) { - fg[0] = - fg[1] = - fg[2] = - fg[3] = image_subpixel_scale * image_subpixel_scale / 2; + fg[0] = fg[1] = fg[2] = fg[3] = 0; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; @@ -288,10 +273,10 @@ namespace agg fg[2] += weight * *fg_ptr++; fg[3] += weight * *fg_ptr++; - fg[0] >>= image_subpixel_shift * 2; - fg[1] >>= image_subpixel_shift * 2; - fg[2] >>= image_subpixel_shift * 2; - fg[3] >>= image_subpixel_shift * 2; + fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2); + fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2); + fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2); + fg[3] = color_type::downshift(fg[3], image_subpixel_shift * 2); } else { @@ -305,10 +290,7 @@ namespace agg } else { - fg[0] = - fg[1] = - fg[2] = - fg[3] = image_subpixel_scale * image_subpixel_scale / 2; + fg[0] = fg[1] = fg[2] = fg[3] = 0; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; @@ -401,10 +383,10 @@ namespace agg fg[order_type::A] += back_a * weight; } - fg[0] >>= image_subpixel_shift * 2; - fg[1] >>= image_subpixel_shift * 2; - fg[2] >>= image_subpixel_shift * 2; - fg[3] >>= image_subpixel_shift * 2; + fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2); + fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2); + fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2); + fg[3] = color_type::downshift(fg[3], image_subpixel_shift * 2); } } @@ -435,17 +417,13 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_rgba_2x2() {} span_image_filter_rgba_2x2(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, &filter) {} @@ -456,7 +434,7 @@ namespace agg base_type::interpolator().begin(x + base_type::filter_dx_dbl(), y + base_type::filter_dy_dbl(), len); - calc_type fg[4]; + long_type fg[4]; const value_type *fg_ptr; const int16* weight_array = base_type::filter().weight_array() + @@ -477,7 +455,7 @@ namespace agg int y_lr = y_hr >> image_subpixel_shift; unsigned weight; - fg[0] = fg[1] = fg[2] = fg[3] = image_filter_scale / 2; + fg[0] = fg[1] = fg[2] = fg[3] = 0; x_hr &= image_subpixel_mask; y_hr &= image_subpixel_mask; @@ -522,12 +500,12 @@ namespace agg fg[2] += weight * *fg_ptr++; fg[3] += weight * *fg_ptr; - fg[0] >>= image_filter_shift; - fg[1] >>= image_filter_shift; - fg[2] >>= image_filter_shift; - fg[3] >>= image_filter_shift; + fg[0] = color_type::downshift(fg[0], image_filter_shift); + fg[1] = color_type::downshift(fg[1], image_filter_shift); + fg[2] = color_type::downshift(fg[2], image_filter_shift); + fg[3] = color_type::downshift(fg[3], image_filter_shift); - if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask; + if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value(); if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A]; if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A]; if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A]; @@ -558,17 +536,13 @@ namespace agg typedef span_image_filter base_type; typedef typename color_type::value_type value_type; typedef typename color_type::calc_type calc_type; - enum base_scale_e - { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask - }; + typedef typename color_type::long_type long_type; //-------------------------------------------------------------------- span_image_filter_rgba() {} span_image_filter_rgba(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, &filter) {} @@ -578,7 +552,7 @@ namespace agg base_type::interpolator().begin(x + base_type::filter_dx_dbl(), y + base_type::filter_dy_dbl(), len); - int fg[4]; + long_type fg[4]; const value_type *fg_ptr; unsigned diameter = base_type::filter().diameter(); @@ -601,7 +575,7 @@ namespace agg int x_lr = x_hr >> image_subpixel_shift; int y_lr = y_hr >> image_subpixel_shift; - fg[0] = fg[1] = fg[2] = fg[3] = image_filter_scale / 2; + fg[0] = fg[1] = fg[2] = fg[3] = 0; int x_fract = x_hr & image_subpixel_mask; unsigned y_count = diameter; @@ -636,17 +610,17 @@ namespace agg fg_ptr = (const value_type*)base_type::source().next_y(); } - fg[0] >>= image_filter_shift; - fg[1] >>= image_filter_shift; - fg[2] >>= image_filter_shift; - fg[3] >>= image_filter_shift; + fg[0] = color_type::downshift(fg[0], image_filter_shift); + fg[1] = color_type::downshift(fg[1], image_filter_shift); + fg[2] = color_type::downshift(fg[2], image_filter_shift); + fg[3] = color_type::downshift(fg[3], image_filter_shift); if(fg[0] < 0) fg[0] = 0; if(fg[1] < 0) fg[1] = 0; if(fg[2] < 0) fg[2] = 0; if(fg[3] < 0) fg[3] = 0; - if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask; + if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value(); if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A]; if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A]; if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A]; @@ -679,8 +653,6 @@ namespace agg typedef typename color_type::long_type long_type; enum base_scale_e { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask, downscale_shift = image_filter_shift }; @@ -688,7 +660,7 @@ namespace agg span_image_resample_rgba_affine() {} span_image_resample_rgba_affine(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, filter) {} @@ -718,7 +690,7 @@ namespace agg x += base_type::filter_dx_int() - radius_x; y += base_type::filter_dy_int() - radius_y; - fg[0] = fg[1] = fg[2] = fg[3] = image_filter_scale / 2; + fg[0] = fg[1] = fg[2] = fg[3] = 0; int y_lr = y >> image_subpixel_shift; int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * @@ -767,7 +739,7 @@ namespace agg if(fg[2] < 0) fg[2] = 0; if(fg[3] < 0) fg[3] = 0; - if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask; + if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value(); if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A]; if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A]; if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A]; @@ -800,8 +772,6 @@ namespace agg typedef typename color_type::long_type long_type; enum base_scale_e { - base_shift = color_type::base_shift, - base_mask = color_type::base_mask, downscale_shift = image_filter_shift }; @@ -809,7 +779,7 @@ namespace agg span_image_resample_rgba() {} span_image_resample_rgba(source_type& src, interpolator_type& inter, - const image_filter_lut& filter) : + image_filter_lut& filter) : base_type(src, inter, filter) {} @@ -846,7 +816,7 @@ namespace agg x += base_type::filter_dx_int() - radius_x; y += base_type::filter_dy_int() - radius_y; - fg[0] = fg[1] = fg[2] = fg[3] = image_filter_scale / 2; + fg[0] = fg[1] = fg[2] = fg[3] = 0; int y_lr = y >> image_subpixel_shift; int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * @@ -894,7 +864,7 @@ namespace agg if(fg[2] < 0) fg[2] = 0; if(fg[3] < 0) fg[3] = 0; - if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask; + if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value(); if(fg[order_type::R] > fg[order_type::R]) fg[order_type::R] = fg[order_type::R]; if(fg[order_type::G] > fg[order_type::G]) fg[order_type::G] = fg[order_type::G]; if(fg[order_type::B] > fg[order_type::B]) fg[order_type::B] = fg[order_type::B]; diff --git a/extern/agg24/include/agg_span_interpolator_adaptor.h b/extern/agg24/include/agg_span_interpolator_adaptor.h index 17ea71291b03..0fdfa7747964 100644 --- a/extern/agg24/include/agg_span_interpolator_adaptor.h +++ b/extern/agg24/include/agg_span_interpolator_adaptor.h @@ -32,16 +32,16 @@ namespace agg //-------------------------------------------------------------------- span_interpolator_adaptor() {} - span_interpolator_adaptor(const trans_type& trans, - const distortion_type& dist) : + span_interpolator_adaptor(trans_type& trans, + distortion_type& dist) : base_type(trans), m_distortion(&dist) { } //-------------------------------------------------------------------- - span_interpolator_adaptor(const trans_type& trans, - const distortion_type& dist, + span_interpolator_adaptor(trans_type& trans, + distortion_type& dist, double x, double y, unsigned len) : base_type(trans, x, y, len), m_distortion(&dist) @@ -49,13 +49,13 @@ namespace agg } //-------------------------------------------------------------------- - const distortion_type& distortion() const + distortion_type& distortion() const { return *m_distortion; } //-------------------------------------------------------------------- - void distortion(const distortion_type& dist) + void distortion(distortion_type& dist) { m_distortion = dist; } @@ -69,7 +69,7 @@ namespace agg private: //-------------------------------------------------------------------- - const distortion_type* m_distortion; + distortion_type* m_distortion; }; } diff --git a/extern/agg24/include/agg_span_interpolator_linear.h b/extern/agg24/include/agg_span_interpolator_linear.h index cbf3d1a414fb..ef10505ce11a 100644 --- a/extern/agg24/include/agg_span_interpolator_linear.h +++ b/extern/agg24/include/agg_span_interpolator_linear.h @@ -38,8 +38,8 @@ namespace agg //-------------------------------------------------------------------- span_interpolator_linear() {} - span_interpolator_linear(const trans_type& trans) : m_trans(&trans) {} - span_interpolator_linear(const trans_type& trans, + span_interpolator_linear(trans_type& trans) : m_trans(&trans) {} + span_interpolator_linear(trans_type& trans, double x, double y, unsigned len) : m_trans(&trans) { @@ -48,7 +48,7 @@ namespace agg //---------------------------------------------------------------- const trans_type& transformer() const { return *m_trans; } - void transformer(const trans_type& trans) { m_trans = &trans; } + void transformer(trans_type& trans) { m_trans = &trans; } //---------------------------------------------------------------- void begin(double x, double y, unsigned len) @@ -95,7 +95,7 @@ namespace agg } private: - const trans_type* m_trans; + trans_type* m_trans; dda2_line_interpolator m_li_x; dda2_line_interpolator m_li_y; }; @@ -125,14 +125,14 @@ namespace agg m_subdiv_size(1 << m_subdiv_shift), m_subdiv_mask(m_subdiv_size - 1) {} - span_interpolator_linear_subdiv(const trans_type& trans, + span_interpolator_linear_subdiv(trans_type& trans, unsigned subdiv_shift = 4) : m_subdiv_shift(subdiv_shift), m_subdiv_size(1 << m_subdiv_shift), m_subdiv_mask(m_subdiv_size - 1), m_trans(&trans) {} - span_interpolator_linear_subdiv(const trans_type& trans, + span_interpolator_linear_subdiv(trans_type& trans, double x, double y, unsigned len, unsigned subdiv_shift = 4) : m_subdiv_shift(subdiv_shift), @@ -213,7 +213,7 @@ namespace agg unsigned m_subdiv_shift; unsigned m_subdiv_size; unsigned m_subdiv_mask; - const trans_type* m_trans; + trans_type* m_trans; dda2_line_interpolator m_li_x; dda2_line_interpolator m_li_y; int m_src_x; diff --git a/extern/agg24/include/agg_span_interpolator_trans.h b/extern/agg24/include/agg_span_interpolator_trans.h index 7c474742fe66..32bc678a8e4a 100644 --- a/extern/agg24/include/agg_span_interpolator_trans.h +++ b/extern/agg24/include/agg_span_interpolator_trans.h @@ -39,8 +39,8 @@ namespace agg //-------------------------------------------------------------------- span_interpolator_trans() {} - span_interpolator_trans(const trans_type& trans) : m_trans(&trans) {} - span_interpolator_trans(const trans_type& trans, + span_interpolator_trans(trans_type& trans) : m_trans(&trans) {} + span_interpolator_trans(trans_type& trans, double x, double y, unsigned) : m_trans(&trans) { @@ -80,7 +80,7 @@ namespace agg } private: - const trans_type* m_trans; + trans_type* m_trans; double m_x; double m_y; int m_ix; diff --git a/extern/agg24/include/agg_trans_affine.h b/extern/agg24/include/agg_trans_affine.h index cbed7c86d876..8933d7618a37 100644 --- a/extern/agg24/include/agg_trans_affine.h +++ b/extern/agg24/include/agg_trans_affine.h @@ -211,14 +211,14 @@ namespace agg // Multiply the matrix by another one and return // the result in a separete matrix. - trans_affine operator * (const trans_affine& m) + trans_affine operator * (const trans_affine& m) const { return trans_affine(*this).multiply(m); } // Multiply the matrix by inverse of another one // and return the result in a separete matrix. - trans_affine operator / (const trans_affine& m) + trans_affine operator / (const trans_affine& m) const { return trans_affine(*this).multiply_inv(m); } diff --git a/extern/agg24/include/agg_trans_perspective.h b/extern/agg24/include/agg_trans_perspective.h index 20a9aa66d0ce..7d4aa26c798f 100644 --- a/extern/agg24/include/agg_trans_perspective.h +++ b/extern/agg24/include/agg_trans_perspective.h @@ -148,22 +148,22 @@ namespace agg // Multiply the matrix by another one and return // the result in a separete matrix. - trans_perspective operator * (const trans_perspective& m) + trans_perspective operator * (const trans_perspective& m) const { return trans_perspective(*this).multiply(m); } - trans_perspective operator * (const trans_affine& m) + trans_perspective operator * (const trans_affine& m) const { return trans_perspective(*this).multiply(m); } // Multiply the matrix by inverse of another one // and return the result in a separete matrix. - trans_perspective operator / (const trans_perspective& m) + trans_perspective operator / (const trans_perspective& m) const { return trans_perspective(*this).multiply_inv(m); } - trans_perspective operator / (const trans_affine& m) + trans_perspective operator / (const trans_affine& m) const { return trans_perspective(*this).multiply_inv(m); } diff --git a/extern/agg24/include/platform/agg_platform_support.h b/extern/agg24/include/platform/agg_platform_support.h index 2b7a18c20552..bad524dab275 100644 --- a/extern/agg24/include/platform/agg_platform_support.h +++ b/extern/agg24/include/platform/agg_platform_support.h @@ -105,7 +105,9 @@ namespace agg pix_format_undefined = 0, // By default. No conversions are applied pix_format_bw, // 1 bit per color B/W pix_format_gray8, // Simple 256 level grayscale + pix_format_sgray8, // Simple 256 level grayscale (sRGB) pix_format_gray16, // Simple 65535 level grayscale + pix_format_gray32, // Grayscale, one 32-bit float per pixel pix_format_rgb555, // 15 bit rgb. Depends on the byte ordering! pix_format_rgb565, // 16 bit rgb. Depends on the byte ordering! pix_format_rgbAAA, // 30 bit rgb. Depends on the byte ordering! @@ -113,17 +115,29 @@ namespace agg pix_format_bgrAAA, // 30 bit bgr. Depends on the byte ordering! pix_format_bgrABB, // 32 bit bgr. Depends on the byte ordering! pix_format_rgb24, // R-G-B, one byte per color component - pix_format_bgr24, // B-G-R, native win32 BMP format. + pix_format_srgb24, // R-G-B, one byte per color component (sRGB) + pix_format_bgr24, // B-G-R, one byte per color component + pix_format_sbgr24, // B-G-R, native win32 BMP format (sRGB) pix_format_rgba32, // R-G-B-A, one byte per color component + pix_format_srgba32, // R-G-B-A, one byte per color component (sRGB) pix_format_argb32, // A-R-G-B, native MAC format + pix_format_sargb32, // A-R-G-B, native MAC format (sRGB) pix_format_abgr32, // A-B-G-R, one byte per color component + pix_format_sabgr32, // A-B-G-R, one byte per color component (sRGB) pix_format_bgra32, // B-G-R-A, native win32 BMP format + pix_format_sbgra32, // B-G-R-A, native win32 BMP format (sRGB) pix_format_rgb48, // R-G-B, 16 bits per color component pix_format_bgr48, // B-G-R, native win32 BMP format. + pix_format_rgb96, // R-G-B, one 32-bit float per color component + pix_format_bgr96, // B-G-R, one 32-bit float per color component pix_format_rgba64, // R-G-B-A, 16 bits byte per color component pix_format_argb64, // A-R-G-B, native MAC format pix_format_abgr64, // A-B-G-R, one byte per color component pix_format_bgra64, // B-G-R-A, native win32 BMP format + pix_format_rgba128, // R-G-B-A, one 32-bit float per color component + pix_format_argb128, // A-R-G-B, one 32-bit float per color component + pix_format_abgr128, // A-B-G-R, one 32-bit float per color component + pix_format_bgra128, // B-G-R-A, one 32-bit float per color component end_of_pix_formats }; @@ -592,6 +606,7 @@ namespace agg double(height) / double(m_initial_height)); } } + trans_affine& trans_affine_resizing() { return m_resize_mtx; } const trans_affine& trans_affine_resizing() const { return m_resize_mtx; } double width() const { return m_rbuf_window.width(); } double height() const { return m_rbuf_window.height(); } diff --git a/extern/agg24/include/util/agg_color_conv.h b/extern/agg24/include/util/agg_color_conv.h index 6e27690e1f71..8b8a0a55d2b0 100644 --- a/extern/agg24/include/util/agg_color_conv.h +++ b/extern/agg24/include/util/agg_color_conv.h @@ -77,6 +77,50 @@ namespace agg }; + // Generic pixel converter. + template + struct conv_pixel + { + void operator()(void* dst, const void* src) const + { + // Read a pixel from the source format and write it to the destination format. + DstFormat::write_plain_color(dst, SrcFormat::read_plain_color(src)); + } + }; + + // Generic row converter. Uses conv_pixel to convert individual pixels. + template + struct conv_row + { + void operator()(void* dst, const void* src, unsigned width) const + { + conv_pixel conv; + do + { + conv(dst, src); + dst = (int8u*)dst + DstFormat::pix_width; + src = (int8u*)src + SrcFormat::pix_width; + } + while (--width); + } + }; + + // Specialization for case where source and destination formats are identical. + template + struct conv_row + { + void operator()(void* dst, const void* src, unsigned width) const + { + memmove(dst, src, width * Format::pix_width); + } + }; + + // Top-level conversion function, converts one pixel format to any other. + template + void convert(RenBuf* dst, const RenBuf* src) + { + color_conv(dst, src, conv_row()); + } } diff --git a/extern/agg24/include/util/agg_color_conv_rgb8.h b/extern/agg24/include/util/agg_color_conv_rgb8.h index 4268b5a72ede..609460dba413 100644 --- a/extern/agg24/include/util/agg_color_conv_rgb8.h +++ b/extern/agg24/include/util/agg_color_conv_rgb8.h @@ -48,10 +48,13 @@ namespace agg { do { - *dst++ = src[2]; - *dst++ = src[1]; - *dst++ = src[0]; - src += 3; + int8u tmp[3]; + tmp[0] = *src++; + tmp[1] = *src++; + tmp[2] = *src++; + *dst++ = tmp[2]; + *dst++ = tmp[1]; + *dst++ = tmp[0]; } while(--width); } @@ -75,11 +78,15 @@ namespace agg { do { - *dst++ = src[I1]; - *dst++ = src[I2]; - *dst++ = src[I3]; - *dst++ = src[I4]; - src += 4; + int8u tmp[4]; + tmp[0] = *src++; + tmp[1] = *src++; + tmp[2] = *src++; + tmp[3] = *src++; + *dst++ = tmp[I1]; + *dst++ = tmp[I2]; + *dst++ = tmp[I3]; + *dst++ = tmp[I4]; } while(--width); } diff --git a/extern/agg24/src/agg_color_rgba.cpp b/extern/agg24/src/agg_color_rgba.cpp new file mode 100644 index 000000000000..9fe1534b033a --- /dev/null +++ b/extern/agg24/src/agg_color_rgba.cpp @@ -0,0 +1,17 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2009 John Horigan (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: john@glyphic.com.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- + +// rgbaN construction from grayN types is no longer required, +// as grayN types now define their own conversions to rgbaN. diff --git a/extern/agg24/src/agg_curves.cpp b/extern/agg24/src/agg_curves.cpp index bf5472a99804..470173471881 100644 --- a/extern/agg24/src/agg_curves.cpp +++ b/extern/agg24/src/agg_curves.cpp @@ -2,8 +2,8 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-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. +// 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. // @@ -29,20 +29,20 @@ namespace agg //------------------------------------------------------------------------ - void curve3_inc::approximation_scale(double s) - { + void curve3_inc::approximation_scale(double s) + { m_scale = s; } //------------------------------------------------------------------------ - double curve3_inc::approximation_scale() const - { + double curve3_inc::approximation_scale() const + { return m_scale; } //------------------------------------------------------------------------ - void curve3_inc::init(double x1, double y1, - double x2, double y2, + void curve3_inc::init(double x1, double y1, + double x2, double y2, double x3, double y3) { m_start_x = x1; @@ -55,13 +55,13 @@ namespace agg double dx2 = x3 - x2; double dy2 = y3 - y2; - double len = sqrt(dx1 * dx1 + dy1 * dy1) + sqrt(dx2 * dx2 + dy2 * dy2); + double len = sqrt(dx1 * dx1 + dy1 * dy1) + sqrt(dx2 * dx2 + dy2 * dy2); m_num_steps = uround(len * 0.25 * m_scale); if(m_num_steps < 4) { - m_num_steps = 4; + m_num_steps = 4; } double subdivide_step = 1.0 / m_num_steps; @@ -72,7 +72,7 @@ namespace agg m_saved_fx = m_fx = x1; m_saved_fy = m_fy = y1; - + m_saved_dfx = m_dfx = tmpx + (x2 - x1) * (2.0 * subdivide_step); m_saved_dfy = m_dfy = tmpy + (y2 - y1) * (2.0 * subdivide_step); @@ -115,10 +115,10 @@ namespace agg --m_step; return path_cmd_line_to; } - m_fx += m_dfx; + m_fx += m_dfx; m_fy += m_dfy; - m_dfx += m_ddfx; - m_dfy += m_ddfy; + m_dfx += m_ddfx; + m_dfy += m_ddfy; *x = m_fx; *y = m_fy; --m_step; @@ -126,8 +126,8 @@ namespace agg } //------------------------------------------------------------------------ - void curve3_div::init(double x1, double y1, - double x2, double y2, + void curve3_div::init(double x1, double y1, + double x2, double y2, double x3, double y3) { m_points.remove_all(); @@ -138,19 +138,19 @@ namespace agg } //------------------------------------------------------------------------ - void curve3_div::recursive_bezier(double x1, double y1, - double x2, double y2, + void curve3_div::recursive_bezier(double x1, double y1, + double x2, double y2, double x3, double y3, unsigned level) { - if(level > curve_recursion_limit) + if(level > curve_recursion_limit) { return; } // Calculate all the mid-points of the line segments //---------------------- - double x12 = (x1 + x2) / 2; + double x12 = (x1 + x2) / 2; double y12 = (y1 + y2) / 2; double x23 = (x2 + x3) / 2; double y23 = (y2 + y3) / 2; @@ -163,7 +163,7 @@ namespace agg double da; if(d > curve_collinearity_epsilon) - { + { // Regular case //----------------- if(d * d <= m_distance_tolerance_square * (dx*dx + dy*dy)) @@ -187,7 +187,7 @@ namespace agg // Finally we can stop the recursion //---------------------- m_points.add(point_d(x123, y123)); - return; + return; } } } @@ -222,13 +222,13 @@ namespace agg // Continue subdivision //---------------------- - recursive_bezier(x1, y1, x12, y12, x123, y123, level + 1); - recursive_bezier(x123, y123, x23, y23, x3, y3, level + 1); + recursive_bezier(x1, y1, x12, y12, x123, y123, level + 1); + recursive_bezier(x123, y123, x23, y23, x3, y3, level + 1); } //------------------------------------------------------------------------ - void curve3_div::bezier(double x1, double y1, - double x2, double y2, + void curve3_div::bezier(double x1, double y1, + double x2, double y2, double x3, double y3) { m_points.add(point_d(x1, y1)); @@ -241,25 +241,25 @@ namespace agg //------------------------------------------------------------------------ - void curve4_inc::approximation_scale(double s) - { + void curve4_inc::approximation_scale(double s) + { m_scale = s; } //------------------------------------------------------------------------ - double curve4_inc::approximation_scale() const - { + double curve4_inc::approximation_scale() const + { return m_scale; } - //------------------------------------------------------------------------ #if defined(_MSC_VER) && _MSC_VER <= 1200 + //------------------------------------------------------------------------ static double MSC60_fix_ICE(double v) { return v; } #endif //------------------------------------------------------------------------ - void curve4_inc::init(double x1, double y1, - double x2, double y2, + void curve4_inc::init(double x1, double y1, + double x2, double y2, double x3, double y3, double x4, double y4) { @@ -275,8 +275,8 @@ namespace agg double dx3 = x4 - x3; double dy3 = y4 - y3; - double len = (sqrt(dx1 * dx1 + dy1 * dy1) + - sqrt(dx2 * dx2 + dy2 * dy2) + + double len = (sqrt(dx1 * dx1 + dy1 * dy1) + + sqrt(dx2 * dx2 + dy2 * dy2) + sqrt(dx3 * dx3 + dy3 * dy3)) * 0.25 * m_scale; #if defined(_MSC_VER) && _MSC_VER <= 1200 @@ -287,7 +287,7 @@ namespace agg if(m_num_steps < 4) { - m_num_steps = 4; + m_num_steps = 4; } double subdivide_step = 1.0 / m_num_steps; @@ -298,7 +298,7 @@ namespace agg double pre2 = 3.0 * subdivide_step2; double pre4 = 6.0 * subdivide_step2; double pre5 = 6.0 * subdivide_step3; - + double tmp1x = x1 - x2 * 2.0 + x3; double tmp1y = y1 - y2 * 2.0 + y3; @@ -359,10 +359,10 @@ namespace agg m_fx += m_dfx; m_fy += m_dfy; - m_dfx += m_ddfx; - m_dfy += m_ddfy; - m_ddfx += m_dddfx; - m_ddfy += m_dddfy; + m_dfx += m_ddfx; + m_dfy += m_ddfy; + m_ddfx += m_dddfx; + m_ddfy += m_dddfy; *x = m_fx; *y = m_fy; @@ -374,8 +374,8 @@ namespace agg //------------------------------------------------------------------------ - void curve4_div::init(double x1, double y1, - double x2, double y2, + void curve4_div::init(double x1, double y1, + double x2, double y2, double x3, double y3, double x4, double y4) { @@ -387,13 +387,13 @@ namespace agg } //------------------------------------------------------------------------ - void curve4_div::recursive_bezier(double x1, double y1, - double x2, double y2, - double x3, double y3, + void curve4_div::recursive_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, double x4, double y4, unsigned level) { - if(level > curve_recursion_limit) + if(level > curve_recursion_limit) { return; } @@ -544,7 +544,7 @@ namespace agg } break; - case 3: + case 3: // Regular case //----------------- if((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy)) @@ -594,14 +594,14 @@ namespace agg // Continue subdivision //---------------------- - recursive_bezier(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1); - recursive_bezier(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1); + recursive_bezier(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1); + recursive_bezier(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1); } //------------------------------------------------------------------------ - void curve4_div::bezier(double x1, double y1, - double x2, double y2, - double x3, double y3, + void curve4_div::bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, double x4, double y4) { m_points.add(point_d(x1, y1)); diff --git a/extern/agg24/src/platform/X11/agg_platform_support.cpp b/extern/agg24/src/platform/X11/agg_platform_support.cpp index d35b6a40314e..46b874d73857 100644 --- a/extern/agg24/src/platform/X11/agg_platform_support.cpp +++ b/extern/agg24/src/platform/X11/agg_platform_support.cpp @@ -27,6 +27,9 @@ #include #include #include "agg_basics.h" +#include "agg_pixfmt_gray.h" +#include "agg_pixfmt_rgb.h" +#include "agg_pixfmt_rgba.h" #include "util/agg_color_conv_rgb8.h" #include "platform/agg_platform_support.h" @@ -170,9 +173,18 @@ namespace agg { default: break; case pix_format_gray8: + case pix_format_sgray8: m_bpp = 8; break; + case pix_format_gray16: + m_bpp = 16; + break; + + case pix_format_gray32: + m_bpp = 32; + break; + case pix_format_rgb565: case pix_format_rgb555: m_bpp = 16; @@ -180,6 +192,8 @@ namespace agg case pix_format_rgb24: case pix_format_bgr24: + case pix_format_srgb24: + case pix_format_sbgr24: m_bpp = 24; break; @@ -187,8 +201,36 @@ namespace agg case pix_format_abgr32: case pix_format_argb32: case pix_format_rgba32: + case pix_format_sbgra32: + case pix_format_sabgr32: + case pix_format_sargb32: + case pix_format_srgba32: m_bpp = 32; break; + + case pix_format_rgb48: + case pix_format_bgr48: + m_bpp = 48; + break; + + case pix_format_bgra64: + case pix_format_abgr64: + case pix_format_argb64: + case pix_format_rgba64: + m_bpp = 64; + break; + + case pix_format_rgb96: + case pix_format_bgr96: + m_bpp = 96; + break; + + case pix_format_bgra128: + case pix_format_abgr128: + case pix_format_argb128: + case pix_format_rgba128: + m_bpp = 128; + break; } m_sw_start = clock(); } @@ -278,14 +320,36 @@ namespace agg switch(m_format) { default: break; - case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgba32()); break; - case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgba32()); break; - case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgba32()); break; - case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgba32()); break; - case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgba32()); break; - case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgba32()); break; - case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgba32()); break; - case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgba32()); break; + case pix_format_sgray8: convert(&rbuf_tmp, src); break; + case pix_format_gray8: convert(&rbuf_tmp, src); break; + case pix_format_gray16: convert(&rbuf_tmp, src); break; + case pix_format_gray32: convert(&rbuf_tmp, src); break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgba32()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgba32()); break; + case pix_format_srgb24: convert(&rbuf_tmp, src); break; + case pix_format_sbgr24: convert(&rbuf_tmp, src); break; + case pix_format_rgb24: convert(&rbuf_tmp, src); break; + case pix_format_bgr24: convert(&rbuf_tmp, src); break; + case pix_format_srgba32: convert(&rbuf_tmp, src); break; + case pix_format_sargb32: convert(&rbuf_tmp, src); break; + case pix_format_sabgr32: convert(&rbuf_tmp, src); break; + case pix_format_sbgra32: convert(&rbuf_tmp, src); break; + case pix_format_rgba32: convert(&rbuf_tmp, src); break; + case pix_format_argb32: convert(&rbuf_tmp, src); break; + case pix_format_abgr32: convert(&rbuf_tmp, src); break; + case pix_format_bgra32: convert(&rbuf_tmp, src); break; + case pix_format_rgb48: convert(&rbuf_tmp, src); break; + case pix_format_bgr48: convert(&rbuf_tmp, src); break; + case pix_format_rgba64: convert(&rbuf_tmp, src); break; + case pix_format_argb64: convert(&rbuf_tmp, src); break; + case pix_format_abgr64: convert(&rbuf_tmp, src); break; + case pix_format_bgra64: convert(&rbuf_tmp, src); break; + case pix_format_rgb96: convert(&rbuf_tmp, src); break; + case pix_format_bgr96: convert(&rbuf_tmp, src); break; + case pix_format_rgba128: convert(&rbuf_tmp, src); break; + case pix_format_argb128: convert(&rbuf_tmp, src); break; + case pix_format_abgr128: convert(&rbuf_tmp, src); break; + case pix_format_bgra128: convert(&rbuf_tmp, src); break; } break; @@ -293,14 +357,36 @@ namespace agg switch(m_format) { default: break; + case pix_format_sgray8: convert(&rbuf_tmp, src); break; + case pix_format_gray8: convert(&rbuf_tmp, src); break; + case pix_format_gray16: convert(&rbuf_tmp, src); break; + case pix_format_gray32: convert(&rbuf_tmp, src); break; case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_abgr32()); break; case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_abgr32()); break; - case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_abgr32()); break; - case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_abgr32()); break; - case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_abgr32()); break; - case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_abgr32()); break; - case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_abgr32()); break; - case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_abgr32()); break; + case pix_format_srgb24: convert(&rbuf_tmp, src); break; + case pix_format_sbgr24: convert(&rbuf_tmp, src); break; + case pix_format_rgb24: convert(&rbuf_tmp, src); break; + case pix_format_bgr24: convert(&rbuf_tmp, src); break; + case pix_format_srgba32: convert(&rbuf_tmp, src); break; + case pix_format_sargb32: convert(&rbuf_tmp, src); break; + case pix_format_sabgr32: convert(&rbuf_tmp, src); break; + case pix_format_sbgra32: convert(&rbuf_tmp, src); break; + case pix_format_rgba32: convert(&rbuf_tmp, src); break; + case pix_format_argb32: convert(&rbuf_tmp, src); break; + case pix_format_abgr32: convert(&rbuf_tmp, src); break; + case pix_format_bgra32: convert(&rbuf_tmp, src); break; + case pix_format_rgb48: convert(&rbuf_tmp, src); break; + case pix_format_bgr48: convert(&rbuf_tmp, src); break; + case pix_format_rgba64: convert(&rbuf_tmp, src); break; + case pix_format_argb64: convert(&rbuf_tmp, src); break; + case pix_format_abgr64: convert(&rbuf_tmp, src); break; + case pix_format_bgra64: convert(&rbuf_tmp, src); break; + case pix_format_rgb96: convert(&rbuf_tmp, src); break; + case pix_format_bgr96: convert(&rbuf_tmp, src); break; + case pix_format_rgba128: convert(&rbuf_tmp, src); break; + case pix_format_argb128: convert(&rbuf_tmp, src); break; + case pix_format_abgr128: convert(&rbuf_tmp, src); break; + case pix_format_bgra128: convert(&rbuf_tmp, src); break; } break; @@ -308,14 +394,36 @@ namespace agg switch(m_format) { default: break; + case pix_format_sgray8: convert(&rbuf_tmp, src); break; + case pix_format_gray8: convert(&rbuf_tmp, src); break; + case pix_format_gray16: convert(&rbuf_tmp, src); break; + case pix_format_gray32: convert(&rbuf_tmp, src); break; case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_argb32()); break; case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_argb32()); break; - case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_argb32()); break; - case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_argb32()); break; - case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_argb32()); break; - case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_argb32()); break; - case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_argb32()); break; - case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_argb32()); break; + case pix_format_srgb24: convert(&rbuf_tmp, src); break; + case pix_format_sbgr24: convert(&rbuf_tmp, src); break; + case pix_format_rgb24: convert(&rbuf_tmp, src); break; + case pix_format_bgr24: convert(&rbuf_tmp, src); break; + case pix_format_srgba32: convert(&rbuf_tmp, src); break; + case pix_format_sargb32: convert(&rbuf_tmp, src); break; + case pix_format_sabgr32: convert(&rbuf_tmp, src); break; + case pix_format_sbgra32: convert(&rbuf_tmp, src); break; + case pix_format_rgba32: convert(&rbuf_tmp, src); break; + case pix_format_argb32: convert(&rbuf_tmp, src); break; + case pix_format_abgr32: convert(&rbuf_tmp, src); break; + case pix_format_bgra32: convert(&rbuf_tmp, src); break; + case pix_format_rgb48: convert(&rbuf_tmp, src); break; + case pix_format_bgr48: convert(&rbuf_tmp, src); break; + case pix_format_rgba64: convert(&rbuf_tmp, src); break; + case pix_format_argb64: convert(&rbuf_tmp, src); break; + case pix_format_abgr64: convert(&rbuf_tmp, src); break; + case pix_format_bgra64: convert(&rbuf_tmp, src); break; + case pix_format_rgb96: convert(&rbuf_tmp, src); break; + case pix_format_bgr96: convert(&rbuf_tmp, src); break; + case pix_format_rgba128: convert(&rbuf_tmp, src); break; + case pix_format_argb128: convert(&rbuf_tmp, src); break; + case pix_format_abgr128: convert(&rbuf_tmp, src); break; + case pix_format_bgra128: convert(&rbuf_tmp, src); break; } break; @@ -323,14 +431,36 @@ namespace agg switch(m_format) { default: break; - case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_bgra32()); break; - case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_bgra32()); break; - case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_bgra32()); break; - case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_bgra32()); break; - case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_bgra32()); break; - case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_bgra32()); break; - case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_bgra32()); break; - case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_bgra32()); break; + case pix_format_sgray8: convert(&rbuf_tmp, src); break; + case pix_format_gray8: convert(&rbuf_tmp, src); break; + case pix_format_gray16: convert(&rbuf_tmp, src); break; + case pix_format_gray32: convert(&rbuf_tmp, src); break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_bgra32()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_bgra32()); break; + case pix_format_srgb24: convert(&rbuf_tmp, src); break; + case pix_format_sbgr24: convert(&rbuf_tmp, src); break; + case pix_format_rgb24: convert(&rbuf_tmp, src); break; + case pix_format_bgr24: convert(&rbuf_tmp, src); break; + case pix_format_srgba32: convert(&rbuf_tmp, src); break; + case pix_format_sargb32: convert(&rbuf_tmp, src); break; + case pix_format_sabgr32: convert(&rbuf_tmp, src); break; + case pix_format_sbgra32: convert(&rbuf_tmp, src); break; + case pix_format_rgba32: convert(&rbuf_tmp, src); break; + case pix_format_argb32: convert(&rbuf_tmp, src); break; + case pix_format_abgr32: convert(&rbuf_tmp, src); break; + case pix_format_bgra32: convert(&rbuf_tmp, src); break; + case pix_format_rgb48: convert(&rbuf_tmp, src); break; + case pix_format_bgr48: convert(&rbuf_tmp, src); break; + case pix_format_rgba64: convert(&rbuf_tmp, src); break; + case pix_format_argb64: convert(&rbuf_tmp, src); break; + case pix_format_abgr64: convert(&rbuf_tmp, src); break; + case pix_format_bgra64: convert(&rbuf_tmp, src); break; + case pix_format_rgb96: convert(&rbuf_tmp, src); break; + case pix_format_bgr96: convert(&rbuf_tmp, src); break; + case pix_format_rgba128: convert(&rbuf_tmp, src); break; + case pix_format_argb128: convert(&rbuf_tmp, src); break; + case pix_format_abgr128: convert(&rbuf_tmp, src); break; + case pix_format_bgra128: convert(&rbuf_tmp, src); break; } break; } @@ -1098,6 +1228,22 @@ namespace agg switch(m_format) { + case pix_format_sgray8: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_gray8: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_gray16: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_gray32: + convert(m_rbuf_img+idx, &rbuf_img); + break; + case pix_format_rgb555: color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb555()); break; @@ -1106,24 +1252,96 @@ namespace agg color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb565()); break; + case pix_format_sbgr24: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgb24: + convert(m_rbuf_img+idx, &rbuf_img); + break; + case pix_format_bgr24: - color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_bgr24()); + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_srgba32: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_sargb32: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_sbgra32: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_sabgr32: + convert(m_rbuf_img+idx, &rbuf_img); break; case pix_format_rgba32: - color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgba32()); + convert(m_rbuf_img+idx, &rbuf_img); break; case pix_format_argb32: - color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_argb32()); + convert(m_rbuf_img+idx, &rbuf_img); break; case pix_format_bgra32: - color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_bgra32()); + convert(m_rbuf_img+idx, &rbuf_img); break; case pix_format_abgr32: - color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_abgr32()); + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgb48: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgr48: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgba64: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_argb64: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgra64: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_abgr64: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgb96: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgr96: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgba128: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_argb128: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgra128: + convert(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_abgr128: + convert(m_rbuf_img+idx, &rbuf_img); break; default: @@ -1169,6 +1387,22 @@ namespace agg const unsigned char* src = rbuf_img(idx).row_ptr(m_flip_y ? h - 1 - y : y); switch(m_format) { + case pix_format_sgray8: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_gray8: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_gray16: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_gray32: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + default: break; case pix_format_rgb555: color_conv_row(tmp_buf, src, w, color_conv_rgb555_to_rgb24()); @@ -1178,28 +1412,100 @@ namespace agg color_conv_row(tmp_buf, src, w, color_conv_rgb565_to_rgb24()); break; + case pix_format_sbgr24: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_srgb24: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + case pix_format_bgr24: - color_conv_row(tmp_buf, src, w, color_conv_bgr24_to_rgb24()); + color_conv_row(tmp_buf, src, w, conv_row()); break; case pix_format_rgb24: - color_conv_row(tmp_buf, src, w, color_conv_rgb24_to_rgb24()); + color_conv_row(tmp_buf, src, w, conv_row()); break; + case pix_format_srgba32: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_sargb32: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_sbgra32: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_sabgr32: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + case pix_format_rgba32: - color_conv_row(tmp_buf, src, w, color_conv_rgba32_to_rgb24()); + color_conv_row(tmp_buf, src, w, conv_row()); break; case pix_format_argb32: - color_conv_row(tmp_buf, src, w, color_conv_argb32_to_rgb24()); + color_conv_row(tmp_buf, src, w, conv_row()); break; case pix_format_bgra32: - color_conv_row(tmp_buf, src, w, color_conv_bgra32_to_rgb24()); + color_conv_row(tmp_buf, src, w, conv_row()); break; case pix_format_abgr32: - color_conv_row(tmp_buf, src, w, color_conv_abgr32_to_rgb24()); + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_bgr48: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_rgb48: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_rgba64: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_argb64: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_bgra64: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_abgr64: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_bgr96: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_rgb96: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_rgba128: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_argb128: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_bgra128: + color_conv_row(tmp_buf, src, w, conv_row()); + break; + + case pix_format_abgr128: + color_conv_row(tmp_buf, src, w, conv_row()); break; } fwrite(tmp_buf, 1, w * 3, fd); diff --git a/extern/agg24/src/platform/win32/agg_platform_support.cpp b/extern/agg24/src/platform/win32/agg_platform_support.cpp index c80f0a88e7b1..d9eba30fd8b7 100644 --- a/extern/agg24/src/platform/win32/agg_platform_support.cpp +++ b/extern/agg24/src/platform/win32/agg_platform_support.cpp @@ -21,8 +21,12 @@ #include #include "platform/agg_platform_support.h" #include "platform/win32/agg_win32_bmp.h" +#include "util/agg_color_conv.h" #include "util/agg_color_conv_rgb8.h" #include "util/agg_color_conv_rgb16.h" +#include "agg_pixfmt_gray.h" +#include "agg_pixfmt_rgb.h" +#include "agg_pixfmt_rgba.h" namespace agg @@ -148,17 +152,24 @@ namespace agg break; case pix_format_gray8: - m_sys_format = pix_format_gray8; + case pix_format_sgray8: + m_sys_format = pix_format_sgray8; m_bpp = 8; m_sys_bpp = 8; break; case pix_format_gray16: - m_sys_format = pix_format_gray8; + m_sys_format = pix_format_sgray8; m_bpp = 16; m_sys_bpp = 8; break; + case pix_format_gray32: + m_sys_format = pix_format_sgray8; + m_bpp = 32; + m_sys_bpp = 8; + break; + case pix_format_rgb565: case pix_format_rgb555: m_sys_format = pix_format_rgb555; @@ -177,35 +188,58 @@ namespace agg case pix_format_rgb24: case pix_format_bgr24: - m_sys_format = pix_format_bgr24; + case pix_format_srgb24: + case pix_format_sbgr24: + m_sys_format = pix_format_sbgr24; m_bpp = 24; m_sys_bpp = 24; break; case pix_format_rgb48: case pix_format_bgr48: - m_sys_format = pix_format_bgr24; + m_sys_format = pix_format_sbgr24; m_bpp = 48; m_sys_bpp = 24; break; + case pix_format_rgb96: + case pix_format_bgr96: + m_sys_format = pix_format_sbgr24; + m_bpp = 96; + m_sys_bpp = 24; + break; + case pix_format_bgra32: case pix_format_abgr32: case pix_format_argb32: case pix_format_rgba32: - m_sys_format = pix_format_bgra32; + case pix_format_sbgra32: + case pix_format_sabgr32: + case pix_format_sargb32: + case pix_format_srgba32: + m_sys_format = pix_format_sbgr24; m_bpp = 32; - m_sys_bpp = 32; + m_sys_bpp = 24; break; case pix_format_bgra64: case pix_format_abgr64: case pix_format_argb64: case pix_format_rgba64: - m_sys_format = pix_format_bgra32; + m_sys_format = pix_format_sbgr24; m_bpp = 64; - m_sys_bpp = 32; + m_sys_bpp = 24; + break; + + case pix_format_bgra128: + case pix_format_abgr128: + case pix_format_argb128: + case pix_format_rgba128: + m_sys_format = pix_format_sbgr24; + m_bpp = 128; + m_sys_bpp = 24; break; + } ::QueryPerformanceFrequency(&m_sw_freq); ::QueryPerformanceCounter(&m_sw_start); @@ -235,10 +269,15 @@ namespace agg switch(format) { case pix_format_gray8: + convert(dst, src); break; case pix_format_gray16: - color_conv(dst, src, color_conv_gray16_to_gray8()); + convert(dst, src); + break; + + case pix_format_gray32: + convert(dst, src); break; case pix_format_rgb565: @@ -261,44 +300,96 @@ namespace agg color_conv(dst, src, color_conv_bgrABB_to_bgr24()); break; - case pix_format_rgb24: + case pix_format_srgb24: color_conv(dst, src, color_conv_rgb24_to_bgr24()); break; + case pix_format_rgb24: + convert(dst, src); + break; + + case pix_format_bgr24: + convert(dst, src); + break; + case pix_format_rgb48: - color_conv(dst, src, color_conv_rgb48_to_bgr24()); + convert(dst, src); break; case pix_format_bgr48: - color_conv(dst, src, color_conv_bgr48_to_bgr24()); + convert(dst, src); + break; + + case pix_format_bgra32: + convert(dst, src); break; case pix_format_abgr32: - color_conv(dst, src, color_conv_abgr32_to_bgra32()); + convert(dst, src); break; case pix_format_argb32: - color_conv(dst, src, color_conv_argb32_to_bgra32()); + convert(dst, src); break; case pix_format_rgba32: - color_conv(dst, src, color_conv_rgba32_to_bgra32()); + convert(dst, src); + break; + + case pix_format_sbgra32: + convert(dst, src); + break; + + case pix_format_sabgr32: + convert(dst, src); + break; + + case pix_format_sargb32: + convert(dst, src); + break; + + case pix_format_srgba32: + convert(dst, src); break; case pix_format_bgra64: - color_conv(dst, src, color_conv_bgra64_to_bgra32()); + convert(dst, src); break; case pix_format_abgr64: - color_conv(dst, src, color_conv_abgr64_to_bgra32()); + convert(dst, src); break; case pix_format_argb64: - color_conv(dst, src, color_conv_argb64_to_bgra32()); + convert(dst, src); break; case pix_format_rgba64: - color_conv(dst, src, color_conv_rgba64_to_bgra32()); + convert(dst, src); + break; + + case pix_format_rgb96: + convert(dst, src); + break; + + case pix_format_bgr96: + convert(dst, src); + break; + + case pix_format_bgra128: + convert(dst, src); + break; + + case pix_format_abgr128: + convert(dst, src); + break; + + case pix_format_argb128: + convert(dst, src); + break; + + case pix_format_rgba128: + convert(dst, src); break; } } @@ -390,7 +481,7 @@ namespace agg switch(m_format) { - case pix_format_gray8: + case pix_format_sgray8: switch(pmap_tmp.bpp()) { //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray8()); break; @@ -399,15 +490,31 @@ namespace agg } break; + case pix_format_gray8: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; + } + break; + case pix_format_gray16: switch(pmap_tmp.bpp()) { //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray16()); break; - case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_gray16()); break; + case 24: convert(dst, &rbuf_tmp); break; //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray16()); break; } break; + case pix_format_gray32: + switch(pmap_tmp.bpp()) + { + //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray32()); break; + case 24: convert(dst, &rbuf_tmp); break; + //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray32()); break; + } + break; + case pix_format_rgb555: switch(pmap_tmp.bpp()) { @@ -426,7 +533,7 @@ namespace agg } break; - case pix_format_rgb24: + case pix_format_srgb24: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb24()); break; @@ -435,7 +542,7 @@ namespace agg } break; - case pix_format_bgr24: + case pix_format_sbgr24: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr24()); break; @@ -444,11 +551,25 @@ namespace agg } break; + case pix_format_rgb24: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgr24: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; + } + break; + case pix_format_rgb48: switch(pmap_tmp.bpp()) { //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb48()); break; - case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb48()); break; + case 24: convert(dst, &rbuf_tmp); break; //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb48()); break; } break; @@ -457,12 +578,12 @@ namespace agg switch(pmap_tmp.bpp()) { //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr48()); break; - case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_bgr48()); break; + case 24: convert(dst, &rbuf_tmp); break; //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr48()); break; } break; - case pix_format_abgr32: + case pix_format_sabgr32: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_abgr32()); break; @@ -471,7 +592,7 @@ namespace agg } break; - case pix_format_argb32: + case pix_format_sargb32: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_argb32()); break; @@ -480,7 +601,7 @@ namespace agg } break; - case pix_format_bgra32: + case pix_format_sbgra32: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgra32()); break; @@ -489,7 +610,7 @@ namespace agg } break; - case pix_format_rgba32: + case pix_format_srgba32: switch(pmap_tmp.bpp()) { case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgba32()); break; @@ -498,42 +619,103 @@ namespace agg } break; + case pix_format_abgr32: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; + } + break; + + case pix_format_argb32: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgra32: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; + } + break; + + case pix_format_rgba32: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; + } + break; + case pix_format_abgr64: switch(pmap_tmp.bpp()) { - //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_abgr64()); break; - case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_abgr64()); break; - //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_abgr64()); break; + case 24: convert(dst, &rbuf_tmp); break; } break; case pix_format_argb64: switch(pmap_tmp.bpp()) { - //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_argb64()); break; - case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_argb64()); break; - //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_argb64()); break; + case 24: convert(dst, &rbuf_tmp); break; } break; case pix_format_bgra64: switch(pmap_tmp.bpp()) { - //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgra64()); break; - case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_bgra64()); break; - //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgra64()); break; + case 24: convert(dst, &rbuf_tmp); break; } break; case pix_format_rgba64: switch(pmap_tmp.bpp()) { - //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgba64()); break; - case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgba64()); break; - //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgba64()); break; + case 24: convert(dst, &rbuf_tmp); break; + } + break; + + case pix_format_rgb96: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgr96: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; + } + break; + + case pix_format_abgr128: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; + } + break; + + case pix_format_argb128: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgra128: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; } break; + case pix_format_rgba128: + switch(pmap_tmp.bpp()) + { + case 24: convert(dst, &rbuf_tmp); break; + } + break; } return true; @@ -630,7 +812,7 @@ namespace agg HDC paintDC; - void* user_data = reinterpret_cast(::GetWindowLong(hWnd, GWL_USERDATA)); + void* user_data = reinterpret_cast(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); platform_support* app = 0; if(user_data) @@ -1053,7 +1235,7 @@ namespace agg height + (height - (rct.bottom - rct.top)), FALSE); - ::SetWindowLong(m_specific->m_hwnd, GWL_USERDATA, (LONG)this); + ::SetWindowLongPtr(m_specific->m_hwnd, GWLP_USERDATA, (LONG)this); m_specific->create_pmap(width, height, &m_rbuf_window); m_initial_width = width; m_initial_height = height; @@ -1120,7 +1302,7 @@ namespace agg char fn[1024]; strcpy(fn, file); int len = strlen(fn); - if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0) + if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0) { strcat(fn, ".bmp"); } @@ -1139,7 +1321,7 @@ namespace agg char fn[1024]; strcpy(fn, file); int len = strlen(fn); - if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0) + if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0) { strcat(fn, ".bmp"); } diff --git a/extern/agg24/src/platform/win32/agg_win32_bmp.cpp b/extern/agg24/src/platform/win32/agg_win32_bmp.cpp index 9a03d43c02c6..8c3bdc83fd70 100644 --- a/extern/agg24/src/platform/win32/agg_win32_bmp.cpp +++ b/extern/agg24/src/platform/win32/agg_win32_bmp.cpp @@ -251,6 +251,12 @@ namespace agg case 64: n *= 8; break; + case 96: n *= 12; + break; + + case 128: n *= 16; + break; + default: n = 0; break; } diff --git a/src/_backend_agg.h b/src/_backend_agg.h index 96e90022c4ba..2d2041b36be4 100644 --- a/src/_backend_agg.h +++ b/src/_backend_agg.h @@ -749,7 +749,7 @@ inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, in filter.calculate(agg::image_filter_spline36()); interpolator_type interpolator(inv_mtx); color_span_alloc_type sa; - image_accessor_type ia(pixf_img, 0); + image_accessor_type ia(pixf_img, agg::gray8(0)); image_span_gen_type image_span_generator(ia, interpolator, filter); span_gen_type output_span_generator(&image_span_generator, gc.color); renderer_type ri(rendererBase, sa, output_span_generator); diff --git a/src/_path.h b/src/_path.h index c653a2614f37..4e7ab8549c9d 100644 --- a/src/_path.h +++ b/src/_path.h @@ -190,7 +190,7 @@ template inline void points_in_path(PointArray &points, const double r, PathIterator &path, - const agg::trans_affine &trans, + agg::trans_affine &trans, ResultArray &result) { typedef agg::conv_transform transformed_path_t; @@ -218,7 +218,7 @@ inline void points_in_path(PointArray &points, template inline bool point_in_path( - double x, double y, const double r, PathIterator &path, const agg::trans_affine &trans) + double x, double y, const double r, PathIterator &path, agg::trans_affine &trans) { std::vector point; std::vector > points; @@ -238,7 +238,7 @@ template void points_on_path(PointArray &points, const double r, PathIterator &path, - const agg::trans_affine &trans, + agg::trans_affine &trans, ResultArray result) { typedef agg::conv_transform transformed_path_t; @@ -261,7 +261,7 @@ void points_on_path(PointArray &points, template inline bool point_on_path( - double x, double y, const double r, PathIterator &path, const agg::trans_affine &trans) + double x, double y, const double r, PathIterator &path, agg::trans_affine &trans) { std::vector point; std::vector > points; @@ -318,7 +318,7 @@ inline void update_limits(double x, double y, extent_limits &e) } template -void update_path_extents(PathIterator &path, const agg::trans_affine &trans, extent_limits &extents) +void update_path_extents(PathIterator &path, agg::trans_affine &trans, extent_limits &extents) { typedef agg::conv_transform transformed_path_t; typedef PathNanRemover nan_removed_t; @@ -451,9 +451,9 @@ void point_in_path_collection(double x, template bool path_in_path(PathIterator1 &a, - const agg::trans_affine &atrans, + agg::trans_affine &atrans, PathIterator2 &b, - const agg::trans_affine &btrans) + agg::trans_affine &btrans) { typedef agg::conv_transform transformed_path_t; typedef PathNanRemover no_nans_t; @@ -863,7 +863,7 @@ __cleanup_path(VertexSource &source, std::vector &vertices, std::vector< template void cleanup_path(PathIterator &path, - const agg::trans_affine &trans, + agg::trans_affine &trans, bool remove_nans, bool do_clip, const agg::rect_base &rect, diff --git a/src/_path_wrapper.cpp b/src/_path_wrapper.cpp index 06d10b27b535..5c508b4e335f 100644 --- a/src/_path_wrapper.cpp +++ b/src/_path_wrapper.cpp @@ -468,6 +468,8 @@ static PyObject *Py_path_intersects_path(PyObject *self, PyObject *args, PyObjec { py::PathIterator p1; py::PathIterator p2; + agg::trans_affine t1; + agg::trans_affine t2; int filled = 0; const char *names[] = { "p1", "p2", "filled", NULL }; bool result; @@ -488,11 +490,11 @@ static PyObject *Py_path_intersects_path(PyObject *self, PyObject *args, PyObjec if (filled) { if (!result) { CALL_CPP("path_intersects_path", - (result = path_in_path(p1, agg::trans_affine(), p2, agg::trans_affine()))); + (result = path_in_path(p1, t1, p2, t2))); } if (!result) { CALL_CPP("path_intersects_path", - (result = path_in_path(p2, agg::trans_affine(), p1, agg::trans_affine()))); + (result = path_in_path(p2, t1, p1, t2))); } } From 7766ebe3791148edd80d7d4557c937203cee87b1 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 10 Nov 2014 15:06:17 -0500 Subject: [PATCH 2/9] Workaround for blending bug in new Agg. --- src/_backend_agg.h | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/_backend_agg.h b/src/_backend_agg.h index 2d2041b36be4..66fc6bf7cb77 100644 --- a/src/_backend_agg.h +++ b/src/_backend_agg.h @@ -38,7 +38,49 @@ #include "path_converters.h" #include "array.h" -typedef agg::pixfmt_rgba32_plain pixfmt; +/********************************************************************** + WORKAROUND: This class is to workaround a bug in Agg SVN where the + blending of RGBA32 pixels does not preserve enough precision +*/ + +template +struct fixed_blender_rgba_plain : agg::conv_rgba_plain +{ + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e { base_shift = color_type::base_shift }; + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, agg::cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + if(alpha == 0) return; + calc_type a = p[Order::A]; + calc_type r = p[Order::R] * a; + calc_type g = p[Order::G] * a; + calc_type b = p[Order::B] * a; + a = ((alpha + a) << base_shift) - alpha * a; + p[Order::A] = (value_type)(a >> base_shift); + p[Order::R] = (value_type)((((cr << base_shift) - r) * alpha + (r << base_shift)) / a); + p[Order::G] = (value_type)((((cg << base_shift) - g) * alpha + (g << base_shift)) / a); + p[Order::B] = (value_type)((((cb << base_shift) - b) * alpha + (b << base_shift)) / a); + } +}; + +/**********************************************************************/ + +typedef fixed_blender_rgba_plain fixed_blender_rgba32_plain; +typedef agg::pixfmt_alpha_blend_rgba pixfmt; typedef agg::renderer_base renderer_base; typedef agg::renderer_scanline_aa_solid renderer_aa; typedef agg::renderer_scanline_bin_solid renderer_bin; @@ -831,7 +873,7 @@ inline void RendererAgg::draw_image(GCAgg &gc, inv_mtx.invert(); typedef agg::span_allocator color_span_alloc_type; - typedef agg::image_accessor_clip image_accessor_type; + typedef agg::image_accessor_clip image_accessor_type; typedef agg::span_interpolator_linear<> interpolator_type; typedef agg::span_image_filter_rgba_nn image_span_gen_type; From 1b937a4fea5a65d0f3904da848d6aa4044fb2abf Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 15 Oct 2014 11:30:02 -0400 Subject: [PATCH 3/9] Make cell_block_limit non-hard-coded --- .../agg24/include/agg_rasterizer_cells_aa.h | 92 ++++++++++--------- .../include/agg_rasterizer_compound_aa.h | 4 +- .../include/agg_rasterizer_scanline_aa.h | 10 +- .../agg_rasterizer_scanline_aa_nogamma.h | 4 +- src/_backend_agg.cpp | 2 +- 5 files changed, 58 insertions(+), 54 deletions(-) diff --git a/extern/agg24/include/agg_rasterizer_cells_aa.h b/extern/agg24/include/agg_rasterizer_cells_aa.h index 1d797bf90114..3809bdb70510 100755 --- a/extern/agg24/include/agg_rasterizer_cells_aa.h +++ b/extern/agg24/include/agg_rasterizer_cells_aa.h @@ -2,15 +2,15 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-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. +// 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. // //---------------------------------------------------------------------------- // -// The author gratefully acknowleges the support of David Turner, -// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType +// The author gratefully acknowleges the support of David Turner, +// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType // libray - in producing this work. See http://www.freetype.org for details. // //---------------------------------------------------------------------------- @@ -19,16 +19,17 @@ // http://www.antigrain.com //---------------------------------------------------------------------------- // -// Adaptation for 32-bit screen coordinates has been sponsored by +// Adaptation for 32-bit screen coordinates has been sponsored by // Liberty Technology Systems, Inc., visit http://lib-sys.com // // Liberty Technology Systems, Inc. is the provider of // PostScript and PDF technology for software developers. -// +// //---------------------------------------------------------------------------- #ifndef AGG_RASTERIZER_CELLS_AA_INCLUDED #define AGG_RASTERIZER_CELLS_AA_INCLUDED +#include #include #include #include "agg_math.h" @@ -48,8 +49,7 @@ namespace agg cell_block_shift = 12, cell_block_size = 1 << cell_block_shift, cell_block_mask = cell_block_size - 1, - cell_block_pool = 256, - cell_block_limit = 1024 + cell_block_pool = 256 }; struct sorted_y @@ -63,7 +63,7 @@ namespace agg typedef rasterizer_cells_aa self_type; ~rasterizer_cells_aa(); - rasterizer_cells_aa(); + rasterizer_cells_aa(unsigned cell_block_limit=1024); void reset(); void style(const cell_type& style_cell); @@ -76,19 +76,19 @@ namespace agg void sort_cells(); - unsigned total_cells() const + unsigned total_cells() const { return m_num_cells; } - unsigned scanline_num_cells(unsigned y) const - { - return m_sorted_y[y - m_min_y].num; + unsigned scanline_num_cells(unsigned y) const + { + return m_sorted_y[y - m_min_y].num; } const cell_type* const* scanline_cells(unsigned y) const - { - return m_sorted_cells.data() + m_sorted_y[y - m_min_y].start; + { + return m_sorted_cells.data() + m_sorted_y[y - m_min_y].start; } bool sorted() const { return m_sorted; } @@ -101,12 +101,13 @@ namespace agg void add_curr_cell(); void render_hline(int ey, int x1, int y1, int x2, int y2); void allocate_block(); - + private: unsigned m_num_blocks; unsigned m_max_blocks; unsigned m_curr_block; unsigned m_num_cells; + unsigned m_cell_block_limit; cell_type** m_cells; cell_type* m_curr_cell_ptr; pod_vector m_sorted_cells; @@ -124,7 +125,7 @@ namespace agg //------------------------------------------------------------------------ - template + template rasterizer_cells_aa::~rasterizer_cells_aa() { if(m_num_blocks) @@ -140,12 +141,13 @@ namespace agg } //------------------------------------------------------------------------ - template - rasterizer_cells_aa::rasterizer_cells_aa() : + template + rasterizer_cells_aa::rasterizer_cells_aa(unsigned cell_block_limit) : m_num_blocks(0), m_max_blocks(0), m_curr_block(0), m_num_cells(0), + m_cell_block_limit(cell_block_limit), m_cells(0), m_curr_cell_ptr(0), m_sorted_cells(), @@ -161,10 +163,10 @@ namespace agg } //------------------------------------------------------------------------ - template + template void rasterizer_cells_aa::reset() { - m_num_cells = 0; + m_num_cells = 0; m_curr_block = 0; m_curr_cell.initial(); m_style_cell.initial(); @@ -176,14 +178,16 @@ namespace agg } //------------------------------------------------------------------------ - template + template AGG_INLINE void rasterizer_cells_aa::add_curr_cell() { if(m_curr_cell.area | m_curr_cell.cover) { if((m_num_cells & cell_block_mask) == 0) { - if(m_num_blocks >= cell_block_limit) return; + if(m_num_blocks >= m_cell_block_limit) { + throw std::overflow_error("Exceeded cell block limit"); + } allocate_block(); } *m_curr_cell_ptr++ = m_curr_cell; @@ -192,7 +196,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template AGG_INLINE void rasterizer_cells_aa::set_curr_cell(int x, int y) { if(m_curr_cell.not_equal(x, y, m_style_cell)) @@ -207,9 +211,9 @@ namespace agg } //------------------------------------------------------------------------ - template - AGG_INLINE void rasterizer_cells_aa::render_hline(int ey, - int x1, int y1, + template + AGG_INLINE void rasterizer_cells_aa::render_hline(int ey, + int x1, int y1, int x2, int y2) { int ex1 = x1 >> poly_subpixel_shift; @@ -305,14 +309,14 @@ namespace agg } //------------------------------------------------------------------------ - template + template AGG_INLINE void rasterizer_cells_aa::style(const cell_type& style_cell) - { - m_style_cell.style(style_cell); + { + m_style_cell.style(style_cell); } //------------------------------------------------------------------------ - template + template void rasterizer_cells_aa::line(int x1, int y1, int x2, int y2) { enum dx_limit_e { dx_limit = 16384 << poly_subpixel_shift }; @@ -358,7 +362,7 @@ namespace agg //Vertical line - we have to calculate start and end cells, //and then - the common values of the area and coverage for - //all cells of the line. We know exactly there's only one + //all cells of the line. We know exactly there's only one //cell, so, we don't have to call render_hline(). incr = 1; if(dx == 0) @@ -463,15 +467,15 @@ namespace agg } //------------------------------------------------------------------------ - template + template void rasterizer_cells_aa::allocate_block() { if(m_curr_block >= m_num_blocks) { if(m_num_blocks >= m_max_blocks) { - cell_type** new_cells = - pod_allocator::allocate(m_max_blocks + + cell_type** new_cells = + pod_allocator::allocate(m_max_blocks + cell_block_pool); if(m_cells) @@ -483,7 +487,7 @@ namespace agg m_max_blocks += cell_block_pool; } - m_cells[m_num_blocks++] = + m_cells[m_num_blocks++] = pod_allocator::allocate(cell_block_size); } @@ -513,7 +517,7 @@ namespace agg void qsort_cells(Cell** start, unsigned num) { Cell** stack[80]; - Cell*** top; + Cell*** top; Cell** limit; Cell** base; @@ -538,7 +542,7 @@ namespace agg i = base + 1; j = limit - 1; - // now ensure that *i <= *base <= *j + // now ensure that *i <= *base <= *j if((*j)->x < (*i)->x) { swap_cells(i, j); @@ -619,7 +623,7 @@ namespace agg //------------------------------------------------------------------------ - template + template void rasterizer_cells_aa::sort_cells() { if(m_sorted) return; //Perform sort only the first time. @@ -636,9 +640,9 @@ namespace agg //for(unsigned nc = 0; nc < m_num_cells; nc++) //{ // cell_type* cell = m_cells[nc >> cell_block_shift] + (nc & cell_block_mask); -// if(cell->x < m_min_x || -// cell->y < m_min_y || -// cell->x > m_max_x || +// if(cell->x < m_min_x || +// cell->y < m_min_y || +// cell->x > m_max_x || // cell->y > m_max_y) // { // cell = cell; // Breakpoint here @@ -661,7 +665,7 @@ namespace agg cell_ptr = *block_ptr++; i = (nb > cell_block_size) ? cell_block_size : nb; nb -= i; - while(i--) + while(i--) { m_sorted_y[cell_ptr->y - m_min_y].start++; ++cell_ptr; @@ -693,7 +697,7 @@ namespace agg ++cell_ptr; } } - + // Finally arrange the X-arrays for(i = 0; i < m_sorted_y.size(); i++) { diff --git a/extern/agg24/include/agg_rasterizer_compound_aa.h b/extern/agg24/include/agg_rasterizer_compound_aa.h index 165806dae4e2..41d508010e88 100755 --- a/extern/agg24/include/agg_rasterizer_compound_aa.h +++ b/extern/agg24/include/agg_rasterizer_compound_aa.h @@ -109,8 +109,8 @@ namespace agg }; //-------------------------------------------------------------------- - rasterizer_compound_aa() : - m_outline(), + rasterizer_compound_aa(unsigned cell_block_limit=1024) : + m_outline(cell_block_limit), m_clipper(), m_filling_rule(fill_non_zero), m_layer_order(layer_direct), diff --git a/extern/agg24/include/agg_rasterizer_scanline_aa.h b/extern/agg24/include/agg_rasterizer_scanline_aa.h index ffc2ddf941dc..15832166462a 100644 --- a/extern/agg24/include/agg_rasterizer_scanline_aa.h +++ b/extern/agg24/include/agg_rasterizer_scanline_aa.h @@ -93,8 +93,8 @@ namespace agg }; //-------------------------------------------------------------------- - rasterizer_scanline_aa() : - m_outline(), + rasterizer_scanline_aa(unsigned cell_block_limit=1024) : + m_outline(cell_block_limit), m_clipper(), m_filling_rule(fill_non_zero), m_auto_close(true), @@ -107,9 +107,9 @@ namespace agg } //-------------------------------------------------------------------- - template - rasterizer_scanline_aa(const GammaF& gamma_function) : - m_outline(), + template + rasterizer_scanline_aa(const GammaF& gamma_function, unsigned cell_block_limit) : + m_outline(cell_block_limit), m_clipper(m_outline), m_filling_rule(fill_non_zero), m_auto_close(true), diff --git a/extern/agg24/include/agg_rasterizer_scanline_aa_nogamma.h b/extern/agg24/include/agg_rasterizer_scanline_aa_nogamma.h index 354416cc267c..6c3d96fc6160 100644 --- a/extern/agg24/include/agg_rasterizer_scanline_aa_nogamma.h +++ b/extern/agg24/include/agg_rasterizer_scanline_aa_nogamma.h @@ -121,8 +121,8 @@ namespace agg }; //-------------------------------------------------------------------- - rasterizer_scanline_aa_nogamma() : - m_outline(), + rasterizer_scanline_aa_nogamma(unsigned cell_block_limit=1024) : + m_outline(cell_block_limit), m_clipper(), m_filling_rule(fill_non_zero), m_auto_close(true), diff --git a/src/_backend_agg.cpp b/src/_backend_agg.cpp index 9c1e10941c9a..36ff8a268da7 100644 --- a/src/_backend_agg.cpp +++ b/src/_backend_agg.cpp @@ -46,7 +46,7 @@ RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi) rendererBase(), rendererAA(), rendererBin(), - theRasterizer(), + theRasterizer(4096), lastclippath(NULL), _fill_color(agg::rgba(1, 1, 1, 0)) { From 5020af9ee0dc569aa8efd0fa299436abac69d252 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 10 Nov 2014 15:18:39 -0500 Subject: [PATCH 4/9] Move typedefs Conflicts: src/_tkagg.cpp --- src/_backend_agg.h | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/_backend_agg.h b/src/_backend_agg.h index 66fc6bf7cb77..74fdda299644 100644 --- a/src/_backend_agg.h +++ b/src/_backend_agg.h @@ -79,21 +79,6 @@ struct fixed_blender_rgba_plain : agg::conv_rgba_plain /**********************************************************************/ -typedef fixed_blender_rgba_plain fixed_blender_rgba32_plain; -typedef agg::pixfmt_alpha_blend_rgba pixfmt; -typedef agg::renderer_base renderer_base; -typedef agg::renderer_scanline_aa_solid renderer_aa; -typedef agg::renderer_scanline_bin_solid renderer_bin; -typedef agg::rasterizer_scanline_aa rasterizer; - -typedef agg::scanline_p8 scanline_p8; -typedef agg::scanline_bin scanline_bin; -typedef agg::amask_no_clip_gray8 alpha_mask_type; -typedef agg::scanline_u8_am scanline_am; - -typedef agg::renderer_base renderer_base_alpha_mask_type; -typedef agg::renderer_scanline_aa_solid renderer_alpha_mask_type; - // a helper class to pass agg::buffer objects around. agg::buffer is // a class in the swig wrapper class BufferRegion @@ -157,10 +142,26 @@ class BufferRegion // the renderer class RendererAgg { + public: + + typedef fixed_blender_rgba_plain fixed_blender_rgba32_plain; + typedef agg::pixfmt_alpha_blend_rgba pixfmt; + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_aa; + typedef agg::renderer_scanline_bin_solid renderer_bin; + typedef agg::rasterizer_scanline_aa rasterizer; + + typedef agg::scanline_p8 scanline_p8; + typedef agg::scanline_bin scanline_bin; + typedef agg::amask_no_clip_gray8 alpha_mask_type; + typedef agg::scanline_u8_am scanline_am; + + typedef agg::renderer_base renderer_base_alpha_mask_type; + typedef agg::renderer_scanline_aa_solid renderer_alpha_mask_type; + /* TODO: Remove facepair_t */ typedef std::pair facepair_t; - public: RendererAgg(unsigned int width, unsigned int height, double dpi); virtual ~RendererAgg(); From 86c4436617d11a5e842e3088c81d34b6ca0d4413 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 10 Nov 2014 15:23:20 -0500 Subject: [PATCH 5/9] Move Agg directory Conflicts: setupext.py --- extern/{agg24 => agg24-svn}/include/agg_alpha_mask_u8.h | 0 extern/{agg24 => agg24-svn}/include/agg_arc.h | 0 extern/{agg24 => agg24-svn}/include/agg_array.h | 0 extern/{agg24 => agg24-svn}/include/agg_arrowhead.h | 0 extern/{agg24 => agg24-svn}/include/agg_basics.h | 0 extern/{agg24 => agg24-svn}/include/agg_bezier_arc.h | 0 extern/{agg24 => agg24-svn}/include/agg_bitset_iterator.h | 0 extern/{agg24 => agg24-svn}/include/agg_blur.h | 0 extern/{agg24 => agg24-svn}/include/agg_bounding_rect.h | 0 extern/{agg24 => agg24-svn}/include/agg_bspline.h | 0 extern/{agg24 => agg24-svn}/include/agg_clip_liang_barsky.h | 0 extern/{agg24 => agg24-svn}/include/agg_color_gray.h | 0 extern/{agg24 => agg24-svn}/include/agg_color_rgba.h | 0 extern/{agg24 => agg24-svn}/include/agg_config.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_adaptor_vcgen.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_adaptor_vpgen.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_bspline.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_clip_polygon.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_clip_polyline.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_close_polygon.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_concat.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_contour.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_curve.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_dash.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_gpc.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_marker.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_marker_adaptor.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_segmentator.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_shorten_path.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_smooth_poly1.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_stroke.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_transform.h | 0 extern/{agg24 => agg24-svn}/include/agg_conv_unclose_polygon.h | 0 extern/{agg24 => agg24-svn}/include/agg_curves.h | 0 extern/{agg24 => agg24-svn}/include/agg_dda_line.h | 0 extern/{agg24 => agg24-svn}/include/agg_ellipse.h | 0 extern/{agg24 => agg24-svn}/include/agg_ellipse_bresenham.h | 0 extern/{agg24 => agg24-svn}/include/agg_embedded_raster_fonts.h | 0 extern/{agg24 => agg24-svn}/include/agg_font_cache_manager.h | 0 extern/{agg24 => agg24-svn}/include/agg_font_cache_manager2.h | 0 extern/{agg24 => agg24-svn}/include/agg_gamma_functions.h | 0 extern/{agg24 => agg24-svn}/include/agg_gamma_lut.h | 0 extern/{agg24 => agg24-svn}/include/agg_glyph_raster_bin.h | 0 extern/{agg24 => agg24-svn}/include/agg_gradient_lut.h | 0 extern/{agg24 => agg24-svn}/include/agg_gsv_text.h | 0 extern/{agg24 => agg24-svn}/include/agg_image_accessors.h | 0 extern/{agg24 => agg24-svn}/include/agg_image_filters.h | 0 extern/{agg24 => agg24-svn}/include/agg_line_aa_basics.h | 0 extern/{agg24 => agg24-svn}/include/agg_math.h | 0 extern/{agg24 => agg24-svn}/include/agg_math_stroke.h | 0 extern/{agg24 => agg24-svn}/include/agg_path_length.h | 0 extern/{agg24 => agg24-svn}/include/agg_path_storage.h | 0 extern/{agg24 => agg24-svn}/include/agg_path_storage_integer.h | 0 extern/{agg24 => agg24-svn}/include/agg_pattern_filters_rgba.h | 0 extern/{agg24 => agg24-svn}/include/agg_pixfmt_amask_adaptor.h | 0 extern/{agg24 => agg24-svn}/include/agg_pixfmt_base.h | 0 extern/{agg24 => agg24-svn}/include/agg_pixfmt_gray.h | 0 extern/{agg24 => agg24-svn}/include/agg_pixfmt_rgb.h | 0 extern/{agg24 => agg24-svn}/include/agg_pixfmt_rgb_packed.h | 0 extern/{agg24 => agg24-svn}/include/agg_pixfmt_rgba.h | 0 extern/{agg24 => agg24-svn}/include/agg_pixfmt_transposer.h | 0 extern/{agg24 => agg24-svn}/include/agg_rasterizer_cells_aa.h | 0 extern/{agg24 => agg24-svn}/include/agg_rasterizer_compound_aa.h | 0 extern/{agg24 => agg24-svn}/include/agg_rasterizer_outline.h | 0 extern/{agg24 => agg24-svn}/include/agg_rasterizer_outline_aa.h | 0 extern/{agg24 => agg24-svn}/include/agg_rasterizer_scanline_aa.h | 0 .../include/agg_rasterizer_scanline_aa_nogamma.h | 0 extern/{agg24 => agg24-svn}/include/agg_rasterizer_sl_clip.h | 0 extern/{agg24 => agg24-svn}/include/agg_renderer_base.h | 0 extern/{agg24 => agg24-svn}/include/agg_renderer_markers.h | 0 extern/{agg24 => agg24-svn}/include/agg_renderer_mclip.h | 0 extern/{agg24 => agg24-svn}/include/agg_renderer_outline_aa.h | 0 extern/{agg24 => agg24-svn}/include/agg_renderer_outline_image.h | 0 extern/{agg24 => agg24-svn}/include/agg_renderer_primitives.h | 0 extern/{agg24 => agg24-svn}/include/agg_renderer_raster_text.h | 0 extern/{agg24 => agg24-svn}/include/agg_renderer_scanline.h | 0 extern/{agg24 => agg24-svn}/include/agg_rendering_buffer.h | 0 .../{agg24 => agg24-svn}/include/agg_rendering_buffer_dynarow.h | 0 extern/{agg24 => agg24-svn}/include/agg_rounded_rect.h | 0 extern/{agg24 => agg24-svn}/include/agg_scanline_bin.h | 0 .../{agg24 => agg24-svn}/include/agg_scanline_boolean_algebra.h | 0 extern/{agg24 => agg24-svn}/include/agg_scanline_p.h | 0 extern/{agg24 => agg24-svn}/include/agg_scanline_storage_aa.h | 0 extern/{agg24 => agg24-svn}/include/agg_scanline_storage_bin.h | 0 extern/{agg24 => agg24-svn}/include/agg_scanline_u.h | 0 extern/{agg24 => agg24-svn}/include/agg_shorten_path.h | 0 extern/{agg24 => agg24-svn}/include/agg_simul_eq.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_allocator.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_converter.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_gouraud.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_gouraud_gray.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_gouraud_rgba.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_gradient.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_gradient_alpha.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_gradient_contour.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_gradient_image.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_image_filter.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_image_filter_gray.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_image_filter_rgb.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_image_filter_rgba.h | 0 .../{agg24 => agg24-svn}/include/agg_span_interpolator_adaptor.h | 0 .../{agg24 => agg24-svn}/include/agg_span_interpolator_linear.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_interpolator_persp.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_interpolator_trans.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_pattern_gray.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_pattern_rgb.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_pattern_rgba.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_solid.h | 0 extern/{agg24 => agg24-svn}/include/agg_span_subdiv_adaptor.h | 0 extern/{agg24 => agg24-svn}/include/agg_trans_affine.h | 0 extern/{agg24 => agg24-svn}/include/agg_trans_bilinear.h | 0 extern/{agg24 => agg24-svn}/include/agg_trans_double_path.h | 0 extern/{agg24 => agg24-svn}/include/agg_trans_perspective.h | 0 extern/{agg24 => agg24-svn}/include/agg_trans_single_path.h | 0 extern/{agg24 => agg24-svn}/include/agg_trans_viewport.h | 0 extern/{agg24 => agg24-svn}/include/agg_trans_warp_magnifier.h | 0 extern/{agg24 => agg24-svn}/include/agg_vcgen_bspline.h | 0 extern/{agg24 => agg24-svn}/include/agg_vcgen_contour.h | 0 extern/{agg24 => agg24-svn}/include/agg_vcgen_dash.h | 0 extern/{agg24 => agg24-svn}/include/agg_vcgen_markers_term.h | 0 extern/{agg24 => agg24-svn}/include/agg_vcgen_smooth_poly1.h | 0 extern/{agg24 => agg24-svn}/include/agg_vcgen_stroke.h | 0 extern/{agg24 => agg24-svn}/include/agg_vcgen_vertex_sequence.h | 0 extern/{agg24 => agg24-svn}/include/agg_vertex_sequence.h | 0 extern/{agg24 => agg24-svn}/include/agg_vpgen_clip_polygon.h | 0 extern/{agg24 => agg24-svn}/include/agg_vpgen_clip_polyline.h | 0 extern/{agg24 => agg24-svn}/include/agg_vpgen_segmentator.h | 0 extern/{agg24 => agg24-svn}/include/ctrl/agg_bezier_ctrl.h | 0 extern/{agg24 => agg24-svn}/include/ctrl/agg_cbox_ctrl.h | 0 extern/{agg24 => agg24-svn}/include/ctrl/agg_ctrl.h | 0 extern/{agg24 => agg24-svn}/include/ctrl/agg_gamma_ctrl.h | 0 extern/{agg24 => agg24-svn}/include/ctrl/agg_gamma_spline.h | 0 extern/{agg24 => agg24-svn}/include/ctrl/agg_polygon_ctrl.h | 0 extern/{agg24 => agg24-svn}/include/ctrl/agg_rbox_ctrl.h | 0 extern/{agg24 => agg24-svn}/include/ctrl/agg_scale_ctrl.h | 0 extern/{agg24 => agg24-svn}/include/ctrl/agg_slider_ctrl.h | 0 extern/{agg24 => agg24-svn}/include/ctrl/agg_spline_ctrl.h | 0 .../{agg24 => agg24-svn}/include/platform/agg_platform_support.h | 0 extern/{agg24 => agg24-svn}/include/platform/mac/agg_mac_pmap.h | 0 .../{agg24 => agg24-svn}/include/platform/win32/agg_win32_bmp.h | 0 extern/{agg24 => agg24-svn}/include/util/agg_color_conv.h | 0 extern/{agg24 => agg24-svn}/include/util/agg_color_conv_rgb16.h | 0 extern/{agg24 => agg24-svn}/include/util/agg_color_conv_rgb8.h | 0 extern/{agg24 => agg24-svn}/src/ChangeLog | 0 extern/{agg24 => agg24-svn}/src/agg_arc.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_arrowhead.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_bezier_arc.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_bspline.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_color_rgba.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_curves.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_embedded_raster_fonts.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_gsv_text.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_image_filters.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_line_aa_basics.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_line_profile_aa.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_rounded_rect.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_sqrt_tables.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_trans_affine.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_trans_double_path.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_trans_single_path.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_trans_warp_magnifier.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_vcgen_bspline.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_vcgen_contour.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_vcgen_dash.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_vcgen_markers_term.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_vcgen_smooth_poly1.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_vcgen_stroke.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_vpgen_clip_polygon.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_vpgen_clip_polyline.cpp | 0 extern/{agg24 => agg24-svn}/src/agg_vpgen_segmentator.cpp | 0 extern/{agg24 => agg24-svn}/src/authors | 0 extern/{agg24 => agg24-svn}/src/copying | 0 extern/{agg24 => agg24-svn}/src/ctrl/agg_bezier_ctrl.cpp | 0 extern/{agg24 => agg24-svn}/src/ctrl/agg_cbox_ctrl.cpp | 0 extern/{agg24 => agg24-svn}/src/ctrl/agg_gamma_ctrl.cpp | 0 extern/{agg24 => agg24-svn}/src/ctrl/agg_gamma_spline.cpp | 0 extern/{agg24 => agg24-svn}/src/ctrl/agg_polygon_ctrl.cpp | 0 extern/{agg24 => agg24-svn}/src/ctrl/agg_rbox_ctrl.cpp | 0 extern/{agg24 => agg24-svn}/src/ctrl/agg_scale_ctrl.cpp | 0 extern/{agg24 => agg24-svn}/src/ctrl/agg_slider_ctrl.cpp | 0 extern/{agg24 => agg24-svn}/src/ctrl/agg_spline_ctrl.cpp | 0 .../src/platform/AmigaOS/agg_platform_support.cpp | 0 .../src/platform/BeOS/agg_platform_support.cpp | 0 .../src/platform/X11/agg_platform_support.cpp | 0 extern/{agg24 => agg24-svn}/src/platform/mac/agg_mac_pmap.cpp | 0 .../src/platform/mac/agg_platform_support.cpp | 0 .../src/platform/sdl/agg_platform_support.cpp | 0 .../src/platform/win32/agg_platform_support.cpp | 0 extern/{agg24 => agg24-svn}/src/platform/win32/agg_win32_bmp.cpp | 0 189 files changed, 0 insertions(+), 0 deletions(-) rename extern/{agg24 => agg24-svn}/include/agg_alpha_mask_u8.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_arc.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_array.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_arrowhead.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_basics.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_bezier_arc.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_bitset_iterator.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_blur.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_bounding_rect.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_bspline.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_clip_liang_barsky.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_color_gray.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_color_rgba.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_config.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_adaptor_vcgen.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_adaptor_vpgen.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_bspline.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_clip_polygon.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_clip_polyline.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_close_polygon.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_concat.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_contour.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_curve.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_dash.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_gpc.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_marker.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_marker_adaptor.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_segmentator.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_shorten_path.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_smooth_poly1.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_stroke.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_transform.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_conv_unclose_polygon.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_curves.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_dda_line.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_ellipse.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_ellipse_bresenham.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_embedded_raster_fonts.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_font_cache_manager.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_font_cache_manager2.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_gamma_functions.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_gamma_lut.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_glyph_raster_bin.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_gradient_lut.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_gsv_text.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_image_accessors.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_image_filters.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_line_aa_basics.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_math.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_math_stroke.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_path_length.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_path_storage.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_path_storage_integer.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_pattern_filters_rgba.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_pixfmt_amask_adaptor.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_pixfmt_base.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_pixfmt_gray.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_pixfmt_rgb.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_pixfmt_rgb_packed.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_pixfmt_rgba.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_pixfmt_transposer.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_rasterizer_cells_aa.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_rasterizer_compound_aa.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_rasterizer_outline.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_rasterizer_outline_aa.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_rasterizer_scanline_aa.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_rasterizer_scanline_aa_nogamma.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_rasterizer_sl_clip.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_renderer_base.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_renderer_markers.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_renderer_mclip.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_renderer_outline_aa.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_renderer_outline_image.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_renderer_primitives.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_renderer_raster_text.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_renderer_scanline.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_rendering_buffer.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_rendering_buffer_dynarow.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_rounded_rect.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_scanline_bin.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_scanline_boolean_algebra.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_scanline_p.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_scanline_storage_aa.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_scanline_storage_bin.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_scanline_u.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_shorten_path.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_simul_eq.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_allocator.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_converter.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_gouraud.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_gouraud_gray.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_gouraud_rgba.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_gradient.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_gradient_alpha.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_gradient_contour.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_gradient_image.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_image_filter.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_image_filter_gray.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_image_filter_rgb.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_image_filter_rgba.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_interpolator_adaptor.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_interpolator_linear.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_interpolator_persp.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_interpolator_trans.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_pattern_gray.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_pattern_rgb.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_pattern_rgba.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_solid.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_span_subdiv_adaptor.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_trans_affine.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_trans_bilinear.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_trans_double_path.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_trans_perspective.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_trans_single_path.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_trans_viewport.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_trans_warp_magnifier.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_vcgen_bspline.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_vcgen_contour.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_vcgen_dash.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_vcgen_markers_term.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_vcgen_smooth_poly1.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_vcgen_stroke.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_vcgen_vertex_sequence.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_vertex_sequence.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_vpgen_clip_polygon.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_vpgen_clip_polyline.h (100%) rename extern/{agg24 => agg24-svn}/include/agg_vpgen_segmentator.h (100%) rename extern/{agg24 => agg24-svn}/include/ctrl/agg_bezier_ctrl.h (100%) rename extern/{agg24 => agg24-svn}/include/ctrl/agg_cbox_ctrl.h (100%) rename extern/{agg24 => agg24-svn}/include/ctrl/agg_ctrl.h (100%) rename extern/{agg24 => agg24-svn}/include/ctrl/agg_gamma_ctrl.h (100%) rename extern/{agg24 => agg24-svn}/include/ctrl/agg_gamma_spline.h (100%) rename extern/{agg24 => agg24-svn}/include/ctrl/agg_polygon_ctrl.h (100%) rename extern/{agg24 => agg24-svn}/include/ctrl/agg_rbox_ctrl.h (100%) rename extern/{agg24 => agg24-svn}/include/ctrl/agg_scale_ctrl.h (100%) rename extern/{agg24 => agg24-svn}/include/ctrl/agg_slider_ctrl.h (100%) rename extern/{agg24 => agg24-svn}/include/ctrl/agg_spline_ctrl.h (100%) rename extern/{agg24 => agg24-svn}/include/platform/agg_platform_support.h (100%) rename extern/{agg24 => agg24-svn}/include/platform/mac/agg_mac_pmap.h (100%) rename extern/{agg24 => agg24-svn}/include/platform/win32/agg_win32_bmp.h (100%) rename extern/{agg24 => agg24-svn}/include/util/agg_color_conv.h (100%) rename extern/{agg24 => agg24-svn}/include/util/agg_color_conv_rgb16.h (100%) rename extern/{agg24 => agg24-svn}/include/util/agg_color_conv_rgb8.h (100%) rename extern/{agg24 => agg24-svn}/src/ChangeLog (100%) rename extern/{agg24 => agg24-svn}/src/agg_arc.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_arrowhead.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_bezier_arc.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_bspline.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_color_rgba.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_curves.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_embedded_raster_fonts.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_gsv_text.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_image_filters.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_line_aa_basics.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_line_profile_aa.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_rounded_rect.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_sqrt_tables.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_trans_affine.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_trans_double_path.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_trans_single_path.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_trans_warp_magnifier.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_vcgen_bspline.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_vcgen_contour.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_vcgen_dash.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_vcgen_markers_term.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_vcgen_smooth_poly1.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_vcgen_stroke.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_vpgen_clip_polygon.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_vpgen_clip_polyline.cpp (100%) rename extern/{agg24 => agg24-svn}/src/agg_vpgen_segmentator.cpp (100%) rename extern/{agg24 => agg24-svn}/src/authors (100%) rename extern/{agg24 => agg24-svn}/src/copying (100%) rename extern/{agg24 => agg24-svn}/src/ctrl/agg_bezier_ctrl.cpp (100%) rename extern/{agg24 => agg24-svn}/src/ctrl/agg_cbox_ctrl.cpp (100%) rename extern/{agg24 => agg24-svn}/src/ctrl/agg_gamma_ctrl.cpp (100%) rename extern/{agg24 => agg24-svn}/src/ctrl/agg_gamma_spline.cpp (100%) rename extern/{agg24 => agg24-svn}/src/ctrl/agg_polygon_ctrl.cpp (100%) rename extern/{agg24 => agg24-svn}/src/ctrl/agg_rbox_ctrl.cpp (100%) rename extern/{agg24 => agg24-svn}/src/ctrl/agg_scale_ctrl.cpp (100%) rename extern/{agg24 => agg24-svn}/src/ctrl/agg_slider_ctrl.cpp (100%) rename extern/{agg24 => agg24-svn}/src/ctrl/agg_spline_ctrl.cpp (100%) rename extern/{agg24 => agg24-svn}/src/platform/AmigaOS/agg_platform_support.cpp (100%) rename extern/{agg24 => agg24-svn}/src/platform/BeOS/agg_platform_support.cpp (100%) rename extern/{agg24 => agg24-svn}/src/platform/X11/agg_platform_support.cpp (100%) rename extern/{agg24 => agg24-svn}/src/platform/mac/agg_mac_pmap.cpp (100%) rename extern/{agg24 => agg24-svn}/src/platform/mac/agg_platform_support.cpp (100%) rename extern/{agg24 => agg24-svn}/src/platform/sdl/agg_platform_support.cpp (100%) rename extern/{agg24 => agg24-svn}/src/platform/win32/agg_platform_support.cpp (100%) rename extern/{agg24 => agg24-svn}/src/platform/win32/agg_win32_bmp.cpp (100%) diff --git a/extern/agg24/include/agg_alpha_mask_u8.h b/extern/agg24-svn/include/agg_alpha_mask_u8.h similarity index 100% rename from extern/agg24/include/agg_alpha_mask_u8.h rename to extern/agg24-svn/include/agg_alpha_mask_u8.h diff --git a/extern/agg24/include/agg_arc.h b/extern/agg24-svn/include/agg_arc.h similarity index 100% rename from extern/agg24/include/agg_arc.h rename to extern/agg24-svn/include/agg_arc.h diff --git a/extern/agg24/include/agg_array.h b/extern/agg24-svn/include/agg_array.h similarity index 100% rename from extern/agg24/include/agg_array.h rename to extern/agg24-svn/include/agg_array.h diff --git a/extern/agg24/include/agg_arrowhead.h b/extern/agg24-svn/include/agg_arrowhead.h similarity index 100% rename from extern/agg24/include/agg_arrowhead.h rename to extern/agg24-svn/include/agg_arrowhead.h diff --git a/extern/agg24/include/agg_basics.h b/extern/agg24-svn/include/agg_basics.h similarity index 100% rename from extern/agg24/include/agg_basics.h rename to extern/agg24-svn/include/agg_basics.h diff --git a/extern/agg24/include/agg_bezier_arc.h b/extern/agg24-svn/include/agg_bezier_arc.h similarity index 100% rename from extern/agg24/include/agg_bezier_arc.h rename to extern/agg24-svn/include/agg_bezier_arc.h diff --git a/extern/agg24/include/agg_bitset_iterator.h b/extern/agg24-svn/include/agg_bitset_iterator.h similarity index 100% rename from extern/agg24/include/agg_bitset_iterator.h rename to extern/agg24-svn/include/agg_bitset_iterator.h diff --git a/extern/agg24/include/agg_blur.h b/extern/agg24-svn/include/agg_blur.h similarity index 100% rename from extern/agg24/include/agg_blur.h rename to extern/agg24-svn/include/agg_blur.h diff --git a/extern/agg24/include/agg_bounding_rect.h b/extern/agg24-svn/include/agg_bounding_rect.h similarity index 100% rename from extern/agg24/include/agg_bounding_rect.h rename to extern/agg24-svn/include/agg_bounding_rect.h diff --git a/extern/agg24/include/agg_bspline.h b/extern/agg24-svn/include/agg_bspline.h similarity index 100% rename from extern/agg24/include/agg_bspline.h rename to extern/agg24-svn/include/agg_bspline.h diff --git a/extern/agg24/include/agg_clip_liang_barsky.h b/extern/agg24-svn/include/agg_clip_liang_barsky.h similarity index 100% rename from extern/agg24/include/agg_clip_liang_barsky.h rename to extern/agg24-svn/include/agg_clip_liang_barsky.h diff --git a/extern/agg24/include/agg_color_gray.h b/extern/agg24-svn/include/agg_color_gray.h similarity index 100% rename from extern/agg24/include/agg_color_gray.h rename to extern/agg24-svn/include/agg_color_gray.h diff --git a/extern/agg24/include/agg_color_rgba.h b/extern/agg24-svn/include/agg_color_rgba.h similarity index 100% rename from extern/agg24/include/agg_color_rgba.h rename to extern/agg24-svn/include/agg_color_rgba.h diff --git a/extern/agg24/include/agg_config.h b/extern/agg24-svn/include/agg_config.h similarity index 100% rename from extern/agg24/include/agg_config.h rename to extern/agg24-svn/include/agg_config.h diff --git a/extern/agg24/include/agg_conv_adaptor_vcgen.h b/extern/agg24-svn/include/agg_conv_adaptor_vcgen.h similarity index 100% rename from extern/agg24/include/agg_conv_adaptor_vcgen.h rename to extern/agg24-svn/include/agg_conv_adaptor_vcgen.h diff --git a/extern/agg24/include/agg_conv_adaptor_vpgen.h b/extern/agg24-svn/include/agg_conv_adaptor_vpgen.h similarity index 100% rename from extern/agg24/include/agg_conv_adaptor_vpgen.h rename to extern/agg24-svn/include/agg_conv_adaptor_vpgen.h diff --git a/extern/agg24/include/agg_conv_bspline.h b/extern/agg24-svn/include/agg_conv_bspline.h similarity index 100% rename from extern/agg24/include/agg_conv_bspline.h rename to extern/agg24-svn/include/agg_conv_bspline.h diff --git a/extern/agg24/include/agg_conv_clip_polygon.h b/extern/agg24-svn/include/agg_conv_clip_polygon.h similarity index 100% rename from extern/agg24/include/agg_conv_clip_polygon.h rename to extern/agg24-svn/include/agg_conv_clip_polygon.h diff --git a/extern/agg24/include/agg_conv_clip_polyline.h b/extern/agg24-svn/include/agg_conv_clip_polyline.h similarity index 100% rename from extern/agg24/include/agg_conv_clip_polyline.h rename to extern/agg24-svn/include/agg_conv_clip_polyline.h diff --git a/extern/agg24/include/agg_conv_close_polygon.h b/extern/agg24-svn/include/agg_conv_close_polygon.h similarity index 100% rename from extern/agg24/include/agg_conv_close_polygon.h rename to extern/agg24-svn/include/agg_conv_close_polygon.h diff --git a/extern/agg24/include/agg_conv_concat.h b/extern/agg24-svn/include/agg_conv_concat.h similarity index 100% rename from extern/agg24/include/agg_conv_concat.h rename to extern/agg24-svn/include/agg_conv_concat.h diff --git a/extern/agg24/include/agg_conv_contour.h b/extern/agg24-svn/include/agg_conv_contour.h similarity index 100% rename from extern/agg24/include/agg_conv_contour.h rename to extern/agg24-svn/include/agg_conv_contour.h diff --git a/extern/agg24/include/agg_conv_curve.h b/extern/agg24-svn/include/agg_conv_curve.h similarity index 100% rename from extern/agg24/include/agg_conv_curve.h rename to extern/agg24-svn/include/agg_conv_curve.h diff --git a/extern/agg24/include/agg_conv_dash.h b/extern/agg24-svn/include/agg_conv_dash.h similarity index 100% rename from extern/agg24/include/agg_conv_dash.h rename to extern/agg24-svn/include/agg_conv_dash.h diff --git a/extern/agg24/include/agg_conv_gpc.h b/extern/agg24-svn/include/agg_conv_gpc.h similarity index 100% rename from extern/agg24/include/agg_conv_gpc.h rename to extern/agg24-svn/include/agg_conv_gpc.h diff --git a/extern/agg24/include/agg_conv_marker.h b/extern/agg24-svn/include/agg_conv_marker.h similarity index 100% rename from extern/agg24/include/agg_conv_marker.h rename to extern/agg24-svn/include/agg_conv_marker.h diff --git a/extern/agg24/include/agg_conv_marker_adaptor.h b/extern/agg24-svn/include/agg_conv_marker_adaptor.h similarity index 100% rename from extern/agg24/include/agg_conv_marker_adaptor.h rename to extern/agg24-svn/include/agg_conv_marker_adaptor.h diff --git a/extern/agg24/include/agg_conv_segmentator.h b/extern/agg24-svn/include/agg_conv_segmentator.h similarity index 100% rename from extern/agg24/include/agg_conv_segmentator.h rename to extern/agg24-svn/include/agg_conv_segmentator.h diff --git a/extern/agg24/include/agg_conv_shorten_path.h b/extern/agg24-svn/include/agg_conv_shorten_path.h similarity index 100% rename from extern/agg24/include/agg_conv_shorten_path.h rename to extern/agg24-svn/include/agg_conv_shorten_path.h diff --git a/extern/agg24/include/agg_conv_smooth_poly1.h b/extern/agg24-svn/include/agg_conv_smooth_poly1.h similarity index 100% rename from extern/agg24/include/agg_conv_smooth_poly1.h rename to extern/agg24-svn/include/agg_conv_smooth_poly1.h diff --git a/extern/agg24/include/agg_conv_stroke.h b/extern/agg24-svn/include/agg_conv_stroke.h similarity index 100% rename from extern/agg24/include/agg_conv_stroke.h rename to extern/agg24-svn/include/agg_conv_stroke.h diff --git a/extern/agg24/include/agg_conv_transform.h b/extern/agg24-svn/include/agg_conv_transform.h similarity index 100% rename from extern/agg24/include/agg_conv_transform.h rename to extern/agg24-svn/include/agg_conv_transform.h diff --git a/extern/agg24/include/agg_conv_unclose_polygon.h b/extern/agg24-svn/include/agg_conv_unclose_polygon.h similarity index 100% rename from extern/agg24/include/agg_conv_unclose_polygon.h rename to extern/agg24-svn/include/agg_conv_unclose_polygon.h diff --git a/extern/agg24/include/agg_curves.h b/extern/agg24-svn/include/agg_curves.h similarity index 100% rename from extern/agg24/include/agg_curves.h rename to extern/agg24-svn/include/agg_curves.h diff --git a/extern/agg24/include/agg_dda_line.h b/extern/agg24-svn/include/agg_dda_line.h similarity index 100% rename from extern/agg24/include/agg_dda_line.h rename to extern/agg24-svn/include/agg_dda_line.h diff --git a/extern/agg24/include/agg_ellipse.h b/extern/agg24-svn/include/agg_ellipse.h similarity index 100% rename from extern/agg24/include/agg_ellipse.h rename to extern/agg24-svn/include/agg_ellipse.h diff --git a/extern/agg24/include/agg_ellipse_bresenham.h b/extern/agg24-svn/include/agg_ellipse_bresenham.h similarity index 100% rename from extern/agg24/include/agg_ellipse_bresenham.h rename to extern/agg24-svn/include/agg_ellipse_bresenham.h diff --git a/extern/agg24/include/agg_embedded_raster_fonts.h b/extern/agg24-svn/include/agg_embedded_raster_fonts.h similarity index 100% rename from extern/agg24/include/agg_embedded_raster_fonts.h rename to extern/agg24-svn/include/agg_embedded_raster_fonts.h diff --git a/extern/agg24/include/agg_font_cache_manager.h b/extern/agg24-svn/include/agg_font_cache_manager.h similarity index 100% rename from extern/agg24/include/agg_font_cache_manager.h rename to extern/agg24-svn/include/agg_font_cache_manager.h diff --git a/extern/agg24/include/agg_font_cache_manager2.h b/extern/agg24-svn/include/agg_font_cache_manager2.h similarity index 100% rename from extern/agg24/include/agg_font_cache_manager2.h rename to extern/agg24-svn/include/agg_font_cache_manager2.h diff --git a/extern/agg24/include/agg_gamma_functions.h b/extern/agg24-svn/include/agg_gamma_functions.h similarity index 100% rename from extern/agg24/include/agg_gamma_functions.h rename to extern/agg24-svn/include/agg_gamma_functions.h diff --git a/extern/agg24/include/agg_gamma_lut.h b/extern/agg24-svn/include/agg_gamma_lut.h similarity index 100% rename from extern/agg24/include/agg_gamma_lut.h rename to extern/agg24-svn/include/agg_gamma_lut.h diff --git a/extern/agg24/include/agg_glyph_raster_bin.h b/extern/agg24-svn/include/agg_glyph_raster_bin.h similarity index 100% rename from extern/agg24/include/agg_glyph_raster_bin.h rename to extern/agg24-svn/include/agg_glyph_raster_bin.h diff --git a/extern/agg24/include/agg_gradient_lut.h b/extern/agg24-svn/include/agg_gradient_lut.h similarity index 100% rename from extern/agg24/include/agg_gradient_lut.h rename to extern/agg24-svn/include/agg_gradient_lut.h diff --git a/extern/agg24/include/agg_gsv_text.h b/extern/agg24-svn/include/agg_gsv_text.h similarity index 100% rename from extern/agg24/include/agg_gsv_text.h rename to extern/agg24-svn/include/agg_gsv_text.h diff --git a/extern/agg24/include/agg_image_accessors.h b/extern/agg24-svn/include/agg_image_accessors.h similarity index 100% rename from extern/agg24/include/agg_image_accessors.h rename to extern/agg24-svn/include/agg_image_accessors.h diff --git a/extern/agg24/include/agg_image_filters.h b/extern/agg24-svn/include/agg_image_filters.h similarity index 100% rename from extern/agg24/include/agg_image_filters.h rename to extern/agg24-svn/include/agg_image_filters.h diff --git a/extern/agg24/include/agg_line_aa_basics.h b/extern/agg24-svn/include/agg_line_aa_basics.h similarity index 100% rename from extern/agg24/include/agg_line_aa_basics.h rename to extern/agg24-svn/include/agg_line_aa_basics.h diff --git a/extern/agg24/include/agg_math.h b/extern/agg24-svn/include/agg_math.h similarity index 100% rename from extern/agg24/include/agg_math.h rename to extern/agg24-svn/include/agg_math.h diff --git a/extern/agg24/include/agg_math_stroke.h b/extern/agg24-svn/include/agg_math_stroke.h similarity index 100% rename from extern/agg24/include/agg_math_stroke.h rename to extern/agg24-svn/include/agg_math_stroke.h diff --git a/extern/agg24/include/agg_path_length.h b/extern/agg24-svn/include/agg_path_length.h similarity index 100% rename from extern/agg24/include/agg_path_length.h rename to extern/agg24-svn/include/agg_path_length.h diff --git a/extern/agg24/include/agg_path_storage.h b/extern/agg24-svn/include/agg_path_storage.h similarity index 100% rename from extern/agg24/include/agg_path_storage.h rename to extern/agg24-svn/include/agg_path_storage.h diff --git a/extern/agg24/include/agg_path_storage_integer.h b/extern/agg24-svn/include/agg_path_storage_integer.h similarity index 100% rename from extern/agg24/include/agg_path_storage_integer.h rename to extern/agg24-svn/include/agg_path_storage_integer.h diff --git a/extern/agg24/include/agg_pattern_filters_rgba.h b/extern/agg24-svn/include/agg_pattern_filters_rgba.h similarity index 100% rename from extern/agg24/include/agg_pattern_filters_rgba.h rename to extern/agg24-svn/include/agg_pattern_filters_rgba.h diff --git a/extern/agg24/include/agg_pixfmt_amask_adaptor.h b/extern/agg24-svn/include/agg_pixfmt_amask_adaptor.h similarity index 100% rename from extern/agg24/include/agg_pixfmt_amask_adaptor.h rename to extern/agg24-svn/include/agg_pixfmt_amask_adaptor.h diff --git a/extern/agg24/include/agg_pixfmt_base.h b/extern/agg24-svn/include/agg_pixfmt_base.h similarity index 100% rename from extern/agg24/include/agg_pixfmt_base.h rename to extern/agg24-svn/include/agg_pixfmt_base.h diff --git a/extern/agg24/include/agg_pixfmt_gray.h b/extern/agg24-svn/include/agg_pixfmt_gray.h similarity index 100% rename from extern/agg24/include/agg_pixfmt_gray.h rename to extern/agg24-svn/include/agg_pixfmt_gray.h diff --git a/extern/agg24/include/agg_pixfmt_rgb.h b/extern/agg24-svn/include/agg_pixfmt_rgb.h similarity index 100% rename from extern/agg24/include/agg_pixfmt_rgb.h rename to extern/agg24-svn/include/agg_pixfmt_rgb.h diff --git a/extern/agg24/include/agg_pixfmt_rgb_packed.h b/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h similarity index 100% rename from extern/agg24/include/agg_pixfmt_rgb_packed.h rename to extern/agg24-svn/include/agg_pixfmt_rgb_packed.h diff --git a/extern/agg24/include/agg_pixfmt_rgba.h b/extern/agg24-svn/include/agg_pixfmt_rgba.h similarity index 100% rename from extern/agg24/include/agg_pixfmt_rgba.h rename to extern/agg24-svn/include/agg_pixfmt_rgba.h diff --git a/extern/agg24/include/agg_pixfmt_transposer.h b/extern/agg24-svn/include/agg_pixfmt_transposer.h similarity index 100% rename from extern/agg24/include/agg_pixfmt_transposer.h rename to extern/agg24-svn/include/agg_pixfmt_transposer.h diff --git a/extern/agg24/include/agg_rasterizer_cells_aa.h b/extern/agg24-svn/include/agg_rasterizer_cells_aa.h similarity index 100% rename from extern/agg24/include/agg_rasterizer_cells_aa.h rename to extern/agg24-svn/include/agg_rasterizer_cells_aa.h diff --git a/extern/agg24/include/agg_rasterizer_compound_aa.h b/extern/agg24-svn/include/agg_rasterizer_compound_aa.h similarity index 100% rename from extern/agg24/include/agg_rasterizer_compound_aa.h rename to extern/agg24-svn/include/agg_rasterizer_compound_aa.h diff --git a/extern/agg24/include/agg_rasterizer_outline.h b/extern/agg24-svn/include/agg_rasterizer_outline.h similarity index 100% rename from extern/agg24/include/agg_rasterizer_outline.h rename to extern/agg24-svn/include/agg_rasterizer_outline.h diff --git a/extern/agg24/include/agg_rasterizer_outline_aa.h b/extern/agg24-svn/include/agg_rasterizer_outline_aa.h similarity index 100% rename from extern/agg24/include/agg_rasterizer_outline_aa.h rename to extern/agg24-svn/include/agg_rasterizer_outline_aa.h diff --git a/extern/agg24/include/agg_rasterizer_scanline_aa.h b/extern/agg24-svn/include/agg_rasterizer_scanline_aa.h similarity index 100% rename from extern/agg24/include/agg_rasterizer_scanline_aa.h rename to extern/agg24-svn/include/agg_rasterizer_scanline_aa.h diff --git a/extern/agg24/include/agg_rasterizer_scanline_aa_nogamma.h b/extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h similarity index 100% rename from extern/agg24/include/agg_rasterizer_scanline_aa_nogamma.h rename to extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h diff --git a/extern/agg24/include/agg_rasterizer_sl_clip.h b/extern/agg24-svn/include/agg_rasterizer_sl_clip.h similarity index 100% rename from extern/agg24/include/agg_rasterizer_sl_clip.h rename to extern/agg24-svn/include/agg_rasterizer_sl_clip.h diff --git a/extern/agg24/include/agg_renderer_base.h b/extern/agg24-svn/include/agg_renderer_base.h similarity index 100% rename from extern/agg24/include/agg_renderer_base.h rename to extern/agg24-svn/include/agg_renderer_base.h diff --git a/extern/agg24/include/agg_renderer_markers.h b/extern/agg24-svn/include/agg_renderer_markers.h similarity index 100% rename from extern/agg24/include/agg_renderer_markers.h rename to extern/agg24-svn/include/agg_renderer_markers.h diff --git a/extern/agg24/include/agg_renderer_mclip.h b/extern/agg24-svn/include/agg_renderer_mclip.h similarity index 100% rename from extern/agg24/include/agg_renderer_mclip.h rename to extern/agg24-svn/include/agg_renderer_mclip.h diff --git a/extern/agg24/include/agg_renderer_outline_aa.h b/extern/agg24-svn/include/agg_renderer_outline_aa.h similarity index 100% rename from extern/agg24/include/agg_renderer_outline_aa.h rename to extern/agg24-svn/include/agg_renderer_outline_aa.h diff --git a/extern/agg24/include/agg_renderer_outline_image.h b/extern/agg24-svn/include/agg_renderer_outline_image.h similarity index 100% rename from extern/agg24/include/agg_renderer_outline_image.h rename to extern/agg24-svn/include/agg_renderer_outline_image.h diff --git a/extern/agg24/include/agg_renderer_primitives.h b/extern/agg24-svn/include/agg_renderer_primitives.h similarity index 100% rename from extern/agg24/include/agg_renderer_primitives.h rename to extern/agg24-svn/include/agg_renderer_primitives.h diff --git a/extern/agg24/include/agg_renderer_raster_text.h b/extern/agg24-svn/include/agg_renderer_raster_text.h similarity index 100% rename from extern/agg24/include/agg_renderer_raster_text.h rename to extern/agg24-svn/include/agg_renderer_raster_text.h diff --git a/extern/agg24/include/agg_renderer_scanline.h b/extern/agg24-svn/include/agg_renderer_scanline.h similarity index 100% rename from extern/agg24/include/agg_renderer_scanline.h rename to extern/agg24-svn/include/agg_renderer_scanline.h diff --git a/extern/agg24/include/agg_rendering_buffer.h b/extern/agg24-svn/include/agg_rendering_buffer.h similarity index 100% rename from extern/agg24/include/agg_rendering_buffer.h rename to extern/agg24-svn/include/agg_rendering_buffer.h diff --git a/extern/agg24/include/agg_rendering_buffer_dynarow.h b/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h similarity index 100% rename from extern/agg24/include/agg_rendering_buffer_dynarow.h rename to extern/agg24-svn/include/agg_rendering_buffer_dynarow.h diff --git a/extern/agg24/include/agg_rounded_rect.h b/extern/agg24-svn/include/agg_rounded_rect.h similarity index 100% rename from extern/agg24/include/agg_rounded_rect.h rename to extern/agg24-svn/include/agg_rounded_rect.h diff --git a/extern/agg24/include/agg_scanline_bin.h b/extern/agg24-svn/include/agg_scanline_bin.h similarity index 100% rename from extern/agg24/include/agg_scanline_bin.h rename to extern/agg24-svn/include/agg_scanline_bin.h diff --git a/extern/agg24/include/agg_scanline_boolean_algebra.h b/extern/agg24-svn/include/agg_scanline_boolean_algebra.h similarity index 100% rename from extern/agg24/include/agg_scanline_boolean_algebra.h rename to extern/agg24-svn/include/agg_scanline_boolean_algebra.h diff --git a/extern/agg24/include/agg_scanline_p.h b/extern/agg24-svn/include/agg_scanline_p.h similarity index 100% rename from extern/agg24/include/agg_scanline_p.h rename to extern/agg24-svn/include/agg_scanline_p.h diff --git a/extern/agg24/include/agg_scanline_storage_aa.h b/extern/agg24-svn/include/agg_scanline_storage_aa.h similarity index 100% rename from extern/agg24/include/agg_scanline_storage_aa.h rename to extern/agg24-svn/include/agg_scanline_storage_aa.h diff --git a/extern/agg24/include/agg_scanline_storage_bin.h b/extern/agg24-svn/include/agg_scanline_storage_bin.h similarity index 100% rename from extern/agg24/include/agg_scanline_storage_bin.h rename to extern/agg24-svn/include/agg_scanline_storage_bin.h diff --git a/extern/agg24/include/agg_scanline_u.h b/extern/agg24-svn/include/agg_scanline_u.h similarity index 100% rename from extern/agg24/include/agg_scanline_u.h rename to extern/agg24-svn/include/agg_scanline_u.h diff --git a/extern/agg24/include/agg_shorten_path.h b/extern/agg24-svn/include/agg_shorten_path.h similarity index 100% rename from extern/agg24/include/agg_shorten_path.h rename to extern/agg24-svn/include/agg_shorten_path.h diff --git a/extern/agg24/include/agg_simul_eq.h b/extern/agg24-svn/include/agg_simul_eq.h similarity index 100% rename from extern/agg24/include/agg_simul_eq.h rename to extern/agg24-svn/include/agg_simul_eq.h diff --git a/extern/agg24/include/agg_span_allocator.h b/extern/agg24-svn/include/agg_span_allocator.h similarity index 100% rename from extern/agg24/include/agg_span_allocator.h rename to extern/agg24-svn/include/agg_span_allocator.h diff --git a/extern/agg24/include/agg_span_converter.h b/extern/agg24-svn/include/agg_span_converter.h similarity index 100% rename from extern/agg24/include/agg_span_converter.h rename to extern/agg24-svn/include/agg_span_converter.h diff --git a/extern/agg24/include/agg_span_gouraud.h b/extern/agg24-svn/include/agg_span_gouraud.h similarity index 100% rename from extern/agg24/include/agg_span_gouraud.h rename to extern/agg24-svn/include/agg_span_gouraud.h diff --git a/extern/agg24/include/agg_span_gouraud_gray.h b/extern/agg24-svn/include/agg_span_gouraud_gray.h similarity index 100% rename from extern/agg24/include/agg_span_gouraud_gray.h rename to extern/agg24-svn/include/agg_span_gouraud_gray.h diff --git a/extern/agg24/include/agg_span_gouraud_rgba.h b/extern/agg24-svn/include/agg_span_gouraud_rgba.h similarity index 100% rename from extern/agg24/include/agg_span_gouraud_rgba.h rename to extern/agg24-svn/include/agg_span_gouraud_rgba.h diff --git a/extern/agg24/include/agg_span_gradient.h b/extern/agg24-svn/include/agg_span_gradient.h similarity index 100% rename from extern/agg24/include/agg_span_gradient.h rename to extern/agg24-svn/include/agg_span_gradient.h diff --git a/extern/agg24/include/agg_span_gradient_alpha.h b/extern/agg24-svn/include/agg_span_gradient_alpha.h similarity index 100% rename from extern/agg24/include/agg_span_gradient_alpha.h rename to extern/agg24-svn/include/agg_span_gradient_alpha.h diff --git a/extern/agg24/include/agg_span_gradient_contour.h b/extern/agg24-svn/include/agg_span_gradient_contour.h similarity index 100% rename from extern/agg24/include/agg_span_gradient_contour.h rename to extern/agg24-svn/include/agg_span_gradient_contour.h diff --git a/extern/agg24/include/agg_span_gradient_image.h b/extern/agg24-svn/include/agg_span_gradient_image.h similarity index 100% rename from extern/agg24/include/agg_span_gradient_image.h rename to extern/agg24-svn/include/agg_span_gradient_image.h diff --git a/extern/agg24/include/agg_span_image_filter.h b/extern/agg24-svn/include/agg_span_image_filter.h similarity index 100% rename from extern/agg24/include/agg_span_image_filter.h rename to extern/agg24-svn/include/agg_span_image_filter.h diff --git a/extern/agg24/include/agg_span_image_filter_gray.h b/extern/agg24-svn/include/agg_span_image_filter_gray.h similarity index 100% rename from extern/agg24/include/agg_span_image_filter_gray.h rename to extern/agg24-svn/include/agg_span_image_filter_gray.h diff --git a/extern/agg24/include/agg_span_image_filter_rgb.h b/extern/agg24-svn/include/agg_span_image_filter_rgb.h similarity index 100% rename from extern/agg24/include/agg_span_image_filter_rgb.h rename to extern/agg24-svn/include/agg_span_image_filter_rgb.h diff --git a/extern/agg24/include/agg_span_image_filter_rgba.h b/extern/agg24-svn/include/agg_span_image_filter_rgba.h similarity index 100% rename from extern/agg24/include/agg_span_image_filter_rgba.h rename to extern/agg24-svn/include/agg_span_image_filter_rgba.h diff --git a/extern/agg24/include/agg_span_interpolator_adaptor.h b/extern/agg24-svn/include/agg_span_interpolator_adaptor.h similarity index 100% rename from extern/agg24/include/agg_span_interpolator_adaptor.h rename to extern/agg24-svn/include/agg_span_interpolator_adaptor.h diff --git a/extern/agg24/include/agg_span_interpolator_linear.h b/extern/agg24-svn/include/agg_span_interpolator_linear.h similarity index 100% rename from extern/agg24/include/agg_span_interpolator_linear.h rename to extern/agg24-svn/include/agg_span_interpolator_linear.h diff --git a/extern/agg24/include/agg_span_interpolator_persp.h b/extern/agg24-svn/include/agg_span_interpolator_persp.h similarity index 100% rename from extern/agg24/include/agg_span_interpolator_persp.h rename to extern/agg24-svn/include/agg_span_interpolator_persp.h diff --git a/extern/agg24/include/agg_span_interpolator_trans.h b/extern/agg24-svn/include/agg_span_interpolator_trans.h similarity index 100% rename from extern/agg24/include/agg_span_interpolator_trans.h rename to extern/agg24-svn/include/agg_span_interpolator_trans.h diff --git a/extern/agg24/include/agg_span_pattern_gray.h b/extern/agg24-svn/include/agg_span_pattern_gray.h similarity index 100% rename from extern/agg24/include/agg_span_pattern_gray.h rename to extern/agg24-svn/include/agg_span_pattern_gray.h diff --git a/extern/agg24/include/agg_span_pattern_rgb.h b/extern/agg24-svn/include/agg_span_pattern_rgb.h similarity index 100% rename from extern/agg24/include/agg_span_pattern_rgb.h rename to extern/agg24-svn/include/agg_span_pattern_rgb.h diff --git a/extern/agg24/include/agg_span_pattern_rgba.h b/extern/agg24-svn/include/agg_span_pattern_rgba.h similarity index 100% rename from extern/agg24/include/agg_span_pattern_rgba.h rename to extern/agg24-svn/include/agg_span_pattern_rgba.h diff --git a/extern/agg24/include/agg_span_solid.h b/extern/agg24-svn/include/agg_span_solid.h similarity index 100% rename from extern/agg24/include/agg_span_solid.h rename to extern/agg24-svn/include/agg_span_solid.h diff --git a/extern/agg24/include/agg_span_subdiv_adaptor.h b/extern/agg24-svn/include/agg_span_subdiv_adaptor.h similarity index 100% rename from extern/agg24/include/agg_span_subdiv_adaptor.h rename to extern/agg24-svn/include/agg_span_subdiv_adaptor.h diff --git a/extern/agg24/include/agg_trans_affine.h b/extern/agg24-svn/include/agg_trans_affine.h similarity index 100% rename from extern/agg24/include/agg_trans_affine.h rename to extern/agg24-svn/include/agg_trans_affine.h diff --git a/extern/agg24/include/agg_trans_bilinear.h b/extern/agg24-svn/include/agg_trans_bilinear.h similarity index 100% rename from extern/agg24/include/agg_trans_bilinear.h rename to extern/agg24-svn/include/agg_trans_bilinear.h diff --git a/extern/agg24/include/agg_trans_double_path.h b/extern/agg24-svn/include/agg_trans_double_path.h similarity index 100% rename from extern/agg24/include/agg_trans_double_path.h rename to extern/agg24-svn/include/agg_trans_double_path.h diff --git a/extern/agg24/include/agg_trans_perspective.h b/extern/agg24-svn/include/agg_trans_perspective.h similarity index 100% rename from extern/agg24/include/agg_trans_perspective.h rename to extern/agg24-svn/include/agg_trans_perspective.h diff --git a/extern/agg24/include/agg_trans_single_path.h b/extern/agg24-svn/include/agg_trans_single_path.h similarity index 100% rename from extern/agg24/include/agg_trans_single_path.h rename to extern/agg24-svn/include/agg_trans_single_path.h diff --git a/extern/agg24/include/agg_trans_viewport.h b/extern/agg24-svn/include/agg_trans_viewport.h similarity index 100% rename from extern/agg24/include/agg_trans_viewport.h rename to extern/agg24-svn/include/agg_trans_viewport.h diff --git a/extern/agg24/include/agg_trans_warp_magnifier.h b/extern/agg24-svn/include/agg_trans_warp_magnifier.h similarity index 100% rename from extern/agg24/include/agg_trans_warp_magnifier.h rename to extern/agg24-svn/include/agg_trans_warp_magnifier.h diff --git a/extern/agg24/include/agg_vcgen_bspline.h b/extern/agg24-svn/include/agg_vcgen_bspline.h similarity index 100% rename from extern/agg24/include/agg_vcgen_bspline.h rename to extern/agg24-svn/include/agg_vcgen_bspline.h diff --git a/extern/agg24/include/agg_vcgen_contour.h b/extern/agg24-svn/include/agg_vcgen_contour.h similarity index 100% rename from extern/agg24/include/agg_vcgen_contour.h rename to extern/agg24-svn/include/agg_vcgen_contour.h diff --git a/extern/agg24/include/agg_vcgen_dash.h b/extern/agg24-svn/include/agg_vcgen_dash.h similarity index 100% rename from extern/agg24/include/agg_vcgen_dash.h rename to extern/agg24-svn/include/agg_vcgen_dash.h diff --git a/extern/agg24/include/agg_vcgen_markers_term.h b/extern/agg24-svn/include/agg_vcgen_markers_term.h similarity index 100% rename from extern/agg24/include/agg_vcgen_markers_term.h rename to extern/agg24-svn/include/agg_vcgen_markers_term.h diff --git a/extern/agg24/include/agg_vcgen_smooth_poly1.h b/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h similarity index 100% rename from extern/agg24/include/agg_vcgen_smooth_poly1.h rename to extern/agg24-svn/include/agg_vcgen_smooth_poly1.h diff --git a/extern/agg24/include/agg_vcgen_stroke.h b/extern/agg24-svn/include/agg_vcgen_stroke.h similarity index 100% rename from extern/agg24/include/agg_vcgen_stroke.h rename to extern/agg24-svn/include/agg_vcgen_stroke.h diff --git a/extern/agg24/include/agg_vcgen_vertex_sequence.h b/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h similarity index 100% rename from extern/agg24/include/agg_vcgen_vertex_sequence.h rename to extern/agg24-svn/include/agg_vcgen_vertex_sequence.h diff --git a/extern/agg24/include/agg_vertex_sequence.h b/extern/agg24-svn/include/agg_vertex_sequence.h similarity index 100% rename from extern/agg24/include/agg_vertex_sequence.h rename to extern/agg24-svn/include/agg_vertex_sequence.h diff --git a/extern/agg24/include/agg_vpgen_clip_polygon.h b/extern/agg24-svn/include/agg_vpgen_clip_polygon.h similarity index 100% rename from extern/agg24/include/agg_vpgen_clip_polygon.h rename to extern/agg24-svn/include/agg_vpgen_clip_polygon.h diff --git a/extern/agg24/include/agg_vpgen_clip_polyline.h b/extern/agg24-svn/include/agg_vpgen_clip_polyline.h similarity index 100% rename from extern/agg24/include/agg_vpgen_clip_polyline.h rename to extern/agg24-svn/include/agg_vpgen_clip_polyline.h diff --git a/extern/agg24/include/agg_vpgen_segmentator.h b/extern/agg24-svn/include/agg_vpgen_segmentator.h similarity index 100% rename from extern/agg24/include/agg_vpgen_segmentator.h rename to extern/agg24-svn/include/agg_vpgen_segmentator.h diff --git a/extern/agg24/include/ctrl/agg_bezier_ctrl.h b/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h similarity index 100% rename from extern/agg24/include/ctrl/agg_bezier_ctrl.h rename to extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h diff --git a/extern/agg24/include/ctrl/agg_cbox_ctrl.h b/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h similarity index 100% rename from extern/agg24/include/ctrl/agg_cbox_ctrl.h rename to extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h diff --git a/extern/agg24/include/ctrl/agg_ctrl.h b/extern/agg24-svn/include/ctrl/agg_ctrl.h similarity index 100% rename from extern/agg24/include/ctrl/agg_ctrl.h rename to extern/agg24-svn/include/ctrl/agg_ctrl.h diff --git a/extern/agg24/include/ctrl/agg_gamma_ctrl.h b/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h similarity index 100% rename from extern/agg24/include/ctrl/agg_gamma_ctrl.h rename to extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h diff --git a/extern/agg24/include/ctrl/agg_gamma_spline.h b/extern/agg24-svn/include/ctrl/agg_gamma_spline.h similarity index 100% rename from extern/agg24/include/ctrl/agg_gamma_spline.h rename to extern/agg24-svn/include/ctrl/agg_gamma_spline.h diff --git a/extern/agg24/include/ctrl/agg_polygon_ctrl.h b/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h similarity index 100% rename from extern/agg24/include/ctrl/agg_polygon_ctrl.h rename to extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h diff --git a/extern/agg24/include/ctrl/agg_rbox_ctrl.h b/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h similarity index 100% rename from extern/agg24/include/ctrl/agg_rbox_ctrl.h rename to extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h diff --git a/extern/agg24/include/ctrl/agg_scale_ctrl.h b/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h similarity index 100% rename from extern/agg24/include/ctrl/agg_scale_ctrl.h rename to extern/agg24-svn/include/ctrl/agg_scale_ctrl.h diff --git a/extern/agg24/include/ctrl/agg_slider_ctrl.h b/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h similarity index 100% rename from extern/agg24/include/ctrl/agg_slider_ctrl.h rename to extern/agg24-svn/include/ctrl/agg_slider_ctrl.h diff --git a/extern/agg24/include/ctrl/agg_spline_ctrl.h b/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h similarity index 100% rename from extern/agg24/include/ctrl/agg_spline_ctrl.h rename to extern/agg24-svn/include/ctrl/agg_spline_ctrl.h diff --git a/extern/agg24/include/platform/agg_platform_support.h b/extern/agg24-svn/include/platform/agg_platform_support.h similarity index 100% rename from extern/agg24/include/platform/agg_platform_support.h rename to extern/agg24-svn/include/platform/agg_platform_support.h diff --git a/extern/agg24/include/platform/mac/agg_mac_pmap.h b/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h similarity index 100% rename from extern/agg24/include/platform/mac/agg_mac_pmap.h rename to extern/agg24-svn/include/platform/mac/agg_mac_pmap.h diff --git a/extern/agg24/include/platform/win32/agg_win32_bmp.h b/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h similarity index 100% rename from extern/agg24/include/platform/win32/agg_win32_bmp.h rename to extern/agg24-svn/include/platform/win32/agg_win32_bmp.h diff --git a/extern/agg24/include/util/agg_color_conv.h b/extern/agg24-svn/include/util/agg_color_conv.h similarity index 100% rename from extern/agg24/include/util/agg_color_conv.h rename to extern/agg24-svn/include/util/agg_color_conv.h diff --git a/extern/agg24/include/util/agg_color_conv_rgb16.h b/extern/agg24-svn/include/util/agg_color_conv_rgb16.h similarity index 100% rename from extern/agg24/include/util/agg_color_conv_rgb16.h rename to extern/agg24-svn/include/util/agg_color_conv_rgb16.h diff --git a/extern/agg24/include/util/agg_color_conv_rgb8.h b/extern/agg24-svn/include/util/agg_color_conv_rgb8.h similarity index 100% rename from extern/agg24/include/util/agg_color_conv_rgb8.h rename to extern/agg24-svn/include/util/agg_color_conv_rgb8.h diff --git a/extern/agg24/src/ChangeLog b/extern/agg24-svn/src/ChangeLog similarity index 100% rename from extern/agg24/src/ChangeLog rename to extern/agg24-svn/src/ChangeLog diff --git a/extern/agg24/src/agg_arc.cpp b/extern/agg24-svn/src/agg_arc.cpp similarity index 100% rename from extern/agg24/src/agg_arc.cpp rename to extern/agg24-svn/src/agg_arc.cpp diff --git a/extern/agg24/src/agg_arrowhead.cpp b/extern/agg24-svn/src/agg_arrowhead.cpp similarity index 100% rename from extern/agg24/src/agg_arrowhead.cpp rename to extern/agg24-svn/src/agg_arrowhead.cpp diff --git a/extern/agg24/src/agg_bezier_arc.cpp b/extern/agg24-svn/src/agg_bezier_arc.cpp similarity index 100% rename from extern/agg24/src/agg_bezier_arc.cpp rename to extern/agg24-svn/src/agg_bezier_arc.cpp diff --git a/extern/agg24/src/agg_bspline.cpp b/extern/agg24-svn/src/agg_bspline.cpp similarity index 100% rename from extern/agg24/src/agg_bspline.cpp rename to extern/agg24-svn/src/agg_bspline.cpp diff --git a/extern/agg24/src/agg_color_rgba.cpp b/extern/agg24-svn/src/agg_color_rgba.cpp similarity index 100% rename from extern/agg24/src/agg_color_rgba.cpp rename to extern/agg24-svn/src/agg_color_rgba.cpp diff --git a/extern/agg24/src/agg_curves.cpp b/extern/agg24-svn/src/agg_curves.cpp similarity index 100% rename from extern/agg24/src/agg_curves.cpp rename to extern/agg24-svn/src/agg_curves.cpp diff --git a/extern/agg24/src/agg_embedded_raster_fonts.cpp b/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp similarity index 100% rename from extern/agg24/src/agg_embedded_raster_fonts.cpp rename to extern/agg24-svn/src/agg_embedded_raster_fonts.cpp diff --git a/extern/agg24/src/agg_gsv_text.cpp b/extern/agg24-svn/src/agg_gsv_text.cpp similarity index 100% rename from extern/agg24/src/agg_gsv_text.cpp rename to extern/agg24-svn/src/agg_gsv_text.cpp diff --git a/extern/agg24/src/agg_image_filters.cpp b/extern/agg24-svn/src/agg_image_filters.cpp similarity index 100% rename from extern/agg24/src/agg_image_filters.cpp rename to extern/agg24-svn/src/agg_image_filters.cpp diff --git a/extern/agg24/src/agg_line_aa_basics.cpp b/extern/agg24-svn/src/agg_line_aa_basics.cpp similarity index 100% rename from extern/agg24/src/agg_line_aa_basics.cpp rename to extern/agg24-svn/src/agg_line_aa_basics.cpp diff --git a/extern/agg24/src/agg_line_profile_aa.cpp b/extern/agg24-svn/src/agg_line_profile_aa.cpp similarity index 100% rename from extern/agg24/src/agg_line_profile_aa.cpp rename to extern/agg24-svn/src/agg_line_profile_aa.cpp diff --git a/extern/agg24/src/agg_rounded_rect.cpp b/extern/agg24-svn/src/agg_rounded_rect.cpp similarity index 100% rename from extern/agg24/src/agg_rounded_rect.cpp rename to extern/agg24-svn/src/agg_rounded_rect.cpp diff --git a/extern/agg24/src/agg_sqrt_tables.cpp b/extern/agg24-svn/src/agg_sqrt_tables.cpp similarity index 100% rename from extern/agg24/src/agg_sqrt_tables.cpp rename to extern/agg24-svn/src/agg_sqrt_tables.cpp diff --git a/extern/agg24/src/agg_trans_affine.cpp b/extern/agg24-svn/src/agg_trans_affine.cpp similarity index 100% rename from extern/agg24/src/agg_trans_affine.cpp rename to extern/agg24-svn/src/agg_trans_affine.cpp diff --git a/extern/agg24/src/agg_trans_double_path.cpp b/extern/agg24-svn/src/agg_trans_double_path.cpp similarity index 100% rename from extern/agg24/src/agg_trans_double_path.cpp rename to extern/agg24-svn/src/agg_trans_double_path.cpp diff --git a/extern/agg24/src/agg_trans_single_path.cpp b/extern/agg24-svn/src/agg_trans_single_path.cpp similarity index 100% rename from extern/agg24/src/agg_trans_single_path.cpp rename to extern/agg24-svn/src/agg_trans_single_path.cpp diff --git a/extern/agg24/src/agg_trans_warp_magnifier.cpp b/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp similarity index 100% rename from extern/agg24/src/agg_trans_warp_magnifier.cpp rename to extern/agg24-svn/src/agg_trans_warp_magnifier.cpp diff --git a/extern/agg24/src/agg_vcgen_bspline.cpp b/extern/agg24-svn/src/agg_vcgen_bspline.cpp similarity index 100% rename from extern/agg24/src/agg_vcgen_bspline.cpp rename to extern/agg24-svn/src/agg_vcgen_bspline.cpp diff --git a/extern/agg24/src/agg_vcgen_contour.cpp b/extern/agg24-svn/src/agg_vcgen_contour.cpp similarity index 100% rename from extern/agg24/src/agg_vcgen_contour.cpp rename to extern/agg24-svn/src/agg_vcgen_contour.cpp diff --git a/extern/agg24/src/agg_vcgen_dash.cpp b/extern/agg24-svn/src/agg_vcgen_dash.cpp similarity index 100% rename from extern/agg24/src/agg_vcgen_dash.cpp rename to extern/agg24-svn/src/agg_vcgen_dash.cpp diff --git a/extern/agg24/src/agg_vcgen_markers_term.cpp b/extern/agg24-svn/src/agg_vcgen_markers_term.cpp similarity index 100% rename from extern/agg24/src/agg_vcgen_markers_term.cpp rename to extern/agg24-svn/src/agg_vcgen_markers_term.cpp diff --git a/extern/agg24/src/agg_vcgen_smooth_poly1.cpp b/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp similarity index 100% rename from extern/agg24/src/agg_vcgen_smooth_poly1.cpp rename to extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp diff --git a/extern/agg24/src/agg_vcgen_stroke.cpp b/extern/agg24-svn/src/agg_vcgen_stroke.cpp similarity index 100% rename from extern/agg24/src/agg_vcgen_stroke.cpp rename to extern/agg24-svn/src/agg_vcgen_stroke.cpp diff --git a/extern/agg24/src/agg_vpgen_clip_polygon.cpp b/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp similarity index 100% rename from extern/agg24/src/agg_vpgen_clip_polygon.cpp rename to extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp diff --git a/extern/agg24/src/agg_vpgen_clip_polyline.cpp b/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp similarity index 100% rename from extern/agg24/src/agg_vpgen_clip_polyline.cpp rename to extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp diff --git a/extern/agg24/src/agg_vpgen_segmentator.cpp b/extern/agg24-svn/src/agg_vpgen_segmentator.cpp similarity index 100% rename from extern/agg24/src/agg_vpgen_segmentator.cpp rename to extern/agg24-svn/src/agg_vpgen_segmentator.cpp diff --git a/extern/agg24/src/authors b/extern/agg24-svn/src/authors similarity index 100% rename from extern/agg24/src/authors rename to extern/agg24-svn/src/authors diff --git a/extern/agg24/src/copying b/extern/agg24-svn/src/copying similarity index 100% rename from extern/agg24/src/copying rename to extern/agg24-svn/src/copying diff --git a/extern/agg24/src/ctrl/agg_bezier_ctrl.cpp b/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp similarity index 100% rename from extern/agg24/src/ctrl/agg_bezier_ctrl.cpp rename to extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp diff --git a/extern/agg24/src/ctrl/agg_cbox_ctrl.cpp b/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp similarity index 100% rename from extern/agg24/src/ctrl/agg_cbox_ctrl.cpp rename to extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp diff --git a/extern/agg24/src/ctrl/agg_gamma_ctrl.cpp b/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp similarity index 100% rename from extern/agg24/src/ctrl/agg_gamma_ctrl.cpp rename to extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp diff --git a/extern/agg24/src/ctrl/agg_gamma_spline.cpp b/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp similarity index 100% rename from extern/agg24/src/ctrl/agg_gamma_spline.cpp rename to extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp diff --git a/extern/agg24/src/ctrl/agg_polygon_ctrl.cpp b/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp similarity index 100% rename from extern/agg24/src/ctrl/agg_polygon_ctrl.cpp rename to extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp diff --git a/extern/agg24/src/ctrl/agg_rbox_ctrl.cpp b/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp similarity index 100% rename from extern/agg24/src/ctrl/agg_rbox_ctrl.cpp rename to extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp diff --git a/extern/agg24/src/ctrl/agg_scale_ctrl.cpp b/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp similarity index 100% rename from extern/agg24/src/ctrl/agg_scale_ctrl.cpp rename to extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp diff --git a/extern/agg24/src/ctrl/agg_slider_ctrl.cpp b/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp similarity index 100% rename from extern/agg24/src/ctrl/agg_slider_ctrl.cpp rename to extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp diff --git a/extern/agg24/src/ctrl/agg_spline_ctrl.cpp b/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp similarity index 100% rename from extern/agg24/src/ctrl/agg_spline_ctrl.cpp rename to extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp diff --git a/extern/agg24/src/platform/AmigaOS/agg_platform_support.cpp b/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp similarity index 100% rename from extern/agg24/src/platform/AmigaOS/agg_platform_support.cpp rename to extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp diff --git a/extern/agg24/src/platform/BeOS/agg_platform_support.cpp b/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp similarity index 100% rename from extern/agg24/src/platform/BeOS/agg_platform_support.cpp rename to extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp diff --git a/extern/agg24/src/platform/X11/agg_platform_support.cpp b/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp similarity index 100% rename from extern/agg24/src/platform/X11/agg_platform_support.cpp rename to extern/agg24-svn/src/platform/X11/agg_platform_support.cpp diff --git a/extern/agg24/src/platform/mac/agg_mac_pmap.cpp b/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp similarity index 100% rename from extern/agg24/src/platform/mac/agg_mac_pmap.cpp rename to extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp diff --git a/extern/agg24/src/platform/mac/agg_platform_support.cpp b/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp similarity index 100% rename from extern/agg24/src/platform/mac/agg_platform_support.cpp rename to extern/agg24-svn/src/platform/mac/agg_platform_support.cpp diff --git a/extern/agg24/src/platform/sdl/agg_platform_support.cpp b/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp similarity index 100% rename from extern/agg24/src/platform/sdl/agg_platform_support.cpp rename to extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp diff --git a/extern/agg24/src/platform/win32/agg_platform_support.cpp b/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp similarity index 100% rename from extern/agg24/src/platform/win32/agg_platform_support.cpp rename to extern/agg24-svn/src/platform/win32/agg_platform_support.cpp diff --git a/extern/agg24/src/platform/win32/agg_win32_bmp.cpp b/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp similarity index 100% rename from extern/agg24/src/platform/win32/agg_win32_bmp.cpp rename to extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp From 14448fabcebc60df7cc46ecdfa3fbf014e9566b6 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 11 Nov 2014 08:30:53 -0500 Subject: [PATCH 6/9] Use Agg workarounds in image module as well --- src/_backend_agg.h | 40 +--------------------------------------- src/_image.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 41 deletions(-) diff --git a/src/_backend_agg.h b/src/_backend_agg.h index 74fdda299644..3672c93774f2 100644 --- a/src/_backend_agg.h +++ b/src/_backend_agg.h @@ -37,45 +37,7 @@ #include "_backend_agg_basic_types.h" #include "path_converters.h" #include "array.h" - -/********************************************************************** - WORKAROUND: This class is to workaround a bug in Agg SVN where the - blending of RGBA32 pixels does not preserve enough precision -*/ - -template -struct fixed_blender_rgba_plain : agg::conv_rgba_plain -{ - typedef ColorT color_type; - typedef Order order_type; - typedef typename color_type::value_type value_type; - typedef typename color_type::calc_type calc_type; - typedef typename color_type::long_type long_type; - enum base_scale_e { base_shift = color_type::base_shift }; - - //-------------------------------------------------------------------- - static AGG_INLINE void blend_pix(value_type* p, - value_type cr, value_type cg, value_type cb, value_type alpha, agg::cover_type cover) - { - blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); - } - - //-------------------------------------------------------------------- - static AGG_INLINE void blend_pix(value_type* p, - value_type cr, value_type cg, value_type cb, value_type alpha) - { - if(alpha == 0) return; - calc_type a = p[Order::A]; - calc_type r = p[Order::R] * a; - calc_type g = p[Order::G] * a; - calc_type b = p[Order::B] * a; - a = ((alpha + a) << base_shift) - alpha * a; - p[Order::A] = (value_type)(a >> base_shift); - p[Order::R] = (value_type)((((cr << base_shift) - r) * alpha + (r << base_shift)) / a); - p[Order::G] = (value_type)((((cg << base_shift) - g) * alpha + (g << base_shift)) / a); - p[Order::B] = (value_type)((((cb << base_shift) - b) * alpha + (b << base_shift)) / a); - } -}; +#include "agg_workaround.h" /**********************************************************************/ diff --git a/src/_image.cpp b/src/_image.cpp index df670397e37d..48a8dfe4cda2 100644 --- a/src/_image.cpp +++ b/src/_image.cpp @@ -25,9 +25,12 @@ #include "_image.h" #include "mplutils.h" +#include "agg_workaround.h" -typedef agg::pixfmt_rgba32_plain pixfmt; -typedef agg::pixfmt_rgba32_pre pixfmt_pre; +typedef fixed_blender_rgba_plain fixed_blender_rgba32_plain; +typedef agg::pixfmt_alpha_blend_rgba pixfmt; +typedef fixed_blender_rgba_pre fixed_blender_rgba32_pre; +typedef agg::pixfmt_alpha_blend_rgba pixfmt_pre; typedef agg::renderer_base renderer_base; typedef agg::span_interpolator_linear<> interpolator_type; typedef agg::rasterizer_scanline_aa rasterizer; From 9b9cd1646d9a3508ae9df669e1c176c97cb8b650 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 11 Nov 2014 08:31:09 -0500 Subject: [PATCH 7/9] Update tests to more accurate results --- .../test_image/rasterize_10dpi.pdf | Bin 2638 -> 2638 bytes .../test_image/rasterize_10dpi.svg | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/tests/baseline_images/test_image/rasterize_10dpi.pdf b/lib/matplotlib/tests/baseline_images/test_image/rasterize_10dpi.pdf index 583715ea662ff6b8a844f885d74564ef2c8ae73a..486fcc0c4a000c2a1004a32d1507d8c097e72dc6 100644 GIT binary patch delta 154 zcmV;L0A>Hq6wVZ|`38S}hJf`9t>+nby=S=cAB1p-n;N75k&%6&c5IhQ^WN%_>3Ne#-2XP58F)=VWFf%bW Iv+@UA0{*&1&;S4c delta 154 zcmV;L0A>Hq6wVZ|`38Rp3;`P$S}!o{`oM7IKM3IvH#0~9A|r=Fo!Bnb>LqeB_ew86 z2}Jcp4nR~^=#iEm5uTgro>OU`-2g<#H_HIgu0`?-8`U}zbo1>@lJzWr=>Jm&AbNkC z;d~#%`cQ^`8HjxhxWoadazW<`Wo~41baG{3Z3<;>WN%_>3Ne#-2XP57F*7kRFfuYU Iv+@UA0>%eFnE(I) diff --git a/lib/matplotlib/tests/baseline_images/test_image/rasterize_10dpi.svg b/lib/matplotlib/tests/baseline_images/test_image/rasterize_10dpi.svg index b6629abd2c76..47e354dd1457 100644 --- a/lib/matplotlib/tests/baseline_images/test_image/rasterize_10dpi.svg +++ b/lib/matplotlib/tests/baseline_images/test_image/rasterize_10dpi.svg @@ -29,8 +29,8 @@ z " style="fill:#ffffff;"/> - + @@ -45,7 +45,7 @@ L86.0824 7.2 z " style="fill:#ffffff;"/> - From f5bbee2ab12af3c498b1e339ce68621e4b792e04 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 11 Nov 2014 08:59:14 -0500 Subject: [PATCH 8/9] Fix directory --- setupext.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setupext.py b/setupext.py index db1672ca6a0c..81c1463db6c0 100755 --- a/setupext.py +++ b/setupext.py @@ -856,7 +856,7 @@ def add_flags(self, ext, add_sources=True): if self.found_external: pkg_config.setup_extension(ext, 'libagg') else: - ext.include_dirs.append('extern/agg24/include') + ext.include_dirs.append('extern/agg24-svn/include') if add_sources: agg_sources = [ 'agg_bezier_arc.cpp', @@ -869,7 +869,7 @@ def add_flags(self, ext, add_sources=True): 'agg_vpgen_segmentator.cpp' ] ext.sources.extend( - os.path.join('extern', 'agg24', 'src', x) for x in agg_sources) + os.path.join('extern', 'agg24-svn', 'src', x) for x in agg_sources) class FreeType(SetupPackage): From cf80280584757ca9569596dd2dc6dc5423c7f92f Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 11 Nov 2014 09:12:11 -0500 Subject: [PATCH 9/9] Add missing file --- extern/agg24-svn/include/agg_color_gray.h | 184 ++++++++-------- extern/agg24-svn/include/agg_color_rgba.h | 250 +++++++++++----------- src/agg_workaround.h | 85 ++++++++ 3 files changed, 302 insertions(+), 217 deletions(-) create mode 100644 src/agg_workaround.h diff --git a/extern/agg24-svn/include/agg_color_gray.h b/extern/agg24-svn/include/agg_color_gray.h index 4ddee04edd45..8d5f2ed8d044 100644 --- a/extern/agg24-svn/include/agg_color_gray.h +++ b/extern/agg24-svn/include/agg_color_gray.h @@ -2,8 +2,8 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-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. +// 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. // @@ -13,12 +13,12 @@ // http://www.antigrain.com //---------------------------------------------------------------------------- // -// Adaptation for high precision colors has been sponsored by +// Adaptation for high precision colors has been sponsored by // Liberty Technology Systems, Inc., visit http://lib-sys.com // // Liberty Technology Systems, Inc. is the provider of // PostScript and PDF technology for software developers. -// +// //---------------------------------------------------------------------------- // // color types gray8, gray16 @@ -132,82 +132,82 @@ namespace agg } //-------------------------------------------------------------------- - template - T convert_from_sRGB() const + template + T convert_from_sRGB() const { typename T::value_type y = sRGB_conv::rgb_from_sRGB(v); return T(y, y, y, sRGB_conv::alpha_from_sRGB(a)); } - template - T convert_to_sRGB() const + template + T convert_to_sRGB() const { typename T::value_type y = sRGB_conv::rgb_to_sRGB(v); return T(y, y, y, sRGB_conv::alpha_to_sRGB(a)); } //-------------------------------------------------------------------- - rgba8 make_rgba8(const linear&) const + rgba8 make_rgba8(const linear&) const { return rgba8(v, v, v, a); } - rgba8 make_rgba8(const sRGB&) const + rgba8 make_rgba8(const sRGB&) const { return convert_from_sRGB(); } - operator rgba8() const + operator rgba8() const { return make_rgba8(Colorspace()); } //-------------------------------------------------------------------- - srgba8 make_srgba8(const linear&) const + srgba8 make_srgba8(const linear&) const { return convert_to_sRGB(); } - srgba8 make_srgba8(const sRGB&) const + srgba8 make_srgba8(const sRGB&) const { return srgba8(v, v, v, a); } - operator srgba8() const + operator srgba8() const { return make_rgba8(Colorspace()); } //-------------------------------------------------------------------- - rgba16 make_rgba16(const linear&) const + rgba16 make_rgba16(const linear&) const { rgba16::value_type rgb = (v << 8) | v; return rgba16(rgb, rgb, rgb, (a << 8) | a); } - rgba16 make_rgba16(const sRGB&) const + rgba16 make_rgba16(const sRGB&) const { return convert_from_sRGB(); } - operator rgba16() const + operator rgba16() const { return make_rgba16(Colorspace()); } //-------------------------------------------------------------------- - rgba32 make_rgba32(const linear&) const + rgba32 make_rgba32(const linear&) const { rgba32::value_type v32 = v / 255.0f; return rgba32(v32, v32, v32, a / 255.0f); } - rgba32 make_rgba32(const sRGB&) const + rgba32 make_rgba32(const sRGB&) const { return convert_from_sRGB(); } - operator rgba32() const + operator rgba32() const { return make_rgba32(Colorspace()); } @@ -250,14 +250,14 @@ namespace agg //-------------------------------------------------------------------- // Fixed-point multiply, exact over int8u. - static AGG_INLINE value_type multiply(value_type a, value_type b) + static AGG_INLINE value_type multiply(value_type a, value_type b) { calc_type t = a * b + base_MSB; return value_type(((t >> base_shift) + t) >> base_shift); } - + //-------------------------------------------------------------------- - static AGG_INLINE value_type demultiply(value_type a, value_type b) + static AGG_INLINE value_type demultiply(value_type a, value_type b) { if (a * b == 0) { @@ -267,19 +267,19 @@ namespace agg { return base_mask; } - else return value_type((a * base_mask + (b >> 1)) / b); + else return value_type((a * base_mask + (b >> 1)) / b); } //-------------------------------------------------------------------- template - static AGG_INLINE T downscale(T a) + static AGG_INLINE T downscale(T a) { return a >> base_shift; } //-------------------------------------------------------------------- template - static AGG_INLINE T downshift(T a, unsigned n) + static AGG_INLINE T downshift(T a, unsigned n) { return a >> n; } @@ -287,32 +287,32 @@ namespace agg //-------------------------------------------------------------------- // Fixed-point multiply, exact over int8u. // Specifically for multiplying a color component by a cover. - static AGG_INLINE value_type mult_cover(value_type a, value_type b) + static AGG_INLINE value_type mult_cover(value_type a, value_type b) { return multiply(a, b); } - + //-------------------------------------------------------------------- - static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return multiply(b, a); } - + //-------------------------------------------------------------------- // Interpolate p to q by a, assuming q is premultiplied by a. - static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return p + q - multiply(p, a); } - + //-------------------------------------------------------------------- // Interpolate p to q by a. - static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) { int t = (q - p) * a + base_MSB - (p > q); return value_type(p + (((t >> base_shift) + t) >> base_shift)); } - + //-------------------------------------------------------------------- self_type& clear() { @@ -330,8 +330,8 @@ namespace agg //-------------------------------------------------------------------- self_type& opacity(double a_) { - if (a_ < 0) a_ = 0; - else if (a_ > 1) a_ = 1; + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; else a = (value_type)uround(a_ * double(base_mask)); return *this; } @@ -341,7 +341,7 @@ namespace agg { return double(a) / double(base_mask); } - + //-------------------------------------------------------------------- self_type& premultiply() { @@ -387,15 +387,15 @@ namespace agg calc_type cv, ca; if (cover == cover_mask) { - if (c.a == base_mask) + if (c.a == base_mask) { *this = c; return; } else { - cv = v + c.v; - ca = a + c.a; + cv = v + c.v; + ca = a + c.a; } } else @@ -490,7 +490,7 @@ namespace agg gray16(const rgba16& c) : v(luminance(c)), a(c.a) {} - + //-------------------------------------------------------------------- gray16(const gray8& c) : v((value_type(c.v) << 8) | c.v), @@ -502,20 +502,20 @@ namespace agg a(sRGB_conv::alpha_from_sRGB(c.a)) {} //-------------------------------------------------------------------- - operator rgba8() const + operator rgba8() const { return rgba8(v >> 8, v >> 8, v >> 8, a >> 8); } //-------------------------------------------------------------------- - operator srgba8() const + operator srgba8() const { value_type y = sRGB_conv::rgb_to_sRGB(v); return srgba8(y, y, y, sRGB_conv::alpha_to_sRGB(a)); } //-------------------------------------------------------------------- - operator rgba16() const + operator rgba16() const { return rgba16(v, v, v, a); } @@ -528,16 +528,16 @@ namespace agg } //-------------------------------------------------------------------- - operator gray8() const + operator gray8() const { return gray8(v >> 8, a >> 8); } //-------------------------------------------------------------------- - operator sgray8() const + operator sgray8() const { return sgray8( - sRGB_conv::rgb_to_sRGB(v), + sRGB_conv::rgb_to_sRGB(v), sRGB_conv::alpha_to_sRGB(a)); } @@ -579,14 +579,14 @@ namespace agg //-------------------------------------------------------------------- // Fixed-point multiply, exact over int16u. - static AGG_INLINE value_type multiply(value_type a, value_type b) + static AGG_INLINE value_type multiply(value_type a, value_type b) { calc_type t = a * b + base_MSB; return value_type(((t >> base_shift) + t) >> base_shift); } - + //-------------------------------------------------------------------- - static AGG_INLINE value_type demultiply(value_type a, value_type b) + static AGG_INLINE value_type demultiply(value_type a, value_type b) { if (a * b == 0) { @@ -596,19 +596,19 @@ namespace agg { return base_mask; } - else return value_type((a * base_mask + (b >> 1)) / b); + else return value_type((a * base_mask + (b >> 1)) / b); } //-------------------------------------------------------------------- template - static AGG_INLINE T downscale(T a) + static AGG_INLINE T downscale(T a) { return a >> base_shift; } //-------------------------------------------------------------------- template - static AGG_INLINE T downshift(T a, unsigned n) + static AGG_INLINE T downshift(T a, unsigned n) { return a >> n; } @@ -616,32 +616,32 @@ namespace agg //-------------------------------------------------------------------- // Fixed-point multiply, almost exact over int16u. // Specifically for multiplying a color component by a cover. - static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return multiply(a, b << 8 | b); } - + //-------------------------------------------------------------------- - static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return mult_cover(b, a) >> 8; } - + //-------------------------------------------------------------------- // Interpolate p to q by a, assuming q is premultiplied by a. - static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return p + q - multiply(p, a); } - + //-------------------------------------------------------------------- // Interpolate p to q by a. - static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) { int t = (q - p) * a + base_MSB - (p > q); return value_type(p + (((t >> base_shift) + t) >> base_shift)); } - + //-------------------------------------------------------------------- self_type& clear() { @@ -659,8 +659,8 @@ namespace agg //-------------------------------------------------------------------- self_type& opacity(double a_) { - if (a_ < 0) a_ = 0; - else if(a_ > 1) a_ = 1; + if (a_ < 0) a = 0; + else if(a_ > 1) a = 1; else a = (value_type)uround(a_ * double(base_mask)); return *this; } @@ -717,15 +717,15 @@ namespace agg calc_type cv, ca; if (cover == cover_mask) { - if (c.a == base_mask) + if (c.a == base_mask) { *this = c; return; } else { - cv = v + c.v; - ca = a + c.a; + cv = v + c.v; + ca = a + c.a; } } else @@ -817,55 +817,55 @@ namespace agg //-------------------------------------------------------------------- gray32(const gray8& c) : - v(value_type(c.v / 255.0)), + v(value_type(c.v / 255.0)), a(value_type(c.a / 255.0)) {} //-------------------------------------------------------------------- gray32(const sgray8& c) : - v(sRGB_conv::rgb_from_sRGB(c.v)), + v(sRGB_conv::rgb_from_sRGB(c.v)), a(sRGB_conv::alpha_from_sRGB(c.a)) {} //-------------------------------------------------------------------- gray32(const gray16& c) : - v(value_type(c.v / 65535.0)), + v(value_type(c.v / 65535.0)), a(value_type(c.a / 65535.0)) {} //-------------------------------------------------------------------- - operator rgba() const + operator rgba() const { return rgba(v, v, v, a); } //-------------------------------------------------------------------- - operator gray8() const + operator gray8() const { return gray8(uround(v * 255.0), uround(a * 255.0)); } //-------------------------------------------------------------------- - operator sgray8() const + operator sgray8() const { // Return (non-premultiplied) sRGB values. return sgray8( - sRGB_conv::rgb_to_sRGB(v), + sRGB_conv::rgb_to_sRGB(v), sRGB_conv::alpha_to_sRGB(a)); } //-------------------------------------------------------------------- - operator gray16() const + operator gray16() const { return gray16(uround(v * 65535.0), uround(a * 65535.0)); } //-------------------------------------------------------------------- - operator rgba8() const + operator rgba8() const { rgba8::value_type y = uround(v * 255.0); return rgba8(y, y, y, uround(a * 255.0)); } //-------------------------------------------------------------------- - operator srgba8() const + operator srgba8() const { srgba8::value_type y = sRGB_conv::rgb_to_sRGB(v); return srgba8(y, y, y, sRGB_conv::alpha_to_sRGB(a)); @@ -921,67 +921,67 @@ namespace agg } //-------------------------------------------------------------------- - static AGG_INLINE value_type invert(value_type x) + static AGG_INLINE value_type invert(value_type x) { return 1 - x; } //-------------------------------------------------------------------- - static AGG_INLINE value_type multiply(value_type a, value_type b) + static AGG_INLINE value_type multiply(value_type a, value_type b) { return value_type(a * b); } //-------------------------------------------------------------------- - static AGG_INLINE value_type demultiply(value_type a, value_type b) + static AGG_INLINE value_type demultiply(value_type a, value_type b) { return (b == 0) ? 0 : value_type(a / b); } //-------------------------------------------------------------------- template - static AGG_INLINE T downscale(T a) + static AGG_INLINE T downscale(T a) { return a; } //-------------------------------------------------------------------- template - static AGG_INLINE T downshift(T a, unsigned n) + static AGG_INLINE T downshift(T a, unsigned n) { return n > 0 ? a / (1 << n) : a; } //-------------------------------------------------------------------- - static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return value_type(a * b / cover_mask); } //-------------------------------------------------------------------- - static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return cover_type(uround(a * b)); } - + //-------------------------------------------------------------------- // Interpolate p to q by a, assuming q is premultiplied by a. - static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return (1 - a) * p + q; // more accurate than "p + q - p * a" } - + //-------------------------------------------------------------------- // Interpolate p to q by a. - static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) { - // The form "p + a * (q - p)" avoids a multiplication, but may produce an - // inaccurate result. For example, "p + (q - p)" may not be exactly equal - // to q. Therefore, stick to the basic expression, which at least produces + // The form "p + a * (q - p)" avoids a multiplication, but may produce an + // inaccurate result. For example, "p + (q - p)" may not be exactly equal + // to q. Therefore, stick to the basic expression, which at least produces // the correct result at either extreme. return (1 - a) * p + a * q; } - + //-------------------------------------------------------------------- self_type& clear() { @@ -1032,7 +1032,7 @@ namespace agg self_type gradient(self_type c, double k) const { return self_type( - value_type(v + (c.v - v) * k), + value_type(v + (c.v - v) * k), value_type(a + (c.a - a) * k)); } diff --git a/extern/agg24-svn/include/agg_color_rgba.h b/extern/agg24-svn/include/agg_color_rgba.h index d8ef69a74fd9..74f871be17b9 100644 --- a/extern/agg24-svn/include/agg_color_rgba.h +++ b/extern/agg24-svn/include/agg_color_rgba.h @@ -2,19 +2,19 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-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. +// 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. // //---------------------------------------------------------------------------- // -// Adaptation for high precision colors has been sponsored by +// Adaptation for high precision colors has been sponsored by // Liberty Technology Systems, Inc., visit http://lib-sys.com // // Liberty Technology Systems, Inc. is the provider of // PostScript and PDF technology for software developers. -// +// //---------------------------------------------------------------------------- // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com @@ -80,8 +80,8 @@ namespace agg //-------------------------------------------------------------------- rgba& opacity(double a_) { - if (a_ < 0) a_ = 0; - else if (a_ > 1) a_ = 1; + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; else a = a_; return *this; } @@ -171,7 +171,7 @@ namespace agg //-------------------------------------------------------------------- static rgba from_wavelength(double wl, double gamma = 1.0); - + //-------------------------------------------------------------------- explicit rgba(double wavelen, double gamma=1.0) { @@ -240,7 +240,7 @@ namespace agg return rgba(r, g, b, a).premultiply(); } - + //===================================================================rgba8 template struct rgba8T @@ -318,9 +318,9 @@ namespace agg //-------------------------------------------------------------------- rgba8T(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask) : - r(value_type(r_)), - g(value_type(g_)), - b(value_type(b_)), + r(value_type(r_)), + g(value_type(g_)), + b(value_type(b_)), a(value_type(a_)) {} //-------------------------------------------------------------------- @@ -341,7 +341,7 @@ namespace agg } //-------------------------------------------------------------------- - operator rgba() const + operator rgba() const { rgba c; convert(c, *this); @@ -385,21 +385,21 @@ namespace agg } //-------------------------------------------------------------------- - static AGG_INLINE value_type invert(value_type x) + static AGG_INLINE value_type invert(value_type x) { return base_mask - x; } //-------------------------------------------------------------------- // Fixed-point multiply, exact over int8u. - static AGG_INLINE value_type multiply(value_type a, value_type b) + static AGG_INLINE value_type multiply(value_type a, value_type b) { calc_type t = a * b + base_MSB; return value_type(((t >> base_shift) + t) >> base_shift); } - + //-------------------------------------------------------------------- - static AGG_INLINE value_type demultiply(value_type a, value_type b) + static AGG_INLINE value_type demultiply(value_type a, value_type b) { if (a * b == 0) { @@ -409,19 +409,19 @@ namespace agg { return base_mask; } - else return value_type((a * base_mask + (b >> 1)) / b); + else return value_type((a * base_mask + (b >> 1)) / b); } //-------------------------------------------------------------------- template - static AGG_INLINE T downscale(T a) + static AGG_INLINE T downscale(T a) { return a >> base_shift; } //-------------------------------------------------------------------- template - static AGG_INLINE T downshift(T a, unsigned n) + static AGG_INLINE T downshift(T a, unsigned n) { return a >> n; } @@ -429,39 +429,39 @@ namespace agg //-------------------------------------------------------------------- // Fixed-point multiply, exact over int8u. // Specifically for multiplying a color component by a cover. - static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return multiply(a, b); } - + //-------------------------------------------------------------------- - static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return multiply(b, a); } - + //-------------------------------------------------------------------- // Interpolate p to q by a, assuming q is premultiplied by a. - static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return p + q - multiply(p, a); } - + //-------------------------------------------------------------------- // Interpolate p to q by a. - static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) { int t = (q - p) * a + base_MSB - (p > q); return value_type(p + (((t >> base_shift) + t) >> base_shift)); } - + //-------------------------------------------------------------------- self_type& clear() { r = g = b = a = 0; return *this; } - + //-------------------------------------------------------------------- self_type& transparent() { @@ -472,8 +472,8 @@ namespace agg //-------------------------------------------------------------------- self_type& opacity(double a_) { - if (a_ < 0) a_ = 0; - else if (a_ > 1) a_ = 1; + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; else a = (value_type)uround(a_ * double(base_mask)); return *this; } @@ -566,17 +566,17 @@ namespace agg calc_type cr, cg, cb, ca; if (cover == cover_mask) { - if (c.a == base_mask) + if (c.a == base_mask) { *this = c; return; } else { - cr = r + c.r; - cg = g + c.g; - cb = b + c.b; - ca = a + c.a; + cr = r + c.r; + cg = g + c.g; + cb = b + c.b; + ca = a + c.a; } } else @@ -683,9 +683,9 @@ namespace agg //-------------------------------------------------------------------- rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) : - r(value_type(r_)), - g(value_type(g_)), - b(value_type(b_)), + r(value_type(r_)), + g(value_type(g_)), + b(value_type(b_)), a(value_type(a_)) {} //-------------------------------------------------------------------- @@ -694,49 +694,49 @@ namespace agg //-------------------------------------------------------------------- rgba16(const rgba& c) : - r((value_type)uround(c.r * double(base_mask))), - g((value_type)uround(c.g * double(base_mask))), - b((value_type)uround(c.b * double(base_mask))), + r((value_type)uround(c.r * double(base_mask))), + g((value_type)uround(c.g * double(base_mask))), + b((value_type)uround(c.b * double(base_mask))), a((value_type)uround(c.a * double(base_mask))) {} //-------------------------------------------------------------------- rgba16(const rgba8& c) : - r(value_type((value_type(c.r) << 8) | c.r)), - g(value_type((value_type(c.g) << 8) | c.g)), - b(value_type((value_type(c.b) << 8) | c.b)), + r(value_type((value_type(c.r) << 8) | c.r)), + g(value_type((value_type(c.g) << 8) | c.g)), + b(value_type((value_type(c.b) << 8) | c.b)), a(value_type((value_type(c.a) << 8) | c.a)) {} //-------------------------------------------------------------------- rgba16(const srgba8& c) : - r(sRGB_conv::rgb_from_sRGB(c.r)), - g(sRGB_conv::rgb_from_sRGB(c.g)), - b(sRGB_conv::rgb_from_sRGB(c.b)), + r(sRGB_conv::rgb_from_sRGB(c.r)), + g(sRGB_conv::rgb_from_sRGB(c.g)), + b(sRGB_conv::rgb_from_sRGB(c.b)), a(sRGB_conv::alpha_from_sRGB(c.a)) {} //-------------------------------------------------------------------- - operator rgba() const + operator rgba() const { return rgba( - r / 65535.0, - g / 65535.0, - b / 65535.0, + r / 65535.0, + g / 65535.0, + b / 65535.0, a / 65535.0); } //-------------------------------------------------------------------- - operator rgba8() const + operator rgba8() const { return rgba8(r >> 8, g >> 8, b >> 8, a >> 8); } //-------------------------------------------------------------------- - operator srgba8() const + operator srgba8() const { // Return (non-premultiplied) sRGB values. return srgba8( - sRGB_conv::rgb_to_sRGB(r), - sRGB_conv::rgb_to_sRGB(g), - sRGB_conv::rgb_to_sRGB(b), + sRGB_conv::rgb_to_sRGB(r), + sRGB_conv::rgb_to_sRGB(g), + sRGB_conv::rgb_to_sRGB(b), sRGB_conv::alpha_to_sRGB(a)); } @@ -777,21 +777,21 @@ namespace agg } //-------------------------------------------------------------------- - static AGG_INLINE value_type invert(value_type x) + static AGG_INLINE value_type invert(value_type x) { return base_mask - x; } //-------------------------------------------------------------------- // Fixed-point multiply, exact over int16u. - static AGG_INLINE value_type multiply(value_type a, value_type b) + static AGG_INLINE value_type multiply(value_type a, value_type b) { calc_type t = a * b + base_MSB; return value_type(((t >> base_shift) + t) >> base_shift); } - + //-------------------------------------------------------------------- - static AGG_INLINE value_type demultiply(value_type a, value_type b) + static AGG_INLINE value_type demultiply(value_type a, value_type b) { if (a * b == 0) { @@ -801,19 +801,19 @@ namespace agg { return base_mask; } - else return value_type((a * base_mask + (b >> 1)) / b); + else return value_type((a * base_mask + (b >> 1)) / b); } //-------------------------------------------------------------------- template - static AGG_INLINE T downscale(T a) + static AGG_INLINE T downscale(T a) { return a >> base_shift; } //-------------------------------------------------------------------- template - static AGG_INLINE T downshift(T a, unsigned n) + static AGG_INLINE T downshift(T a, unsigned n) { return a >> n; } @@ -821,39 +821,39 @@ namespace agg //-------------------------------------------------------------------- // Fixed-point multiply, almost exact over int16u. // Specifically for multiplying a color component by a cover. - static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return multiply(a, (b << 8) | b); } - + //-------------------------------------------------------------------- - static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return multiply((a << 8) | a, b) >> 8; } - + //-------------------------------------------------------------------- // Interpolate p to q by a, assuming q is premultiplied by a. - static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return p + q - multiply(p, a); } - + //-------------------------------------------------------------------- // Interpolate p to q by a. - static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) { int t = (q - p) * a + base_MSB - (p > q); return value_type(p + (((t >> base_shift) + t) >> base_shift)); } - + //-------------------------------------------------------------------- self_type& clear() { r = g = b = a = 0; return *this; } - + //-------------------------------------------------------------------- self_type& transparent() { @@ -864,8 +864,8 @@ namespace agg //-------------------------------------------------------------------- AGG_INLINE self_type& opacity(double a_) { - if (a_ < 0) a_ = 0; - if (a_ > 1) a_ = 1; + if (a_ < 0) a = 0; + if (a_ > 1) a = 1; a = value_type(uround(a_ * double(base_mask))); return *this; } @@ -879,7 +879,7 @@ namespace agg //-------------------------------------------------------------------- AGG_INLINE self_type& premultiply() { - if (a != base_mask) + if (a != base_mask) { if (a == 0) { @@ -958,17 +958,17 @@ namespace agg calc_type cr, cg, cb, ca; if (cover == cover_mask) { - if (c.a == base_mask) + if (c.a == base_mask) { *this = c; return; } else { - cr = r + c.r; - cg = g + c.g; - cb = b + c.b; - ca = a + c.a; + cr = r + c.r; + cg = g + c.g; + cb = b + c.b; + ca = a + c.a; } } else @@ -1057,58 +1057,58 @@ namespace agg //-------------------------------------------------------------------- rgba32(const rgba8& c) : - r(value_type(c.r / 255.0)), - g(value_type(c.g / 255.0)), - b(value_type(c.b / 255.0)), + r(value_type(c.r / 255.0)), + g(value_type(c.g / 255.0)), + b(value_type(c.b / 255.0)), a(value_type(c.a / 255.0)) {} //-------------------------------------------------------------------- rgba32(const srgba8& c) : - r(sRGB_conv::rgb_from_sRGB(c.r)), - g(sRGB_conv::rgb_from_sRGB(c.g)), - b(sRGB_conv::rgb_from_sRGB(c.b)), + r(sRGB_conv::rgb_from_sRGB(c.r)), + g(sRGB_conv::rgb_from_sRGB(c.g)), + b(sRGB_conv::rgb_from_sRGB(c.b)), a(sRGB_conv::alpha_from_sRGB(c.a)) {} //-------------------------------------------------------------------- rgba32(const rgba16& c) : - r(value_type(c.r / 65535.0)), - g(value_type(c.g / 65535.0)), - b(value_type(c.b / 65535.0)), + r(value_type(c.r / 65535.0)), + g(value_type(c.g / 65535.0)), + b(value_type(c.b / 65535.0)), a(value_type(c.a / 65535.0)) {} //-------------------------------------------------------------------- - operator rgba() const + operator rgba() const { return rgba(r, g, b, a); } //-------------------------------------------------------------------- - operator rgba8() const + operator rgba8() const { return rgba8( - uround(r * 255.0), - uround(g * 255.0), - uround(b * 255.0), + uround(r * 255.0), + uround(g * 255.0), + uround(b * 255.0), uround(a * 255.0)); } //-------------------------------------------------------------------- - operator srgba8() const + operator srgba8() const { return srgba8( - sRGB_conv::rgb_to_sRGB(r), - sRGB_conv::rgb_to_sRGB(g), - sRGB_conv::rgb_to_sRGB(b), + sRGB_conv::rgb_to_sRGB(r), + sRGB_conv::rgb_to_sRGB(g), + sRGB_conv::rgb_to_sRGB(b), sRGB_conv::alpha_to_sRGB(a)); } //-------------------------------------------------------------------- - operator rgba16() const + operator rgba16() const { return rgba8( - uround(r * 65535.0), - uround(g * 65535.0), - uround(b * 65535.0), + uround(r * 65535.0), + uround(g * 65535.0), + uround(b * 65535.0), uround(a * 65535.0)); } @@ -1149,74 +1149,74 @@ namespace agg } //-------------------------------------------------------------------- - static AGG_INLINE value_type invert(value_type x) + static AGG_INLINE value_type invert(value_type x) { return 1 - x; } //-------------------------------------------------------------------- - static AGG_INLINE value_type multiply(value_type a, value_type b) + static AGG_INLINE value_type multiply(value_type a, value_type b) { return value_type(a * b); } //-------------------------------------------------------------------- - static AGG_INLINE value_type demultiply(value_type a, value_type b) + static AGG_INLINE value_type demultiply(value_type a, value_type b) { return (b == 0) ? 0 : value_type(a / b); } //-------------------------------------------------------------------- template - static AGG_INLINE T downscale(T a) + static AGG_INLINE T downscale(T a) { return a; } //-------------------------------------------------------------------- template - static AGG_INLINE T downshift(T a, unsigned n) + static AGG_INLINE T downshift(T a, unsigned n) { return n > 0 ? a / (1 << n) : a; } //-------------------------------------------------------------------- - static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { return value_type(a * b / cover_mask); } //-------------------------------------------------------------------- - static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) { return cover_type(uround(a * b)); } - + //-------------------------------------------------------------------- // Interpolate p to q by a, assuming q is premultiplied by a. - static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) { return (1 - a) * p + q; // more accurate than "p + q - p * a" } - + //-------------------------------------------------------------------- // Interpolate p to q by a. - static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) { - // The form "p + a * (q - p)" avoids a multiplication, but may produce an - // inaccurate result. For example, "p + (q - p)" may not be exactly equal - // to q. Therefore, stick to the basic expression, which at least produces + // The form "p + a * (q - p)" avoids a multiplication, but may produce an + // inaccurate result. For example, "p + (q - p)" may not be exactly equal + // to q. Therefore, stick to the basic expression, which at least produces // the correct result at either extreme. return (1 - a) * p + a * q; } - + //-------------------------------------------------------------------- self_type& clear() { r = g = b = a = 0; return *this; } - + //-------------------------------------------------------------------- self_type& transparent() { @@ -1227,8 +1227,8 @@ namespace agg //-------------------------------------------------------------------- AGG_INLINE self_type& opacity(double a_) { - if (a_ < 0) a_ = 0; - else if (a_ > 1) a_ = 1; + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; else a = value_type(a_); return *this; } @@ -1293,17 +1293,17 @@ namespace agg { if (cover == cover_mask) { - if (c.is_opaque()) + if (c.is_opaque()) { *this = c; return; } else { - r += c.r; - g += c.g; - b += c.b; - a += c.a; + r += c.r; + g += c.g; + b += c.b; + a += c.a; } } else diff --git a/src/agg_workaround.h b/src/agg_workaround.h new file mode 100644 index 000000000000..bfadf39284d4 --- /dev/null +++ b/src/agg_workaround.h @@ -0,0 +1,85 @@ +#ifndef __AGG_WORKAROUND_H__ +#define __AGG_WORKAROUND_H__ + +#include "agg_pixfmt_rgba.h" + +/********************************************************************** + WORKAROUND: This class is to workaround a bug in Agg SVN where the + blending of RGBA32 pixels does not preserve enough precision +*/ + +template +struct fixed_blender_rgba_pre : agg::conv_rgba_pre +{ + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, + value_type alpha, agg::cover_type cover) + { + blend_pix(p, + color_type::mult_cover(cr, cover), + color_type::mult_cover(cg, cover), + color_type::mult_cover(cb, cover), + color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, + value_type alpha) + { + alpha = base_mask - alpha; + p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr); + p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg); + p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb); + p[Order::A] = (value_type)(base_mask - ((alpha * (base_mask - p[Order::A])) >> base_shift)); + } +}; + + +template +struct fixed_blender_rgba_plain : agg::conv_rgba_plain +{ + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e { base_shift = color_type::base_shift }; + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, agg::cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + if(alpha == 0) return; + calc_type a = p[Order::A]; + calc_type r = p[Order::R] * a; + calc_type g = p[Order::G] * a; + calc_type b = p[Order::B] * a; + a = ((alpha + a) << base_shift) - alpha * a; + p[Order::A] = (value_type)(a >> base_shift); + p[Order::R] = (value_type)((((cr << base_shift) - r) * alpha + (r << base_shift)) / a); + p[Order::G] = (value_type)((((cg << base_shift) - g) * alpha + (g << base_shift)) / a); + p[Order::B] = (value_type)((((cb << base_shift) - b) * alpha + (b << base_shift)) / a); + } +}; + +#endif