[graphics/drawy/gsoc2026] src: fix: Improve word wrapping and scaling text
Abdelhadi Wael <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit b99fd07d0a101a45ae8eaa3720da9c83a949795e by Abdelhadi Wael.
Committed on 21/07/2026 at 23:55.
Pushed by mlaurent into branch 'gsoc2026'.
fix: Improve word wrapping and scaling text
- don't cache text in horizontal resize
- makes scaling text more accuarte (avoid wrapping while scaling)
M +26 -20 src/gui/item/text.cpp
M +1 -0 src/gui/item/text.hpp
M +1 -1 src/widgets/transformhandler/resizetransformhandler.cpp
https://invent.kde.org/graphics/drawy/-/commit/b99fd07d0a101a45ae8eaa3720da9c83a949795e
diff --git a/src/gui/item/text.cpp b/src/gui/item/text.cpp
index 6f4e0b6e..6f26f9a7 100644
--- a/src/gui/item/text.cpp
+++ b/src/gui/item/text.cpp
@@ -77,14 +77,10 @@ void TextItem::draw(QPainter &painter, const QPointF &offset)
painter.translate(m_boundingBox.topLeft() - offset);
painter.setOpacity(painter.opacity() * (property(Property::Type::Opacity).value<int>() / 255.0));
- QTransform transform{m_transform};
- const auto [scaleX, scaleY]{Common::Utils::Math::extractScale(transform)};
-
- if (m_mode == Mode::Normal && qFuzzyCompare(1.0, scaleY) && !qFuzzyCompare(1.0, scaleX)) {
+ if (m_isHorizontalResize) {
+ QTransform transform{m_transform};
+ const auto [scaleX, scaleY]{Common::Utils::Math::extractScale(transform)};
painter.scale(1.0 / scaleX, 1.0);
- const qreal width = m_wrapWidth > 0 ? m_wrapWidth : m_boundingBox.width();
- const qreal targetWidth = std::max(width * scaleX, minWrapWidth());
- m_document.setTextWidth(targetWidth);
}
QAbstractTextDocumentLayout::PaintContext ctx;
@@ -126,12 +122,16 @@ void TextItem::resize(const QTransform operation)
QTransform transform{m_transform};
const auto [scaleX, scaleY]{Common::Utils::Math::extractScale(transform)};
- if (m_mode == Mode::Normal && qFuzzyCompare(1.0, scaleY) && !qFuzzyCompare(1.0, scaleX)) {
+ m_isHorizontalResize = m_mode == Mode::Normal && qFuzzyCompare(1.0, scaleY) && !qFuzzyCompare(1.0, scaleX);
+
+ if (m_isHorizontalResize) {
const qreal width = m_wrapWidth > 0 ? m_wrapWidth : m_boundingBox.width();
const qreal targetWidth = std::max(width * scaleX, minWrapWidth());
- m_document.setTextWidth(targetWidth);
- m_boundingBox.setHeight(m_document.size().height());
+ if (qRound(m_document.textWidth()) != targetWidth) {
+ m_document.setTextWidth(targetWidth);
+ m_boundingBox.setHeight(m_document.size().height());
+ }
}
}
@@ -140,15 +140,9 @@ void TextItem::commitTransformation()
const auto [scaleX, scaleY]{Common::Utils::Math::extractScale(m_transform)};
const QTransform filtered{scaleX, 0, 0, scaleY, 0, 0};
- if (!qFuzzyCompare(1.0, scaleX)) {
- if (qFuzzyCompare(1.0, scaleY)) {
- const qreal width = m_wrapWidth > 0 ? m_wrapWidth : m_boundingBox.width();
- m_wrapWidth = std::max(width * scaleX, minWrapWidth());
- } else {
- if (m_wrapWidth > 0) {
- m_wrapWidth = std::max(m_wrapWidth * scaleX, minWrapWidth());
- }
- }
+ if (m_isHorizontalResize) {
+ const qreal width = m_wrapWidth > 0 ? m_wrapWidth : m_boundingBox.width();
+ m_wrapWidth = std::max(width * scaleX, minWrapWidth());
}
m_boundingBox = filtered.map(m_boundingBox).boundingRect();
@@ -160,12 +154,17 @@ void TextItem::commitTransformation()
Item::setProperty(Property::Type::FontSize, Property{newFontSize, Property::Type::FontSize});
}
updateBoundingBox();
+ m_isHorizontalResize = false;
}
void TextItem::scaleTextFragments(const qreal scaleY)
{
+ const QSignalBlocker blocker{m_document};
m_cursor.beginEditBlock();
+ m_document.setTextWidth(-1);
+ const qreal oldIdealWidth = m_document.idealWidth();
+
QTextBlock block = m_document.firstBlock();
while (block.isValid()) {
for (auto it = block.begin(); !it.atEnd(); ++it) {
@@ -181,6 +180,13 @@ void TextItem::scaleTextFragments(const qreal scaleY)
block = block.next();
}
+ m_document.setTextWidth(-1);
+ const qreal newIdealWidth = m_document.idealWidth();
+ const qreal scale = newIdealWidth / oldIdealWidth;
+ if (m_wrapWidth > 0) {
+ m_wrapWidth = std::max(m_wrapWidth * scale, minWrapWidth());
+ }
+
m_cursor.endEditBlock();
}
@@ -552,7 +558,7 @@ void TextItem::deserialize(const QJsonObject &obj)
bool TextItem::needsCaching() const
{
- return true;
+ return !m_isHorizontalResize;
}
QDebug operator<<(QDebug d, const TextItem &t)
diff --git a/src/gui/item/text.hpp b/src/gui/item/text.hpp
index 13ec2ddc..4240e6ef 100644
--- a/src/gui/item/text.hpp
+++ b/src/gui/item/text.hpp
@@ -90,5 +90,6 @@ private:
int m_preeditCursorPos{0};
qreal m_wrapWidth{-1};
+ bool m_isHorizontalResize{false};
};
LIBDRAWYGUI_EXPORT QDebug operator<<(QDebug d, const TextItem &t);
diff --git a/src/widgets/transformhandler/resizetransformhandler.cpp b/src/widgets/transformhandler/resizetransformhandler.cpp
index 1e5c2091..533c63a2 100644
--- a/src/widgets/transformhandler/resizetransformhandler.cpp
+++ b/src/widgets/transformhandler/resizetransformhandler.cpp
@@ -180,7 +180,7 @@ TransformHandler::State ResizeTransformHandler::mouseMoved(ApplicationContext *c
item->resize(transformUpdate);
}
- if (!item->needsCaching()) {
+ if (!item->needsCaching() && item->formType() != Item::FormType::Text) {
item->commitTransformation();
}