mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add (broken) support for clipping to the pdf paint engine
This commit is contained in:
parent
b287b0e27f
commit
61cedb3282
@ -39,7 +39,7 @@ class GraphicsState(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def stack_reset_needed(self):
|
def stack_reset_needed(self):
|
||||||
return 'transform' in self.ops
|
return 'transform' in self.ops or 'clip' in self.ops
|
||||||
|
|
||||||
def read_state(self, state):
|
def read_state(self, state):
|
||||||
flags = state.state()
|
flags = state.state()
|
||||||
@ -76,7 +76,15 @@ class GraphicsState(object):
|
|||||||
self.ops['line_join'] = {Qt.MiterJoin:0, Qt.RoundJoin:1,
|
self.ops['line_join'] = {Qt.MiterJoin:0, Qt.RoundJoin:1,
|
||||||
Qt.BevelJoin:2}.get(pen.joinStyle(), 0)
|
Qt.BevelJoin:2}.get(pen.joinStyle(), 0)
|
||||||
|
|
||||||
# TODO: Handle clipping
|
if flags & QPaintEngine.DirtyClipPath:
|
||||||
|
self.ops['clip'] = (state.clipOperation(), state.clipPath())
|
||||||
|
elif flags & QPaintEngine.DirtyClipRegion:
|
||||||
|
path = QPainterPath()
|
||||||
|
for rect in state.clipRegion().rects():
|
||||||
|
path.addRect(rect)
|
||||||
|
self.ops['clip'] = (state.clipOperation(), path)
|
||||||
|
|
||||||
|
# TODO: Add support for opacity
|
||||||
|
|
||||||
def __call__(self, engine):
|
def __call__(self, engine):
|
||||||
canvas = engine.canvas
|
canvas = engine.canvas
|
||||||
@ -94,6 +102,24 @@ class GraphicsState(object):
|
|||||||
if 'transform' in ops:
|
if 'transform' in ops:
|
||||||
engine.qt_system = ops['transform']
|
engine.qt_system = ops['transform']
|
||||||
set_transform(ops['transform'], canvas.transform)
|
set_transform(ops['transform'], canvas.transform)
|
||||||
|
|
||||||
|
if 'clip' in ops:
|
||||||
|
prev_clip_path = engine.graphics_state.ops.get('clip', (None, None))[1]
|
||||||
|
op, path = ops['clip']
|
||||||
|
if op == Qt.ReplaceClip:
|
||||||
|
pass
|
||||||
|
elif op == Qt.IntersectClip:
|
||||||
|
if prev_clip_path is not None:
|
||||||
|
ops['clip'] = (op, path.intersected(prev_clip_path))
|
||||||
|
elif op == Qt.UniteClip:
|
||||||
|
if prev_clip_path is not None:
|
||||||
|
path.addPath(prev_clip_path)
|
||||||
|
else:
|
||||||
|
ops['clip'] = (Qt.NoClip, None)
|
||||||
|
path = ops['clip'][1]
|
||||||
|
if path is not None:
|
||||||
|
engine.set_clip(path)
|
||||||
|
|
||||||
if 'fill_color' in ops:
|
if 'fill_color' in ops:
|
||||||
canvas.setFillColor(ops['fill_color'])
|
canvas.setFillColor(ops['fill_color'])
|
||||||
if 'stroke_color' in ops:
|
if 'stroke_color' in ops:
|
||||||
@ -203,7 +229,7 @@ class PdfEngine(QPaintEngine):
|
|||||||
state = GraphicsState(state)
|
state = GraphicsState(state)
|
||||||
self.graphics_state = state(self)
|
self.graphics_state = state(self)
|
||||||
|
|
||||||
def drawPath(self, path):
|
def convert_path(self, path):
|
||||||
p = self.canvas.beginPath()
|
p = self.canvas.beginPath()
|
||||||
path = path.simplified()
|
path = path.simplified()
|
||||||
i = 0
|
i = 0
|
||||||
@ -221,11 +247,24 @@ class PdfEngine(QPaintEngine):
|
|||||||
path.elementAt(j).x, path.elementAt(j)), (i, i+1))
|
path.elementAt(j).x, path.elementAt(j)), (i, i+1))
|
||||||
i += 2
|
i += 2
|
||||||
p.curveTo(*(c1 + c2 + em))
|
p.curveTo(*(c1 + c2 + em))
|
||||||
with self:
|
return p
|
||||||
|
|
||||||
|
def drawPath(self, path):
|
||||||
|
p = self.convert_path(path)
|
||||||
|
old = self.canvas._fillMode
|
||||||
self.canvas._fillMode = {Qt.OddEvenFill:FILL_EVEN_ODD,
|
self.canvas._fillMode = {Qt.OddEvenFill:FILL_EVEN_ODD,
|
||||||
Qt.WindingFill:FILL_NON_ZERO}[path.fillRule()]
|
Qt.WindingFill:FILL_NON_ZERO}[path.fillRule()]
|
||||||
self.canvas.drawPath(p, stroke=self.do_stroke,
|
self.canvas.drawPath(p, stroke=self.do_stroke,
|
||||||
fill=self.do_fill)
|
fill=self.do_fill)
|
||||||
|
self.canvas._fillMode = old
|
||||||
|
|
||||||
|
def set_clip(self, path):
|
||||||
|
p = self.convert_path(path)
|
||||||
|
old = self.canvas._fillMode
|
||||||
|
self.canvas._fillMode = {Qt.OddEvenFill:FILL_EVEN_ODD,
|
||||||
|
Qt.WindingFill:FILL_NON_ZERO}[path.fillRule()]
|
||||||
|
self.canvas.clipPath(p, fill=0, stroke=0)
|
||||||
|
self.canvas._fillMode = old
|
||||||
|
|
||||||
def drawPoints(self, points):
|
def drawPoints(self, points):
|
||||||
for point in points:
|
for point in points:
|
||||||
@ -304,12 +343,13 @@ class PdfEngine(QPaintEngine):
|
|||||||
for point in points[1:]:
|
for point in points[1:]:
|
||||||
p.lineTo(*point)
|
p.lineTo(*point)
|
||||||
p.close()
|
p.close()
|
||||||
with self:
|
old = self.canvas._fillMode
|
||||||
self.canvas._fillMode = {self.OddEvenMode:FILL_EVEN_ODD,
|
self.canvas._fillMode = {self.OddEvenMode:FILL_EVEN_ODD,
|
||||||
self.WindingMode:FILL_NON_ZERO}.get(mode,
|
self.WindingMode:FILL_NON_ZERO}.get(mode,
|
||||||
FILL_EVEN_ODD)
|
FILL_EVEN_ODD)
|
||||||
self.canvas.drawPath(p, fill=(mode in (self.OddEvenMode,
|
self.canvas.drawPath(p, fill=(mode in (self.OddEvenMode,
|
||||||
self.WindingMode, self.ConvexMode)))
|
self.WindingMode, self.ConvexMode)))
|
||||||
|
self.canvas._fillMode = old
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self.canvas.saveState()
|
self.canvas.saveState()
|
||||||
@ -362,6 +402,9 @@ if __name__ == '__main__':
|
|||||||
p.begin(dev)
|
p.begin(dev)
|
||||||
xmax, ymax = p.viewport().width(), p.viewport().height()
|
xmax, ymax = p.viewport().width(), p.viewport().height()
|
||||||
try:
|
try:
|
||||||
|
cp = QPainterPath()
|
||||||
|
cp.addRect(0, 0, xmax, 1000)
|
||||||
|
p.setClipPath(cp)
|
||||||
p.drawRect(0, 0, xmax, ymax)
|
p.drawRect(0, 0, xmax, ymax)
|
||||||
p.drawPolyline(QPoint(0, 0), QPoint(xmax, 0), QPoint(xmax, ymax),
|
p.drawPolyline(QPoint(0, 0), QPoint(xmax, 0), QPoint(xmax, ymax),
|
||||||
QPoint(0, ymax), QPoint(0, 0))
|
QPoint(0, ymax), QPoint(0, 0))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user