Speed up dirty_cells
This commit is contained in:
parent
eaa6c7656a
commit
efeb2ebdaa
@ -2,7 +2,7 @@
|
|||||||
# vim:fileencoding=utf-8
|
# vim:fileencoding=utf-8
|
||||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
from typing import Tuple, Iterator, Union, Sequence
|
from typing import Tuple, Iterator, Sequence
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, QTimer, QRect, Qt
|
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
|
||||||
@ -10,7 +10,7 @@ from PyQt5.QtWidgets import QWidget
|
|||||||
|
|
||||||
from .config import build_ansi_color_tables, Options, fg_color_table, bg_color_table
|
from .config import build_ansi_color_tables, Options, fg_color_table, bg_color_table
|
||||||
from .data_types import Line, Cursor, HAS_BG_MASK, COL_SHIFT, COL_MASK, as_color
|
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, first_intersecting_bucket, last_intersecting_bucket
|
||||||
from .tracker import ChangeTracker
|
from .tracker import ChangeTracker
|
||||||
from .screen import wrap_cursor_position
|
from .screen import wrap_cursor_position
|
||||||
from .keys import key_event_to_data
|
from .keys import key_event_to_data
|
||||||
@ -124,23 +124,15 @@ class TerminalWidget(QWidget):
|
|||||||
pass
|
pass
|
||||||
self.update(reg)
|
self.update(reg)
|
||||||
|
|
||||||
def dirty_lines(self, region: QRegion) -> Iterator[Tuple[int, QRegion]]:
|
def dirty_cells(self, region: QRegion) -> Iterator[Tuple[int]]:
|
||||||
w = self.width() - 2 * self.hmargin
|
for rect in region.rects():
|
||||||
for i, y in enumerate(self.line_positions):
|
left, top, w, h = rect.getRect()
|
||||||
ir = region.intersected(QRect(self.hmargin, y, w, self.cell_height))
|
right, bottom = left + w, top + h
|
||||||
if not ir.isEmpty():
|
for lnum in range(min(0, first_intersecting_bucket(self.cell_height, top, self.vmargin)),
|
||||||
yield i, ir
|
max(self.lines_per_screen - 1, last_intersecting_bucket(self.cell_height, bottom, self.vmargin))):
|
||||||
|
for cnum in range(min(0, first_intersecting_bucket(self.cell_width, left, self.hmargin)),
|
||||||
def dirty_cells(self, y: int, line_region: QRegion) -> Iterator[int]:
|
max(self.cells_per_line - 1, last_intersecting_bucket(self.cell_width, right, self.hmargin))):
|
||||||
for i, x in enumerate(self.cell_positions):
|
yield lnum, cnum
|
||||||
if line_region.intersects(QRect(x, y, self.cell_width, self.cell_height)):
|
|
||||||
yield i
|
|
||||||
|
|
||||||
def line(self, screen_line: int) -> Union[Line, None]:
|
|
||||||
try:
|
|
||||||
return self.linebuf[screen_line]
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def paintEvent(self, ev):
|
def paintEvent(self, ev):
|
||||||
if self.size() != self.layout_size:
|
if self.size() != self.layout_size:
|
||||||
@ -155,18 +147,12 @@ class TerminalWidget(QWidget):
|
|||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
for lnum, line_region in self.dirty_lines(r):
|
for lnum, cnum in self.dirty_cells(r):
|
||||||
line = self.line(lnum)
|
|
||||||
if line is not None:
|
|
||||||
ypos = self.line_positions[lnum]
|
|
||||||
for cnum in self.dirty_cells(ypos, line_region):
|
|
||||||
p.save()
|
|
||||||
try:
|
try:
|
||||||
self.paint_cell(p, line, cnum, ypos)
|
self.paint_cell(p, cnum, lnum)
|
||||||
except Exception:
|
except Exception:
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
p.restore()
|
|
||||||
|
|
||||||
def paint_cursor(self, painter):
|
def paint_cursor(self, painter):
|
||||||
x, y = wrap_cursor_position(self.cursor.x, self.cursor.y, len(self.line_positions), len(self.cell_positions))
|
x, y = wrap_cursor_position(self.cursor.x, self.cursor.y, len(self.line_positions), len(self.cell_positions))
|
||||||
@ -178,9 +164,10 @@ class TerminalWidget(QWidget):
|
|||||||
painter.setPen(QPen(self.cursor_color))
|
painter.setPen(QPen(self.cursor_color))
|
||||||
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, col: int, row: int) -> None:
|
||||||
|
line = self.linebuf[row]
|
||||||
ch, attrs, colors = line.basic_cell_data(col)
|
ch, attrs, colors = line.basic_cell_data(col)
|
||||||
x = self.cell_positions[col]
|
x, y = self.cell_positions[col], self.line_positions[row]
|
||||||
if colors & HAS_BG_MASK:
|
if colors & HAS_BG_MASK:
|
||||||
bg = as_color(colors >> COL_SHIFT, bg_color_table())
|
bg = as_color(colors >> COL_SHIFT, bg_color_table())
|
||||||
if bg is not None:
|
if bg is not None:
|
||||||
@ -193,8 +180,11 @@ class TerminalWidget(QWidget):
|
|||||||
text = chr(ch) + line.combining_chars.get(col, '')
|
text = chr(ch) + line.combining_chars.get(col, '')
|
||||||
fg = as_color(colors & COL_MASK, fg_color_table())
|
fg = as_color(colors & COL_MASK, fg_color_table())
|
||||||
if fg is not None:
|
if fg is not None:
|
||||||
|
painter.save()
|
||||||
painter.setPen(QPen(fg))
|
painter.setPen(QPen(fg))
|
||||||
painter.drawText(x, y + self.baseline_offset, text)
|
painter.drawText(x, y + self.baseline_offset, text)
|
||||||
|
if fg is not None:
|
||||||
|
painter.restore()
|
||||||
|
|
||||||
def keyPressEvent(self, ev):
|
def keyPressEvent(self, ev):
|
||||||
mods = ev.modifiers()
|
mods = ev.modifiers()
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import math
|
||||||
import sys
|
import sys
|
||||||
import termios
|
import termios
|
||||||
import struct
|
import struct
|
||||||
@ -108,3 +109,13 @@ def timeit(name, do_timing=False):
|
|||||||
yield
|
yield
|
||||||
if do_timing:
|
if do_timing:
|
||||||
print('Time for {}: {}'.format(name, monotonic() - st))
|
print('Time for {}: {}'.format(name, monotonic() - st))
|
||||||
|
|
||||||
|
|
||||||
|
def first_intersecting_bucket(sz, boundary, offset=0):
|
||||||
|
' Solve the eqn: offset + (n + 1) * sz >= boundary '
|
||||||
|
return int(math.ceil((boundary - offset) / sz)) - 1
|
||||||
|
|
||||||
|
|
||||||
|
def last_intersecting_bucket(sz, boundary, offset):
|
||||||
|
' Solve the eqn: offset + n * sz <= boundary '
|
||||||
|
return int(math.floor((boundary - offset) / sz))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user