| 205 | } |
| 206 | |
| 207 | bool GenerateChartByPoints(uint32_t width, uint32_t height, vector<m2::PointD> const & geometry, MapStyle mapStyle, |
| 208 | vector<uint8_t> & frameBuffer) |
| 209 | { |
| 210 | frameBuffer.clear(); |
| 211 | if (width == 0 || height == 0) |
| 212 | return false; |
| 213 | |
| 214 | agg::rgba8 const kBackgroundColor = agg::rgba8(255, 255, 255, 0); |
| 215 | agg::rgba8 const kLineColor = GetLineColor(mapStyle); |
| 216 | agg::rgba8 const kCurveColor = GetCurveColor(mapStyle); |
| 217 | double constexpr kLineWidthPxl = 2.0; |
| 218 | |
| 219 | using TBlender = BlendAdaptor<agg::rgba8, agg::order_rgba>; |
| 220 | using TPixelFormat = agg::pixfmt_custom_blend_rgba<TBlender, agg::rendering_buffer>; |
| 221 | using TBaseRenderer = agg::renderer_base<TPixelFormat>; |
| 222 | using TPath = agg::poly_container_adaptor<vector<m2::PointD>>; |
| 223 | using TStroke = agg::conv_stroke<TPath>; |
| 224 | |
| 225 | agg::rendering_buffer renderBuffer; |
| 226 | TPixelFormat pixelFormat(renderBuffer, agg::comp_op_src_over); |
| 227 | TBaseRenderer baseRenderer(pixelFormat); |
| 228 | |
| 229 | frameBuffer.assign(width * kAltitudeChartBPP * height, 0); |
| 230 | renderBuffer.attach(&frameBuffer[0], static_cast<unsigned>(width), static_cast<unsigned>(height), |
| 231 | static_cast<int>(width * kAltitudeChartBPP)); |
| 232 | |
| 233 | // Background. |
| 234 | baseRenderer.reset_clipping(true); |
| 235 | unsigned const op = pixelFormat.comp_op(); |
| 236 | pixelFormat.comp_op(agg::comp_op_src); |
| 237 | baseRenderer.clear(kBackgroundColor); |
| 238 | pixelFormat.comp_op(op); |
| 239 | |
| 240 | agg::rasterizer_scanline_aa<> rasterizer; |
| 241 | rasterizer.clip_box(0, 0, width, height); |
| 242 | |
| 243 | if (geometry.empty()) |
| 244 | return true; /* No chart line to draw. */ |
| 245 | |
| 246 | // Polygon under chart line. |
| 247 | agg::path_storage underChartGeometryPath; |
| 248 | underChartGeometryPath.move_to(geometry.front().x, static_cast<double>(height)); |
| 249 | for (auto const & p : geometry) |
| 250 | underChartGeometryPath.line_to(p.x, p.y); |
| 251 | underChartGeometryPath.line_to(geometry.back().x, static_cast<double>(height)); |
| 252 | underChartGeometryPath.close_polygon(); |
| 253 | |
| 254 | agg::conv_curve<agg::path_storage> curve(underChartGeometryPath); |
| 255 | rasterizer.add_path(curve); |
| 256 | agg::scanline32_p8 scanline; |
| 257 | agg::render_scanlines_aa_solid(rasterizer, scanline, baseRenderer, kCurveColor); |
| 258 | |
| 259 | // Chart line. |
| 260 | TPath path_adaptor(geometry, false); |
| 261 | TStroke stroke(path_adaptor); |
| 262 | stroke.width(kLineWidthPxl); |
| 263 | stroke.line_cap(agg::round_cap); |
| 264 | stroke.line_join(agg::round_join); |