From 68bae59ae820ee87c292ecea3c1da4f6b714ce83 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 30 Oct 2016 21:12:57 +0530 Subject: [PATCH] Remove unused code --- kitty/render.py | 294 ------------------------------------------------ kitty/term.py | 109 ------------------ 2 files changed, 403 deletions(-) delete mode 100644 kitty/render.py delete mode 100644 kitty/term.py diff --git a/kitty/render.py b/kitty/render.py deleted file mode 100644 index 891604c78..000000000 --- a/kitty/render.py +++ /dev/null @@ -1,294 +0,0 @@ -#!/usr/bin/env python -# vim:fileencoding=utf-8 -# License: GPL v3 Copyright: 2016, Kovid Goyal - -from functools import lru_cache -from collections import Counter, deque, defaultdict -from itertools import chain - -from PyQt5.QtCore import QObject, pyqtSignal, Qt, QTimer, QRect -from PyQt5.QtGui import QPixmap, QRegion, QPainter, QPen, QColor, QFontMetrics, QFont - -from .config import build_ansi_color_tables, fg_color_table, bg_color_table -from .data_types import Cursor, COL_SHIFT, COL_MASK, as_color, BOLD_MASK, ITALIC_MASK -from .screen import wrap_cursor_position -from .tracker import merge_ranges -from .utils import set_current_font_metrics - - -def ascii_width(fm: QFontMetrics) -> int: - ans = 0 - for i in range(32, 128): - ans = max(ans, fm.widthChar(chr(i))) - return ans - - -@lru_cache(maxsize=2**11) -def pixmap_for_text(ch, cc, color, default_fg, font, w, h, baseline): - p = QPixmap(w, h) - p.fill(Qt.transparent) - fg = as_color(color & COL_MASK, fg_color_table()) or default_fg - painter = QPainter(p) - painter.setFont(font) - painter.setPen(QPen(QColor(*fg))) - painter.setRenderHints(QPainter.TextAntialiasing | QPainter.Antialiasing) - painter.drawText(0, baseline, chr(ch) + (cc or '')) - painter.end() - return p - - -class Renderer(QObject): - - update_required = pyqtSignal() - relayout_lines = pyqtSignal(object, object) - cells_per_line = 80 - lines_per_screen = 24 - last_painted_cursor_at = 0, 0 - _has_focus = True - - def __init__(self, screen, dpix, dpiy, parent=None): - QObject.__init__(self, parent) - self.dpix, self.dpiy = dpix, dpiy - self.screen = screen - screen.change_default_color.connect(self.change_default_color) - self.bufpix = QPixmap(10, 10) - self.pending_changes = deque() - self.debounce_update_timer = t = QTimer(self) - t.setSingleShot(True) - t.setInterval(20) - t.timeout.connect(self.do_render) - self.cursor = Cursor() - - def apply_opts(self, opts): - pixmap_for_text.cache_clear() - build_ansi_color_tables(opts) - self.opts = opts - self.default_bg = self.original_bg = QColor(opts.background) - self.default_fg = self.original_fg = QColor(opts.foreground).getRgb()[:3] - self.current_font = f = QFont(opts.font_family) - f.setPointSizeF(opts.font_size) - self.font_metrics = fm = QFontMetrics(f) - self.bold_font = b = QFont(f) - b.setBold(True) - self.italic_font = i = QFont(f) - i.setItalic(True) - self.bi_font = bi = QFont(i) - bi.setBold(True) - self.cell_height = fm.lineSpacing() - self.cell_width = ascii_width(fm) - set_current_font_metrics(fm, self.cell_width) - self.baseline_offset = fm.ascent() - self.cursor_color = c = QColor(opts.cursor) - c.setAlphaF(opts.cursor_opacity) - - def resize(self, size): - self.bufpix = QPixmap(size) - self.bufpix.fill(self.default_bg) - previous, self.cells_per_line = self.cells_per_line, size.width() // self.cell_width - previousl, self.lines_per_screen = self.lines_per_screen, size.height() // self.cell_height - self.hmargin = (size.width() - self.cells_per_line * self.cell_width) // 2 - self.vmargin = (size.height() % self.cell_height) // 2 - self.line_positions = tuple(self.vmargin + i * self.cell_height for i in range(self.lines_per_screen)) - self.cell_positions = tuple(self.hmargin + i * self.cell_width for i in range(self.cells_per_line)) - self.row_rects = {lnum: QRect(self.hmargin, self.line_positions[lnum], self.cell_width * - self.cells_per_line, self.cell_height) for lnum in range(self.lines_per_screen)} - self.col_rects = {cnum: QRect(self.cell_positions[cnum], self.vmargin, self.cell_width, - self.cell_height * self.lines_per_screen) for cnum in range(self.cells_per_line)} - self.cell_rects = { - lnum: {cnum: self.col_rects[cnum].intersected(self.row_rects[lnum]) for cnum in self.col_rects} - for lnum in self.row_rects - } - self.line_width = self.cells_per_line * self.cell_width - if (previous, previousl) != (self.cells_per_line, self.lines_per_screen): - self.screen.resize(self.lines_per_screen, self.cells_per_line) - self.relayout_lines.emit(self.cells_per_line, self.lines_per_screen) - self.dirtied() - - def dirtied(self): - self.update_screen({'screen': True}) - - def size(self): - return self.bufpix.size() - - def render(self, painter): - painter.drawPixmap(0, 0, self.bufpix) - - def change_default_color(self, which, val): - if which in ('fg', 'bg'): - if not val: - setattr(self, 'default_' + which, getattr(self, 'original_' + which)) - self.dirtied() - else: - val = QColor(val) - if val.isValid(): - if which == 'fg': - self.default_fg = val.getRgb()[:3] - else: - self.default_bg = val - self.dirtied() - - def update_screen(self, changes): - self.pending_changes.append(changes) - if not self.debounce_update_timer.isActive(): - self.debounce_update_timer.start() - - def wrap_cursor_pos(self): - self.cursorx, self.cursory = wrap_cursor_position(self.cursor.x, self.cursor.y, self.lines_per_screen, self.cells_per_line) - - def set_has_focus(self, yes): - if yes != self._has_focus: - self._has_focus = yes - self.wrap_cursor_pos() - self.update_screen({'screen': False, 'lines': set(), 'cells': {self.cursory: {(self.cursorx, self.cursorx)}}}) - - def line(self, lnum): - return self.screen.line(lnum) - - def common_bg_color(self): - c = Counter() - for rdiv in range(1, 4): - lnum = int(self.lines_per_screen * rdiv / 4) - for cdiv in range(1, 4): - cnum = int(self.cells_per_line * cdiv / 4) - bgcol = self.line(lnum).bgcolor(cnum) - c[bgcol] += 1 - return c.most_common(1)[0][0] - - def do_render(self): - dirty_lines = set() - dirty_cell_ranges = defaultdict(set) - screen_dirtied = False - - while self.pending_changes: - c = self.pending_changes.popleft() - self.cursor = c.get('cursor') or self.cursor - if not screen_dirtied: - if c['screen']: - screen_dirtied = True - continue - dirty_lines |= c['lines'] - for l, ranges in c['cells'].items(): - if l not in dirty_lines: - for r in ranges: - dirty_cell_ranges[l].add(r) - - if screen_dirtied: - dirty_cell_ranges = {} - dirty_lines = tuple(range(self.lines_per_screen)) - else: - dirty_cell_ranges = {l: tuple(merge_ranges(r)) for l, r in dirty_cell_ranges.items() if l not in dirty_lines} - - self.paint(dirty_lines, dirty_cell_ranges, screen_dirtied) - self.update_required.emit() - - def calculate_dirty_region(self, dirty_lines, dirty_cell_ranges): - ans = QRegion() - for lnum in dirty_lines: - ans += self.row_rects[lnum] - for lnum, ranges in dirty_cell_ranges.items(): - lrect = self.cell_rects[lnum] - for start, stop in ranges: - for cnum in range(start, stop + 1): - ans += lrect[cnum] - return ans - - def paint(self, dirty_lines, dirty_cell_ranges, screen_dirtied): - self.current_bgcol = self.common_bg_color() - bg = self.default_bg - if self.current_bgcol & 0xff: - cbg = as_color(self.current_bgcol, bg_color_table()) - if cbg: - bg = QColor(*cbg) - self.wrap_cursor_pos() - self.cursor_painted = False - self.old_cursorx, self.old_cursory = self.last_painted_cursor_at - self.cursor_moved = self.old_cursorx != self.cursorx or self.old_cursory != self.cursory - region = QRegion(self.bufpix.rect()) if screen_dirtied else self.calculate_dirty_region(dirty_lines, dirty_cell_ranges) - if self.cursor_moved: - r = QRect(self.cell_positions[self.old_cursorx], self.line_positions[self.old_cursory], self.cell_width, self.cell_height) - if region.contains(r): - self.cursor_moved = False - else: - region += r - - p = QPainter(self.bufpix) - p.save() - p.setClipRegion(region) - p.fillRect(self.bufpix.rect(), bg) - p.restore() - - for lnum in dirty_lines: - self.paint_line(p, lnum, range(self.cells_per_line)) - - for lnum, ranges in dirty_cell_ranges.items(): - self.paint_line(p, lnum, chain.from_iterable(range(start, stop + 1) for start, stop in ranges)) - - if not self.cursor_painted: - self.paint_cell(p, self.line(self.cursory), self.cursory, self.cursorx) - - if self.cursor_moved: - self.paint_cell(p, self.line(self.old_cursory), self.old_cursory, self.old_cursorx) - - p.end() - - def paint_line(self, painter, lnum, cell_range): - line = self.line(lnum) - for cnum in cell_range: - self.paint_cell(painter, line, lnum, cnum) - - def paint_cell(self, painter, line, lnum, cnum): - paint_cursor = False - if not self.cursor_painted: - self.cursor_painted = paint_cursor = lnum == self.cursory and cnum == self.cursorx - ch, attrs, colors = line.basic_cell_data(cnum) - x, y = self.cell_positions[cnum], self.line_positions[lnum] - bgcol = colors >> COL_SHIFT - if bgcol != self.current_bgcol: - bg = as_color(colors >> COL_SHIFT, bg_color_table()) - if bg is not None: - r = QRect(x, y, self.cell_width, self.cell_height) - painter.fillRect(r, QColor(*bg)) - if paint_cursor: - self.paint_cursor(painter, cnum, lnum) - if ch == 0 or ch == 32: - # An empty cell - pass - else: - font = self.current_font - b, i = attrs & BOLD_MASK, attrs & ITALIC_MASK - if b: - font = self.bi_font if i else self.bold_font - elif i: - font = self.italic_font - p = pixmap_for_text(ch, line.combining_chars.get(cnum), colors & COL_MASK, - self.default_fg, font, self.cell_width * 2, self.cell_height, self.baseline_offset) - painter.drawPixmap(x, y, p) - - def paint_cursor(self, painter, x, y): - self.last_painted_cursor_at = x, y - r = QRect(self.cell_positions[x], self.line_positions[y], self.cell_width, self.cell_height) - cc = self.cursor_color - if self.cursor.color: - q = QColor(self.cursor.color) - if q.isValid(): - cc = q - cc.setAlphaF(self.opts.cursor_opacity) - - def width(w=2, vert=True): - dpi = self.dpix if vert else self.dpiy - return int(w * dpi / 72) - - if self._has_focus: - cs = self.cursor.shape or self.opts.cursor_shape - if cs == 'block': - painter.fillRect(r, cc) - elif cs == 'beam': - w = width(1.5) - painter.fillRect(r.left(), r.top(), w, self.cell_height, cc) - elif cs == 'underline': - y = r.top() + self.font_metrics.underlinePos() + self.baseline_offset - w = width(vert=False) - painter.fillRect(r.left(), min(y, r.bottom() - w), self.cell_width, w, cc) - else: - painter.setPen(QPen(cc)) - painter.drawRect(r) diff --git a/kitty/term.py b/kitty/term.py deleted file mode 100644 index 96084a4e4..000000000 --- a/kitty/term.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python -# vim:fileencoding=utf-8 -# License: GPL v3 Copyright: 2016, Kovid Goyal - - -from PyQt5.QtCore import pyqtSignal, QTimer, Qt -from PyQt5.QtGui import QPainter -from PyQt5.QtWidgets import QWidget, QApplication - -from .config import Options -from .tracker import ChangeTracker -from .keys import key_event_to_data -from .screen import Screen -from .render import Renderer -from pyte.streams import Stream, DebugStream -from pyte import modes as mo - - -class TerminalWidget(QWidget): - - relayout_lines = pyqtSignal(object, object) - write_to_child = pyqtSignal(object) - title_changed = pyqtSignal(object) - icon_changed = pyqtSignal(object) - send_data_to_child = pyqtSignal(object) - - def __init__(self, opts: Options, parent: QWidget=None, dump_commands: bool=False): - QWidget.__init__(self, parent) - self.setAttribute(Qt.WA_OpaquePaintEvent, True) - self.setAutoFillBackground(False) - self.setFocusPolicy(Qt.WheelFocus) - self.debounce_resize_timer = t = QTimer(self) - t.setSingleShot(True) - t.setInterval(50) - t.timeout.connect(self.do_layout) - - self.tracker = ChangeTracker(self) - sclass = DebugStream if dump_commands else Stream - self.screen = Screen(opts, self.tracker, parent=self) - for s in 'write_to_child title_changed icon_changed'.split(): - getattr(self.screen, s).connect(getattr(self, s)) - self.stream = sclass(self.screen) - self.feed = self.stream.feed - self.renderer = Renderer(self.screen, self.logicalDpiX(), self.logicalDpiY(), self) - self.tracker.dirtied.connect(self.renderer.update_screen) - self.renderer.update_required.connect(self.update_required) - self.renderer.relayout_lines.connect(self.relayout_lines) - self.apply_opts(opts) - - def update_required(self): - self.update() - - def apply_opts(self, opts): - self.screen.apply_opts(opts) - self.opts = opts - self.renderer.apply_opts(opts) - self.do_layout() - - def do_layout(self): - self.renderer.resize(self.size()) - self.update() - - def resizeEvent(self, ev): - self.debounce_resize_timer.start() - - def paintEvent(self, ev): - if self.size() != self.renderer.size(): - return - p = QPainter(self) - self.renderer.render(p) - p.end() - - def keyPressEvent(self, ev): - mods = ev.modifiers() - if mods & Qt.ControlModifier and mods & Qt.ShiftModifier: - ev.accept() - return # Terminal shortcuts - data = key_event_to_data(ev, mods) - if data: - self.send_data_to_child.emit(data) - ev.accept() - return - return QWidget.keyPressEvent(self, ev) - - def mousePressEvent(self, ev): - if ev.button() == Qt.MiddleButton: - c = QApplication.clipboard() - if c.supportsSelection(): - text = c.text(c.Selection) - if text: - text = text.encode('utf-8') - if self.screen.in_bracketed_paste_mode: - text = mo.BRACKETED_PASTE_START + text + mo.BRACKETED_PASTE_END - self.send_data_to_child.emit(text) - ev.accept() - return - return QWidget.mousePressEvent(self, ev) - - def focusInEvent(self, ev): - if self.screen.enable_focus_tracking: - self.send_data_to_child.emit(b'\x1b[I') - self.renderer.set_has_focus(True) - return QWidget.focusInEvent(self, ev) - - def focusOutEvent(self, ev): - if self.screen.enable_focus_tracking: - self.send_data_to_child.emit(b'\x1b[O') - self.renderer.set_has_focus(False) - return QWidget.focusOutEvent(self, ev)