Mirror: terminal names, reload drawings, turned text groups, a leak

Found by review of #1354:
- Terminal names (shown on the folio) read backwards on a mirrored
  symbol: Terminal::paint() now mirrors them back about the centre of
  their box, in the frame they are drawn in.
- "Reload the drawings of the symbols" left mirrored symbols with the old
  drawing: reloadPicture() refreshes the mirrored pictures too.
- Turning a group of texts on a mirrored symbol left the group's
  readable mirror about the centre of its old box until the next layout:
  ElementTextItemGroup::setRotation() reapplies it, as texts already do.
- The mirrored build of a symbol's drawing leaked the texts of its
  primitives, which only the drawing without mirror keeps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-07 12:13:27 +13:00
parent a5b5d49b98
commit a3b1468b0f
4 changed files with 33 additions and 0 deletions
@@ -379,6 +379,9 @@ bool ElementPictureFactory::build(const ElementsLocation &location,
const auto uuid_ = cacheKey(location);
if (!mirror.isIdentity()) {
//The primitives are those of the drawing without mirror,
//already kept by the build of that one
qDeleteAll(primitives_.m_texts);
const QPair<QUuid, int> key(uuid_, (mirror.m11() < 0 ? 1 : 0)
| (mirror.m22() < 0 ? 2 : 0));
if (!picture) {
+7
View File
@@ -2186,6 +2186,13 @@ Element::ReloadPictureResult Element::reloadPicture()
m_picture = picture;
m_low_zoom_picture = low_zoom_picture;
if (isMirrored())
ElementPictureFactory::instance()->getMirroredPictures(
m_location,
m_horizontal_mirror,
m_vertical_mirror,
m_mirrored_picture,
m_mirrored_low_zoom_picture);
update();
return ReloadPictureResult::Reloaded;
}
@@ -648,6 +648,10 @@ QRectF ElementTextItemGroup::boundingRect() const
void ElementTextItemGroup::setRotation(qreal angle)
{
QGraphicsItemGroup::setRotation(angle);
//On a mirrored element, the mirror that keeps this group readable
//is about the centre of its turned box
if (m_parent_element)
m_parent_element->keepReadable(this);
emit rotationChanged(angle);
}
+19
View File
@@ -306,6 +306,23 @@ void Terminal::paint(
QFontMetrics fm(d->m_label_font);
QSizeF text_size = fm.size(Qt::TextSingleLine, display_name);
// On a mirrored element, mirror the name a second time about
// the centre of its box, in the frame it is drawn in (turned
// by label_rotation): its box stays where the element's mirror
// puts it, but it reads normally (Element::keepReadable())
const Element *mirrored = qgraphicsitem_cast<Element *>(parentItem());
if (mirrored && !mirrored->isMirrored()) mirrored = nullptr;
auto keep_readable = [painter, mirrored](const QRectF &rect, qreal label_rotation) {
if (!mirrored) return;
const QTransform mirror = QTransform().rotate(label_rotation)
* mirrored->mirrorTransform()
* QTransform().rotate(-label_rotation);
const QPointF c = rect.center();
painter->setTransform(QTransform::fromTranslate(-c.x(), -c.y())
* mirror
* QTransform::fromTranslate(c.x(), c.y()), true);
};
if (!qFuzzyIsNull(d->m_label_rotation)) {
painter->save();
painter->translate(label_pos);
@@ -321,6 +338,7 @@ void Terminal::paint(
else if (d->m_label_valignment & Qt::AlignBottom) ry = -text_size.height();
QRectF text_rect(QPointF(rx, ry), text_size);
keep_readable(text_rect, d->m_label_rotation);
painter->drawText(text_rect, static_cast<int>(d->m_label_halignment | d->m_label_valignment), display_name);
painter->restore();
} else {
@@ -334,6 +352,7 @@ void Terminal::paint(
else if (d->m_label_valignment & Qt::AlignBottom) dy = -text_size.height();
QRectF text_rect(label_pos + QPointF(dx, dy), text_size);
keep_readable(text_rect, 0);
if (d->m_label_frame) {
painter->drawRect(text_rect.adjusted(-1, -1, 1, 1));
}