diff --git a/headers/libs/agg/agg_span_pattern_filter_rgba32.h b/headers/libs/agg/agg_span_pattern_filter_rgba32.h new file mode 100755 index 0000000000..aea103c862 --- /dev/null +++ b/headers/libs/agg/agg_span_pattern_filter_rgba32.h @@ -0,0 +1,391 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.2 +// Copyright (C) 2002-2004 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 +//---------------------------------------------------------------------------- +// +// classes span_pattern_filter_rgba32* +// +//---------------------------------------------------------------------------- +#ifndef AGG_SPAN_PATTERN_FILTER_RGBA32_INCLUDED +#define AGG_SPAN_PATTERN_FILTER_RGBA32_INCLUDED + +#include "agg_basics.h" +#include "agg_color_rgba8.h" +#include "agg_span_image_filter.h" + + +namespace agg +{ + + //===========================================span_pattern_filter_rgba32_nn + template > + class span_pattern_filter_rgba32_nn : + public span_image_filter + { + public: + typedef Interpolator interpolator_type; + typedef Allocator alloc_type; + typedef span_image_filter base_type; + typedef rgba8 color_type; + + //-------------------------------------------------------------------- + span_pattern_filter_rgba32_nn(alloc_type& alloc) : + base_type(alloc), + m_remainder_x(1), + m_remainder_y(1) + {} + + //-------------------------------------------------------------------- + span_pattern_filter_rgba32_nn(alloc_type& alloc, + const rendering_buffer& src, + interpolator_type& inter) : + base_type(alloc, src, color_type(0,0,0,0), inter, 0), + m_remainder_x(src.width()), + m_remainder_y(src.height()) + {} + + //-------------------------------------------------------------------- + void source_image(const rendering_buffer& src) + { + base_type::source_image(src); + m_remainder_x = RemainderX(src.width()); + m_remainder_y = RemainderX(src.height()); + } + + //-------------------------------------------------------------------- + color_type* generate(int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + const unsigned char *fg_ptr; + color_type* span = base_type::allocator().span(); + do + { + base_type::interpolator().coordinates(&x, &y); + + x = m_remainder_x(x >> image_subpixel_shift); + y = m_remainder_y(y >> image_subpixel_shift); + + fg_ptr = base_type::source_image().row(y) + (x << 2); + span->r = fg_ptr[Order::R]; + span->g = fg_ptr[Order::G]; + span->b = fg_ptr[Order::B]; + span->a = fg_ptr[Order::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + + return base_type::allocator().span(); + } + + private: + RemainderX m_remainder_x; + RemainderY m_remainder_y; + }; + + + + + + + + + + + //=====================================span_pattern_filter_rgba32_bilinear + template > + class span_pattern_filter_rgba32_bilinear : + public span_image_filter + { + public: + typedef Interpolator interpolator_type; + typedef Allocator alloc_type; + typedef span_image_filter base_type; + typedef rgba8 color_type; + + //-------------------------------------------------------------------- + span_pattern_filter_rgba32_bilinear(alloc_type& alloc) : + base_type(alloc), + m_remainder_x(1), + m_remainder_y(1) + {} + + //-------------------------------------------------------------------- + span_pattern_filter_rgba32_bilinear(alloc_type& alloc, + const rendering_buffer& src, + interpolator_type& inter) : + base_type(alloc, src, color_type(0,0,0,0), inter, 0), + m_remainder_x(src.width()), + m_remainder_y(src.height()) + {} + + //-------------------------------------------------------------------- + void source_image(const rendering_buffer& src) + { + base_type::source_image(src); + m_remainder_x = RemainderX(src.width()); + m_remainder_y = RemainderX(src.height()); + } + + //-------------------------------------------------------------------- + color_type* generate(int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + int fg[4]; + const int8u *fg_ptr; + color_type* span = base_type::allocator().span(); + + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned x1 = m_remainder_x(x_lr); + unsigned x2 = x1 + 1; + if(x2 >= base_type::source_image().width()) x2 = 0; + x1 <<= 2; + x2 <<= 2; + + unsigned y1 = m_remainder_y(y_lr); + unsigned y2 = y1 + 1; + if(y2 >= base_type::source_image().height()) y2 = 0; + const int8u* ptr1 = base_type::source_image().row(y1); + const int8u* ptr2 = base_type::source_image().row(y2); + + fg[0] = + fg[1] = + fg[2] = + fg[3] = image_subpixel_size * image_subpixel_size / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + int weight; + fg_ptr = ptr1 + x1; + weight = (image_subpixel_size - x_hr) * + (image_subpixel_size - y_hr); + fg[0] += weight * fg_ptr[0]; + fg[1] += weight * fg_ptr[1]; + fg[2] += weight * fg_ptr[2]; + fg[3] += weight * fg_ptr[3]; + + fg_ptr = ptr1 + x2; + weight = x_hr * (image_subpixel_size - y_hr); + fg[0] += weight * fg_ptr[0]; + fg[1] += weight * fg_ptr[1]; + fg[2] += weight * fg_ptr[2]; + fg[3] += weight * fg_ptr[3]; + + fg_ptr = ptr2 + x1; + weight = (image_subpixel_size - x_hr) * y_hr; + fg[0] += weight * fg_ptr[0]; + fg[1] += weight * fg_ptr[1]; + fg[2] += weight * fg_ptr[2]; + fg[3] += weight * fg_ptr[3]; + + fg_ptr = ptr2 + x2; + weight = x_hr * y_hr; + fg[0] += weight * fg_ptr[0]; + fg[1] += weight * fg_ptr[1]; + fg[2] += weight * fg_ptr[2]; + fg[3] += weight * fg_ptr[3]; + + span->r = (int8u)(fg[Order::R] >> image_subpixel_shift * 2); + span->g = (int8u)(fg[Order::G] >> image_subpixel_shift * 2); + span->b = (int8u)(fg[Order::B] >> image_subpixel_shift * 2); + span->a = (int8u)(fg[Order::A] >> image_subpixel_shift * 2); + ++span; + ++base_type::interpolator(); + + } while(--len); + + return base_type::allocator().span(); + } + private: + RemainderX m_remainder_x; + RemainderY m_remainder_y; + }; + + + + + + //==============================================span_pattern_filter_rgba32 + template > + class span_pattern_filter_rgba32 : + public span_image_filter + { + public: + typedef Interpolator interpolator_type; + typedef Allocator alloc_type; + typedef span_image_filter base_type; + typedef rgba8 color_type; + + //-------------------------------------------------------------------- + span_pattern_filter_rgba32(alloc_type& alloc) : + base_type(alloc) + {} + + //-------------------------------------------------------------------- + span_pattern_filter_rgba32(alloc_type& alloc, + const rendering_buffer& src, + interpolator_type& inter, + const image_filter_base& filter) : + base_type(alloc, src, color_type(0,0,0,0), inter, &filter), + m_remainder_x(src.width()), + m_remainder_y(src.height()) + {} + + //-------------------------------------------------------------------- + void source_image(const rendering_buffer& src) + { + base_type::source_image(src); + m_remainder_x = RemainderX(src.width()); + m_remainder_y = RemainderX(src.height()); + } + + //-------------------------------------------------------------------- + color_type* generate(int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + int fg[4]; + + const unsigned char *fg_ptr; + + unsigned dimension = base_type::filter().dimension(); + int start = base_type::filter().start(); + const int* weight_array = base_type::filter().weight_array_int(); + + color_type* span = base_type::allocator().span(); + + int x_count; + int weight_y; + + do + { + base_type::interpolator().coordinates(&x, &y); + + x -= base_type::filter_dx_int(); + y -= base_type::filter_dy_int(); + + int x_hr = x; + int y_hr = y; + + int x_fract = x_hr & image_subpixel_mask; + unsigned y_count = dimension; + + int y_lr = m_remainder_y((y >> image_subpixel_shift) + start); + int x_int = m_remainder_x((x >> image_subpixel_shift) + start); + int x_lr; + + y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); + fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2; + + do + { + x_count = dimension; + weight_y = weight_array[y_hr]; + x_hr = image_subpixel_mask - x_fract; + x_lr = x_int; + fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2); + + do + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_size / 2) >> + image_filter_shift; + + fg[0] += *fg_ptr++ * weight; + fg[1] += *fg_ptr++ * weight; + fg[2] += *fg_ptr++ * weight; + fg[3] += *fg_ptr++ * weight; + + x_hr += image_subpixel_size; + ++x_lr; + if(x_lr >= int(base_type::source_image().width())) + { + x_lr = 0; + fg_ptr = base_type::source_image().row(y_lr); + } + + } while(--x_count); + + y_hr += image_subpixel_size; + ++y_lr; + if(y_lr >= int(base_type::source_image().height())) y_lr = 0; + + } while(--y_count); + + fg[0] >>= image_filter_shift; + fg[1] >>= image_filter_shift; + fg[2] >>= image_filter_shift; + 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::A] > 255) fg[Order::A] = 255; + if(fg[Order::R] > fg[Order::A]) fg[Order::R] = fg[Order::A]; + if(fg[Order::G] > fg[Order::A]) fg[Order::G] = fg[Order::A]; + if(fg[Order::B] > fg[Order::A]) fg[Order::B] = fg[Order::A]; + + span->r = fg[Order::R]; + span->g = fg[Order::G]; + span->b = fg[Order::B]; + span->a = fg[Order::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + + return base_type::allocator().span(); + } + + private: + RemainderX m_remainder_x; + RemainderY m_remainder_y; + }; + + +} + + +#endif + + + diff --git a/src/libs/agg/Jamfile b/src/libs/agg/Jamfile index e363827858..158c7f0fbe 100644 --- a/src/libs/agg/Jamfile +++ b/src/libs/agg/Jamfile @@ -13,35 +13,41 @@ SharedLibrary agg : src/agg_bezier_arc.cpp src/agg_bspline.cpp src/agg_curves.cpp + src/agg_embedded_raster_fonts.cpp + src/agg_gsv_text.cpp + src/agg_image_filters.cpp + src/agg_line_aa_basics.cpp + src/agg_line_profile_aa.cpp + src/agg_path_storage.cpp + src/agg_rasterizer_scanline_aa.cpp + src/agg_rounded_rect.cpp + src/agg_sqrt_tables.cpp + src/agg_trans_affine.cpp + src/agg_trans_double_path.cpp + src/agg_trans_single_path.cpp + src/agg_trans_warp_magnifier.cpp + src/agg_vcgen_bspline.cpp src/agg_vcgen_contour.cpp src/agg_vcgen_dash.cpp src/agg_vcgen_markers_term.cpp src/agg_vcgen_smooth_poly1.cpp src/agg_vcgen_stroke.cpp - src/agg_vcgen_bspline.cpp - src/agg_gsv_text.cpp - src/agg_image_filters.cpp - src/agg_path_storage.cpp - src/agg_rasterizer_scanline_aa.cpp - src/agg_line_aa_basics.cpp - src/agg_line_profile_aa.cpp - src/agg_rounded_rect.cpp - src/agg_sqrt_tables.cpp - src/agg_embedded_raster_fonts.cpp - src/agg_trans_affine.cpp - src/agg_trans_warp_magnifier.cpp - src/agg_trans_single_path.cpp - src/agg_trans_double_path.cpp src/agg_vpgen_clip_polygon.cpp + src/agg_vpgen_clip_polyline.cpp src/agg_vpgen_segmentator.cpp + src/ctrl/agg_bezier_ctrl.cpp src/ctrl/agg_cbox_ctrl.cpp src/ctrl/agg_gamma_ctrl.cpp src/ctrl/agg_gamma_spline.cpp + src/ctrl/agg_polygon_ctrl.cpp src/ctrl/agg_rbox_ctrl.cpp + src/ctrl/agg_scale_ctrl.cpp src/ctrl/agg_slider_ctrl.cpp src/ctrl/agg_spline_ctrl.cpp - src/ctrl/agg_scale_ctrl.cpp - gpc/gpc.c + + # uncomment this line to enable the General Polygon Clipper + # see the license in gpc.c for usage information + #gpc/gpc.c ; LinkSharedOSLibs libagg.so : root be diff --git a/src/libs/agg/font_freetype/agg_font_freetype.cpp b/src/libs/agg/font_freetype/agg_font_freetype.cpp index 0af06f6f09..4ec567d488 100755 --- a/src/libs/agg/font_freetype/agg_font_freetype.cpp +++ b/src/libs/agg/font_freetype/agg_font_freetype.cpp @@ -771,10 +771,10 @@ namespace agg m_resolution, m_height, m_width, - m_matrix.xx, - m_matrix.xy, - m_matrix.yx, - m_matrix.yy, + int(m_matrix.xx), + int(m_matrix.xy), + int(m_matrix.yx), + int(m_matrix.yy), int(m_hinting), int(m_flip_y), gamma_hash); @@ -827,6 +827,7 @@ namespace agg { case glyph_ren_native_mono: m_last_error = FT_Render_Glyph(m_cur_face->glyph, FT_RENDER_MODE_MONO); +//printf("%i\n", m_last_error); if(m_last_error == 0) { decompose_ft_bitmap_mono(m_cur_face->glyph->bitmap, @@ -1007,6 +1008,7 @@ namespace agg { switch(m_data_type) { + default: return; case glyph_data_mono: m_scanlines_bin.serialize(data); break; case glyph_data_gray8: m_scanlines_aa.serialize(data); break; case glyph_data_outline: @@ -1019,6 +1021,7 @@ namespace agg m_path16.serialize(data); } break; + case glyph_data_invalid: break; } } } diff --git a/src/libs/agg/src/agg_path_storage.cpp b/src/libs/agg/src/agg_path_storage.cpp index c520bc801d..ab94cb63db 100644 --- a/src/libs/agg/src/agg_path_storage.cpp +++ b/src/libs/agg/src/agg_path_storage.cpp @@ -234,7 +234,7 @@ namespace agg x_ctrl = x0; y_ctrl = y0; } - curve3(x_ctrl, x_ctrl, x_to, y_to); + curve3(x_ctrl, y_ctrl, x_to, y_to); } } diff --git a/src/libs/agg/src/agg_vcgen_contour.cpp b/src/libs/agg/src/agg_vcgen_contour.cpp index 2a5c665bf1..293ac5bd2c 100755 --- a/src/libs/agg/src/agg_vcgen_contour.cpp +++ b/src/libs/agg/src/agg_vcgen_contour.cpp @@ -26,15 +26,20 @@ namespace agg //------------------------------------------------------------------------ vcgen_contour::vcgen_contour() : m_src_vertices(), + m_out_vertices(), m_width(1.0), + m_line_join(bevel_join), + m_inner_line_join(miter_join_revert), + m_approx_scale(1.0), m_abs_width(1.0), m_signed_width(1.0), m_miter_limit(4.0), + m_inner_miter_limit(1.0 + 1.0/64.0), m_status(initial), m_src_vertex(0), m_closed(0), m_orientation(0), - m_auto_detect(true) + m_auto_detect(false) { } @@ -116,8 +121,8 @@ namespace agg //------------------------------------------------------------------------ unsigned vcgen_contour::vertex(double* x, double* y) { - bool done = false; - while(!done) + unsigned cmd = path_cmd_line_to; + while(!is_stop(cmd)) { switch(m_status) { @@ -125,98 +130,62 @@ namespace agg rewind(0); case ready: - if(m_src_vertices.size() < 3) + if(m_src_vertices.size() < 2 + unsigned(m_closed != 0)) { - return path_cmd_stop; + cmd = path_cmd_stop; + break; } - m_src_vertex = 0; m_status = outline; + cmd = path_cmd_move_to; + m_src_vertex = 0; + m_out_vertex = 0; case outline: if(m_src_vertex >= m_src_vertices.size()) { m_status = end_poly; - return path_cmd_end_poly | m_orientation | m_closed; - } - if(calc_miter(m_src_vertices.prev(m_src_vertex), - m_src_vertices.curr(m_src_vertex), - m_src_vertices.next(m_src_vertex))) - { - m_status = add_point; + break; } + stroke_calc_join(m_out_vertices, + m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.next(m_src_vertex), + m_src_vertices.prev(m_src_vertex).dist, + m_src_vertices.curr(m_src_vertex).dist, + m_signed_width, + m_line_join, + m_inner_line_join, + m_miter_limit, + m_inner_miter_limit, + m_approx_scale); ++m_src_vertex; - *x = m_x1; - *y = m_y1; - return ((m_src_vertex == 1) ? path_cmd_move_to : path_cmd_line_to); + m_status = out_vertices; + m_out_vertex = 0; - case add_point: - *x = m_x2; - *y = m_y2; - m_status = outline; - return path_cmd_line_to; + case out_vertices: + if(m_out_vertex >= m_out_vertices.size()) + { + m_status = outline; + } + else + { + const point_type& c = m_out_vertices[m_out_vertex++]; + *x = c.x; + *y = c.y; + return cmd; + } + break; case end_poly: - done = true; - break; + if(!m_closed) return path_cmd_stop; + m_status = stop; + return path_cmd_end_poly | path_flags_close | path_flags_ccw; + + case stop: + return path_cmd_stop; } } - return path_cmd_stop; + return cmd; } - - - //------------------------------------------------------------------------ - bool vcgen_contour::calc_miter(const vertex_dist& v0, - const vertex_dist& v1, - const vertex_dist& v2) - { - double dx1, dy1, dx2, dy2; - - dx1 = m_signed_width * (v1.y - v0.y) / v0.dist; - dy1 = m_signed_width * (v1.x - v0.x) / v0.dist; - - dx2 = m_signed_width * (v2.y - v1.y) / v1.dist; - dy2 = m_signed_width * (v2.x - v1.x) / v1.dist; - - double xi; - double yi; - - if(!calc_intersection(v0.x + dx1, v0.y - dy1, - v1.x + dx1, v1.y - dy1, - v1.x + dx2, v1.y - dy2, - v2.x + dx2, v2.y - dy2, - &xi, &yi)) - { - m_x1 = v1.x + dx1; - m_y1 = v1.y - dy1; - return false; - } - else - { - double d1 = calc_distance(v1.x, v1.y, xi, yi); - double lim = m_abs_width * m_miter_limit; - if(d1 > lim) - { - d1 = lim / d1; - m_x1 = v1.x + dx1; - m_y1 = v1.y - dy1; - m_x2 = v1.x + dx2; - m_y2 = v1.y - dy2; - - m_x1 += (xi - m_x1) * d1; - m_y1 += (yi - m_y1) * d1; - m_x2 += (xi - m_x2) * d1; - m_y2 += (yi - m_y2) * d1; - return true; - } - else - { - m_x1 = xi; - m_y1 = yi; - } - } - return false; - } - - } diff --git a/src/libs/agg/src/agg_vcgen_stroke.cpp b/src/libs/agg/src/agg_vcgen_stroke.cpp index 0c7430ed2d..0e7ee6ac00 100755 --- a/src/libs/agg/src/agg_vcgen_stroke.cpp +++ b/src/libs/agg/src/agg_vcgen_stroke.cpp @@ -29,10 +29,12 @@ namespace agg m_out_vertices(), m_width(0.5), m_miter_limit(4.0), + m_inner_miter_limit(1.0 + 1.0/64.0), m_approx_scale(1.0), m_shorten(0.0), m_line_cap(butt_cap), m_line_join(miter_join), + m_inner_line_join(miter_join_revert), m_closed(0), m_status(initial), m_src_vertex(0), @@ -86,6 +88,7 @@ namespace agg { m_src_vertices.close(m_closed != 0); shorten_path(m_src_vertices, m_shorten, m_closed); + if(m_src_vertices.size() < 3) m_closed = 0; } m_status = ready; m_src_vertex = 0; @@ -105,7 +108,7 @@ namespace agg rewind(0); case ready: - if(m_src_vertices.size() < 2 + unsigned(m_closed != 0)) + if(m_src_vertices.size() < 2 + unsigned(m_closed != 0)) { cmd = path_cmd_stop; break; @@ -117,9 +120,13 @@ namespace agg break; case cap1: - calc_cap(m_src_vertices[0], - m_src_vertices[1], - m_src_vertices[0].dist); + stroke_calc_cap(m_out_vertices, + m_src_vertices[0], + m_src_vertices[1], + m_src_vertices[0].dist, + m_line_cap, + m_width, + m_approx_scale); m_src_vertex = 1; m_prev_status = outline1; m_status = out_vertices; @@ -127,9 +134,13 @@ namespace agg break; case cap2: - calc_cap(m_src_vertices[m_src_vertices.size() - 1], - m_src_vertices[m_src_vertices.size() - 2], - m_src_vertices[m_src_vertices.size() - 2].dist); + stroke_calc_cap(m_out_vertices, + m_src_vertices[m_src_vertices.size() - 1], + m_src_vertices[m_src_vertices.size() - 2], + m_src_vertices[m_src_vertices.size() - 2].dist, + m_line_cap, + m_width, + m_approx_scale); m_prev_status = outline2; m_status = out_vertices; m_out_vertex = 0; @@ -153,12 +164,18 @@ namespace agg break; } } - - calc_join(m_src_vertices.prev(m_src_vertex), - m_src_vertices.curr(m_src_vertex), - m_src_vertices.next(m_src_vertex), - m_src_vertices.prev(m_src_vertex).dist, - m_src_vertices.curr(m_src_vertex).dist); + stroke_calc_join(m_out_vertices, + m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.next(m_src_vertex), + m_src_vertices.prev(m_src_vertex).dist, + m_src_vertices.curr(m_src_vertex).dist, + m_width, + m_line_join, + m_inner_line_join, + m_miter_limit, + m_inner_miter_limit, + m_approx_scale); ++m_src_vertex; m_prev_status = m_status; m_status = out_vertices; @@ -178,11 +195,18 @@ namespace agg } --m_src_vertex; - calc_join(m_src_vertices.next(m_src_vertex), - m_src_vertices.curr(m_src_vertex), - m_src_vertices.prev(m_src_vertex), - m_src_vertices.curr(m_src_vertex).dist, - m_src_vertices.prev(m_src_vertex).dist); + stroke_calc_join(m_out_vertices, + m_src_vertices.next(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex).dist, + m_src_vertices.prev(m_src_vertex).dist, + m_width, + m_line_join, + m_inner_line_join, + m_miter_limit, + m_inner_miter_limit, + m_approx_scale); m_prev_status = m_status; m_status = out_vertices; @@ -196,7 +220,7 @@ namespace agg } else { - const coord_type& c = m_out_vertices[m_out_vertex++]; + const point_type& c = m_out_vertices[m_out_vertex++]; *x = c.x; *y = c.y; return cmd; @@ -219,202 +243,4 @@ namespace agg return cmd; } - - - //------------------------------------------------------------------------ - void vcgen_stroke::calc_arc(double x, double y, - double dx1, double dy1, - double dx2, double dy2) - { - double a1 = atan2(dy1, dx1); - double a2 = atan2(dy2, dx2); - double da = a1 - a2; - - if(fabs(da) < vcgen_stroke_theta) - { - m_out_vertices.add(coord_type(x + dx1, y + dy1)); - m_out_vertices.add(coord_type(x + dx2, y + dy2)); - return; - } - - bool ccw = da > 0.0 && da < pi; - - da = fabs(1.0 / (m_width * m_approx_scale)); - if(!ccw) - { - if(a1 > a2) a2 += 2 * pi; - while(a1 < a2) - { - m_out_vertices.add(coord_type(x + cos(a1) * m_width, y + sin(a1) * m_width)); - a1 += da; - } - } - else - { - if(a1 < a2) a2 -= 2 * pi; - while(a1 > a2) - { - m_out_vertices.add(coord_type(x + cos(a1) * m_width, y + sin(a1) * m_width)); - a1 -= da; - } - } - m_out_vertices.add(coord_type(x + dx2, y + dy2)); - } - - - //------------------------------------------------------------------------ - void vcgen_stroke::calc_cap(const vertex_dist& v0, - const vertex_dist& v1, - double len) - { - m_out_vertices.remove_all(); - - double dx1 = m_width * (v1.y - v0.y) / len; - double dy1 = m_width * (v1.x - v0.x) / len; - double dx2 = 0; - double dy2 = 0; - - - if(m_line_cap == square_cap) - { - dx2 = dy1; - dy2 = dx1; - } - - if(m_line_cap == round_cap) - { - double a1 = atan2(dy1, -dx1); - double a2 = a1 + pi; - double da = fabs(1.0 / (m_width * m_approx_scale)); - while(a1 < a2) - { - m_out_vertices.add(coord_type(v0.x + cos(a1) * m_width, - v0.y + sin(a1) * m_width)); - a1 += da; - } - m_out_vertices.add(coord_type(v0.x + dx1, v0.y - dy1)); - } - else - { - m_out_vertices.add(coord_type(v0.x - dx1 - dx2, v0.y + dy1 - dy2)); - m_out_vertices.add(coord_type(v0.x + dx1 - dx2, v0.y - dy1 - dy2)); - } - } - - - - //------------------------------------------------------------------------ - void vcgen_stroke::calc_miter(const vertex_dist& v0, - const vertex_dist& v1, - const vertex_dist& v2, - double dx1, double dy1, - double dx2, double dy2, - bool revert_flag) - { - double xi = v1.x; - double yi = v1.y; - if(!calc_intersection(v0.x + dx1, v0.y - dy1, - v1.x + dx1, v1.y - dy1, - v1.x + dx2, v1.y - dy2, - v2.x + dx2, v2.y - dy2, - &xi, &yi)) - { - // The calculation didn't succeed, most probaly - // the the three points lie one straight line - //---------------- - m_out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); - } - else - { - double d1 = calc_distance(v1.x, v1.y, xi, yi); - double lim = m_width * m_miter_limit; - if(d1 > lim) - { - // Miter limit exceeded - //------------------------ - if(revert_flag) - { - // For the compatibility with SVG, PDF, etc, - // we use a simple bevel join instead of - // "smart" bevel - //------------------- - m_out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); - m_out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); - } - else - { - // Smart bevel that cuts the miter at the limit point - //------------------- - d1 = lim / d1; - double x1 = v1.x + dx1; - double y1 = v1.y - dy1; - double x2 = v1.x + dx2; - double y2 = v1.y - dy2; - - x1 += (xi - x1) * d1; - y1 += (yi - y1) * d1; - x2 += (xi - x2) * d1; - y2 += (yi - y2) * d1; - m_out_vertices.add(coord_type(x1, y1)); - m_out_vertices.add(coord_type(x2, y2)); - } - } - else - { - // Inside the miter limit - //--------------------- - m_out_vertices.add(coord_type(xi, yi)); - } - } - } - - - //------------------------------------------------------------------------ - void vcgen_stroke::calc_join(const vertex_dist& v0, - const vertex_dist& v1, - const vertex_dist& v2, - double len1, double len2) - { - double dx1, dy1, dx2, dy2; - - dx1 = m_width * (v1.y - v0.y) / len1; - dy1 = m_width * (v1.x - v0.x) / len1; - - dx2 = m_width * (v2.y - v1.y) / len2; - dy2 = m_width * (v2.x - v1.x) / len2; - - m_out_vertices.remove_all(); - if(m_line_join == miter_join) - { - calc_miter(v0, v1, v2, dx1, dy1, dx2, dy2, m_line_join == miter_join_revert); - } - else - { - if(calc_point_location(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y) > 0.0) - { - calc_miter(v0, v1, v2, dx1, dy1, dx2, dy2, false); - } - else - { - if(m_line_join == round_join) - { - calc_arc(v1.x, v1.y, dx1, -dy1, dx2, -dy2); - } - else - { - if(m_line_join == miter_join_revert) - { - calc_miter(v0, v1, v2, dx1, dy1, dx2, dy2, true); - } - else - { - m_out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1)); - m_out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2)); - } - } - } - } - } - - } diff --git a/src/libs/agg/src/agg_vpgen_clip_polyline.cpp b/src/libs/agg/src/agg_vpgen_clip_polyline.cpp new file mode 100644 index 0000000000..b6d7b3b310 --- /dev/null +++ b/src/libs/agg/src/agg_vpgen_clip_polyline.cpp @@ -0,0 +1,142 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.2 +// Copyright (C) 2002-2004 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 +//---------------------------------------------------------------------------- + +#include +#include "agg_vpgen_clip_polyline.h" + +namespace agg +{ + static double clip_epsilon = 1e-10; + + + //---------------------------------------------------------------------------- + void vpgen_clip_polyline::reset() + { + m_vertex = 0; + m_num_vertices = 0; + } + + //---------------------------------------------------------------------------- + void vpgen_clip_polyline::move_to(double x, double y) + { + m_vertex = 0; + m_num_vertices = 0; + m_f1 = clipping_flags(x, y); + if(m_f1 == 0) + { + m_x[0] = x; + m_y[0] = y; + m_cmd[0] = path_cmd_move_to; + m_num_vertices = 1; + } + m_x1 = x; + m_y1 = y; + } + + + //---------------------------------------------------------------------------- + bool vpgen_clip_polyline::move_point(double& x, double& y, unsigned& flags) + { + double bound; + + if(flags & (clip_x1 | clip_x2)) + { + bound = (flags & clip_x1) ? m_clip_box.x1 : m_clip_box.x2; + y = (bound - m_x1) * (m_y2 - m_y1) / (m_x2 - m_x1) + m_y1; + x = bound; + flags = clipping_flags_y(y); + } + if(fabs(m_y2 - m_y1) < clip_epsilon && fabs(m_x2 - m_x1) < clip_epsilon) + { + return false; + } + if(flags & (clip_y1 | clip_y2)) + { + bound = (flags & clip_y1) ? m_clip_box.y1 : m_clip_box.y2; + x = (bound - m_y1) * (m_x2 - m_x1) / (m_y2 - m_y1) + m_x1; + y = bound; + } + flags = 0; + return true; + } + + //---------------------------------------------------------------------------- + void vpgen_clip_polyline::clip_line_segment() + { + if((m_f1 & m_f2) == 0) + { + if(m_f1) + { + if(!move_point(m_x1, m_y1, m_f1)) return; + if(m_f1) return; + m_x[0] = m_x1; + m_y[0] = m_y1; + m_cmd[0] = path_cmd_move_to; + m_num_vertices = 1; + } + if(m_f2) + { // Move Point 2 + if(!move_point(m_x2, m_y2, m_f2)) return; + } + m_x[m_num_vertices] = m_x2; + m_y[m_num_vertices] = m_y2; + m_cmd[m_num_vertices++] = path_cmd_line_to; + } + } + + + + //---------------------------------------------------------------------------- + void vpgen_clip_polyline::line_to(double x, double y) + { + m_vertex = 0; + m_num_vertices = 0; + unsigned f = m_f2 = clipping_flags(m_x2 = x, m_y2 = y); + + if(m_f2 == m_f1) + { + if(m_f2 == 0) + { + m_x[0] = x; + m_y[0] = y; + m_cmd[0] = path_cmd_line_to; + m_num_vertices = 1; + } + } + else + { + clip_line_segment(); + } + + m_f1 = f; + m_x1 = x; + m_y1 = y; + } + + + //---------------------------------------------------------------------------- + unsigned vpgen_clip_polyline::vertex(double* x, double* y) + { + if(m_vertex < m_num_vertices) + { + *x = m_x[m_vertex]; + *y = m_y[m_vertex]; + return m_cmd[m_vertex++]; + } + return path_cmd_stop; + } + + +} diff --git a/src/libs/agg/src/agg_vpgen_segmentator.cpp b/src/libs/agg/src/agg_vpgen_segmentator.cpp index 42a0c04de0..77fc3062be 100644 --- a/src/libs/agg/src/agg_vpgen_segmentator.cpp +++ b/src/libs/agg/src/agg_vpgen_segmentator.cpp @@ -26,6 +26,7 @@ namespace agg m_dx = 0.0; m_dy = 0.0; m_dl = 2.0; + m_ddl = 2.0; m_cmd = path_cmd_move_to; } @@ -48,10 +49,13 @@ namespace agg unsigned cmd = m_cmd; m_cmd = path_cmd_line_to; - if(m_dl > 1.0) + if(m_dl >= 1.0 - m_ddl) { m_dl = 1.0; m_cmd = path_cmd_stop; + *x = m_x1 + m_dx; + *y = m_y1 + m_dy; + return cmd; } *x = m_x1 + m_dx * m_dl; *y = m_y1 + m_dy * m_dl; diff --git a/src/libs/agg/src/ctrl/agg_bezier_ctrl.cpp b/src/libs/agg/src/ctrl/agg_bezier_ctrl.cpp new file mode 100644 index 0000000000..dfbd7138e5 --- /dev/null +++ b/src/libs/agg/src/ctrl/agg_bezier_ctrl.cpp @@ -0,0 +1,199 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.2 +// Copyright (C) 2002-2004 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 +//---------------------------------------------------------------------------- +// +// classes bezier_ctrl_impl, bezier_ctrl +// +//---------------------------------------------------------------------------- + +#include +#include +#include "ctrl/agg_bezier_ctrl.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + bezier_ctrl_impl::bezier_ctrl_impl() : + ctrl(0,0,1,1,false), + m_stroke(m_curve), + m_poly(4, 5.0), + m_idx(0) + { + m_poly.in_polygon_check(false); + m_poly.xn(0) = 100.0; + m_poly.yn(0) = 0.0; + m_poly.xn(1) = 100.0; + m_poly.yn(1) = 50.0; + m_poly.xn(2) = 50.0; + m_poly.yn(2) = 100.0; + m_poly.xn(3) = 0.0; + m_poly.yn(3) = 100.0; + } + + + //------------------------------------------------------------------------ + void bezier_ctrl_impl::curve(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + m_poly.xn(0) = x1; + m_poly.yn(0) = y1; + m_poly.xn(1) = x2; + m_poly.yn(1) = y2; + m_poly.xn(2) = x3; + m_poly.yn(2) = y3; + m_poly.xn(3) = x4; + m_poly.yn(3) = y4; + curve(); + } + + //------------------------------------------------------------------------ + curve4& bezier_ctrl_impl::curve() + { + m_curve.init(m_poly.xn(0), m_poly.yn(0), + m_poly.xn(1), m_poly.yn(1), + m_poly.xn(2), m_poly.yn(2), + m_poly.xn(3), m_poly.yn(3)); + return m_curve; + } + + //------------------------------------------------------------------------ + void bezier_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + + switch(idx) + { + default: + case 0: // Control line 1 + m_curve.init(m_poly.xn(0), m_poly.yn(0), + (m_poly.xn(0) + m_poly.xn(1)) * 0.5, + (m_poly.yn(0) + m_poly.yn(1)) * 0.5, + (m_poly.xn(0) + m_poly.xn(1)) * 0.5, + (m_poly.yn(0) + m_poly.yn(1)) * 0.5, + m_poly.xn(1), m_poly.yn(1)); + m_stroke.rewind(0); + break; + + case 1: // Control line 2 + m_curve.init(m_poly.xn(2), m_poly.yn(2), + (m_poly.xn(2) + m_poly.xn(3)) * 0.5, + (m_poly.yn(2) + m_poly.yn(3)) * 0.5, + (m_poly.xn(2) + m_poly.xn(3)) * 0.5, + (m_poly.yn(2) + m_poly.yn(3)) * 0.5, + m_poly.xn(3), m_poly.yn(3)); + m_stroke.rewind(0); + break; + + case 2: // Curve itself + m_curve.init(m_poly.xn(0), m_poly.yn(0), + m_poly.xn(1), m_poly.yn(1), + m_poly.xn(2), m_poly.yn(2), + m_poly.xn(3), m_poly.yn(3)); + m_stroke.rewind(0); + break; + + case 3: // Point 1 + m_ellipse.init(m_poly.xn(0), m_poly.yn(0), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 4: // Point 2 + m_ellipse.init(m_poly.xn(1), m_poly.yn(1), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 5: // Point 3 + m_ellipse.init(m_poly.xn(2), m_poly.yn(2), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 6: // Point 4 + m_ellipse.init(m_poly.xn(3), m_poly.yn(3), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + } + } + + + //------------------------------------------------------------------------ + unsigned bezier_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + switch(m_idx) + { + case 0: + case 1: + case 2: + cmd = m_stroke.vertex(x, y); + break; + + case 3: + case 4: + case 5: + case 6: + case 7: + cmd = m_ellipse.vertex(x, y); + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + return cmd; + } + + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::in_rect(double x, double y) const + { + return false; + } + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + return m_poly.on_mouse_button_down(x, y); + } + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + return m_poly.on_mouse_move(x, y, button_flag); + } + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::on_mouse_button_up(double x, double y) + { + return m_poly.on_mouse_button_up(x, y); + } + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + return m_poly.on_arrow_keys(left, right, down, up); + } + +} + diff --git a/src/libs/agg/src/ctrl/agg_cbox_ctrl.cpp b/src/libs/agg/src/ctrl/agg_cbox_ctrl.cpp index 55f0237ecb..b07870d95a 100644 --- a/src/libs/agg/src/ctrl/agg_cbox_ctrl.cpp +++ b/src/libs/agg/src/ctrl/agg_cbox_ctrl.cpp @@ -131,8 +131,8 @@ namespace agg m_text.start_point(m_x1 + m_text_height * 2.0, m_y1 + m_text_height / 5.0); m_text.size(m_text_height, m_text_width); m_text_poly.width(m_text_thickness); - m_text_poly.line_join(vcgen_stroke::round_join); - m_text_poly.line_cap(vcgen_stroke::round_cap); + m_text_poly.line_join(round_join); + m_text_poly.line_cap(round_cap); m_text_poly.rewind(0); break; diff --git a/src/libs/agg/src/ctrl/agg_gamma_ctrl.cpp b/src/libs/agg/src/ctrl/agg_gamma_ctrl.cpp index 5e39a67765..09f7448f2c 100644 --- a/src/libs/agg/src/ctrl/agg_gamma_ctrl.cpp +++ b/src/libs/agg/src/ctrl/agg_gamma_ctrl.cpp @@ -245,8 +245,8 @@ namespace agg m_text.size(m_text_height, m_text_width); m_text.start_point(m_xt1 + m_border_width * 2.0, (m_yt1 + m_yt2) * 0.5 - m_text_height * 0.5); m_text_poly.width(m_text_thickness); - m_text_poly.line_join(vcgen_stroke::round_join); - m_text_poly.line_cap(vcgen_stroke::round_cap); + m_text_poly.line_join(round_join); + m_text_poly.line_cap(round_cap); m_text_poly.rewind(0); break; } diff --git a/src/libs/agg/src/ctrl/agg_polygon_ctrl.cpp b/src/libs/agg/src/ctrl/agg_polygon_ctrl.cpp new file mode 100644 index 0000000000..6c6b858068 --- /dev/null +++ b/src/libs/agg/src/ctrl/agg_polygon_ctrl.cpp @@ -0,0 +1,337 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.2 +// Copyright (C) 2002-2004 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 +//---------------------------------------------------------------------------- +// +// classes polygon_ctrl_impl +// +//---------------------------------------------------------------------------- + +#include "ctrl/agg_polygon_ctrl.h" + +namespace agg +{ + + polygon_ctrl_impl::~polygon_ctrl_impl() + { + delete [] m_polygon; + } + + + polygon_ctrl_impl::polygon_ctrl_impl(unsigned np, double point_radius) : + ctrl(0, 0, 1, 1, false), + m_polygon(new double[np * 2]), + m_num_points(np), + m_node(-1), + m_edge(-1), + m_vs(m_polygon, m_num_points, false), + m_stroke(m_vs), + m_point_radius(point_radius), + m_status(0), + m_dx(0.0), + m_dy(0.0) + { + m_stroke.width(1.0); + } + + + void polygon_ctrl_impl::rewind(unsigned) + { + m_status = 0; + m_stroke.rewind(0); + } + + unsigned polygon_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + double r = m_point_radius; + if(m_status == 0) + { + cmd = m_stroke.vertex(x, y); + if(!is_stop(cmd)) + { + transform_xy(x, y); + return cmd; + } + if(m_node >= 0 && m_node == int(m_status)) r *= 1.2; + m_ellipse.init(xn(m_status), yn(m_status), r, r, 32); + ++m_status; + } + cmd = m_ellipse.vertex(x, y); + if(!is_stop(cmd)) + { + transform_xy(x, y); + return cmd; + } + if(m_status >= m_num_points) return path_cmd_stop; + if(m_node >= 0 && m_node == int(m_status)) r *= 1.2; + m_ellipse.init(xn(m_status), yn(m_status), r, r, 32); + ++m_status; + cmd = m_ellipse.vertex(x, y); + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + return cmd; + } + + + bool polygon_ctrl_impl::check_edge(unsigned i, double x, double y) const + { + bool ret = false; + + unsigned n1 = i; + unsigned n2 = (i + m_num_points - 1) % m_num_points; + double x1 = xn(n1); + double y1 = yn(n1); + double x2 = xn(n2); + double y2 = yn(n2); + + double dx = x2 - x1; + double dy = y2 - y1; + + if(sqrt(dx*dx + dy*dy) > 0.0000001) + { + double x3 = x; + double y3 = y; + double x4 = x3 - dy; + double y4 = y3 + dx; + + double den = (y4-y3) * (x2-x1) - (x4-x3) * (y2-y1); + double u1 = ((x4-x3) * (y1-y3) - (y4-y3) * (x1-x3)) / den; + + double xi = x1 + u1 * (x2 - x1); + double yi = y1 + u1 * (y2 - y1); + + dx = xi - x; + dy = yi - y; + + if (u1 > 0.0 && u1 < 1.0 && sqrt(dx*dx + dy*dy) <= m_point_radius) + { + ret = true; + } + } + return ret; + } + + + + bool polygon_ctrl_impl::in_rect(double x, double y) const + { + return false; + } + + + bool polygon_ctrl_impl::on_mouse_button_down(double x, double y) + { + unsigned i; + bool ret = false; + m_node = -1; + m_edge = -1; + inverse_transform_xy(&x, &y); + for (i = 0; i < m_num_points; i++) + { + if(sqrt( (x-xn(i)) * (x-xn(i)) + (y-yn(i)) * (y-yn(i)) ) < m_point_radius) + { + m_dx = x - xn(i); + m_dy = y - yn(i); + m_node = int(i); + ret = true; + break; + } + } + + if(!ret) + { + for (i = 0; i < m_num_points; i++) + { + if(check_edge(i, x, y)) + { + m_dx = x; + m_dy = y; + m_edge = int(i); + ret = true; + break; + } + } + } + + if(!ret) + { + if(point_in_polygon(x, y)) + { + m_dx = x; + m_dy = y; + m_node = int(m_num_points); + ret = true; + } + } + return ret; + } + + + bool polygon_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + bool ret = false; + double dx; + double dy; + inverse_transform_xy(&x, &y); + if(m_node == int(m_num_points)) + { + dx = x - m_dx; + dy = y - m_dy; + unsigned i; + for(i = 0; i < m_num_points; i++) + { + xn(i) += dx; + yn(i) += dy; + } + m_dx = x; + m_dy = y; + ret = true; + } + else + { + if(m_edge >= 0) + { + unsigned n1 = m_edge; + unsigned n2 = (n1 + m_num_points - 1) % m_num_points; + dx = x - m_dx; + dy = y - m_dy; + xn(n1) += dx; + yn(n1) += dy; + xn(n2) += dx; + yn(n2) += dy; + m_dx = x; + m_dy = y; + ret = true; + } + else + { + if(m_node >= 0) + { + xn(m_node) = x - m_dx; + yn(m_node) = y - m_dy; + ret = true; + } + } + } + return ret; + } + + bool polygon_ctrl_impl::on_mouse_button_up(double x, double y) + { + bool ret = (m_node >= 0) || (m_edge >= 0); + m_node = -1; + m_edge = -1; + return ret; + } + + + bool polygon_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + return false; + } + + + //======= Crossings Multiply algorithm of InsideTest ======================== + // + // By Eric Haines, 3D/Eye Inc, erich@eye.com + // + // This version is usually somewhat faster than the original published in + // Graphics Gems IV; by turning the division for testing the X axis crossing + // into a tricky multiplication test this part of the test became faster, + // which had the additional effect of making the test for "both to left or + // both to right" a bit slower for triangles than simply computing the + // intersection each time. The main increase is in triangle testing speed, + // which was about 15% faster; all other polygon complexities were pretty much + // the same as before. On machines where division is very expensive (not the + // case on the HP 9000 series on which I tested) this test should be much + // faster overall than the old code. Your mileage may (in fact, will) vary, + // depending on the machine and the test data, but in general I believe this + // code is both shorter and faster. This test was inspired by unpublished + // Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson. + // Related work by Samosky is in: + // + // Samosky, Joseph, "SectionView: A system for interactively specifying and + // visualizing sections through three-dimensional medical image data", + // M.S. Thesis, Department of Electrical Engineering and Computer Science, + // Massachusetts Institute of Technology, 1993. + // + // Shoot a test ray along +X axis. The strategy is to compare vertex Y values + // to the testing point's Y and quickly discard edges which are entirely to one + // side of the test ray. Note that CONVEX and WINDING code can be added as + // for the CrossingsTest() code; it is left out here for clarity. + // + // Input 2D polygon _pgon_ with _numverts_ number of vertices and test point + // _point_, returns 1 if inside, 0 if outside. + bool polygon_ctrl_impl::point_in_polygon(double tx, double ty) const + { + if(m_num_points < 3) return false; + if(!m_in_polygon_check) return false; + + unsigned j; + int yflag0, yflag1, inside_flag; + double vtx0, vty0, vtx1, vty1; + + vtx0 = xn(m_num_points - 1); + vty0 = yn(m_num_points - 1); + + // get test bit for above/below X axis + yflag0 = (vty0 >= ty); + + vtx1 = xn(0); + vty1 = yn(0); + + inside_flag = 0; + for (j = 1; j <= m_num_points; ++j) + { + yflag1 = (vty1 >= ty); + // Check if endpoints straddle (are on opposite sides) of X axis + // (i.e. the Y's differ); if so, +X ray could intersect this edge. + // The old test also checked whether the endpoints are both to the + // right or to the left of the test point. However, given the faster + // intersection point computation used below, this test was found to + // be a break-even proposition for most polygons and a loser for + // triangles (where 50% or more of the edges which survive this test + // will cross quadrants and so have to have the X intersection computed + // anyway). I credit Joseph Samosky with inspiring me to try dropping + // the "both left or both right" part of my code. + if (yflag0 != yflag1) + { + // Check intersection of pgon segment with +X ray. + // Note if >= point's X; if so, the ray hits it. + // The division operation is avoided for the ">=" test by checking + // the sign of the first vertex wrto the test point; idea inspired + // by Joseph Samosky's and Mark Haigh-Hutchinson's different + // polygon inclusion tests. + if ( ((vty1-ty) * (vtx0-vtx1) >= + (vtx1-tx) * (vty0-vty1)) == yflag1 ) + { + inside_flag ^= 1; + } + } + + // Move to the next pair of vertices, retaining info as possible. + yflag0 = yflag1; + vtx0 = vtx1; + vty0 = vty1; + + unsigned k = (j >= m_num_points) ? j - m_num_points : j; + vtx1 = xn(k); + vty1 = yn(k); + } + return inside_flag != 0; + } +} + diff --git a/src/libs/agg/src/ctrl/agg_rbox_ctrl.cpp b/src/libs/agg/src/ctrl/agg_rbox_ctrl.cpp index b9f2fd8295..425e467cee 100644 --- a/src/libs/agg/src/ctrl/agg_rbox_ctrl.cpp +++ b/src/libs/agg/src/ctrl/agg_rbox_ctrl.cpp @@ -146,8 +146,8 @@ namespace agg m_text.start_point(m_xs1 + m_dy * 1.5, m_ys1 + m_dy / 2.0); m_text.size(m_text_height, m_text_width); m_text_poly.width(m_text_thickness); - m_text_poly.line_join(vcgen_stroke::round_join); - m_text_poly.line_cap(vcgen_stroke::round_cap); + m_text_poly.line_join(round_join); + m_text_poly.line_cap(round_cap); m_text_poly.rewind(0); break; diff --git a/src/libs/agg/src/ctrl/agg_slider_ctrl.cpp b/src/libs/agg/src/ctrl/agg_slider_ctrl.cpp index d6395d96cf..75c2a0b1fa 100644 --- a/src/libs/agg/src/ctrl/agg_slider_ctrl.cpp +++ b/src/libs/agg/src/ctrl/agg_slider_ctrl.cpp @@ -168,8 +168,8 @@ namespace agg m_text.start_point(m_x1, m_y1); m_text.size((m_y2 - m_y1) * 1.2, m_y2 - m_y1); m_text_poly.width(m_text_thickness); - m_text_poly.line_join(vcgen_stroke::round_join); - m_text_poly.line_cap(vcgen_stroke::round_cap); + m_text_poly.line_join(round_join); + m_text_poly.line_cap(round_cap); m_text_poly.rewind(0); break; diff --git a/src/libs/agg/src/dbg_new/agg_dbg_new.cpp b/src/libs/agg/src/dbg_new/agg_dbg_new.cpp index 3b5d5fab32..92d8de593b 100644 --- a/src/libs/agg/src/dbg_new/agg_dbg_new.cpp +++ b/src/libs/agg/src/dbg_new/agg_dbg_new.cpp @@ -123,7 +123,7 @@ namespace agg #ifdef _WIN32 if(dbg_new_level == -1) { - FILE* fd = fopen("stdout.txt", "wt"); + FILE* fd = fopen("stdout.txt", "w"); fclose(fd); } #endif diff --git a/src/libs/agg/src/platform/BeOS/agg_platform_support.cpp b/src/libs/agg/src/platform/BeOS/agg_platform_support.cpp index 9ceaddac76..4db743b227 100644 --- a/src/libs/agg/src/platform/BeOS/agg_platform_support.cpp +++ b/src/libs/agg/src/platform/BeOS/agg_platform_support.cpp @@ -160,7 +160,6 @@ class AGGView : public BView { virtual void FrameResized(float width, float height) { - delete fBitmap; BRect r(0.0, 0.0, width, height); BBitmap* bitmap = new BBitmap(r, 0, B_RGBA32); if (bitmap->IsValid()) {