mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Handle non-solid pens
This commit is contained in:
parent
9f13e30737
commit
0dd9c26dbe
@ -109,7 +109,6 @@ class PdfEngine(QPaintEngine):
|
||||
|
||||
def init_page(self):
|
||||
self.pdf.transform(self.pdf_system)
|
||||
self.pdf.set_rgb_colorspace()
|
||||
self.graphics.reset()
|
||||
self.pdf.save_stack()
|
||||
self.current_page_inited = True
|
||||
|
@ -15,7 +15,7 @@ from PyQt4.Qt import (
|
||||
|
||||
from calibre.ebooks.pdf.render.common import (
|
||||
Name, Array, fmtnum, Stream, Dictionary)
|
||||
from calibre.ebooks.pdf.render.serialize import Path, Color
|
||||
from calibre.ebooks.pdf.render.serialize import Path
|
||||
|
||||
def convert_path(path): # {{{
|
||||
p = Path()
|
||||
@ -392,8 +392,6 @@ class Graphics(object):
|
||||
return color, opacity, pattern, do_fill
|
||||
|
||||
def apply_stroke(self, state, pdf_system, painter):
|
||||
# TODO: Handle pens with non solid brushes by setting the colorspace
|
||||
# for stroking to a pattern
|
||||
# TODO: Support miter limit by using QPainterPathStroker
|
||||
pen = state.stroke
|
||||
self.pending_state.do_stroke = True
|
||||
@ -427,14 +425,10 @@ class Graphics(object):
|
||||
pdf.current_page.write(' 0 d ')
|
||||
|
||||
# Stroke fill
|
||||
b = pen.brush()
|
||||
vals = list(b.color().getRgbF())
|
||||
vals[-1] *= state.opacity
|
||||
color = Color(*vals)
|
||||
pdf.set_stroke_color(color)
|
||||
|
||||
if vals[-1] < 1e-5 or b.style() == Qt.NoBrush:
|
||||
self.pending_state.do_stroke = False
|
||||
color, opacity, pattern, self.pending_state.do_stroke = self.convert_brush(
|
||||
pen.brush(), state.brush_origin, state.opacity, pdf_system,
|
||||
painter.transform())
|
||||
self.pdf.apply_stroke(color, pattern, opacity)
|
||||
|
||||
def apply_fill(self, state, pdf_system, painter):
|
||||
self.pending_state.do_fill = True
|
||||
@ -458,7 +452,7 @@ class Graphics(object):
|
||||
the brush origin before painting an object. While not perfect, this is
|
||||
better than nothing.
|
||||
'''
|
||||
if not self.current_state.do_fill:
|
||||
if not hasattr(self, 'last_fill') or not self.current_state.do_fill:
|
||||
return
|
||||
|
||||
if isinstance(self.last_fill.brush, TexturePattern):
|
||||
|
@ -10,7 +10,6 @@ __docformat__ = 'restructuredtext en'
|
||||
import hashlib
|
||||
from future_builtins import map
|
||||
from itertools import izip
|
||||
from collections import namedtuple
|
||||
|
||||
from PyQt4.Qt import QBuffer, QByteArray, QImage, Qt, QColor, qRgba
|
||||
|
||||
@ -23,8 +22,6 @@ from calibre.ebooks.pdf.render.links import Links
|
||||
|
||||
PDFVER = b'%PDF-1.3'
|
||||
|
||||
Color = namedtuple('Color', 'red green blue opacity')
|
||||
|
||||
class IndirectObjects(object):
|
||||
|
||||
def __init__(self):
|
||||
@ -353,9 +350,6 @@ class PDFStream(object):
|
||||
cm = ' '.join(map(fmtnum, vals))
|
||||
self.current_page.write_line(cm + ' cm')
|
||||
|
||||
def set_rgb_colorspace(self):
|
||||
self.current_page.write_line('/DeviceRGB CS /DeviceRGB cs')
|
||||
|
||||
def save_stack(self):
|
||||
self.current_page.write_line('q')
|
||||
|
||||
@ -391,13 +385,11 @@ class PDFStream(object):
|
||||
def serialize(self, o):
|
||||
serialize(o, self.current_page)
|
||||
|
||||
def set_stroke_color(self, color):
|
||||
opacity = color.opacity
|
||||
def set_stroke_opacity(self, opacity):
|
||||
if opacity not in self.stroke_opacities:
|
||||
op = Dictionary({'Type':Name('ExtGState'), 'CA': opacity})
|
||||
self.stroke_opacities[opacity] = self.objects.add(op)
|
||||
self.current_page.set_opacity(self.stroke_opacities[opacity])
|
||||
self.current_page.write_line(' '.join(map(fmtnum, color[:3])) + ' SC')
|
||||
|
||||
def set_fill_opacity(self, opacity):
|
||||
opacity = float(opacity)
|
||||
@ -518,17 +510,27 @@ class PDFStream(object):
|
||||
serialize(Name(name), self.current_page)
|
||||
self.current_page.write_line(' Do Q')
|
||||
|
||||
def apply_color_space(self, color, pattern, stroke=False):
|
||||
wl = self.current_page.write_line
|
||||
if color is not None and pattern is None:
|
||||
wl(' '.join(map(fmtnum, color)) + (' RG' if stroke else ' rg'))
|
||||
elif color is None and pattern is not None:
|
||||
wl('/Pattern %s /%s %s'%('CS' if stroke else 'cs', pattern,
|
||||
'SCN' if stroke else 'scn'))
|
||||
elif color is not None and pattern is not None:
|
||||
col = ' '.join(map(fmtnum, color))
|
||||
wl('/PCSp %s %s /%s %s'%('CS' if stroke else 'cs', col, pattern,
|
||||
'SCN' if stroke else 'scn'))
|
||||
|
||||
def apply_fill(self, color=None, pattern=None, opacity=None):
|
||||
if opacity is not None:
|
||||
self.set_fill_opacity(opacity)
|
||||
wl = self.current_page.write_line
|
||||
if color is not None and pattern is None:
|
||||
wl(' '.join(map(fmtnum, color)) + ' rg')
|
||||
elif color is None and pattern is not None:
|
||||
wl('/Pattern cs /%s scn'%pattern)
|
||||
elif color is not None and pattern is not None:
|
||||
col = ' '.join(map(fmtnum, color))
|
||||
wl('/PCSp cs %s /%s scn'%(col, pattern))
|
||||
self.apply_color_space(color, pattern)
|
||||
|
||||
def apply_stroke(self, color=None, pattern=None, opacity=None):
|
||||
if opacity is not None:
|
||||
self.set_stroke_opacity(opacity)
|
||||
self.apply_color_space(color, pattern, stroke=True)
|
||||
|
||||
def end(self):
|
||||
if self.current_page.getvalue():
|
||||
|
@ -12,7 +12,7 @@ from tempfile import gettempdir
|
||||
|
||||
from PyQt4.Qt import (QBrush, QColor, QPoint, QPixmap, QPainterPath, QRectF,
|
||||
QApplication, QPainter, Qt, QImage, QLinearGradient,
|
||||
QPointF)
|
||||
QPointF, QPen)
|
||||
QBrush, QColor, QPoint, QPixmap, QPainterPath, QRectF, Qt, QPointF
|
||||
|
||||
from calibre.ebooks.pdf.render.engine import PdfDevice
|
||||
@ -69,6 +69,14 @@ def full(p, xmax, ymax):
|
||||
g.setColorAt(1, QColor('#fff'))
|
||||
p.fillRect(x, y, w, w, QBrush(g))
|
||||
|
||||
pen = QPen(QBrush(Qt.blue))
|
||||
pen.setWidth(xmax/3)
|
||||
p.setPen(pen)
|
||||
x += w + w/10
|
||||
y += w
|
||||
p.drawLine(x, y, x+w, y)
|
||||
|
||||
|
||||
def run(dev, func):
|
||||
p = QPainter(dev)
|
||||
if isinstance(dev, PdfDevice):
|
||||
@ -91,12 +99,18 @@ def brush(p, xmax, ymax):
|
||||
|
||||
p.fillRect(0, y+xmax/1.9, w, w, QBrush(pix))
|
||||
|
||||
def pen(p, xmax, ymax):
|
||||
pix = QPixmap(I('console.png'))
|
||||
pen = QPen(QBrush(pix), 60)
|
||||
p.setPen(pen)
|
||||
p.drawRect(0, xmax/3, xmax/3, xmax/2)
|
||||
|
||||
def main():
|
||||
app = QApplication([])
|
||||
app
|
||||
tdir = gettempdir()
|
||||
pdf = os.path.join(tdir, 'painter.pdf')
|
||||
func = full
|
||||
func = pen
|
||||
dpi = 100
|
||||
with open(pdf, 'wb') as f:
|
||||
dev = PdfDevice(f, xdpi=dpi, ydpi=dpi, compress=False)
|
||||
|
Loading…
x
Reference in New Issue
Block a user