diff --git a/drawBot/context/baseContext.py b/drawBot/context/baseContext.py index 29784d2e..13d05a41 100644 --- a/drawBot/context/baseContext.py +++ b/drawBot/context/baseContext.py @@ -2104,7 +2104,7 @@ def __init__(self): # overwrite by a subclass - def _newPage(self, width, height): + def _newPage(self, width, height, pageOptions): pass def _save(self): @@ -2166,13 +2166,13 @@ def size(self, width=None, height=None): if height is not None: self.height = height - def newPage(self, width=None, height=None): + def newPage(self, width=None, height=None, options=None): if self.width is None and width is None: raise DrawBotError("A page must have a width") if self.height is None and height is None: raise DrawBotError("A page must have a height") self.hasPage = True - self._newPage(width, height) + self._newPage(width, height, options) def saveImage(self, path, options): if not self.hasPage: diff --git a/drawBot/context/gifContext.py b/drawBot/context/gifContext.py index c69f1c0f..f2be658d 100644 --- a/drawBot/context/gifContext.py +++ b/drawBot/context/gifContext.py @@ -28,8 +28,8 @@ def _frameDuration(self, seconds): # gifsicle -h: Set frame delay to TIME (in 1/100sec). self._delayData[-1] = int(seconds * 100) - def _newPage(self, width, height): - super(GIFContext, self)._newPage(width, height) + def _newPage(self, width, height, pageOptions): + super(GIFContext, self)._newPage(width, height, pageOptions) self._delayData.append(self._delay) def _writeDataToFile(self, data, path, options): diff --git a/drawBot/context/mp4Context.py b/drawBot/context/mp4Context.py index 2543e465..81f970b4 100644 --- a/drawBot/context/mp4Context.py +++ b/drawBot/context/mp4Context.py @@ -28,7 +28,7 @@ def __init__(self): def _frameDuration(self, frameDuration): self._frameDurations[-1] = frameDuration - def _newPage(self, width, height): + def _newPage(self, width, height, pageOptions): super(MP4Context, self)._newPage(width, height) self._frameDurations.append(self._defaultFrameDuration) # https://github.com/typemytype/drawbot/issues/391 diff --git a/drawBot/context/pdfContext.py b/drawBot/context/pdfContext.py index d4b979aa..a3d4db35 100644 --- a/drawBot/context/pdfContext.py +++ b/drawBot/context/pdfContext.py @@ -29,26 +29,41 @@ def __init__(self): self._hasContext = False self._cachedImages = {} - def _newPage(self, width, height): + def _newPage(self, width, height, options): self.size(width, height) mediaBox = Quartz.CGRectMake(0, 0, self.width, self.height) + auxiliaryInfo = { + Quartz.kCGPDFContextAuthor: "DrawBot" + } + # auxiliaryInfo[Quartz.kCGPDFContextMediaBox] = AppKit.NSValue.valueWithRect_(mediaBox) + if "bleed" in options: + leftBleed, topBleed, rightBleed, bottomBleed = options["bleed"] + + mediaBox = Quartz.CGRectMake(0, 0, self.width + leftBleed + rightBleed, self.height + topBleed + bottomBleed) + bleedBox = Quartz.CGRectMake(leftBleed, topBleed, self.width, self.height) + + auxiliaryInfo[Quartz.kCGPDFContextBleedBox] = AppKit.NSValue.valueWithRect_(bleedBox) + auxiliaryInfo[Quartz.kCGPDFContextTrimBox] = AppKit.NSValue.valueWithRect_(bleedBox) + + auxiliaryInfo[Quartz.kCGPDFContextMediaBox] = AppKit.NSValue.valueWithRect_(mediaBox) + # reset the context self.reset() if self._hasContext: # add a new page - Quartz.CGContextEndPage(self._pdfContext) - Quartz.CGContextBeginPage(self._pdfContext, mediaBox) + Quartz.CGPDFContextEndPage(self._pdfContext) + Quartz.CGPDFContextBeginPage(self._pdfContext, auxiliaryInfo) else: # create a new pdf document self._pdfData = Quartz.CFDataCreateMutable(None, 0) dataConsumer = Quartz.CGDataConsumerCreateWithCFData(self._pdfData) - self._pdfContext = Quartz.CGPDFContextCreate(dataConsumer, mediaBox, None) - Quartz.CGContextBeginPage(self._pdfContext, mediaBox) + self._pdfContext = Quartz.CGPDFContextCreate(dataConsumer, mediaBox, auxiliaryInfo) + Quartz.CGPDFContextBeginPage(self._pdfContext, auxiliaryInfo) self._hasContext = True def _closeContext(self): - Quartz.CGContextEndPage(self._pdfContext) + Quartz.CGPDFContextEndPage(self._pdfContext) Quartz.CGPDFContextClose(self._pdfContext) self._hasContext = False diff --git a/drawBot/context/printContext.py b/drawBot/context/printContext.py index e4e846af..4a1c4b60 100644 --- a/drawBot/context/printContext.py +++ b/drawBot/context/printContext.py @@ -41,8 +41,8 @@ class PrintContext(BaseContext): fileExtensions = ["*"] validateSaveImageOptions = False - def _newPage(self, width, height): - print("newPage %s %s" % (width, height)) + def _newPage(self, width, height, pageOptions): + print("newPage %s %s %s" % (width, height, pageOptions)) def _save(self): print("save") diff --git a/drawBot/context/svgContext.py b/drawBot/context/svgContext.py index b79a6d6a..a39f560b 100644 --- a/drawBot/context/svgContext.py +++ b/drawBot/context/svgContext.py @@ -312,7 +312,7 @@ def _reset(self, other=None): self._embeddedFonts = set() self._embeddedImages = dict() - def _newPage(self, width, height): + def _newPage(self, width, height, pageOptions): if hasattr(self, "_svgContext"): self._svgContext.endtag("svg") self.reset() diff --git a/drawBot/drawBotDrawingTools.py b/drawBot/drawBotDrawingTools.py index 810e6bc3..7ced8d45 100644 --- a/drawBot/drawBotDrawingTools.py +++ b/drawBot/drawBotDrawingTools.py @@ -106,7 +106,7 @@ def _addInstruction(self, callback, *args, **kwargs): self._instructionsStack.append([]) if self._requiresNewFirstPage and not self._hasPage: self._hasPage = True - self._instructionsStack[-1].insert(0, ("newPage", [self.width(), self.height()], {})) + self._instructionsStack[-1].insert(0, ("newPage", [self.width(), self.height(), {}], {})) self._instructionsStack[-1].append((callback, args, kwargs)) def _drawInContext(self, context): @@ -260,7 +260,7 @@ def size(self, width, height=None): else: raise DrawBotError("Can't use 'size()' after drawing has begun. Try to move it to the top of your script.") - def newPage(self, width=None, height=None): + def newPage(self, width=None, height=None, bleed=None): """ Create a new canvas to draw in. This will act like a page in a pdf or a frame in a mov. @@ -293,11 +293,18 @@ def newPage(self, width=None, height=None): if width is None and height is None: width = self.width() height = self.height() + pageOptions = {} + if bleed is not None: + if isinstance(bleed, (int, float)): + bleed = (bleed, bleed, bleed, bleed) + if len(bleed) != 4: + raise DrawBotError("Bleed must be a tuple of 4 values.") + pageOptions["bleed"] = bleed self._width = width self._height = height self._hasPage = True self._dummyContext = DummyContext() - self._addInstruction("newPage", width, height) + self._addInstruction("newPage", width, height, pageOptions) def pages(self): """