mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
py3: Full fix for svg2painterpath (I hope)
This commit is contained in:
parent
e5b32b2c2f
commit
3d795076c6
@ -495,7 +495,11 @@ class Ornamental(Style):
|
|||||||
def __call__(self, painter, rect, color_theme, title_block, subtitle_block, footer_block):
|
def __call__(self, painter, rect, color_theme, title_block, subtitle_block, footer_block):
|
||||||
if not self.PATH_CACHE:
|
if not self.PATH_CACHE:
|
||||||
from calibre.utils.speedups import svg_path_to_painter_path
|
from calibre.utils.speedups import svg_path_to_painter_path
|
||||||
|
try:
|
||||||
self.__class__.PATH_CACHE['corner'] = svg_path_to_painter_path(self.CORNER_VECTOR)
|
self.__class__.PATH_CACHE['corner'] = svg_path_to_painter_path(self.CORNER_VECTOR)
|
||||||
|
except Exception:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
p = painter
|
p = painter
|
||||||
painter.setRenderHint(QPainter.Antialiasing)
|
painter.setRenderHint(QPainter.Antialiasing)
|
||||||
g = QRadialGradient(QPointF(rect.center()), rect.width())
|
g = QRadialGradient(QPointF(rect.center()), rect.width())
|
||||||
@ -503,7 +507,10 @@ class Ornamental(Style):
|
|||||||
painter.fillRect(rect, QBrush(g))
|
painter.fillRect(rect, QBrush(g))
|
||||||
painter.save()
|
painter.save()
|
||||||
painter.setWindow(0, 0, *self.VIEWPORT)
|
painter.setWindow(0, 0, *self.VIEWPORT)
|
||||||
|
try:
|
||||||
path = self.PATH_CACHE['corner']
|
path = self.PATH_CACHE['corner']
|
||||||
|
except KeyError:
|
||||||
|
path = QPainterPath()
|
||||||
pen = p.pen()
|
pen = p.pen()
|
||||||
pen.setColor(self.ccolor1)
|
pen.setColor(self.ccolor1)
|
||||||
p.setPen(pen)
|
p.setPen(pen)
|
||||||
|
@ -55,15 +55,15 @@ def svg_path_to_painter_path(d):
|
|||||||
from PyQt5.Qt import QPainterPath
|
from PyQt5.Qt import QPainterPath
|
||||||
cmd = last_cmd = b''
|
cmd = last_cmd = b''
|
||||||
path = QPainterPath()
|
path = QPainterPath()
|
||||||
moveto_abs, moveto_rel = b'Mm'
|
moveto_abs, moveto_rel = b'M', b'm'
|
||||||
closepath1, closepath2 = b'Zz'
|
closepath1, closepath2 = b'Z', b'z'
|
||||||
lineto_abs, lineto_rel = b'Ll'
|
lineto_abs, lineto_rel = b'L', b'l'
|
||||||
hline_abs, hline_rel = b'Hh'
|
hline_abs, hline_rel = b'H', b'h'
|
||||||
vline_abs, vline_rel = b'Vv'
|
vline_abs, vline_rel = b'V', b'v'
|
||||||
curveto_abs, curveto_rel = b'Cc'
|
curveto_abs, curveto_rel = b'C', b'c'
|
||||||
smoothcurveto_abs, smoothcurveto_rel = b'Ss'
|
smoothcurveto_abs, smoothcurveto_rel = b'S', b's'
|
||||||
quadcurveto_abs, quadcurveto_rel = b'Qq'
|
quadcurveto_abs, quadcurveto_rel = b'Q', b'q'
|
||||||
smoothquadcurveto_abs, smoothquadcurveto_rel = b'Tt'
|
smoothquadcurveto_abs, smoothquadcurveto_rel = b'T', b't'
|
||||||
|
|
||||||
# Store the last parsed values
|
# Store the last parsed values
|
||||||
# x/y = end position
|
# x/y = end position
|
||||||
@ -74,16 +74,21 @@ def svg_path_to_painter_path(d):
|
|||||||
d = d.encode('ascii')
|
d = d.encode('ascii')
|
||||||
d = d.replace(b',', b' ').replace(b'\n', b' ')
|
d = d.replace(b',', b' ').replace(b'\n', b' ')
|
||||||
end = len(d)
|
end = len(d)
|
||||||
data = ReadOnlyFileBuffer(d)
|
pos = [0]
|
||||||
|
|
||||||
|
def read_byte():
|
||||||
|
p = pos[0]
|
||||||
|
pos[0] += 1
|
||||||
|
return d[p:p+1]
|
||||||
|
|
||||||
def parse_float():
|
def parse_float():
|
||||||
chars = []
|
chars = []
|
||||||
while data.tell() < end:
|
while pos[0] < end:
|
||||||
c = data.read(1)
|
c = read_byte()
|
||||||
if c == b' ' and not chars:
|
if c == b' ' and not chars:
|
||||||
continue
|
continue
|
||||||
if c == b'-' or b'0' <= c[0] <= b'9' or c == b'.':
|
if c in b'-.0123456789':
|
||||||
chars.append(c[0])
|
chars.append(c)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
if not chars:
|
if not chars:
|
||||||
@ -97,16 +102,14 @@ def svg_path_to_painter_path(d):
|
|||||||
|
|
||||||
repeated_command = None
|
repeated_command = None
|
||||||
|
|
||||||
while data.tell() < end:
|
while pos[0] < end:
|
||||||
last_cmd = cmd
|
last_cmd = cmd
|
||||||
cmd = data.read(1) if repeated_command is None else repeated_command
|
cmd = read_byte() if repeated_command is None else repeated_command
|
||||||
if isinstance(cmd, memoryview):
|
|
||||||
cmd = cmd.tobytes()
|
|
||||||
repeated_command = None
|
repeated_command = None
|
||||||
|
|
||||||
if cmd == b' ':
|
if cmd == b' ':
|
||||||
continue
|
continue
|
||||||
elif cmd == moveto_abs:
|
if cmd == moveto_abs:
|
||||||
x, y = parse_float(), parse_float()
|
x, y = parse_float(), parse_float()
|
||||||
path.moveTo(x, y)
|
path.moveTo(x, y)
|
||||||
elif cmd == moveto_rel:
|
elif cmd == moveto_rel:
|
||||||
@ -178,11 +181,11 @@ def svg_path_to_painter_path(d):
|
|||||||
x1, y1 = x, y
|
x1, y1 = x, y
|
||||||
x, y = parse_floats(2, x, y)
|
x, y = parse_floats(2, x, y)
|
||||||
path.quadTo(x1, y1, x, y)
|
path.quadTo(x1, y1, x, y)
|
||||||
elif cmd[0:1] in b'-.0123456789':
|
elif cmd in b'-.0123456789':
|
||||||
# A new number begins
|
# A new number begins
|
||||||
# In this case, multiple parameters tuples are specified for the last command
|
# In this case, multiple parameters tuples are specified for the last command
|
||||||
# We rewind to reparse data correctly
|
# We rewind to reparse data correctly
|
||||||
data.seek(-1, os.SEEK_CUR)
|
pos[0] -= 1
|
||||||
|
|
||||||
# Handle extra parameters
|
# Handle extra parameters
|
||||||
if last_cmd == moveto_abs:
|
if last_cmd == moveto_abs:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user