Speed up painting of cells by doing the minimum work for empty cells

This commit is contained in:
Kovid Goyal
2016-10-20 09:35:53 +05:30
parent 0c5f41b2b3
commit 08f1ecc362
2 changed files with 23 additions and 11 deletions

View File

@@ -81,6 +81,7 @@ REVERSE_MASK = 1 << REVERSE_SHIFT
STRIKE_MASK = 1 << STRIKE_SHIFT STRIKE_MASK = 1 << STRIKE_SHIFT
COL_MASK = 0xFFFFFFFF COL_MASK = 0xFFFFFFFF
COL_SHIFT = 32 COL_SHIFT = 32
HAS_BG_MASK = 0xFF << COL_SHIFT
class Line: class Line:
@@ -159,6 +160,11 @@ class Line:
c.strikethrough = bool((attrs >> STRIKE_SHIFT) & 0b1) c.strikethrough = bool((attrs >> STRIKE_SHIFT) & 0b1)
return c return c
def basic_cell_data(self, pos: int):
c = self.char[pos]
cols = self.color[pos]
return c & CHAR_MASK, c >> ATTRS_SHIFT, cols
def set_text(self, text: str, offset_in_text: int, sz: int, cursor: Cursor) -> None: def set_text(self, text: str, offset_in_text: int, sz: int, cursor: Cursor) -> None:
' Set the specified text in this line, with attributes taken from the cursor ' ' Set the specified text in this line, with attributes taken from the cursor '
attrs = self.cursor_to_attrs(cursor) | 1 attrs = self.cursor_to_attrs(cursor) | 1

View File

@@ -8,8 +8,8 @@ from PyQt5.QtCore import pyqtSignal, QTimer, QRect, Qt
from PyQt5.QtGui import QColor, QPainter, QFont, QFontMetrics, QRegion, QPen from PyQt5.QtGui import QColor, QPainter, QFont, QFontMetrics, QRegion, QPen
from PyQt5.QtWidgets import QWidget from PyQt5.QtWidgets import QWidget
from .config import build_ansi_color_tables, Options from .config import build_ansi_color_tables, Options, fg_color_table, bg_color_table
from .data_types import Line, Cursor from .data_types import Line, Cursor, HAS_BG_MASK, COL_SHIFT, COL_MASK, as_color
from .utils import set_current_font_metrics from .utils import set_current_font_metrics
from .tracker import ChangeTracker from .tracker import ChangeTracker
from .screen import wrap_cursor_position from .screen import wrap_cursor_position
@@ -179,15 +179,21 @@ class TerminalWidget(QWidget):
painter.drawRect(r) painter.drawRect(r)
def paint_cell(self, painter: QPainter, line: Line, col: int, y: int) -> None: def paint_cell(self, painter: QPainter, line: Line, col: int, y: int) -> None:
x, c = self.cell_positions[col], line.cursor_from(col) ch, attrs, colors = line.basic_cell_data(col)
fg, bg, decoration_fg = c.colors() x = self.cell_positions[col]
text = line.text_at(col) if colors & HAS_BG_MASK:
if fg is not None: bg = as_color(colors >> COL_SHIFT, bg_color_table())
painter.setPen(QPen(fg)) if bg is not None:
if bg is not None: r = QRect(x, y, self.cell_width, self.cell_height)
r = QRect(x, y, self.cell_width, self.cell_height) painter.fillRect(r, bg)
painter.fillRect(r, bg) if ch == 0 or ch == 32:
if text.rstrip(): # An empty cell
pass
else:
text = chr(ch) + line.combining_chars.get(col, '')
fg = as_color(colors & COL_MASK, fg_color_table())
if fg is not None:
painter.setPen(QPen(fg))
painter.drawText(x, y + self.baseline_offset, text) painter.drawText(x, y + self.baseline_offset, text)
def keyPressEvent(self, ev): def keyPressEvent(self, ev):