File Extend-character-clipping-by-grouping-it-with-spaces.patch of Package konsole

From ed6d8b702fd590d83d3b1db25bf2d1245b1cae33 Mon Sep 17 00:00:00 2001
From: Mariusz Glebocki <mglb@arccos-1.net>
Date: Fri, 15 Feb 2019 21:50:47 -0500
Subject: Extend character clipping by grouping it with spaces
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Summary:
Group spaces following any non-wide character with the character. This
allows for rendering ambiguous characters with wide glyphs without
clipping them. Characters are still clipped when followed by another
visible character.

{F6591346}

BUG 401298

Test Plan:
* Display: `⛰ ⛩ `
and/or:
* Install Font Awesome or other font with square icons in Private Use
  Area
* Pick some icons using KCharSelect or similar tool (or copy this:
  `     `)
* Put space after each icon and display them in Konsole

**Actual result:**
Only left half of icons is rendered
**Expected result:**
Full icon should be rendered (it can be clipped on top or bottom though)

Reviewers: #konsole, hindenburg

Reviewed By: #konsole, hindenburg

Subscribers: hindenburg, konsole-devel

Tags: #konsole

Differential Revision: https://phabricator.kde.org/D18784
---
 src/TerminalDisplay.cpp | 38 ++++++++++++++++++++++++++++++--------
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/src/TerminalDisplay.cpp b/src/TerminalDisplay.cpp
index 3f4b943..76cdae3 100644
--- a/src/TerminalDisplay.cpp
+++ b/src/TerminalDisplay.cpp
@@ -1893,14 +1893,27 @@ void TerminalDisplay::drawContents(QPainter& paint, const QRect& rect)
             const RenditionFlags currentRendition = _image[loc(x, y)].rendition;
             const bool rtl = isRtl(_image[loc(x, y)]);
 
-            if(_image[loc(x, y)].character <= 0x7e || rtl) {
-                while (x + len <= rect.right() &&
-                        _image[loc(x + len, y)].foregroundColor == currentForeground &&
-                        _image[loc(x + len, y)].backgroundColor == currentBackground &&
-                        (_image[loc(x + len, y)].rendition & ~RE_EXTENDED_CHAR) == (currentRendition & ~RE_EXTENDED_CHAR) &&
-                        (_image[qMin(loc(x + len, y) + 1, _imageSize - 1)].character == 0) == doubleWidth &&
-                        _image[loc(x + len, y)].isLineChar() == lineDraw &&
-                        (_image[loc(x + len, y)].character <= 0x7e || rtl)) {
+            const auto isInsideDrawArea = [&](int column) { return column <= rect.right(); };
+            const auto hasSameColors = [&](int column) {
+                return _image[loc(column, y)].foregroundColor == currentForeground
+                    && _image[loc(column, y)].backgroundColor == currentBackground;
+            };
+            const auto hasSameRendition = [&](int column) {
+                return (_image[loc(column, y)].rendition & ~RE_EXTENDED_CHAR)
+                    == (currentRendition & ~RE_EXTENDED_CHAR);
+            };
+            const auto hasSameWidth = [&](int column) {
+                const int characterLoc = qMin(loc(column, y) + 1, _imageSize - 1);
+                return (_image[characterLoc].character == 0) == doubleWidth;
+            };
+            const auto canBeGrouped = [&](int column) {
+                return _image[loc(column, y)].character <= 0x7e || rtl;
+            };
+
+            if (canBeGrouped(x)) {
+                while (isInsideDrawArea(x + len) && hasSameColors(x + len)
+                        && hasSameRendition(x + len) && hasSameWidth(x + len)
+                        && canBeGrouped(x + len)) {
                     const uint c = _image[loc(x + len, y)].character;
                     if ((_image[loc(x + len, y)].rendition & RE_EXTENDED_CHAR) != 0) {
                         // sequence of characters
@@ -1929,6 +1942,15 @@ void TerminalDisplay::drawContents(QPainter& paint, const QRect& rect)
                     }
                     len++;
                 }
+            } else {
+                // Group spaces following any non-wide character with the character. This allows for
+                // rendering ambiguous characters with wide glyphs without clipping them.
+                while (!doubleWidth && isInsideDrawArea(x + len)
+                        && _image[loc(x + len, y)].character == ' ' && hasSameColors(x + len)
+                        && hasSameRendition(x + len)) {
+                    // disstrU intentionally not modified - trailing spaces are meaningless
+                    len++;
+                }
             }
             if ((x + len < _usedColumns) && (_image[loc(x + len, y)].character == 0u)) {
                 len++; // Adjust for trailing part of multi-column character
-- 
cgit v1.1
openSUSE Build Service is sponsored by