From bcf54baad8c989eb4da0871e88e1616823688692 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 12 Jan 2013 13:55:55 +0530 Subject: [PATCH] Implement spreads for linear gradients --- src/calibre/ebooks/pdf/render/gradients.py | 44 ++++++++++++++++++---- src/calibre/ebooks/pdf/render/test.py | 5 ++- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/calibre/ebooks/pdf/render/gradients.py b/src/calibre/ebooks/pdf/render/gradients.py index ed1a2d0713..0c6a2485d1 100644 --- a/src/calibre/ebooks/pdf/render/gradients.py +++ b/src/calibre/ebooks/pdf/render/gradients.py @@ -7,7 +7,7 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import sys +import sys, copy from future_builtins import map from collections import namedtuple @@ -83,8 +83,7 @@ class LinearGradientPattern(Dictionary): stop = gradient.finalStop() stops = list(map(lambda x: [x[0], x[1].getRgbF()], gradient.stops())) spread = gradient.spread() - if False and spread != gradient.PadSpread: - # TODO: Finish this implementation + if spread != gradient.PadSpread: inv = matrix.inverted()[0] page_rect = tuple(map(inv.map, ( QPointF(0, 0), QPointF(pixel_page_width, 0), QPointF(0, pixel_page_height), @@ -103,23 +102,52 @@ class LinearGradientPattern(Dictionary): llimit, rlimit = start, stop reflect = False - base_stops = list(stops) + base_stops = copy.deepcopy(stops) reversed_stops = list(reversed(stops)) do_reflect = spread == gradient.ReflectSpread - # totl = abs(stops[-1][0] - stops[0][0]) - # intervals = [abs(stops[i+1] - stops[i])/totl for i in xrange(len(stops)-1)] + totl = abs(stops[-1][0] - stops[0][0]) + intervals = [abs(stops[i+1][0] - stops[i][0])/totl + for i in xrange(len(stops)-1)] while in_page(llimit): reflect ^= True llimit -= offset estops = reversed_stops if (reflect and do_reflect) else base_stops - stops = estops + stops + stops = copy.deepcopy(estops) + stops + + first_is_reflected = reflect + reflect = False while in_page(rlimit): reflect ^= True rlimit += offset estops = reversed_stops if (reflect and do_reflect) else base_stops - stops = stops + estops + stops = stops + copy.deepcopy(estops) + + start, stop = llimit, rlimit + + num = len(stops) // len(base_stops) + if num > 1: + # Adjust the stop parameter values + t = base_stops[0][0] + rlen = totl/num + reflect = first_is_reflected ^ True + intervals = [i*rlen for i in intervals] + rintervals = list(reversed(intervals)) + + for i in xrange(num): + reflect ^= True + pos = i * len(base_stops) + tvals = [t] + for ival in (rintervals if reflect and do_reflect else + intervals): + tvals.append(tvals[-1] + ival) + for j in xrange(len(base_stops)): + stops[pos+j][0] = tvals[j] + t = tvals[-1] + + # In case there were rounding errors + stops[-1][0] = base_stops[-1][0] return start, stop, tuple(Stop(s[0], s[1]) for s in stops) diff --git a/src/calibre/ebooks/pdf/render/test.py b/src/calibre/ebooks/pdf/render/test.py index 4ad72245dd..a68daea97b 100644 --- a/src/calibre/ebooks/pdf/render/test.py +++ b/src/calibre/ebooks/pdf/render/test.py @@ -86,10 +86,11 @@ def brush(p, xmax, ymax): x = 0 y = 0 w = xmax/2 - g = QLinearGradient(QPointF(x, y), QPointF(x, y+w)) + g = QLinearGradient(QPointF(x, y+w/3), QPointF(x, y+(2*w/3))) g.setColorAt(0, QColor('#f00')) g.setColorAt(0.5, QColor('#fff')) g.setColorAt(1, QColor('#00f')) + g.setSpread(g.ReflectSpread) p.fillRect(x, y, w, w, QBrush(g)) p.drawRect(x, y, w, w) @@ -112,7 +113,7 @@ def main(): app tdir = os.path.abspath('.') pdf = os.path.join(tdir, 'painter.pdf') - func = full + func = brush dpi = 100 with open(pdf, 'wb') as f: dev = PdfDevice(f, xdpi=dpi, ydpi=dpi, compress=False)