void ThermalAssistantWindow::PaintRadarBackground(Canvas &canvas, fixed max_lift) const { canvas.Clear(look.background_color); canvas.SelectHollowBrush(); canvas.Select(look.inner_circle_pen); canvas.DrawCircle(mid.x, mid.y, radius / 2); canvas.Select(look.outer_circle_pen); canvas.DrawCircle(mid.x, mid.y, radius); if (small) return; canvas.SetTextColor(COLOR_BLACK); canvas.Select(look.circle_label_font); canvas.SetBackgroundColor(look.background_color); canvas.SetBackgroundOpaque(); TCHAR lift_string[10]; FormatUserVerticalSpeed(max_lift, lift_string, ARRAY_SIZE(lift_string)); PixelSize s = canvas.CalcTextSize(lift_string); canvas.text(mid.x - s.cx / 2, mid.y + radius - s.cy * 0.75, lift_string); FormatUserVerticalSpeed(fixed_zero, lift_string, ARRAY_SIZE(lift_string)); s = canvas.CalcTextSize(lift_string); canvas.text(mid.x - s.cx / 2, mid.y + radius / 2 - s.cy * 0.75, lift_string); canvas.SetBackgroundTransparent(); }
void ThermalAssistantWindow::PaintRadarBackground(Canvas &canvas) const { canvas.clear(hbBackground); canvas.SelectHollowBrush(); canvas.Select(hpInnerCircle); canvas.circle(mid.x, mid.y, radius / 2); canvas.Select(hpOuterCircle); canvas.circle(mid.x, mid.y, radius); if (small) return; canvas.SetTextColor(COLOR_BLACK); canvas.Select(hfLabels); canvas.SetBackgroundColor(hcBackground); canvas.SetBackgroundOpaque(); TCHAR lift_string[10]; Units::FormatUserVerticalSpeed(max_lift, lift_string, ARRAY_SIZE(lift_string)); PixelSize s = canvas.CalcTextSize(lift_string); canvas.text(mid.x - s.cx / 2, mid.y + radius - s.cy * 0.75, lift_string); Units::FormatUserVerticalSpeed(fixed_zero, lift_string, ARRAY_SIZE(lift_string)); s = canvas.CalcTextSize(lift_string); canvas.text(mid.x - s.cx / 2, mid.y + radius / 2 - s.cy * 0.75, lift_string); canvas.SetBackgroundTransparent(); }
void FlarmTrafficControl::PaintRelativeAltitude(Canvas &canvas, PixelRect rc, fixed relative_altitude) const { // Format relative altitude TCHAR buffer[20]; Unit unit = Units::GetUserAltitudeUnit(); FormatRelativeUserAltitude(relative_altitude, buffer, false); // Calculate unit size canvas.Select(look.info_units_font); const unsigned unit_width = UnitSymbolRenderer::GetSize(canvas, unit).cx; const unsigned unit_height = UnitSymbolRenderer::GetAscentHeight(look.info_units_font, unit); const unsigned space_width = unit_width / 3; // Calculate value size canvas.Select(look.info_values_font); const unsigned value_height = look.info_values_font.GetAscentHeight(); const unsigned value_width = canvas.CalcTextSize(buffer).cx; // Calculate positions const unsigned max_height = std::max(unit_height, value_height); // Paint value canvas.DrawText(rc.right - unit_width - space_width - value_width, rc.bottom - value_height, buffer); // Paint unit canvas.Select(look.info_units_font); UnitSymbolRenderer::Draw(canvas, RasterPoint(rc.right - unit_width, rc.bottom - unit_height), unit, look.unit_fraction_pen); // Paint label canvas.Select(look.info_labels_font); const unsigned label_width = canvas.CalcTextSize(_("Rel. Alt.")).cx; canvas.DrawText(rc.right - label_width, rc.bottom - max_height - look.info_labels_font.GetHeight(), _("Rel. Alt.")); }
void MapWindow::DrawTaskOffTrackIndicator(Canvas &canvas) { if (Calculated().circling || !Basic().location_available || !Basic().track_available || !GetMapSettings().detour_cost_markers_enabled) return; const TaskStats &task_stats = Calculated().task_stats; const ElementStat ¤t_leg = task_stats.current_leg; if (!task_stats.task_valid || !current_leg.location_remaining.IsValid()) return; const GeoPoint target = current_leg.location_remaining; GeoVector vec(Basic().location, target); if ((Basic().track - vec.bearing).AsDelta().AbsoluteDegrees() < fixed(10)) // insignificant error return; fixed distance_max = std::min(vec.distance, render_projection.GetScreenDistanceMeters() * fixed(0.7)); // too short to bother if (distance_max < fixed(5000)) return; GeoPoint start = Basic().location; canvas.Select(*look.overlay_font); canvas.SetTextColor(COLOR_BLACK); canvas.SetBackgroundTransparent(); GeoPoint dloc; int ilast = 0; for (fixed d = fixed(1) / 4; d <= fixed(1); d += fixed(1) / 4) { dloc = FindLatitudeLongitude(start, Basic().track, distance_max * d); fixed distance0 = start.Distance(dloc); fixed distance1 = target.Distance(dloc); fixed distance = fixed(distance0 + distance1) / vec.distance; int idist = iround((distance - fixed(1)) * 100); if ((idist != ilast) && (idist > 0) && (idist < 1000)) { TCHAR Buffer[5]; _stprintf(Buffer, _T("%d"), idist); RasterPoint sc = render_projection.GeoToScreen(dloc); PixelSize tsize = canvas.CalcTextSize(Buffer); canvas.DrawText(sc.x - tsize.cx / 2, sc.y - tsize.cy / 2, Buffer); ilast = idist; } } }
static void Draw(Canvas &canvas) { PixelRect rc = canvas.GetRect(); rc.Grow(-0.2 * rc.GetSize().cx); /* draw the banner text with a large font */ Font small_font; small_font.LoadFile("/opt/LK8000/share/fonts/DejaVuSansCondensed.ttf", (rc.GetSize().cy / 25)); canvas.Select(small_font); canvas.SetTextColor(COLOR_BLACK); canvas.SetBackgroundTransparent(); const TCHAR *const text = _T("Powered Off"); const PixelSize text_size = canvas.CalcTextSize(text); const RasterPoint text_pos = { rc.left + 16, rc.bottom - 16 - text_size.cy }; canvas.DrawText(text_pos.x, text_pos.y, text); Font big_font; big_font.LoadFile("/opt/LK8000/share/fonts/DejaVuSansCondensed-Bold.ttf", (rc.GetSize().cy / 10)); canvas.Select(big_font); const TCHAR *const text2 = _T("LK8000"); const PixelSize text2_size = canvas.CalcTextSize(text2); const RasterPoint text2_pos = { (rc.left + rc.GetSize().cx + text2_size.cx) / 2, (rc.top + (rc.GetSize().cy / 10)) }; canvas.DrawText(text2_pos.x, text2_pos.y, text2); const double Scale = (double)rc.GetSize().cx / (double)bird_size.cx; RasterPoint polygon[array_size(bird_polygon)] = {}; std::transform(std::begin(bird_polygon), std::end(bird_polygon), std::begin(polygon), [Scale, rc, text2_size, text2_pos]( const RasterPoint& pt ) { return RasterPoint(pt.x*Scale + rc.left, pt.y*Scale + text2_pos.y + text2_size.cy); }); canvas.SelectBlackBrush(); canvas.DrawPolygon(polygon, array_size(polygon)); }
void FlarmTrafficControl::PaintClimbRate(Canvas &canvas, PixelRect rc, fixed climb_rate) const { // Paint label canvas.Select(look.info_labels_font); const unsigned label_width = canvas.CalcTextSize(_("Vario")).cx; canvas.DrawText(rc.right - label_width, rc.top, _("Vario")); // Format climb rate TCHAR buffer[20]; Unit unit = Units::GetUserVerticalSpeedUnit(); FormatUserVerticalSpeed(climb_rate, buffer, false); // Calculate unit size canvas.Select(look.info_units_font); const unsigned unit_width = UnitSymbolRenderer::GetSize(canvas, unit).cx; const unsigned unit_height = UnitSymbolRenderer::GetAscentHeight(look.info_units_font, unit); UPixelScalar space_width = unit_width / 3; // Calculate value size canvas.Select(look.info_values_font); const unsigned value_height = look.info_values_font.GetAscentHeight(); const unsigned value_width = canvas.CalcTextSize(buffer).cx; // Calculate positions const int max_height = std::max(unit_height, value_height); const int y = rc.top + look.info_units_font.GetHeight() + max_height; // Paint value canvas.DrawText(rc.right - unit_width - space_width - value_width, y - value_height, buffer); // Paint unit canvas.Select(look.info_units_font); UnitSymbolRenderer::Draw(canvas, RasterPoint(rc.right - unit_width, y - unit_height), unit, look.unit_fraction_pen); }
void InfoBoxWindow::PaintValue(Canvas &canvas, Color background_color) { if (data.value.empty()) return; canvas.SetTextColor(look.GetValueColor(data.value_color)); canvas.Select(look.unit_font); int unit_width = UnitSymbolRenderer::GetSize(canvas, data.value_unit).cx; canvas.Select(look.value_font); int ascent_height = look.value_font.GetAscentHeight(); PixelSize value_size = canvas.CalcTextSize(data.value); if (unsigned(value_size.cx + unit_width) > value_rect.GetWidth()) { canvas.Select(look.small_value_font); ascent_height = look.small_value_font.GetAscentHeight(); value_size = canvas.CalcTextSize(data.value); } int x = std::max(0, (value_rect.left + value_rect.right - value_size.cx - unit_width) / 2); int y = (value_rect.top + value_rect.bottom - value_size.cy) / 2; canvas.TextAutoClipped(x, y, data.value); if (unit_width != 0) { const int unit_height = UnitSymbolRenderer::GetAscentHeight(look.unit_font, data.value_unit); canvas.Select(look.unit_font); UnitSymbolRenderer::Draw(canvas, { x + value_size.cx, y + ascent_height - unit_height }, data.value_unit, look.unit_fraction_pen); } }
/** * Paints a "No Traffic" sign on the given canvas * @param canvas The canvas to paint on */ void FlarmTrafficWindow::PaintRadarNoTraffic(Canvas &canvas) const { if (small) return; const TCHAR* str = _("No Traffic"); canvas.Select(look.no_traffic_font); PixelSize ts = canvas.CalcTextSize(str); canvas.SetTextColor(look.default_color); canvas.text(radar_mid.x - (ts.cx / 2), radar_mid.y - (radius / 2), str); }
void ThermalAssistantWindow::PaintNotCircling(Canvas &canvas) const { if (small) return; const TCHAR* str = _("Not Circling"); canvas.Select(hfNoTraffic); PixelSize ts = canvas.CalcTextSize(str); canvas.SetTextColor(hcStandard); canvas.text(mid.x - (ts.cx / 2), mid.y - (radius / 2), str); }
void ThermalAssistantWindow::PaintNotCircling(Canvas &canvas) const { if (small) return; const TCHAR* str = _("Not Circling"); canvas.Select(look.overlay_font); PixelSize ts = canvas.CalcTextSize(str); canvas.SetTextColor(look.text_color); canvas.text(mid.x - (ts.cx / 2), mid.y - (radius / 2), str); }
void TabDisplay::PaintButton(Canvas &canvas, unsigned CaptionStyle, const TCHAR *caption, const PixelRect &rc, const Bitmap *bmp, const bool isDown, bool inverse) { PixelRect rcTextFinal = rc; const UPixelScalar buttonheight = rc.bottom - rc.top; const PixelSize text_size = canvas.CalcTextSize(caption); const int textwidth = text_size.cx; const int textheight = text_size.cy; UPixelScalar textheightoffset = 0; if (textwidth > (rc.right - rc.left)) // assume 2 lines textheightoffset = std::max(0, (int)(buttonheight - textheight * 2) / 2); else textheightoffset = std::max(0, (int)(buttonheight - textheight) / 2); rcTextFinal.top += textheightoffset; canvas.DrawFilledRectangle(rc, canvas.GetBackgroundColor()); if (bmp != NULL) { const PixelSize bitmap_size = bmp->GetSize(); const int offsetx = (rc.right - rc.left - bitmap_size.cx / 2) / 2; const int offsety = (rc.bottom - rc.top - bitmap_size.cy) / 2; if (inverse) // black background canvas.CopyNotOr(rc.left + offsetx, rc.top + offsety, bitmap_size.cx / 2, bitmap_size.cy, *bmp, bitmap_size.cx / 2, 0); else canvas.CopyAnd(rc.left + offsetx, rc.top + offsety, bitmap_size.cx / 2, bitmap_size.cy, *bmp, bitmap_size.cx / 2, 0); } else { #ifndef USE_GDI if (IsDithered()) CaptionStyle |= DT_UNDERLINE; #endif canvas.DrawFormattedText(&rcTextFinal, caption, CaptionStyle); } }
void KnobTextEntryWindow::OnPaint(Canvas &canvas) { const PixelRect rc = GetClientRect(); canvas.Clear(Color(0x40, 0x40, 0x00)); // Do the actual painting of the text const DialogLook &look = UIGlobals::GetDialogLook(); canvas.Select(look.text_font); PixelSize tsize = canvas.CalcTextSize(buffer); PixelSize tsizec = canvas.CalcTextSize(buffer, cursor); PixelSize tsizea = canvas.CalcTextSize(buffer, cursor + 1); BulkPixelPoint p[5]; p[0].x = 10; p[0].y = (rc.GetHeight() - tsize.cy - 5) / 2; p[2].x = p[0].x + tsizec.cx; p[2].y = p[0].y + tsize.cy + 5; p[3].x = p[0].x + tsizea.cx; p[3].y = p[0].y + tsize.cy + 5; p[1].x = p[2].x; p[1].y = p[2].y - 2; p[4].x = p[3].x; p[4].y = p[3].y - 2; canvas.SelectWhitePen(); canvas.DrawPolyline(p + 1, 4); canvas.SetBackgroundTransparent(); canvas.SetTextColor(COLOR_WHITE); canvas.DrawText(p[0].x, p[0].y, buffer); }
/** * Paints the radar circle on the given canvas * @param canvas The canvas to paint on */ void FlarmTrafficWindow::PaintRadarBackground(Canvas &canvas) const { canvas.SelectHollowBrush(); canvas.Select(look.radar_pen); canvas.SetTextColor(look.radar_color); // Paint circles canvas.circle(radar_mid.x, radar_mid.y, radius); canvas.circle(radar_mid.x, radar_mid.y, radius / 2); PaintRadarPlane(canvas); if (small) return; // Paint zoom strings canvas.Select(look.label_font); canvas.SetBackgroundOpaque(); canvas.SetBackgroundColor(look.background_color); TCHAR distance_string[10]; FormatUserDistanceSmart(distance, distance_string, ARRAY_SIZE(distance_string)); PixelSize s = canvas.CalcTextSize(distance_string); canvas.text(radar_mid.x - s.cx / 2, radar_mid.y + radius - s.cy * 0.75, distance_string); FormatUserDistanceSmart(distance / 2, distance_string, ARRAY_SIZE(distance_string)); s = canvas.CalcTextSize(distance_string); canvas.text(radar_mid.x - s.cx / 2, radar_mid.y + radius / 2 - s.cy * 0.75, distance_string); canvas.SetBackgroundTransparent(); PaintNorth(canvas); }
static void OnTextPaint(gcc_unused WndOwnerDrawFrame *Sender, Canvas &canvas) { const PixelRect rc = Sender->GetClientRect(); canvas.Clear(Color(0x40, 0x40, 0x00)); // Do the actual painting of the text const DialogLook &look = UIGlobals::GetDialogLook(); canvas.Select(*look.text_font); PixelSize tsize = canvas.CalcTextSize(edittext); PixelSize tsizec = canvas.CalcTextSize(edittext, cursor); PixelSize tsizea = canvas.CalcTextSize(edittext, cursor + 1); RasterPoint p[5]; p[0].x = 10; p[0].y = (rc.bottom - rc.top - tsize.cy - 5) / 2; p[2].x = p[0].x + tsizec.cx; p[2].y = p[0].y + tsize.cy + 5; p[3].x = p[0].x + tsizea.cx; p[3].y = p[0].y + tsize.cy + 5; p[1].x = p[2].x; p[1].y = p[2].y - 2; p[4].x = p[3].x; p[4].y = p[3].y - 2; canvas.SelectWhitePen(); canvas.DrawPolyline(p + 1, 4); canvas.SetBackgroundTransparent(); canvas.SetTextColor(COLOR_WHITE); canvas.DrawText(p[0].x, p[0].y, edittext); }
void WndProperty::OnPaint(Canvas &canvas) { const bool focused = edit.HasFocus(); /* background and selector */ if (focused) { canvas.Clear(look.focused.background_color); } else { /* don't need to erase the background when it has been done by the parent window already */ if (HaveClipping()) canvas.Clear(look.background_color); } WindowControl::OnPaint(canvas); /* kludge: don't draw caption if width is too small (but not 0), used by the polar configuration panel. This concept needs to be redesigned. */ if (caption_width != 0 && !caption.empty()) { canvas.SetTextColor(focused ? look.focused.text_color : look.text_color); canvas.SetBackgroundTransparent(); canvas.Select(*look.text_font); PixelSize tsize = canvas.CalcTextSize(caption.c_str()); RasterPoint org; if (caption_width < 0) { org.x = edit_rc.left; org.y = edit_rc.top - tsize.cy; } else { org.x = caption_width - tsize.cx - Layout::FastScale(3); org.y = (GetHeight() - tsize.cy) / 2; } if (org.x < 1) org.x = 1; if (HaveClipping()) canvas.text(org.x, org.y, caption.c_str()); else canvas.text_clipped(org.x, org.y, caption_width - org.x, caption.c_str()); } }
void InfoBoxWindow::PaintTitle(Canvas &canvas) { if (data.title.empty()) return; if (!pressed && !HasFocus() && !dragging && !force_draw_selector && settings.border_style == InfoBoxSettings::BorderStyle::SHADED) canvas.DrawFilledRectangle(title_rect, look.caption_background_color); canvas.SetTextColor(look.GetTitleColor(data.title_color)); const Font &font = look.title_font; canvas.Select(font); PixelSize tsize = canvas.CalcTextSize(data.title); PixelScalar halftextwidth = (title_rect.left + title_rect.right - tsize.cx) / 2; PixelScalar x = std::max(PixelScalar(1), PixelScalar(title_rect.left + halftextwidth)); PixelScalar y = title_rect.top; canvas.TextAutoClipped(x, y, data.title); if (settings.border_style == InfoBoxSettings::BorderStyle::TAB && halftextwidth > Layout::Scale(3)) { PixelScalar ytop = title_rect.top + font.GetCapitalHeight() / 2; PixelScalar ytopedge = ytop + Layout::GetTextPadding(); PixelScalar ybottom = title_rect.top + Layout::Scale(6) + font.GetCapitalHeight(); canvas.Select(look.border_pen); RasterPoint tab[8]; tab[0].x = tab[1].x = title_rect.left; tab[0].y = tab[7].y = ybottom; tab[2].x = title_rect.left + Layout::GetTextPadding(); tab[2].y = tab[5].y = tab[3].y = tab[4].y = ytop; tab[1].y = tab[6].y = ytopedge; tab[5].x = title_rect.right - Layout::GetTextPadding(); tab[6].x = tab[7].x = title_rect.right; tab[3].x = title_rect.left + halftextwidth - Layout::Scale(1); tab[4].x = title_rect.right - halftextwidth + Layout::Scale(1); canvas.DrawPolyline(tab, 4); canvas.DrawPolyline(tab + 4, 4); } }
virtual void OnPaint(Canvas &canvas) { canvas.SelectWhiteBrush(); if (has_focus()) canvas.SelectBlackPen(); else canvas.SelectWhitePen(); canvas.clear(); unsigned text_height = canvas.CalcTextSize(_T("W")).cy; for (int i = num_events - 1, y = 4; i >= 0; --i, y += text_height) { const struct key_event &event = events[i]; TCHAR buffer[64]; _stprintf(buffer, _T("key %s = 0x%x"), event.down ? _T("down") : _T("up"), event.code); canvas.text(4, y, buffer); } }
void InfoBoxWindow::PaintTitle(Canvas &canvas) { if (data.title.empty()) return; canvas.SetTextColor(look.GetTitleColor(data.title_color)); const Font &font = *look.title.font; canvas.Select(font); PixelSize tsize = canvas.CalcTextSize(data.title); PixelScalar halftextwidth = (title_rect.left + title_rect.right - tsize.cx) / 2; PixelScalar x = max(PixelScalar(1), PixelScalar(title_rect.left + halftextwidth)); PixelScalar y = title_rect.top + 1 + font.GetCapitalHeight() - font.GetAscentHeight(); canvas.TextAutoClipped(x, y, data.title); if (settings.border_style == apIbTab && halftextwidth > Layout::Scale(3)) { PixelScalar ytop = title_rect.top + font.GetCapitalHeight() / 2; PixelScalar ytopedge = ytop + Layout::Scale(2); PixelScalar ybottom = title_rect.top + Layout::Scale(6) + font.GetCapitalHeight(); canvas.Select(look.border_pen); RasterPoint tab[8]; tab[0].x = tab[1].x = title_rect.left; tab[0].y = tab[7].y = ybottom; tab[2].x = title_rect.left + Layout::Scale(2); tab[2].y = tab[5].y = tab[3].y = tab[4].y = ytop; tab[1].y = tab[6].y = ytopedge; tab[5].x = title_rect.right - Layout::Scale(2); tab[6].x = tab[7].x = title_rect.right; tab[3].x = title_rect.left + halftextwidth - Layout::Scale(1); tab[4].x = title_rect.right - halftextwidth + Layout::Scale(1); canvas.DrawPolyline(tab, 4); canvas.DrawPolyline(tab + 4, 4); } }
void InfoBoxWindow::PaintComment(Canvas &canvas) { if (data.comment.empty()) return; canvas.SetTextColor(look.GetCommentColor(data.comment_color)); const Font &font = look.title_font; canvas.Select(font); PixelSize tsize = canvas.CalcTextSize(data.comment); int x = std::max(1, (comment_rect.left + comment_rect.right - tsize.cx) / 2); int y = comment_rect.top; canvas.TextAutoClipped(x, y, data.comment); }
/** * Paints the radar circle on the given canvas * @param canvas The canvas to paint on */ void FlarmTrafficWindow::PaintNorth(Canvas &canvas) const { DoublePoint2D p(0, -1); if (!enable_north_up) { p = fr.Rotate(p); } canvas.SetTextColor(look.background_color); canvas.Select(look.radar_pen); canvas.Select(look.radar_brush); canvas.SetBackgroundTransparent(); canvas.Select(look.label_font); PixelSize s = canvas.CalcTextSize(_T("N")); canvas.DrawCircle(radar_mid.x + iround(p.x * radius), radar_mid.y + iround(p.y * radius), s.cy * 0.65); canvas.DrawText(radar_mid.x + iround(p.x * radius) - s.cx / 2, radar_mid.y + iround(p.y * radius) - s.cy / 2, _T("N")); }
void FlarmTrafficControl::PaintDistance(Canvas &canvas, PixelRect rc, fixed distance) const { // Format distance TCHAR buffer[20]; Unit unit = FormatUserDistanceSmart(distance, buffer, false, fixed(1000)); // Calculate unit size canvas.Select(look.info_units_font); const unsigned unit_width = UnitSymbolRenderer::GetSize(canvas, unit).cx; const unsigned unit_height = UnitSymbolRenderer::GetAscentHeight(look.info_units_font, unit); const unsigned space_width = unit_width / 3; // Calculate value size canvas.Select(look.info_values_font); const unsigned value_height = look.info_values_font.GetAscentHeight(); const unsigned value_width = canvas.CalcTextSize(buffer).cx; // Calculate positions const unsigned max_height = std::max(unit_height, value_height); // Paint value canvas.DrawText(rc.left, rc.bottom - value_height, buffer); // Paint unit canvas.Select(look.info_units_font); UnitSymbolRenderer::Draw(canvas, RasterPoint(rc.left + value_width + space_width, rc.bottom - unit_height), unit, look.unit_fraction_pen); // Paint label canvas.Select(look.info_labels_font); canvas.DrawText(rc.left, rc.bottom - max_height - look.info_labels_font.GetHeight(), _("Distance")); }
void InfoBoxWindow::PaintComment(Canvas &canvas) { if (data.comment.empty()) return; canvas.SetTextColor(look.GetCommentColor(data.comment_color)); const Font &font = *look.comment.font; canvas.Select(font); PixelSize tsize = canvas.CalcTextSize(data.comment); PixelScalar x = max(PixelScalar(1), PixelScalar((comment_rect.left + comment_rect.right - tsize.cx) / 2)); PixelScalar y = comment_rect.top + 1 + font.GetCapitalHeight() - font.GetAscentHeight(); canvas.TextAutoClipped(x, y, data.comment); }
/** * Paints the radar circle on the given canvas * @param canvas The canvas to paint on */ void FlarmTrafficWindow::PaintNorth(Canvas &canvas) const { fixed x = fixed_zero, y = fixed_minus_one; if (!enable_north_up) { FastRotation::Pair p = fr.Rotate(x, y); x = p.first; y = p.second; } canvas.SetTextColor(look.background_color); canvas.Select(look.radar_pen); canvas.Select(look.radar_brush); canvas.SetBackgroundTransparent(); canvas.Select(look.label_font); PixelSize s = canvas.CalcTextSize(_T("N")); canvas.circle(radar_mid.x + iround(x * radius), radar_mid.y + iround(y * radius), s.cy * 0.65); canvas.text(radar_mid.x + iround(x * radius) - s.cx / 2, radar_mid.y + iround(y * radius) - s.cy / 2, _T("N")); }
//------------------------------------------------------------------------------ int main(int argc, char *argv[]) { QApplication app(argc, argv); Canvas c; Pen(Pen::SOLID, 1, Color(0, 0, 0)); { c.Select(Brush(Color(128, 128, 0, Color::TRANSPARENT))); c.DrawKeyhole(200, 100, 50, 100, Angle::Degrees(-20), Angle::Degrees(20)); c.DrawKeyhole(400, 100, 50, 100, Angle::Degrees(70), Angle::Degrees(110)); c.DrawKeyhole(200, 300, 50, 100, Angle::Degrees(160), Angle::Degrees(200)); c.DrawKeyhole(400, 300, 50, 100, Angle::Degrees(-110), Angle::Degrees(-70)); c.show(); app.exec(); } { c.Clear(); c.DrawKeyhole(200, 100, 50, 100, Angle::Degrees(35), Angle::Degrees(55)); c.DrawKeyhole(400, 100, 50, 100, Angle::Degrees(125), Angle::Degrees(145)); c.DrawKeyhole(200, 300, 50, 100, Angle::Degrees(215), Angle::Degrees(235)); c.DrawKeyhole(400, 300, 50, 100, Angle::Degrees(305), Angle::Degrees(325)); c.show(); app.exec(); } { c.Clear(); c.DrawFilledRectangle(0, 0, 100, 100, Color(128, 128, 128, Color::TRANSPARENT)); c.DrawFilledRectangle(100, 100, 200, 200, Color(128, 0, 0, Color::TRANSPARENT)); c.DrawFilledRectangle(150, 150, 250, 250, Color(0, 128, 0, Color::TRANSPARENT)); c.DrawFilledRectangle(200, 200, 300, 300, Color(0, 0, 128, Color::TRANSPARENT)); c.DrawTransparentText(0, 0, "0"); c.DrawTransparentText(0, 100, "100"); c.DrawTransparentText(0, 200, "200"); c.DrawTransparentText(0, 300, "300"); c.DrawTransparentText(0, 400, "400"); c.DrawTransparentText(0, 500, "500"); c.DrawTransparentText(100, c.GetFontHeight(), "100"); c.DrawTransparentText(200, c.GetFontHeight(), "200"); c.DrawTransparentText(300, c.GetFontHeight(), "300"); c.DrawTransparentText(400, c.GetFontHeight(), "400"); c.DrawTransparentText(500, c.GetFontHeight(), "500"); c.show(); app.exec(); } { c.Clear(); c.DrawOutlineRectangle(100, 100, 200, 200, Color(255, 0, 0)); c.show(); app.exec(); } { c.Clear(); c.DrawRoundRectangle(100, 100, 200, 200, 10, 10); c.DrawRoundRectangle(200, 200, 300, 300, 100, 100); c.DrawRoundRectangle(300, 300, 400, 400, 50, 50); c.show(); app.exec(); } { c.Clear(); PixelRect rc; rc.left = 100; rc.top = 100; rc.right = 200; rc.bottom = 200; c.DrawRaisedEdge(rc); c.show(); app.exec(); } { c.Clear(); RasterPoint rp[4]; rp[0] = {100, 100}; rp[1] = {200, 200}; rp[2] = {200, 300}; rp[3] = {300, 400}; c.DrawPolyline(rp, 4); c.show(); app.exec(); } { c.Clear(); RasterPoint rp[6]; rp[0] = {100, 100}; rp[1] = {150, 50}; rp[2] = {200, 100}; rp[3] = {200, 200}; rp[4] = {150, 200}; rp[5] = {100, 100}; c.DrawPolygon(rp, 6); c.show(); app.exec(); } { c.Clear(); RasterPoint rp[4]; rp[0] = {100, 100}; rp[1] = {200, 50}; rp[2] = {200, 150}; rp[3] = {150, 200}; c.DrawTriangleFan(rp, 4); c.show(); app.exec(); } { c.Clear(); c.DrawHLine(100, 200, 100, Color(255, 0, 0)); c.DrawHLine(100, 200, 200, Color(0, 255, 0)); c.DrawHLine(100, 200, 300, Color(0, 0, 255)); c.show(); app.exec(); } { c.Clear(); c.DrawLine(100, 100, 200, 200); c.DrawCircle(250, 250, 50); c.DrawSegment(100, 250, 50, Angle::Degrees(10), Angle::Degrees(30), false); c.show(); app.exec(); } { c.Clear(); c.DrawAnnulus(100, 100, 50, 100, Angle::Degrees(10), Angle::Degrees(60)); c.DrawAnnulus(300, 100, 50, 100, Angle::Degrees(0), Angle::Degrees(360)); c.DrawAnnulus(100, 300, 50, 100, Angle::Degrees(0), Angle::Degrees(0)); c.show(); app.exec(); } { PixelSize rc = c.CalcTextSize("Hello"); std::cout << "Size of \"Hello\": " << rc.cx << ", " << rc.cy << std::endl; c.DrawClippedText(100, 100, rc.cx / 2, "Hello"); c.show(); app.exec(); } { std::cout << "Height of font: " << c.GetFontHeight() << std::endl; } { c.Clear(); c.DrawText(0, 50, "50"); c.Clear(); c.show(); return app.exec(); } }
void FinalGlideBarRenderer::Draw(Canvas &canvas, const PixelRect &rc, const DerivedInfo &calculated, const GlideSettings &glide_settings, const bool final_glide_bar_mc0_enabled) const { #ifdef ENABLE_OPENGL const ScopeAlphaBlend alpha_blend; #endif BulkPixelPoint GlideBar[6] = { { 0, 0 }, { 9, -9 }, { 18, 0 }, { 18, 0 }, { 9, 0 }, { 0, 0 } }; BulkPixelPoint GlideBar0[4] = { { 0, 0 }, { 9, -9 }, { 9, 0 }, { 0, 0 } }; BulkPixelPoint clipping_arrow[6] = { { 0, 0 }, { 9, 9 }, { 18, 0 }, { 18, 6 }, { 9, 15 }, { 0, 6 } }; BulkPixelPoint clipping_arrow0[4] = { { 0, 0 }, { 9, 9 }, { 9, 15 }, { 0, 6 } }; TCHAR Value[10]; const TaskStats &task_stats = calculated.task_stats; const ElementStat &total = task_stats.total; const GlideResult &solution = total.solution_remaining; const GlideResult &solution_mc0 = total.solution_mc0; if (!task_stats.task_valid || !solution.IsOk() || !solution_mc0.IsDefined()) return; const int y0 = (rc.bottom + rc.top) / 2; /* NOTE: size_divisor replaces the fixed value 9 that was used throughout * the code below which caused fixed size rendering regardless of * map size (except the effects of Layout::Scale()). This method * is not usable with variable map sizes (e.g. because of the cross-section * area). size_divisor is used to introduce a screen size dependent scaling. * That workaround is an ugly hack and needs a rework. */ const int size_divisor = std::max(Layout::Scale(3000u / rc.GetHeight()), 4u); int dy_glidebar = 0; int dy_glidebar0 = 0; FormatUserAltitude(solution.SelectAltitudeDifference(glide_settings), Value, false); canvas.Select(*look.font); const PixelSize text_size = canvas.CalcTextSize(Value); int clipping_arrow_offset = Layout::Scale(4); int clipping_arrow0_offset = Layout::Scale(4); // 468 meters is it's size. Will be divided by 9 to fit screen resolution. int altitude_difference = (int) solution.SelectAltitudeDifference(glide_settings); int altitude_difference0 = (int) solution_mc0.SelectAltitudeDifference(glide_settings); // TODO feature: should be an angle if in final glide mode // cut altitude_difference at +- 468 meters (55 units) if (altitude_difference > 468) altitude_difference = 468; if (altitude_difference < -468) altitude_difference = -468; // 55 units is size, 468 meters div by 9 means 55. int Offset = altitude_difference / size_divisor; Offset = Layout::Scale(Offset); if (altitude_difference <= 0) { GlideBar[1].y = Layout::Scale(9); dy_glidebar = text_size.cy + 2; } else { GlideBar[1].y = -Layout::Scale(9); clipping_arrow[1].y = -clipping_arrow[1].y; clipping_arrow[3].y = -clipping_arrow[3].y; clipping_arrow[4].y = -clipping_arrow[4].y; clipping_arrow[5].y = -clipping_arrow[5].y; clipping_arrow_offset = -clipping_arrow_offset; dy_glidebar = -1; } // cut altitude_difference0 at +- 468 meters (55 units) if (altitude_difference0 > 468) altitude_difference0 = 468; if (altitude_difference0 < -468) altitude_difference0 = -468; // 55 units is size, therefore div by 9. int Offset0 = altitude_difference0 / size_divisor; Offset0 = Layout::Scale(Offset0); if (altitude_difference0 <= 0) { GlideBar0[1].y = Layout::Scale(9); dy_glidebar0 = text_size.cy + 2; } else { GlideBar0[1].y = -Layout::Scale(9); clipping_arrow0[1].y = -clipping_arrow0[1].y; clipping_arrow0[2].y = -clipping_arrow0[2].y; clipping_arrow0[3].y = -clipping_arrow0[3].y; clipping_arrow0_offset = -clipping_arrow0_offset; dy_glidebar0 = -1; } for (unsigned i = 0; i < 6; i++) { GlideBar[i].y += y0 + dy_glidebar; GlideBar[i].x = Layout::Scale(GlideBar[i].x) + rc.left; } GlideBar[0].y -= Offset; GlideBar[1].y -= Offset; GlideBar[2].y -= Offset; for (unsigned i = 0; i < 4; i++) { GlideBar0[i].y += y0 + dy_glidebar0; GlideBar0[i].x = Layout::Scale(GlideBar0[i].x) + rc.left; } GlideBar0[0].y -= Offset0; GlideBar0[1].y -= Offset0; if ((altitude_difference0 >= altitude_difference) && (altitude_difference > 0)) { // both above and mc0 arrow larger than mc arrow GlideBar0[2].y = GlideBar[1].y; // both below GlideBar0[3].y = GlideBar[0].y; } // prepare clipping arrow for (unsigned i = 0; i < 6; i++) { clipping_arrow[i].y = Layout::Scale(clipping_arrow[i].y) + y0 - Offset + clipping_arrow_offset + dy_glidebar; clipping_arrow[i].x = Layout::Scale(clipping_arrow[i].x) + rc.left; } // prepare clipping arrow mc0 for (unsigned i = 0; i < 4; i++) { clipping_arrow0[i].y = Layout::Scale(clipping_arrow0[i].y) + y0 - Offset0 + clipping_arrow0_offset + dy_glidebar0; clipping_arrow0[i].x = Layout::Scale(clipping_arrow0[i].x) + rc.left; } // draw actual glide bar if (altitude_difference <= 0) { if (calculated.common_stats.landable_reachable) { canvas.Select(look.pen_below_landable); canvas.Select(look.brush_below_landable); } else { canvas.Select(look.pen_below); canvas.Select(look.brush_below); } } else { canvas.Select(look.pen_above); canvas.Select(look.brush_above); } canvas.DrawPolygon(GlideBar, 6); // draw clipping arrow if ((altitude_difference <= -468 ) || (altitude_difference >= 468)) canvas.DrawPolygon(clipping_arrow, 6); // draw glide bar at mc 0 if (altitude_difference0 <= 0 && final_glide_bar_mc0_enabled) { if (calculated.common_stats.landable_reachable) { canvas.Select(look.pen_below_landable); canvas.Select(look.brush_below_landable_mc0); } else { canvas.Select(look.pen_below); canvas.Select(look.brush_below_mc0); } } else { canvas.Select(look.pen_above); canvas.Select(look.brush_above_mc0); } if ( ( (altitude_difference != altitude_difference0) || (altitude_difference0 < 0) ) && final_glide_bar_mc0_enabled) { canvas.DrawPolygon(GlideBar0, 4); if ((altitude_difference0 <= -468 ) || (altitude_difference0 >= 468)) canvas.DrawPolygon(clipping_arrow0, 4); } // draw cross (x) on final glide bar if unreachable at current Mc // or above final glide but impeded by obstacle int cross_sign = 0; if (!total.IsAchievable()) cross_sign = 1; if (calculated.terrain_warning_location.IsValid() && altitude_difference > 0 ) cross_sign = -1; if (cross_sign != 0) { canvas.Select(task_look.bearing_pen); canvas.DrawLine(Layout::Scale(9 - 5), y0 + cross_sign * Layout::Scale(9 - 5), Layout::Scale(9 + 5), y0 + cross_sign * Layout::Scale(9 + 5)); canvas.DrawLine(Layout::Scale(9 - 5), y0 + cross_sign * Layout::Scale(9 + 5), Layout::Scale(9 + 5), y0 + cross_sign * Layout::Scale(9 - 5)); } canvas.SetTextColor(COLOR_BLACK); canvas.SetBackgroundColor(COLOR_WHITE); TextInBoxMode style; style.shape = LabelShape::ROUNDED_BLACK; style.move_in_view = true; if (text_size.cx < Layout::Scale(18)) { style.align = TextInBoxMode::Alignment::RIGHT; TextInBox(canvas, Value, Layout::Scale(18), y0, style, rc); } else TextInBox(canvas, Value, 0, y0, style, rc); }
void GaugeVario::RenderBugs(Canvas &canvas) { static int last_bugs = -1; static PixelRect label_rect = {-1,-1,-1,-1}; static PixelRect value_rect = {-1,-1,-1,-1}; static RasterPoint label_pos = {-1,-1}; static RasterPoint value_pos = {-1,-1}; if (!bugs_initialised) { const PixelRect rc = GetClientRect(); PixelSize tSize; label_pos.x = 1; label_pos.y = rc.bottom - 2 - look.text_font->GetCapitalHeight() - look.text_font->GetAscentHeight(); value_pos.x = 1; value_pos.y = rc.bottom - 1 - look.text_font->GetAscentHeight(); label_rect.left = label_pos.x; label_rect.top = label_pos.y + look.text_font->GetAscentHeight() - look.text_font->GetCapitalHeight(); value_rect.left = value_pos.x; value_rect.top = value_pos.y + look.text_font->GetAscentHeight() - look.text_font->GetCapitalHeight(); canvas.Select(*look.text_font); tSize = canvas.CalcTextSize(TEXT_BUG); label_rect.right = label_rect.left + tSize.cx; label_rect.bottom = label_rect.top + look.text_font->GetCapitalHeight() + look.text_font->GetHeight() - look.text_font->GetAscentHeight(); tSize = canvas.CalcTextSize(_T("100%")); value_rect.right = value_rect.left + tSize.cx; value_rect.bottom = value_rect.top + look.text_font->GetCapitalHeight(); bugs_initialised = true; } int bugs = iround((fixed(1) - GetComputerSettings().polar.bugs) * 100); if (!IsPersistent() || bugs != last_bugs) { canvas.Select(*look.text_font); if (IsPersistent()) canvas.SetBackgroundColor(look.background_color); else canvas.SetBackgroundTransparent(); if (IsPersistent() || last_bugs < 1 || bugs < 1) { if (bugs > 0) { canvas.SetTextColor(look.dimmed_text_color); if (IsPersistent()) canvas.DrawOpaqueText(label_pos.x, label_pos.y, label_rect, TEXT_BUG); else canvas.DrawText(label_pos.x, label_pos.y, TEXT_BUG); } else if (IsPersistent()) canvas.DrawFilledRectangle(label_rect, look.background_color); } if (bugs > 0) { TCHAR buffer[18]; _stprintf(buffer, _T("%d%%"), bugs); canvas.SetTextColor(look.text_color); if (IsPersistent()) canvas.DrawOpaqueText(value_pos.x, value_pos.y, value_rect, buffer); else canvas.DrawText(value_pos.x, value_pos.y, buffer); } else if (IsPersistent()) canvas.DrawFilledRectangle(value_rect, look.background_color); if (IsPersistent()) last_bugs = bugs; } }
void GaugeVario::RenderBallast(Canvas &canvas) { static int last_ballast = -1; static PixelRect label_rect = {-1,-1,-1,-1}; static PixelRect value_rect = {-1,-1,-1,-1}; static RasterPoint label_pos = {-1,-1}; static RasterPoint value_pos = {-1,-1}; if (!ballast_initialised) { // ontime init, origin and background rect const PixelRect rc = GetClientRect(); PixelSize tSize; // position of ballast label label_pos.x = 1; label_pos.y = rc.top + 2 + look.text_font->GetCapitalHeight() * 2 - look.text_font->GetAscentHeight(); // position of ballast value value_pos.x = 1; value_pos.y = rc.top + 1 + look.text_font->GetCapitalHeight() - look.text_font->GetAscentHeight(); // set upper left corner label_rect.left = label_pos.x; label_rect.top = label_pos.y + look.text_font->GetAscentHeight() - look.text_font->GetCapitalHeight(); // set upper left corner value_rect.left = value_pos.x; value_rect.top = value_pos.y + look.text_font->GetAscentHeight() - look.text_font->GetCapitalHeight(); // get max label size canvas.Select(*look.text_font); tSize = canvas.CalcTextSize(TEXT_BALLAST); // update back rect with max label size label_rect.right = label_rect.left + tSize.cx; label_rect.bottom = label_rect.top + look.text_font->GetCapitalHeight(); // get max value size tSize = canvas.CalcTextSize(_T("100%")); value_rect.right = value_rect.left + tSize.cx; // update back rect with max label size value_rect.bottom = value_rect.top + look.text_font->GetCapitalHeight(); ballast_initialised = true; } int ballast = iround(GetGlidePolar().GetBallast() * 100); if (!IsPersistent() || ballast != last_ballast) { // ballast hase been changed canvas.Select(*look.text_font); if (IsPersistent()) canvas.SetBackgroundColor(look.background_color); else canvas.SetBackgroundTransparent(); if (IsPersistent() || last_ballast < 1 || ballast < 1) { // new ballast is 0, hide label if (ballast > 0) { canvas.SetTextColor(look.dimmed_text_color); // ols ballast was 0, show label if (IsPersistent()) canvas.DrawOpaqueText(label_pos.x, label_pos.y, label_rect, TEXT_BALLAST); else canvas.DrawText(label_pos.x, label_pos.y, TEXT_BALLAST); } else if (IsPersistent()) canvas.DrawFilledRectangle(label_rect, look.background_color); } // new ballast 0, hide value if (ballast > 0) { TCHAR buffer[18]; _stprintf(buffer, _T("%u%%"), ballast); canvas.SetTextColor(look.text_color); if (IsPersistent()) canvas.DrawOpaqueText(value_pos.x, value_pos.y, value_rect, buffer); else canvas.DrawText(value_pos.x, value_pos.y, buffer); } else if (IsPersistent()) canvas.DrawFilledRectangle(value_rect, look.background_color); if (IsPersistent()) last_ballast = ballast; } }
// TODO code: Optimise vario rendering, this is slow void GaugeVario::RenderValue(Canvas &canvas, int x, int y, DrawInfo *value_info, DrawInfo *label_info, fixed value, const TCHAR *label) { PixelSize tsize; #ifndef FIXED_MATH value = (double)iround(value * 10) / 10; // prevent the -0.0 case #endif if (!value_info->initialised) { value_info->rc.right = x - Layout::Scale(5); value_info->rc.top = y + Layout::Scale(3) + look.text_font->GetCapitalHeight(); value_info->rc.left = value_info->rc.right; // update back rect with max label size value_info->rc.bottom = value_info->rc.top + look.value_font->GetCapitalHeight(); value_info->text_position.x = value_info->rc.left; value_info->text_position.y = value_info->rc.top + look.value_font->GetCapitalHeight() - look.value_font->GetAscentHeight(); value_info->last_value = fixed(-9999); value_info->last_text[0] = '\0'; value_info->last_unit = Unit::UNDEFINED; value_info->initialised = true; } if (!label_info->initialised) { label_info->rc.right = x; label_info->rc.top = y + Layout::Scale(1); label_info->rc.left = label_info->rc.right; // update back rect with max label size label_info->rc.bottom = label_info->rc.top + look.text_font->GetCapitalHeight(); label_info->text_position.x = label_info->rc.left; label_info->text_position.y = label_info->rc.top + look.text_font->GetCapitalHeight() - look.text_font->GetAscentHeight(); label_info->last_value = fixed(-9999); label_info->last_text[0] = '\0'; label_info->initialised = true; } canvas.SetBackgroundTransparent(); if (!IsPersistent() || (dirty && !StringIsEqual(label_info->last_text, label))) { canvas.SetTextColor(look.dimmed_text_color); canvas.Select(*look.text_font); tsize = canvas.CalcTextSize(label); label_info->text_position.x = label_info->rc.right - tsize.cx; if (IsPersistent()) { canvas.SetBackgroundColor(look.background_color); canvas.DrawOpaqueText(label_info->text_position.x, label_info->text_position.y, label_info->rc, label); label_info->rc.left = label_info->text_position.x; _tcscpy(label_info->last_text, label); } else { canvas.DrawText(label_info->text_position.x, label_info->text_position.y, label); } } if (!IsPersistent() || (dirty && value_info->last_value != value)) { TCHAR buffer[18]; canvas.SetBackgroundColor(look.background_color); canvas.SetTextColor(look.text_color); _stprintf(buffer, _T("%.1f"), (double)value); canvas.Select(*look.value_font); tsize = canvas.CalcTextSize(buffer); value_info->text_position.x = value_info->rc.right - tsize.cx; if (IsPersistent()) { canvas.DrawOpaqueText(value_info->text_position.x, value_info->text_position.y, value_info->rc, buffer); value_info->rc.left = value_info->text_position.x; value_info->last_value = value; } else { canvas.DrawText(value_info->text_position.x, value_info->text_position.y, buffer); } } if (!IsPersistent() || value_info->last_unit != Units::current.vertical_speed_unit) { value_info->last_unit = Units::current.vertical_speed_unit; const UnitSymbol *unit_symbol = units_look.GetSymbol(value_info->last_unit); unit_symbol->Draw(canvas, x - Layout::Scale(5), value_info->rc.top, look.background_color, COLOR_GRAY); } }
void TabDisplay::PaintButton(Canvas &canvas, unsigned CaptionStyle, const TCHAR *caption, const PixelRect &rc, const Bitmap *bmp, const bool isDown, bool inverse) { PixelRect rcTextFinal = rc; const UPixelScalar buttonheight = rc.bottom - rc.top; const PixelSize text_size = canvas.CalcTextSize(caption); const int textwidth = text_size.cx; const int textheight = text_size.cy; UPixelScalar textheightoffset = 0; if (textwidth > (rc.right - rc.left)) // assume 2 lines textheightoffset = std::max(0, (int)(buttonheight - textheight * 2) / 2); else textheightoffset = std::max(0, (int)(buttonheight - textheight) / 2); rcTextFinal.top += textheightoffset; canvas.DrawFilledRectangle(rc, canvas.GetBackgroundColor()); if (bmp != nullptr) { const PixelSize bitmap_size = bmp->GetSize(); const int offsetx = (rc.right - rc.left - bitmap_size.cx / 2) / 2; const int offsety = (rc.bottom - rc.top - bitmap_size.cy) / 2; #ifdef ENABLE_OPENGL if (inverse) { OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); /* invert the texture color */ OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR); /* copy the texture alpha */ OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE); OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); } else /* simple copy */ OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const GLEnable scope(GL_TEXTURE_2D); const GLBlend blend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GLTexture &texture = *bmp->GetNative(); texture.Bind(); texture.Draw(rc.left + offsetx, rc.top + offsety); #else if (inverse) // black background canvas.CopyNotOr(rc.left + offsetx, rc.top + offsety, bitmap_size.cx / 2, bitmap_size.cy, *bmp, bitmap_size.cx / 2, 0); else canvas.CopyAnd(rc.left + offsetx, rc.top + offsety, bitmap_size.cx / 2, bitmap_size.cy, *bmp, bitmap_size.cx / 2, 0); #endif } else { #ifndef USE_GDI if (IsDithered()) CaptionStyle |= DT_UNDERLINE; #endif canvas.DrawFormattedText(&rcTextFinal, caption, CaptionStyle); } }
void VarioBarRenderer::Draw(Canvas &canvas, const PixelRect &rc, const MoreData &basic, const DerivedInfo &calculated, const GlidePolar &glide_polar, const bool vario_bar_avg_enabled) const { #ifdef ENABLE_OPENGL const ScopeAlphaBlend alpha_blend; #endif RasterPoint VarioBar[6] = { { 0, 0 }, { 9, -9 }, { 18, 0 }, { 18, 0 }, { 9, 0 }, { 0, 0 } }; RasterPoint VarioBarAvg[4] = { { 0, 0 }, { 9, -9 }, { 9, 0 }, { 0, 0 } }; RasterPoint clipping_arrow[6] = { { 0, 0 }, { 9, 9 }, { 18, 0 }, { 18, 6 }, { 9, 15 }, { 0, 6 } }; RasterPoint clipping_arrow_av[4] = { { 0, 0 }, { 9, 9 }, { 9, 15 }, { 0, 6 } }; RasterPoint mc_arrow[6] = { { 0, 0 }, { 9, -9 }, { 18, 0 }, { 18, -2 }, { 9, -11 }, { 0, -2 } }; TCHAR Value[10]; const int y0 = (rc.bottom + rc.top) / 2; /* NOTE: size_divisor replaces the fixed value 9 that was used throughout * the code sink which caused fixed size rendering regardless of * map size (except the effects of Layout::Scale()). This method * is not usable with variable map sizes (e.g. because of the cross-section * area). size_divisor is used to introduce a screen size dependent scaling. * That workaround is an ugly hack and needs a rework. */ const auto size_divisor = std::max((fixed) Layout::Scale(70 / (rc.bottom - rc.top)), fixed(0.15)); PixelScalar dy_variobar = 0; PixelScalar dy_variobar_av = 0; PixelScalar dy_variobar_mc = 0; PixelScalar clipping_arrow_offset = Layout::Scale(4); PixelScalar clipping_arrow_av_offset = Layout::Scale(4); // PixelScalar clipping_arrow_mc_offset = Layout::Scale(4); auto vario_gross = basic.brutto_vario; FormatUserVerticalSpeed(vario_gross, Value, false, true); canvas.Select(*look.font); const PixelSize text_size = canvas.CalcTextSize(Value); auto vario_avg = calculated.average; // cut vario_gross at +- 5 meters/s if (vario_gross > fixed(5)) vario_gross = fixed(5); if (vario_gross < fixed(-5)) vario_gross = fixed(-5); int Offset = (int)(vario_gross / size_divisor); Offset = Layout::Scale(Offset); if (!positive(vario_gross)) { VarioBar[1].y = Layout::Scale(9); dy_variobar = text_size.cy + 2; } else { VarioBar[1].y = -Layout::Scale(9); clipping_arrow[1].y = -clipping_arrow[1].y; clipping_arrow[3].y = -clipping_arrow[3].y; clipping_arrow[4].y = -clipping_arrow[4].y; clipping_arrow[5].y = -clipping_arrow[5].y; clipping_arrow_offset = -clipping_arrow_offset; dy_variobar = -1; } // cut vario_avg at +- 5 meters/s if (vario_avg > fixed(5)) vario_avg = fixed(5); if (vario_avg < fixed(-5)) vario_avg = fixed(-5); int OffsetAvg = int(vario_avg / size_divisor); OffsetAvg = Layout::Scale(OffsetAvg); if (!positive(vario_avg)) { VarioBarAvg[1].y = Layout::Scale(9); dy_variobar_av = text_size.cy + 2; } else { VarioBarAvg[1].y = -Layout::Scale(9); clipping_arrow_av[1].y = -clipping_arrow_av[1].y; clipping_arrow_av[2].y = -clipping_arrow_av[2].y; clipping_arrow_av[3].y = -clipping_arrow_av[3].y; clipping_arrow_av_offset = -clipping_arrow_av_offset; dy_variobar_av = -1; } //clip MC Value auto mc_val = glide_polar.GetMC(); if (mc_val > fixed(5)) mc_val = fixed(5); if (!positive(mc_val)) { dy_variobar_mc = text_size.cy + 2; }else{ dy_variobar_mc = -1; } int OffsetMC = int(mc_val / size_divisor); OffsetMC = Layout::Scale(OffsetMC); for (unsigned i = 0; i < 6; i++) { VarioBar[i].y += y0 + dy_variobar; VarioBar[i].x = rc.right - Layout::Scale(VarioBar[i].x); } VarioBar[0].y -= Offset; VarioBar[1].y -= Offset; VarioBar[2].y -= Offset; for (unsigned i = 0; i < 4; i++) { VarioBarAvg[i].y += y0 + dy_variobar_av; VarioBarAvg[i].x = rc.right-Layout::Scale(VarioBarAvg[i].x); } VarioBarAvg[0].y -= OffsetAvg; VarioBarAvg[1].y -= OffsetAvg; // prepare mc arrow for (unsigned i = 0; i < 6; i++) { mc_arrow[i].y = Layout::Scale(mc_arrow[i].y) + y0 - OffsetMC + dy_variobar_mc; mc_arrow[i].x = rc.right - Layout::Scale(mc_arrow[i].x); } // prepare clipping arrow for (unsigned i = 0; i < 6; i++) { clipping_arrow[i].y = Layout::Scale(clipping_arrow[i].y) + y0 - Offset + clipping_arrow_offset + dy_variobar; clipping_arrow[i].x = rc.right - Layout::Scale(clipping_arrow[i].x); } // prepare clipping avg for (unsigned i = 0; i < 4; i++) { clipping_arrow_av[i].y = Layout::Scale(clipping_arrow_av[i].y) + y0 - OffsetAvg + clipping_arrow_av_offset + dy_variobar_av; clipping_arrow_av[i].x = rc.right-Layout::Scale(clipping_arrow_av[i].x); } // draw actual vario bar if (!positive(vario_gross)) { canvas.Select(look.pen_sink); canvas.Select(look.brush_sink); } else { canvas.Select(look.pen_climb); canvas.Select(look.brush_climb); } canvas.DrawPolygon(VarioBar, 6); // draw clipping arrow if (vario_gross <= fixed(-5) || vario_gross >= fixed(5)) canvas.DrawPolygon(clipping_arrow, 6); // draw avg vario bar if (!positive(vario_avg) && vario_bar_avg_enabled) { canvas.Select(look.pen_sink); canvas.Select(look.brush_sink_avg); } else { canvas.Select(look.pen_climb); canvas.Select(look.brush_climb_avg); } canvas.DrawPolygon(VarioBarAvg, 4); if (vario_avg <= fixed(-5.0) || vario_avg >= fixed(5.0)) canvas.DrawPolygon(clipping_arrow_av, 4); //draw MC arrow canvas.Select(look.pen_mc); canvas.Select(look.brush_mc); canvas.DrawPolygon(mc_arrow, 6); //draw text canvas.SetTextColor(COLOR_BLACK); canvas.SetBackgroundColor(COLOR_WHITE); TextInBoxMode style; style.shape = LabelShape::ROUNDED_BLACK; style.move_in_view = true; if (text_size.cx < Layout::Scale(18)) { style.align = TextInBoxMode::Alignment::RIGHT; TextInBox(canvas, Value, rc.right, y0, style, rc); } else TextInBox(canvas, Value, rc.right-Layout::Scale(18), y0, style, rc); }