void AirspaceRenderer::Draw(Canvas &canvas, #ifndef ENABLE_OPENGL Canvas &buffer_canvas, Canvas &stencil_canvas, #endif const WindowProjection &projection, const AirspaceRendererSettings &settings, const AirspaceWarningCopy &awc, const AirspacePredicate &visible) { if (airspace_database == NULL) return; #ifdef ENABLE_OPENGL if (settings.fill_mode == AirspaceRendererSettings::AS_FILL_ALL) { AirspaceFillRenderer renderer(canvas, projection, airspace_look, awc, settings); airspace_database->visit_within_range(projection.GetGeoScreenCenter(), projection.GetScreenDistanceMeters(), renderer, visible); } else { AirspaceVisitorRenderer renderer(canvas, projection, airspace_look, awc, settings); airspace_database->visit_within_range(projection.GetGeoScreenCenter(), projection.GetScreenDistanceMeters(), renderer, visible); } #else MapDrawHelper helper(canvas, buffer_canvas, stencil_canvas, projection, settings); AirspaceVisitorMap v(helper, awc, settings, airspace_look); // JMW TODO wasteful to draw twice, can't it be drawn once? // we are using two draws so borders go on top of everything airspace_database->visit_within_range(projection.GetGeoScreenCenter(), projection.GetScreenDistanceMeters(), v, visible); awc.visit_warned(v); awc.visit_inside(v); v.draw_intercepts(); AirspaceOutlineRenderer outline_renderer(canvas, projection, airspace_look, settings.black_outline); airspace_database->visit_within_range(projection.GetGeoScreenCenter(), projection.GetScreenDistanceMeters(), outline_renderer, visible); awc.visit_warned(outline_renderer); awc.visit_inside(outline_renderer); #endif m_airspace_intersections = awc.get_locations(); }
inline bool AirspaceRenderer::DrawFill(Canvas &buffer_canvas, Canvas &stencil_canvas, const WindowProjection &projection, const AirspaceRendererSettings &settings, const AirspaceWarningCopy &awc, const AirspacePredicate &visible) { StencilMapCanvas helper(buffer_canvas, stencil_canvas, projection, settings); AirspaceVisitorMap v(helper, awc, settings, look); // JMW TODO wasteful to draw twice, can't it be drawn once? // we are using two draws so borders go on top of everything const auto range = airspaces->QueryWithinRange(projection.GetGeoScreenCenter(), projection.GetScreenDistanceMeters()); for (const auto &i : range) { const AbstractAirspace &airspace = i.GetAirspace(); if (visible(airspace)) v.Visit(airspace); } return v.Commit(); }
inline void AirspaceRenderer::DrawOutline(Canvas &canvas, const WindowProjection &projection, const AirspaceRendererSettings &settings, const AirspacePredicate &visible) const { AirspaceOutlineRenderer outline_renderer(canvas, projection, look, settings); airspaces->VisitWithinRange(projection.GetGeoScreenCenter(), projection.GetScreenDistanceMeters(), outline_renderer, visible); }
bool TrailRenderer::LoadTrace(const TraceComputer &trace_computer, unsigned min_time, const WindowProjection &projection) { trace.clear(); trace_computer.LockedCopyTo(trace, min_time, projection.GetGeoScreenCenter(), projection.DistancePixelsToMeters(3)); return !trace.empty(); }
void AirspaceRenderer::Draw(Canvas &canvas, #ifndef ENABLE_OPENGL Canvas &stencil_canvas, #endif const WindowProjection &projection, const AirspaceRendererSettings &settings, const AirspaceWarningCopy &awc, const AirspacePredicate &visible) { if (airspaces == NULL || airspaces->IsEmpty()) return; #ifdef ENABLE_OPENGL if (settings.fill_mode == AirspaceRendererSettings::FillMode::ALL || settings.fill_mode == AirspaceRendererSettings::FillMode::NONE) { AirspaceFillRenderer renderer(canvas, projection, look, awc, settings); airspaces->VisitWithinRange(projection.GetGeoScreenCenter(), projection.GetScreenDistanceMeters(), renderer, visible); } else { AirspaceVisitorRenderer renderer(canvas, projection, look, awc, settings); airspaces->VisitWithinRange(projection.GetGeoScreenCenter(), projection.GetScreenDistanceMeters(), renderer, visible); } #else if (settings.fill_mode != AirspaceRendererSettings::FillMode::NONE) DrawFillCached(canvas, stencil_canvas, projection, settings, awc, visible); DrawOutline(canvas, projection, settings, visible); #endif intersections = awc.GetLocations(); }
inline void AirspaceRenderer::DrawOutline(Canvas &canvas, const WindowProjection &projection, const AirspaceRendererSettings &settings, const AirspacePredicate &visible) const { const auto range = airspaces->QueryWithinRange(projection.GetGeoScreenCenter(), projection.GetScreenDistanceMeters()); AirspaceOutlineRenderer outline_renderer(canvas, projection, look, settings); for (const auto &i : range) { const AbstractAirspace &airspace = i.GetAirspace(); if (visible(airspace)) outline_renderer.Visit(airspace); } }
void AirspaceLabelRenderer::DrawInternal(Canvas &canvas, #ifndef ENABLE_OPENGL Canvas &stencil_canvas, #endif const WindowProjection &projection, const AirspaceRendererSettings &settings, const AirspaceWarningCopy &awc, const AirspacePredicate &visible, const AirspaceWarningConfig &config) { AirspaceLabelList labels; for (const auto &i : airspaces->QueryWithinRange(projection.GetGeoScreenCenter(), projection.GetScreenDistanceMeters())) { const AbstractAirspace &airspace = i.GetAirspace(); if (visible(airspace)) labels.Add(airspace.GetCenter(), airspace.GetType(), airspace.GetBase(), airspace.GetTop()); } if(settings.label_selection == AirspaceRendererSettings::LabelSelection::ALL) { labels.Sort(config); // default paint settings canvas.SetTextColor(look.label_text_color); canvas.Select(*look.name_font); canvas.Select(look.label_pen); canvas.Select(look.label_brush); canvas.SetBackgroundTransparent(); // draw TCHAR topText[NAME_SIZE + 1]; TCHAR baseText[NAME_SIZE + 1]; for (const auto &label : labels) { // size of text AirspaceFormatter::FormatAltitudeShort(topText, label.top, false); PixelSize topSize = canvas.CalcTextSize(topText); AirspaceFormatter::FormatAltitudeShort(baseText, label.base, false); PixelSize baseSize = canvas.CalcTextSize(baseText); int labelWidth = std::max(topSize.cx, baseSize.cx) + 2 * Layout::GetTextPadding(); int labelHeight = topSize.cy + baseSize.cy; // box const auto pos = projection.GeoToScreen(label.pos); PixelRect rect; rect.left = pos.x - labelWidth / 2; rect.top = pos.y; rect.right = rect.left + labelWidth; rect.bottom = rect.top + labelHeight; canvas.Rectangle(rect.left, rect.top, rect.right, rect.bottom); #ifdef USE_GDI canvas.DrawLine(rect.left + Layout::GetTextPadding(), rect.top + labelHeight / 2, rect.right - Layout::GetTextPadding(), rect.top + labelHeight / 2); #else canvas.DrawHLine(rect.left + Layout::GetTextPadding(), rect.right - Layout::GetTextPadding(), rect.top + labelHeight / 2, look.label_pen.GetColor()); #endif // top text int x = rect.right - Layout::GetTextPadding() - topSize.cx; int y = rect.top; canvas.DrawText(x, y, topText); // base text x = rect.right - Layout::GetTextPadding() - baseSize.cx; y = rect.bottom - baseSize.cy; canvas.DrawText(x, y, baseText); } } }