Example #1
0
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();
}
Example #3
0
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);
}
Example #4
0
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);
  }
}
Example #6
0
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);
    }
  }
}