//------------------------------------------------------------------------ void create_star(double xc, double yc, double r1, double r2, unsigned n, double start_angle = 0.0) { m_ps.remove_all(); unsigned i; start_angle *= agg::pi / 180.0; for(i = 0; i < n; i++) { double a = agg::pi * 2.0 * i / n - agg::pi / 2.0; double dx = cos(a + start_angle); double dy = sin(a + start_angle); if(i & 1) { m_ps.line_to(xc + dx * r1, yc + dy * r1); } else { if(i) m_ps.line_to(xc + dx * r2, yc + dy * r2); else m_ps.move_to(xc + dx * r2, yc + dy * r2); } } m_ps.close_polygon(); }
//------------------------------------------------------------------------ void create_star(agg::path_storage& ps) { double r = initial_width(); if(initial_height() < r) r = initial_height(); double r1 = r / 3 - 8.0; double r2 = r1 / 1.45; unsigned nr = 14; unsigned i; for(i = 0; i < nr; i++) { double a = agg::pi * 2.0 * i / nr - agg::pi / 2.0; double dx = cos(a); double dy = sin(a); if(i & 1) { ps.line_to(m_polygon_cx + dx * r1, m_polygon_cy + dy * r1); } else { if(i) ps.line_to(m_polygon_cx + dx * r2, m_polygon_cy + dy * r2); else ps.move_to(m_polygon_cx + dx * r2, m_polygon_cy + dy * r2); } } }
void compose_path() { unsigned flag = 0; if (m_close.cur_item() == 1) flag = agg::path_flags_cw; if (m_close.cur_item() == 2) flag = agg::path_flags_ccw; m_path.remove_all(); m_path.move_to(28.47, 6.45); m_path.curve3(21.58, 1.12, 19.82, 0.29); m_path.curve3(17.19, -0.93, 14.21, -0.93); m_path.curve3(9.57, -0.93, 6.57, 2.25); m_path.curve3(3.56, 5.42, 3.56, 10.60); m_path.curve3(3.56, 13.87, 5.03, 16.26); m_path.curve3(7.03, 19.58, 11.99, 22.51); m_path.curve3(16.94, 25.44, 28.47, 29.64); m_path.line_to(28.47, 31.40); m_path.curve3(28.47, 38.09, 26.34, 40.58); m_path.curve3(24.22, 43.07, 20.17, 43.07); m_path.curve3(17.09, 43.07, 15.28, 41.41); m_path.curve3(13.43, 39.75, 13.43, 37.60); m_path.line_to(13.53, 34.77); m_path.curve3(13.53, 32.52, 12.38, 31.30); m_path.curve3(11.23, 30.08, 9.38, 30.08); m_path.curve3(7.57, 30.08, 6.42, 31.35); m_path.curve3(5.27, 32.62, 5.27, 34.81); m_path.curve3(5.27, 39.01, 9.57, 42.53); m_path.curve3(13.87, 46.04, 21.63, 46.04); m_path.curve3(27.59, 46.04, 31.40, 44.04); m_path.curve3(34.28, 42.53, 35.64, 39.31); m_path.curve3(36.52, 37.21, 36.52, 30.71); m_path.line_to(36.52, 15.53); m_path.curve3(36.52, 9.13, 36.77, 7.69); m_path.curve3(37.01, 6.25, 37.57, 5.76); m_path.curve3(38.13, 5.27, 38.87, 5.27); m_path.curve3(39.65, 5.27, 40.23, 5.62); m_path.curve3(41.26, 6.25, 44.19, 9.18); m_path.line_to(44.19, 6.45); m_path.curve3(38.72, -0.88, 33.74, -0.88); m_path.curve3(31.35, -0.88, 29.93, 0.78); m_path.curve3(28.52, 2.44, 28.47, 6.45); m_path.close_polygon(flag); m_path.move_to(28.47, 9.62); m_path.line_to(28.47, 26.66); m_path.curve3(21.09, 23.73, 18.95, 22.51); m_path.curve3(15.09, 20.36, 13.43, 18.02); m_path.curve3(11.77, 15.67, 11.77, 12.89); m_path.curve3(11.77, 9.38, 13.87, 7.06); m_path.curve3(15.97, 4.74, 18.70, 4.74); m_path.curve3(22.41, 4.74, 28.47, 9.62); m_path.close_polygon(flag); }
void CAggMemoryDC::Lines( const PointFVector& pts, const Color& clr, const REAL width/*=1.0*/) { if (m_buf==0) return; unsigned count=pts.size()/2; ATLASSERT(count>0); ATLASSERT((float)count/2.0f>0); pixel_format pixf(m_rbuf); ren_base renb(pixf); solid_renderer ren_solid(renb); m_path.remove_all(); for(unsigned i=0; i<count; ++i) { m_path.move_to(pts[i*2].x, pts[i*2].y); m_path.line_to(pts[i*2+1].x, pts[i*2+1].y); } typedef agg::conv_stroke<conv_path_trans_type> conv_stroke_outline; conv_stroke_outline stroke(m_transpath); stroke.width(width); m_ras_aa.add_path(stroke); ren_solid.color(agg::rgba8(clr.GetR(), clr.GetG(), clr.GetB(), clr.GetA())); agg::render_scanlines(m_ras_aa, m_sl, ren_solid); }
unsigned parse_lion(agg::path_storage& path, agg::rgba8* colors, unsigned* path_idx) { // Parse the lion and then detect its bounding // box and arrange polygons orientations (make all polygons // oriented clockwise or counterclockwise) const char* ptr = g_lion; unsigned npaths = 0; while(*ptr) { if(*ptr != 'M' && isalnum(*ptr)) { unsigned c = 0; sscanf(ptr, "%x", &c); // New color. Every new color creates new path in the path object. path.close_polygon(); colors[npaths] = agg::rgb8_packed(c); path_idx[npaths] = path.start_new_path(); npaths++; while(*ptr && *ptr != '\n') ptr++; if(*ptr == '\n') ptr++; } else { float x = 0.0; float y = 0.0; while(*ptr && *ptr != '\n') { int c = *ptr; while(*ptr && !isdigit(*ptr)) ptr++; x = atof(ptr); while(*ptr && isdigit(*ptr)) ptr++; while(*ptr && !isdigit(*ptr)) ptr++; y = atof(ptr); if(c == 'M') { path.close_polygon(); path.move_to(x, y); } else { path.line_to(x, y); } while(*ptr && isdigit(*ptr)) ptr++; while(*ptr && *ptr != '\n' && !isalpha(*ptr)) ptr++; } if(*ptr == '\n') ptr++; } } path.arrange_orientations_all_paths(agg::path_flags_cw); return npaths; }
void CAggMemoryDC::SolidPolygon( const PointF* points, const Color& clr, unsigned point_count) { if (m_buf==0) return; if(m_npaths>0) { m_pathCache.close_polygon(); m_colorsCache[m_countpaths] = agg::rgba8(clr.GetR(), clr.GetG(), clr.GetB(), clr.GetA()); m_path_idxCache[m_countpaths] = m_pathCache.start_new_path(); m_countpaths++; m_pathCache.move_to(points->x, points->y); while(--point_count>0) { points++; m_pathCache.line_to(points->x, points->y); } } else { pixel_format pixf(m_rbuf); ren_base renb(pixf); solid_renderer ren_solid(renb); ATLASSERT(point_count>0); m_path.remove_all(); m_path.move_to(points->x, points->y); while(--point_count>0) { points++; m_path.line_to(points->x, points->y); } m_ras_aa.reset(); m_ras_aa.clip_box(0, 0, m_rcUpdate.Width(), m_rcUpdate.Height()); m_ras_aa.add_path(m_transpath); ren_solid.color(agg::rgba8(clr.GetR(), clr.GetG(), clr.GetB(), clr.GetA())); agg::render_scanlines(m_ras_aa, m_sl, ren_solid); } }
void CAggMemoryDC::LollyPop( const GraphTypes::RectF& rc, const GraphTypes::Color& clr, const GraphTypes::Color& clroutline, bool bLeft) { if (m_buf==0) return; pixel_format pixf(m_rbuf); ren_base renb(pixf); agg::line_profile_aa lnprof; lnprof.width(1.0); solid_renderer ren_solid(renb); outline_renderer outline_rd(renb, lnprof); outline_rasterizer_aa outline_rt(outline_rd); outline_rd.color(agg::rgba8(clroutline.GetR(), clroutline.GetG(), clroutline.GetB(), clroutline.GetA())); REAL radius=rc.Height/2; REAL split=rc.Width-rc.Height; REAL xcenter=bLeft? (rc.x+radius) : (rc.x+rc.Width-radius); REAL ycenter=rc.y+radius; agg::ellipse circle(xcenter, ycenter, radius, radius, 10); typedef agg::conv_transform<agg::ellipse, agg::trans_affine> conv_ellipse_trans_type; conv_ellipse_trans_type m_transcircle(circle, m_mtx); // connector line PointF p1, p2; p1.x=bLeft ? (rc.x+rc.Width-split) : rc.x; p1.y=rc.y+radius; p2.x=bLeft ? (rc.x+rc.Width) : (rc.x+split); p2.y=p1.y; m_path.remove_all(); m_path.move_to(p1.x, p1.y); m_path.line_to(p2.x, p2.y); m_ras_aa.reset(); m_ras_aa.add_path(m_transcircle); outline_rt.add_path(m_transcircle); outline_rt.add_path(m_transpath); ren_solid.color(agg::rgba8(clr.GetR(), clr.GetG(), clr.GetB(), clr.GetA())); agg::render_scanlines(m_ras_aa, m_sl, ren_solid); outline_rt.render(true); }
void make_gb_poly(agg::path_storage& ps) { ps.remove_all(); unsigned i; const double* p = poly1; ps.move_to(p[0], p[1]); p += 2; for(i = 1; i < sizeof(poly1) / sizeof(double) / 2; i++) { ps.line_to(p[0], p[1]); p += 2; } ps.close_polygon(); p = poly2; ps.move_to(p[0], p[1]); p += 2; for(i = 1; i < sizeof(poly2) / sizeof(double) / 2; i++) { ps.line_to(p[0], p[1]); p += 2; } ps.close_polygon(); }
void CAggMemoryDC::SolidPolygon( const PointF* points, const Color& clr, unsigned point_count, REAL widthoutline, const Color& clroutline ) { if (m_buf==0) return; ATLASSERT(point_count>0); pixel_format pixf(m_rbuf); ren_base renb(pixf); solid_renderer ren_solid(renb); m_ras_aa.reset(); m_path.remove_all(); m_path.move_to(points->x, points->y); while(--point_count>0) { points++; m_path.line_to(points->x, points->y); } m_path.close_polygon(); m_ras_aa.add_path(m_transpath); ren_solid.color(agg::rgba8(clr.GetR(), clr.GetG(), clr.GetB(), clr.GetA())); agg::render_scanlines(m_ras_aa, m_sl, ren_solid); if(widthoutline>REAL(0)) { typedef agg::conv_stroke<conv_path_trans_type> conv_trans_stroke_outline; ren_solid.color(agg::rgba8(clroutline.GetR(), clroutline.GetG(), clroutline.GetB(), clroutline.GetA())); conv_trans_stroke_outline stroke(m_transpath); stroke.width(widthoutline); m_ras_aa.add_path(stroke); agg::render_scanlines(m_ras_aa, m_sl, ren_solid); } }
void CAggMemoryDC::LinearGradientRect( const RectF& rc, const Color& clrstart, const Color& clrend, bool bHorizontal/*=true*/) { // The gradient color array typedef agg::pod_auto_array<agg::rgba8, 256> color_array_type; // Gradient shape function (linear, radial, custom, etc) //----------------- typedef agg::gradient_xy gradient_func_type; // Span interpolator. This object is used in all span generators // that operate with transformations during iterating of the spans, // for example, image transformers use the interpolator too. //----------------- typedef agg::span_interpolator_linear<> interpolator_type; // Span allocator is an object that allocates memory for // the array of colors that will be used to render the // color spans. One object can be shared between different // span generators. //----------------- typedef agg::span_allocator<agg::rgba8> span_allocator_type; // Finally, the gradient span generator working with the agg::rgba8 // color type. // The 4-th argument is the color function that should have // the [] operator returning the color in range of [0...255]. // In our case it will be a simple look-up table of 256 colors. //----------------- typedef agg::span_gradient<agg::rgba8, interpolator_type, gradient_func_type, color_array_type> span_gradient_type; // The gradient scanline renderer type //----------------- typedef agg::renderer_scanline_aa<ren_base, span_allocator_type, span_gradient_type> renderer_gradient_type; // Common declarations (pixel format and basic renderer). //---------------- pixel_format pixf(m_rbuf); ren_base renb(pixf); // The gradient objects declarations //---------------- gradient_func_type gradient_func; // The gradient function agg::trans_affine gradient_mtx; // Affine transformer interpolator_type span_interpolator(gradient_mtx); // Span interpolator span_allocator_type span_allocator; // Span Allocator color_array_type color_array; // Gradient colors // Declare the gradient span itself. // The last two arguments are so called "d1" and "d2" // defining two distances in pixels, where the gradient starts // and where it ends. The actual meaning of "d1" and "d2" depands // on the gradient function. //---------------- span_gradient_type span_gradient(span_interpolator, gradient_func, color_array, bHorizontal ? rc.x : rc.y, bHorizontal ? rc.x+rc.Width : rc.y+rc.Height); // The gradient renderer //---------------- renderer_gradient_type ren_gradient(renb, span_allocator, span_gradient); fill_color_array(color_array, agg::rgba8(clrstart.GetR(), clrstart.GetG(), clrstart.GetB(), clrstart.GetA()), agg::rgba8(clrend.GetR(), clrend.GetG(), clrend.GetB(), clrend.GetA())); m_path.remove_all(); m_path.move_to(rc.x, rc.y); m_path.line_to(rc.x+rc.Width, rc.y); m_path.line_to(rc.x+rc.Width, rc.y+rc.Height); m_path.line_to(rc.x, rc.y+rc.Height); m_path.close_polygon(); m_ras_aa.reset(); m_ras_aa.clip_box(0, 0, m_rcUpdate.Width(), m_rcUpdate.Height()); m_ras_aa.add_path(m_transpath); agg::render_scanlines(m_ras_aa, m_sl, ren_gradient); }
void roadmap_canvas_draw_multiple_lines (int count, int *lines, RoadMapGuiPoint *points, int fast_draw) { int i; int count_of_points; dbg_time_start(DBG_TIME_DRAW_LINES); #ifdef WIN32_PROFILE ResumeCAPAll(); #endif #ifdef _WIN32_ if (fast_draw) { roadmap_canvas_native_draw_multiple_lines (count, lines, points, CurrentPen->color.r, CurrentPen->color.g, CurrentPen->color.b, CurrentPen->thickness); return; } #endif if (!fast_draw) { raso.round_cap(true); raso.line_join(agg::outline_miter_accurate_join); } else { raso.round_cap(false); raso.line_join(agg::outline_no_join); } // raso.accurate_join(true); static agg::path_storage path; for (i = 0; i < count; ++i) { int first = 1; count_of_points = *lines; if (count_of_points < 2) continue; dbg_time_start(DBG_TIME_CREATE_PATH); for (int j=0; j<count_of_points; j++) { if (first) { first = 0; path.move_to(points->x, points->y); } else { path.line_to(points->x, points->y); } points++; } dbg_time_end(DBG_TIME_CREATE_PATH); dbg_time_start(DBG_TIME_ADD_PATH); #if 0 if (fast_draw) { renderer_pr ren_pr(agg_renb); agg::rasterizer_outline<renderer_pr> ras_line(ren_pr); ren_pr.line_color(CurrentPen->color); ras_line.add_path(path); } else { #endif raso.add_path(path); //} path.remove_all (); dbg_time_end(DBG_TIME_ADD_PATH); lines += 1; } #ifdef WIN32_PROFILE SuspendCAPAll(); #endif return; dbg_time_end(DBG_TIME_DRAW_LINES); } void roadmap_canvas_draw_multiple_polygons (int count, int *polygons, RoadMapGuiPoint *points, int filled, int fast_draw) { int i; int count_of_points; static agg::path_storage path; for (i = 0; i < count; ++i) { count_of_points = *polygons; int first = 1; for (int j=0; j<count_of_points; j++) { if (first) { first = 0; path.move_to(points->x, points->y); } else { path.line_to(points->x, points->y); } points++; } path.close_polygon(); if (filled) { ras.reset(); ras.add_path(path); ren_solid.color(CurrentPen->color); agg::render_scanlines( ras, sl, ren_solid); } else if (fast_draw) { renderer_pr ren_pr(agg_renb); agg::rasterizer_outline<renderer_pr> ras_line(ren_pr); ren_pr.line_color(CurrentPen->color); ras_line.add_path(path); } else { raso.add_path(path); } path.remove_all (); polygons += 1; } }
the_application(agg::pix_format_e format, bool flip_y) : agg::platform_support(format, flip_y), m_method (10.0, 10.0, 130.0, 55.0, !flip_y), m_radius (130 + 10.0, 10.0 + 4.0, 130 + 300.0, 10.0 + 8.0 + 4.0, !flip_y), m_shadow_ctrl(4), m_shape(m_path) { add_ctrl(m_method); m_method.text_size(8); m_method.add_item("Single Color"); m_method.add_item("Color LUT"); m_method.cur_item(1); add_ctrl(m_radius); m_radius.range(0.0, 40.0); m_radius.value(15.0); m_radius.label("Blur Radius=%1.2f"); add_ctrl(m_shadow_ctrl); m_path.remove_all(); m_path.move_to(28.47, 6.45); m_path.curve3(21.58, 1.12, 19.82, 0.29); m_path.curve3(17.19, -0.93, 14.21, -0.93); m_path.curve3(9.57, -0.93, 6.57, 2.25); m_path.curve3(3.56, 5.42, 3.56, 10.60); m_path.curve3(3.56, 13.87, 5.03, 16.26); m_path.curve3(7.03, 19.58, 11.99, 22.51); m_path.curve3(16.94, 25.44, 28.47, 29.64); m_path.line_to(28.47, 31.40); m_path.curve3(28.47, 38.09, 26.34, 40.58); m_path.curve3(24.22, 43.07, 20.17, 43.07); m_path.curve3(17.09, 43.07, 15.28, 41.41); m_path.curve3(13.43, 39.75, 13.43, 37.60); m_path.line_to(13.53, 34.77); m_path.curve3(13.53, 32.52, 12.38, 31.30); m_path.curve3(11.23, 30.08, 9.38, 30.08); m_path.curve3(7.57, 30.08, 6.42, 31.35); m_path.curve3(5.27, 32.62, 5.27, 34.81); m_path.curve3(5.27, 39.01, 9.57, 42.53); m_path.curve3(13.87, 46.04, 21.63, 46.04); m_path.curve3(27.59, 46.04, 31.40, 44.04); m_path.curve3(34.28, 42.53, 35.64, 39.31); m_path.curve3(36.52, 37.21, 36.52, 30.71); m_path.line_to(36.52, 15.53); m_path.curve3(36.52, 9.13, 36.77, 7.69); m_path.curve3(37.01, 6.25, 37.57, 5.76); m_path.curve3(38.13, 5.27, 38.87, 5.27); m_path.curve3(39.65, 5.27, 40.23, 5.62); m_path.curve3(41.26, 6.25, 44.19, 9.18); m_path.line_to(44.19, 6.45); m_path.curve3(38.72, -0.88, 33.74, -0.88); m_path.curve3(31.35, -0.88, 29.93, 0.78); m_path.curve3(28.52, 2.44, 28.47, 6.45); m_path.close_polygon(); m_path.move_to(28.47, 9.62); m_path.line_to(28.47, 26.66); m_path.curve3(21.09, 23.73, 18.95, 22.51); m_path.curve3(15.09, 20.36, 13.43, 18.02); m_path.curve3(11.77, 15.67, 11.77, 12.89); m_path.curve3(11.77, 9.38, 13.87, 7.06); m_path.curve3(15.97, 4.74, 18.70, 4.74); m_path.curve3(22.41, 4.74, 28.47, 9.62); m_path.close_polygon(); agg::trans_affine shape_mtx; shape_mtx *= agg::trans_affine_scaling(4.0); shape_mtx *= agg::trans_affine_translation(150, 100); m_path.transform(shape_mtx); agg::bounding_rect_single(m_shape, 0, &m_shape_bounds.x1, &m_shape_bounds.y1, &m_shape_bounds.x2, &m_shape_bounds.y2); m_shadow_ctrl.xn(0) = m_shape_bounds.x1; m_shadow_ctrl.yn(0) = m_shape_bounds.y1; m_shadow_ctrl.xn(1) = m_shape_bounds.x2; m_shadow_ctrl.yn(1) = m_shape_bounds.y1; m_shadow_ctrl.xn(2) = m_shape_bounds.x2; m_shadow_ctrl.yn(2) = m_shape_bounds.y2; m_shadow_ctrl.xn(3) = m_shape_bounds.x1; m_shadow_ctrl.yn(3) = m_shape_bounds.y2; m_shadow_ctrl.line_color(agg::rgba(0, 0.3, 0.5, 0.3)); m_color_lut.resize(256); unsigned i; const agg::int8u* p = g_gradient_colors; for(i = 0; i < 256; i++) { m_color_lut[i] = agg::rgba8(p[0], p[1], p[2], (i > 63) ? 255 : i * 4);//p[3]); //m_color_lut[i].premultiply(); p += 4; } }
void ASSDrawEngine::AddDrawCmdToAGGPathStorage(DrawCmd* cmd, agg::path_storage& path, DRAWCMDMODE mode) { if (mode == HILITE && cmd->prev) path.move_to(cmd->prev->m_point->x(), cmd->prev->m_point->y()); switch(cmd->type) { case M: path.move_to(cmd->m_point->x(),cmd->m_point->y()); break; case B: if (cmd->initialized) { //path.move_to(cmd->prev->m_point->x(),cmd->prev->m_point->y()); PointList::iterator iterate = cmd->controlpoints.begin(); int x[2], y[2]; x[0] = (*iterate)->x(); y[0] = (*iterate)->y(); iterate++; x[1] = (*iterate)->x(); y[1] = (*iterate)->y(); path.curve4(x[0], y[0], x[1], y[1], cmd->m_point->x(),cmd->m_point->y()); break; } case L: if (mode == CTRL_LN) path.move_to(cmd->m_point->x(),cmd->m_point->y()); else path.line_to(cmd->m_point->x(),cmd->m_point->y()); break; case S: unsigned np = cmd->controlpoints.size(); agg::pod_array<double> m_polygon(np * 2); unsigned _pn = 0; PointList::iterator iterate = cmd->controlpoints.begin(); while (iterate != cmd->controlpoints.end()) { m_polygon[_pn] = (*iterate)->x(); _pn++; m_polygon[_pn] = (*iterate)->y(); _pn++; iterate++; } //m_polygon[_pn++] = cmd->m_point->x(); //m_polygon[_pn++] = cmd->m_point->y(); //path.move_to(cmd->prev->m_point->x(),cmd->prev->m_point->y()); if (mode == CTRL_LN) { _pn = 0; while (_pn < np * 2) { path.line_to((int) m_polygon[_pn],(int) m_polygon[_pn + 1]); _pn += 2; } path.line_to(cmd->m_point->x(), cmd->m_point->y()); } else { //path.line_to((int) m_polygon[0],(int) m_polygon[1]); aggpolygon poly(&m_polygon[0], np, false, false); agg::conv_bcspline<agg::simple_polygon_vertex_source> bspline(poly); bspline.interpolation_step(0.01); agg::path_storage npath; npath.join_path(bspline); path.join_path(npath); if (mode == HILITE) path.move_to((int) m_polygon[np * 2 - 2], (int) m_polygon[np * 2 - 1] ); path.line_to(cmd->m_point->x(), cmd->m_point->y()); } break; } }
the_application(agg::pix_format_e format, bool flip_y) : agg::platform_support(format, flip_y), m_method (10.0, 10.0, 130.0, 70.0, !flip_y), m_radius (130 + 10.0, 10.0 + 4.0, 130 + 300.0, 10.0 + 8.0 + 4.0, !flip_y), m_shadow_ctrl(4), m_channel_r (10.0, 80.0, "Red", !flip_y), m_channel_g (10.0, 95.0, "Green", !flip_y), m_channel_b (10.0, 110.0, "Blue", !flip_y), m_shape(m_path) { add_ctrl(m_method); m_method.text_size(8); m_method.add_item("Stack Blur"); m_method.add_item("Recursive Blur"); m_method.add_item("Channels"); m_method.cur_item(0); add_ctrl(m_radius); m_radius.range(0.0, 40.0); m_radius.value(15.0); m_radius.label("Blur Radius=%1.2f"); add_ctrl(m_shadow_ctrl); add_ctrl(m_channel_r); add_ctrl(m_channel_g); add_ctrl(m_channel_b); m_channel_g.status(true); m_path.remove_all(); m_path.move_to(28.47, 6.45); m_path.curve3(21.58, 1.12, 19.82, 0.29); m_path.curve3(17.19, -0.93, 14.21, -0.93); m_path.curve3(9.57, -0.93, 6.57, 2.25); m_path.curve3(3.56, 5.42, 3.56, 10.60); m_path.curve3(3.56, 13.87, 5.03, 16.26); m_path.curve3(7.03, 19.58, 11.99, 22.51); m_path.curve3(16.94, 25.44, 28.47, 29.64); m_path.line_to(28.47, 31.40); m_path.curve3(28.47, 38.09, 26.34, 40.58); m_path.curve3(24.22, 43.07, 20.17, 43.07); m_path.curve3(17.09, 43.07, 15.28, 41.41); m_path.curve3(13.43, 39.75, 13.43, 37.60); m_path.line_to(13.53, 34.77); m_path.curve3(13.53, 32.52, 12.38, 31.30); m_path.curve3(11.23, 30.08, 9.38, 30.08); m_path.curve3(7.57, 30.08, 6.42, 31.35); m_path.curve3(5.27, 32.62, 5.27, 34.81); m_path.curve3(5.27, 39.01, 9.57, 42.53); m_path.curve3(13.87, 46.04, 21.63, 46.04); m_path.curve3(27.59, 46.04, 31.40, 44.04); m_path.curve3(34.28, 42.53, 35.64, 39.31); m_path.curve3(36.52, 37.21, 36.52, 30.71); m_path.line_to(36.52, 15.53); m_path.curve3(36.52, 9.13, 36.77, 7.69); m_path.curve3(37.01, 6.25, 37.57, 5.76); m_path.curve3(38.13, 5.27, 38.87, 5.27); m_path.curve3(39.65, 5.27, 40.23, 5.62); m_path.curve3(41.26, 6.25, 44.19, 9.18); m_path.line_to(44.19, 6.45); m_path.curve3(38.72, -0.88, 33.74, -0.88); m_path.curve3(31.35, -0.88, 29.93, 0.78); m_path.curve3(28.52, 2.44, 28.47, 6.45); m_path.close_polygon(); m_path.move_to(28.47, 9.62); m_path.line_to(28.47, 26.66); m_path.curve3(21.09, 23.73, 18.95, 22.51); m_path.curve3(15.09, 20.36, 13.43, 18.02); m_path.curve3(11.77, 15.67, 11.77, 12.89); m_path.curve3(11.77, 9.38, 13.87, 7.06); m_path.curve3(15.97, 4.74, 18.70, 4.74); m_path.curve3(22.41, 4.74, 28.47, 9.62); m_path.close_polygon(); agg::trans_affine shape_mtx; shape_mtx *= agg::trans_affine_scaling(4.0); shape_mtx *= agg::trans_affine_translation(150, 100); m_path.transform(shape_mtx); agg::bounding_rect_single(m_shape, 0, &m_shape_bounds.x1, &m_shape_bounds.y1, &m_shape_bounds.x2, &m_shape_bounds.y2); m_shadow_ctrl.xn(0) = m_shape_bounds.x1; m_shadow_ctrl.yn(0) = m_shape_bounds.y1; m_shadow_ctrl.xn(1) = m_shape_bounds.x2; m_shadow_ctrl.yn(1) = m_shape_bounds.y1; m_shadow_ctrl.xn(2) = m_shape_bounds.x2; m_shadow_ctrl.yn(2) = m_shape_bounds.y2; m_shadow_ctrl.xn(3) = m_shape_bounds.x1; m_shadow_ctrl.yn(3) = m_shape_bounds.y2; m_shadow_ctrl.line_color(agg::rgba(0, 0.3, 0.5, 0.3)); }