  void OnroadAlerts::paintEvent(QPaintEvent *event) {
    QPainter p(this);
    p.setBrush(QBrush(bg));
    p.setPen(Qt::NoPen);
    p.drawRect(rect());
  }
  
  NvgWindow::~NvgWindow() {
    makeCurrent();
    doneCurrent();
 
</s> remove   p.setBrush(QBrush(bg));
 </s> add   static std::map<cereal::ControlsState::AlertSize, const int> alert_sizes = {
    {cereal::ControlsState::AlertSize::NONE, 0},
    {cereal::ControlsState::AlertSize::SMALL, 271},
    {cereal::ControlsState::AlertSize::MID, 420},
    {cereal::ControlsState::AlertSize::FULL, height()},
  };
  int h = alert_sizes[alert_size];
  if (h == 0) {
    return;
  }

  QRect r = QRect(0, height() - h, width(), h);

  // draw background + gradient </s> remove 
void configFont(QPainter &p, QString family, int size, int weight) {
  QFont f(family);
  f.setPixelSize(size);
  f.setWeight(weight);
  p.setFont(f);
}
 </s> add #include "selfdrive/ui/qt/util.h" </s> remove   setVisible(size != cereal::ControlsState::AlertSize::NONE);
  repaint();
 </s> add   update(); </s> remove   title->setText(text1);
  msg->setText(text2);
  msg->setVisible(!msg->text().isEmpty());

  if (size == cereal::ControlsState::AlertSize::SMALL) {
    setFixedHeight(241);
    title->setStyleSheet("font-size: 70px; font-weight: 500;");
  } else if (size == cereal::ControlsState::AlertSize::MID) {
    setFixedHeight(390);
    msg->setStyleSheet("font-size: 65px; font-weight: 400;");
    title->setStyleSheet("font-size: 80px; font-weight: 500;");
  } else if (size == cereal::ControlsState::AlertSize::FULL) {
    setFixedHeight(vwp_h);
    int title_size = (title->text().size() > 15) ? 130 : 110;
    title->setStyleSheet(QString("font-size: %1px; font-weight: 500;").arg(title_size));
    msg->setStyleSheet("font-size: 90px; font-weight: 400;");
  }
 </s> add 
  p.setCompositionMode(QPainter::CompositionMode_DestinationOver);

  p.setBrush(QBrush(bg));
  p.drawRect(r);

  QLinearGradient g(0, r.y(), 0, r.bottom());
  g.setColorAt(0, QColor::fromRgbF(0, 0, 0, 0.05));
  g.setColorAt(1, QColor::fromRgbF(0, 0, 0, 0.35));
  p.setBrush(QBrush(g));
  p.fillRect(r, g);
  p.setCompositionMode(QPainter::CompositionMode_SourceOver);

  // remove bottom border
  r = QRect(0, height() - h, width(), h - 30);

  // text
  const QPoint c = r.center();
  p.setPen(QColor(0xff, 0xff, 0xff));
  p.setRenderHint(QPainter::TextAntialiasing);
  if (alert_size == cereal::ControlsState::AlertSize::SMALL) {
    configFont(p, "Open Sans", 74, "SemiBold");
    p.drawText(r, Qt::AlignCenter, text1);
  } else if (alert_size == cereal::ControlsState::AlertSize::MID) {
    configFont(p, "Open Sans", 88, "Bold");
    p.drawText(QRect(0, c.y() - 125, width(), 150), Qt::AlignHCenter | Qt::AlignTop, text1);
    configFont(p, "Open Sans", 66, "Regular");
    p.drawText(QRect(0, c.y() + 21, width(), 90), Qt::AlignHCenter, text2);
  } else if (alert_size == cereal::ControlsState::AlertSize::FULL) {
    // TODO: offset from center to match old NVG UI, but why was it this way?
    bool l = text1.length() > 15;
    configFont(p, "Open Sans", l ? 132 : 177, "Bold");
    p.drawText(QRect(0, r.y() + (l ? 240 : 270), width() - 60, 350), Qt::AlignHCenter | Qt::TextWordWrap, text1);
    configFont(p, "Open Sans", 88, "Regular");
    p.drawText(QRect(0, r.height() - (l ? 361 : 420), width() - 60, 300), Qt::AlignHCenter | Qt::TextWordWrap, text2);
  }
  void OnroadAlerts::paintEvent(QPaintEvent *event) {
    QPainter p(this);
    p.setBrush(QBrush(bg));
    p.setPen(Qt::NoPen);
  p.setCompositionMode(QPainter::CompositionMode_DestinationOver);

  p.setBrush(QBrush(bg));
  p.drawRect(r);

  QLinearGradient g(0, r.y(), 0, r.bottom());
  g.setColorAt(0, QColor::fromRgbF(0, 0, 0, 0.05));
  g.setColorAt(1, QColor::fromRgbF(0, 0, 0, 0.35));
  p.setBrush(QBrush(g));
  p.fillRect(r, g);
  p.setCompositionMode(QPainter::CompositionMode_SourceOver);

  // remove bottom border
  r = QRect(0, height() - h, width(), h - 30);

  // text
  const QPoint c = r.center();
  p.setPen(QColor(0xff, 0xff, 0xff));
  p.setRenderHint(QPainter::TextAntialiasing);
  if (alert_size == cereal::ControlsState::AlertSize::SMALL) {
    configFont(p, "Open Sans", 74, "SemiBold");
    p.drawText(r, Qt::AlignCenter, text1);
  } else if (alert_size == cereal::ControlsState::AlertSize::MID) {
    configFont(p, "Open Sans", 88, "Bold");
    p.drawText(QRect(0, c.y() - 125, width(), 150), Qt::AlignHCenter | Qt::AlignTop, text1);
    configFont(p, "Open Sans", 66, "Regular");
    p.drawText(QRect(0, c.y() + 21, width(), 90), Qt::AlignHCenter, text2);
  } else if (alert_size == cereal::ControlsState::AlertSize::FULL) {
    // TODO: offset from center to match old NVG UI, but why was it this way?
    bool l = text1.length() > 15;
    configFont(p, "Open Sans", l ? 132 : 177, "Bold");
    p.drawText(QRect(0, r.y() + (l ? 240 : 270), width() - 60, 350), Qt::AlignHCenter | Qt::TextWordWrap, text1);
    configFont(p, "Open Sans", 88, "Regular");
    p.drawText(QRect(0, r.height() - (l ? 361 : 420), width() - 60, 300), Qt::AlignHCenter | Qt::TextWordWrap, text2);
  }
  }
  
  NvgWindow::~NvgWindow() {
    makeCurrent();
    doneCurrent();
keep keep keep keep replace keep keep keep keep keep
 match nvg onroad alerts (#20854) 
selfdrive/ui/qt/onroad.cc