Beispiel #1
0
 def paintEvent(self, event):
     canvas_size = self.rect()
     width = self.current_pixmap_size.width()
     extrax = canvas_size.width() - width
     if extrax < 0:
         extrax = 0
     x = int(extrax//2)
     height = self.current_pixmap_size.height()
     extray = canvas_size.height() - height
     if extray < 0:
         extray = 0
     y = int(extray//2)
     target = QRect(x, y, width, height)
     p = QPainter(self)
     p.setRenderHints(QPainter.RenderHint.Antialiasing | QPainter.RenderHint.SmoothPixmapTransform)
     try:
         dpr = self.devicePixelRatioF()
     except AttributeError:
         dpr = self.devicePixelRatio()
     spmap = self.pixmap.scaled(target.size() * dpr, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)
     spmap.setDevicePixelRatio(dpr)
     p.drawPixmap(target, spmap)
     if gprefs['bd_overlay_cover_size']:
         sztgt = target.adjusted(0, 0, 0, -4)
         f = p.font()
         f.setBold(True)
         p.setFont(f)
         sz = '\u00a0%d x %d\u00a0'%(self.pixmap.width(), self.pixmap.height())
         flags = Qt.AlignmentFlag.AlignBottom|Qt.AlignmentFlag.AlignRight|Qt.TextFlag.TextSingleLine
         szrect = p.boundingRect(sztgt, flags, sz)
         p.fillRect(szrect.adjusted(0, 0, 0, 4), QColor(0, 0, 0, 200))
         p.setPen(QPen(QColor(255,255,255)))
         p.drawText(sztgt, flags, sz)
     p.end()
Beispiel #2
0
def create_icon(text, palette=None, sz=None, divider=2, fill='white'):
    if isinstance(fill, string_or_bytes):
        fill = QColor(fill)
    sz = sz or int(
        math.ceil(tprefs['toolbar_icon_size'] *
                  QApplication.instance().devicePixelRatio()))
    if palette is None:
        palette = QApplication.palette()
    img = QImage(sz, sz, QImage.Format.Format_ARGB32)
    img.fill(Qt.GlobalColor.transparent)
    p = QPainter(img)
    p.setRenderHints(QPainter.RenderHint.TextAntialiasing
                     | QPainter.RenderHint.Antialiasing)
    if fill is not None:
        qDrawShadeRect(p,
                       img.rect(),
                       palette,
                       fill=fill,
                       lineWidth=1,
                       midLineWidth=1)
    f = p.font()
    f.setFamily('Liberation Sans'), f.setPixelSize(int(
        sz // divider)), f.setBold(True)
    p.setFont(f), p.setPen(QColor('#2271d5'))
    p.drawText(img.rect().adjusted(2, 2, -2, -2), Qt.AlignmentFlag.AlignCenter,
               text)
    p.end()
    return QIcon(QPixmap.fromImage(img))
Beispiel #3
0
    def paint_line_numbers(self, ev):
        painter = QPainter(self.line_number_area)
        painter.fillRect(ev.rect(), self.line_number_palette.color(QPalette.ColorRole.Base))

        block = self.firstVisibleBlock()
        num = block.blockNumber()
        top = int(self.blockBoundingGeometry(block).translated(self.contentOffset()).top())
        bottom = top + int(self.blockBoundingRect(block).height())
        current = self.textCursor().block().blockNumber()
        painter.setPen(self.line_number_palette.color(QPalette.ColorRole.Text))

        while block.isValid() and top <= ev.rect().bottom():
            if block.isVisible() and bottom >= ev.rect().top():
                if current == num:
                    painter.save()
                    painter.setPen(self.line_number_palette.color(QPalette.ColorRole.BrightText))
                    f = QFont(self.font())
                    f.setBold(True)
                    painter.setFont(f)
                    self.last_current_lnum = (top, bottom - top)
                painter.drawText(0, top, self.line_number_area.width() - 5, self.fontMetrics().height(),
                              Qt.AlignmentFlag.AlignRight, unicode_type(num + 1))
                if current == num:
                    painter.restore()
            block = block.next()
            top = bottom
            bottom = top + int(self.blockBoundingRect(block).height())
            num += 1
Beispiel #4
0
    def paintEvent(self, event):
        pmap = self.blank if self.pixmap is None or self.pixmap.isNull(
        ) else self.pixmap
        target = self.rect()
        scaled, width, height = fit_image(pmap.width(), pmap.height(),
                                          target.width(), target.height())
        target.setRect(target.x(), target.y(), width, height)
        p = QPainter(self)
        p.setRenderHints(QPainter.RenderHint.Antialiasing
                         | QPainter.RenderHint.SmoothPixmapTransform)
        p.drawPixmap(target, pmap)

        if self.pixmap is not None and not self.pixmap.isNull():
            sztgt = target.adjusted(0, 0, 0, -4)
            f = p.font()
            f.setBold(True)
            p.setFont(f)
            sz = u'\u00a0%d x %d\u00a0' % (self.pixmap.width(),
                                           self.pixmap.height())
            flags = int(Qt.AlignmentFlag.AlignBottom
                        | Qt.AlignmentFlag.AlignRight
                        | Qt.TextFlag.TextSingleLine)
            szrect = p.boundingRect(sztgt, flags, sz)
            p.fillRect(szrect.adjusted(0, 0, 0, 4), QColor(0, 0, 0, 200))
            p.setPen(QPen(QColor(255, 255, 255)))
            p.drawText(sztgt, flags, sz)
        p.end()
Beispiel #5
0
def generate_masthead(title,
                      output_path=None,
                      width=600,
                      height=60,
                      as_qimage=False,
                      font_family=None):
    init_environment()
    font_family = font_family or cprefs[
        'title_font_family'] or 'Liberation Serif'
    img = QImage(width, height, QImage.Format.Format_ARGB32)
    img.fill(Qt.GlobalColor.white)
    p = QPainter(img)
    p.setRenderHints(QPainter.RenderHint.Antialiasing
                     | QPainter.RenderHint.TextAntialiasing)
    f = QFont(font_family)
    f.setStyleStrategy(QFont.StyleStrategy.PreferAntialias)
    f.setPixelSize((height * 3) // 4), f.setBold(True)
    p.setFont(f)
    p.drawText(img.rect(),
               Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter,
               sanitize(title))
    p.end()
    if as_qimage:
        return img
    data = pixmap_to_data(img)
    if output_path is None:
        return data
    with open(output_path, 'wb') as f:
        f.write(data)
Beispiel #6
0
 def paintEvent(self, ev):
     shown = self.button.isChecked()
     ls = self.fm.lineSpacing()
     painter = QPainter(self)
     if self.mouse_over:
         tool = QStyleOption()
         tool.rect = self.rect()
         tool.state = QStyle.StateFlag.State_Raised | QStyle.StateFlag.State_Active | QStyle.StateFlag.State_MouseOver
         s = self.style()
         s.drawPrimitive(QStyle.PrimitiveElement.PE_PanelButtonTool, tool,
                         painter, self)
     painter.drawText(
         0, 0, self.width(), ls,
         Qt.AlignmentFlag.AlignCenter | Qt.TextFlag.TextSingleLine,
         self.text)
     text = _('Hide') if shown else _('Show')
     f = self.font()
     f.setBold(True)
     painter.setFont(f)
     painter.drawText(
         0,
         self.height() - ls, self.width(), ls,
         Qt.AlignmentFlag.AlignCenter | Qt.TextFlag.TextSingleLine, text)
     x = (self.width() - ICON_SZ) // 2
     y = ls + (self.height() - ICON_SZ - 2 * ls) // 2
     pmap = self.bright_icon if shown else self.dull_icon
     painter.drawPixmap(x, y, pmap)
     painter.end()
Beispiel #7
0
 def paintEvent(self, ev):
     p = QPainter(self)
     p.setClipRect(ev.rect())
     bg = self.palette().color(QPalette.ColorRole.AlternateBase)
     if self.hovering:
         bg = bg.lighter(115)
     p.fillRect(self.rect(), bg)
     try:
         p.drawText(self.rect(), Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter|Qt.TextFlag.TextSingleLine, self.rendered_text)
     finally:
         p.end()
Beispiel #8
0
def message_image(text, width=500, height=400, font_size=20):
    init_environment()
    img = QImage(width, height, QImage.Format.Format_ARGB32)
    img.fill(Qt.GlobalColor.white)
    p = QPainter(img)
    f = QFont()
    f.setPixelSize(font_size)
    p.setFont(f)
    r = img.rect().adjusted(10, 10, -10, -10)
    p.drawText(r, Qt.AlignmentFlag.AlignJustify | Qt.AlignmentFlag.AlignVCenter | Qt.TextFlag.TextWordWrap, text)
    p.end()
    return pixmap_to_data(img)
Beispiel #9
0
 def paintEvent(self, ev):
     br = ev.region().boundingRect()
     QWidget.paintEvent(self, ev)
     p = QPainter(self)
     p.setClipRect(br)
     f = p.font()
     f.setBold(True)
     f.setPointSize(20)
     p.setFont(f)
     p.setPen(Qt.PenStyle.SolidLine)
     r = QRect(0, self.dummy.geometry().top() + 10, self.geometry().width(), 150)
     p.drawText(r, Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop | Qt.TextFlag.TextSingleLine, self.text)
     p.end()
Beispiel #10
0
    def paint_line_numbers(self, ev):
        painter = QPainter(self.line_number_area)
        painter.fillRect(
            ev.rect(), self.line_number_palette.color(QPalette.ColorRole.Base))

        block = self.firstVisibleBlock()
        num = block.blockNumber()
        top = int(
            self.blockBoundingGeometry(block).translated(
                self.contentOffset()).top())
        bottom = top + int(self.blockBoundingRect(block).height())
        current = self.textCursor().block().blockNumber()
        painter.setPen(self.line_number_palette.color(QPalette.ColorRole.Text))

        while block.isValid() and top <= ev.rect().bottom():
            if block.isVisible() and bottom >= ev.rect().top():
                set_bold = False
                set_italic = False
                if current == num:
                    set_bold = True
                if num + 1 in self.clicked_line_numbers:
                    set_italic = True
                painter.save()
                if set_bold or set_italic:
                    f = QFont(self.font())
                    if set_bold:
                        f.setBold(set_bold)
                        painter.setPen(
                            self.line_number_palette.color(
                                QPalette.ColorRole.BrightText))
                    f.setItalic(set_italic)
                    painter.setFont(f)
                else:
                    painter.setFont(self.font())
                painter.drawText(0, top,
                                 self.line_number_area.width() - 5,
                                 self.fontMetrics().height(),
                                 Qt.AlignmentFlag.AlignRight, str(num + 1))
                painter.restore()
            block = block.next()
            top = bottom
            bottom = top + int(self.blockBoundingRect(block).height())
            num += 1
Beispiel #11
0
    def paintEvent(self, event):
        w = self.viewport().rect().width()
        painter = QPainter(self.viewport())
        painter.setClipRect(event.rect())
        painter.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform, True)
        floor = event.rect().bottom()
        ceiling = event.rect().top()
        fv = self.firstVisibleBlock().blockNumber()
        origin = self.contentOffset()
        doc = self.document()
        lines = []

        for num, text in self.headers:
            top, bot = num, num + 3
            if bot < fv:
                continue
            y_top = self.blockBoundingGeometry(doc.findBlockByNumber(top)).translated(origin).y()
            y_bot = self.blockBoundingGeometry(doc.findBlockByNumber(bot)).translated(origin).y()
            if max(y_top, y_bot) < ceiling:
                continue
            if min(y_top, y_bot) > floor:
                break
            painter.setFont(self.heading_font)
            br = painter.drawText(3, y_top, w, y_bot - y_top - 5, Qt.TextFlag.TextSingleLine, text)
            painter.setPen(QPen(self.palette().text(), 2))
            painter.drawLine(0, br.bottom()+3, w, br.bottom()+3)

        for top, bot, kind in self.changes:
            if bot < fv:
                continue
            y_top = self.blockBoundingGeometry(doc.findBlockByNumber(top)).translated(origin).y()
            y_bot = self.blockBoundingGeometry(doc.findBlockByNumber(bot)).translated(origin).y()
            if max(y_top, y_bot) < ceiling:
                continue
            if min(y_top, y_bot) > floor:
                break
            if y_top != y_bot:
                painter.fillRect(0,  y_top, w, y_bot - y_top, self.diff_backgrounds[kind])
            lines.append((y_top, y_bot, kind))
            if top in self.images:
                img, maxw = self.images[top][:2]
                if bot > top + 1 and not img.isNull():
                    y_top = self.blockBoundingGeometry(doc.findBlockByNumber(top+1)).translated(origin).y() + 3
                    y_bot -= 3
                    scaled, imgw, imgh = fit_image(int(img.width()/img.devicePixelRatio()), int(img.height()/img.devicePixelRatio()), w - 3, y_bot - y_top)
                    painter.drawPixmap(QRect(3, y_top, imgw, imgh), img)

        painter.end()
        PlainTextEdit.paintEvent(self, event)
        painter = QPainter(self.viewport())
        painter.setClipRect(event.rect())
        for top, bottom, kind in sorted(lines, key=lambda t_b_k:{'replace':0}.get(t_b_k[2], 1)):
            painter.setPen(QPen(self.diff_foregrounds[kind], 1))
            painter.drawLine(0, top, w, top)
            painter.drawLine(0, bottom - 1, w, bottom - 1)
Beispiel #12
0
    def paintEvent(self, ev):
        offset = QPoint(0, 0)
        p = QPainter(self)
        p.setClipRect(ev.rect())
        bottom = self.rect().bottom()

        if self.results:
            for i, (prefix, full, text) in enumerate(self.results):
                size = prefix.size()
                if offset.y() + size.height() > bottom:
                    break
                self.max_result = i
                offset.setX(0)
                if i in (self.current_result, self.mouse_hover_result):
                    p.save()
                    if i != self.current_result:
                        p.setPen(Qt.PenStyle.DotLine)
                    p.drawLine(offset, QPoint(self.width(), offset.y()))
                    p.restore()
                offset.setY(offset.y() + self.MARGIN // 2)
                p.drawStaticText(offset, prefix)
                offset.setX(self.maxwidth + 5)
                p.drawStaticText(offset, self.divider)
                offset.setX(offset.x() + self.divider.size().width())
                p.drawStaticText(offset, full)
                offset.setY(offset.y() + size.height() + self.MARGIN // 2)
                if i in (self.current_result, self.mouse_hover_result):
                    offset.setX(0)
                    p.save()
                    if i != self.current_result:
                        p.setPen(Qt.PenStyle.DotLine)
                    p.drawLine(offset, QPoint(self.width(), offset.y()))
                    p.restore()
        else:
            p.drawText(self.rect(), Qt.AlignmentFlag.AlignCenter,
                       _('No results found'))

        p.end()
Beispiel #13
0
 def failed_img(self):
     if self._failed_img is None:
         try:
             dpr = self.devicePixelRatioF()
         except AttributeError:
             dpr = self.devicePixelRatio()
         i = QImage(200, 150, QImage.Format.Format_ARGB32)
         i.setDevicePixelRatio(dpr)
         i.fill(Qt.GlobalColor.white)
         p = QPainter(i)
         r = i.rect().adjusted(10, 10, -10, -10)
         n = QPen(Qt.PenStyle.DashLine)
         n.setColor(Qt.GlobalColor.black)
         p.setPen(n)
         p.drawRect(r)
         p.setPen(Qt.GlobalColor.black)
         f = self.font()
         f.setPixelSize(20)
         p.setFont(f)
         p.drawText(r.adjusted(10, 0, -10, 0), Qt.AlignmentFlag.AlignCenter | Qt.TextFlag.TextWordWrap, _('Image could not be rendered'))
         p.end()
         self._failed_img = QPixmap.fromImage(i)
     return self._failed_img
Beispiel #14
0
    def paint_line_numbers(self, ev):
        painter = QPainter(self.line_number_area)
        painter.fillRect(ev.rect(), self.line_number_palette.color(QPalette.ColorRole.Base))

        block = self.firstVisibleBlock()
        num = block.blockNumber()
        top = int(self.blockBoundingGeometry(block).translated(self.contentOffset()).top())
        bottom = top + int(self.blockBoundingRect(block).height())
        painter.setPen(self.line_number_palette.color(QPalette.ColorRole.Text))
        change_starts = {x[0] for x in self.changes}

        while block.isValid() and top <= ev.rect().bottom():
            r = ev.rect()
            if block.isVisible() and bottom >= r.top():
                text = unicode_type(self.line_number_map.get(num, ''))
                is_start = text != '-' and num in change_starts
                if is_start:
                    painter.save()
                    f = QFont(self.font())
                    f.setBold(True)
                    painter.setFont(f)
                    painter.setPen(self.line_number_palette.color(QPalette.ColorRole.BrightText))
                if text == '-':
                    painter.drawLine(r.left() + 2, (top + bottom)//2, r.right() - 2, (top + bottom)//2)
                else:
                    if self.right:
                        painter.drawText(r.left() + 3, top, r.right(), self.fontMetrics().height(),
                                Qt.AlignmentFlag.AlignLeft, text)
                    else:
                        painter.drawText(r.left() + 2, top, r.right() - 5, self.fontMetrics().height(),
                                Qt.AlignmentFlag.AlignRight, text)
                if is_start:
                    painter.restore()
            block = block.next()
            top = bottom
            bottom = top + int(self.blockBoundingRect(block).height())
            num += 1
Beispiel #15
0
def decoration_for_style(palette, style, icon_size, device_pixel_ratio, is_dark):
    style_key = (is_dark, icon_size, device_pixel_ratio, tuple((k, style[k]) for k in sorted(style)))
    sentinel = object()
    ans = decoration_cache.get(style_key, sentinel)
    if ans is not sentinel:
        return ans
    ans = None
    kind = style.get('kind')
    if kind == 'color':
        key = 'dark' if is_dark else 'light'
        val = style.get(key)
        if val is None:
            which = style.get('which')
            val = (builtin_colors_dark if is_dark else builtin_colors_light).get(which)
        if val is None:
            val = style.get('background-color')
        if val is not None:
            ans = QColor(val)
    elif kind == 'decoration':
        which = style.get('which')
        if which is not None:
            q = builtin_decorations.get(which)
            if q is not None:
                style = q
        sz = int(math.ceil(icon_size * device_pixel_ratio))
        canvas = QImage(sz, sz, QImage.Format.Format_ARGB32)
        canvas.fill(Qt.GlobalColor.transparent)
        canvas.setDevicePixelRatio(device_pixel_ratio)
        p = QPainter(canvas)
        p.setRenderHint(QPainter.RenderHint.Antialiasing, True)
        p.setPen(palette.color(QPalette.ColorRole.WindowText))
        irect = QRect(0, 0, icon_size, icon_size)
        adjust = -2
        text_rect = p.drawText(irect.adjusted(0, adjust, 0, adjust), Qt.AlignmentFlag.AlignHCenter| Qt.AlignmentFlag.AlignTop, 'a')
        p.drawRect(irect)
        fm = p.fontMetrics()
        pen = p.pen()
        if 'text-decoration-color' in style:
            pen.setColor(QColor(style['text-decoration-color']))
        lstyle = style.get('text-decoration-style') or 'solid'
        q = {'dotted': Qt.PenStyle.DotLine, 'dashed': Qt.PenStyle.DashLine, }.get(lstyle)
        if q is not None:
            pen.setStyle(q)
        lw = fm.lineWidth()
        if lstyle == 'double':
            lw * 2
        pen.setWidth(fm.lineWidth())
        q = style.get('text-decoration-line') or 'underline'
        pos = text_rect.bottom()
        height = irect.bottom() - pos
        if q == 'overline':
            pos = height
        elif q == 'line-through':
            pos = text_rect.center().y() - adjust - lw // 2
        p.setPen(pen)
        if lstyle == 'wavy':
            p.drawPath(wavy_path(icon_size, height, pos))
        else:
            p.drawLine(0, pos, irect.right(), pos)
        p.end()
        ans = QPixmap.fromImage(canvas)
    elif 'background-color' in style:
        ans = QColor(style['background-color'])
    decoration_cache[style_key] = ans
    return ans