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