def __init__(self, bs, x, y, w=None, h=None, name=None, fill=None, stroke=None, strokeWidth=None): # Call the base element with all standard attributes. Element.__init__(self, x=x, y=y, w=w, h=h, name=name, fill=fill, stroke=stroke, strokeWidth=strokeWidth) if not isinstance(bs, BabelString): bs = BabelString(bs) self.bs = bs # Store the BabelString in self.
def addPageNumber(self, page, pad, leftStyle, rightStyle): # Add text element with page number if page.pn % 2 == 0: # Even page number? style = leftStyle x = pad else: # Odd page number style = rightStyle x = page.w - pad pn = BabelString(str(page.pn), style) # Center the page number. #e = Text(pn, page.w/2, pad/2) e = Text(pn, x=x, y=pad * 3 / 4, w=page.w - 2 * pad, fill=0.9) page.addElement(e)
def compose(self, doc, page, parent=None): """Compose the cell as background color, with recipes text block on top. """ label = self._getLabel() bs = BabelString(label, self.style) tw, th = bs.textSize if self.layout == SPOTSAMPLE: # Mark abbreviated color recipes by parenthesis. # They are not an exact match, but closest known value for this color. # Used padding-bottom (self.pb) also as gutter between color rectangle and labels e = Rect(x=0, y=th + self.pb, w=self.w, h=self.h - th - self.pb, fill=self.c) self.addElement(e) e = Text(bs, x=self.w / 2, y=th - self.style.get('lineHeight', 0) + self.pb, w=self.w, h=self.h) self.addElement(e) else: # Default layout is OVERLAY e = Rect(x=0, y=0, w=self.w, h=self.h, fill=self.c) self.addElement(e) e = Text(bs, x=self.w / 2, y=th - self.style.get('lineHeight', 0) + self.pb, w=self.w, h=self.h) self.addElement(e)
def oneColumnPage(cls, theme, doc, page=None, parent=None, pageNumbers=None, **kwargs): """ >>> from pagebotnano.document import Document >>> from pagebotnano.themes import BackToTheCity >>> template = OneColumnTemplate() >>> theme = BackToTheCity() >>> doc = Document() >>> page = template.oneColumnPage(theme, doc, pageNumbers=NONE) >>> page.compose(doc) >>> page.find(MAIN) <TextBox name=mainText w=535 h=782> >>> page = doc.newPage(template=oneColumnPage) """ page = cls._initialize(theme, doc, page, parent) # Add text element with the main text column of this page e = TextBox('', name=MAIN, x=page.pl, y=page.pb, w=page.pw, h=page.ph) page.addElement(e) if pageNumbers is None: pageNumbers = [LEFT, RIGHT] if LEFT in pageNumbers and page.pn % 2 == 0: # Even page number?: bs = BabelString(str(page.pn), style) e = Text(bs, name=PN_LEFT, x=page.pl, y=page.pb / 2) page.addElement(e) if CENTER in pageNumbers: e = Text('', name=PN_CENTER, x=page.pl + page.pw, y=page.pb / 2) page.addElement(e) if RIGHT in pageNumbers: e = Text('', name=PN_RIGHT, x=page.pl + page.pw, y=page.pb / 2) page.addElement(e) return page
def makeColorSpecimen(layoutData): pageSize, fontSize, fileName, layout, textColor, labels, extension = layoutData labelSize = fontSize * LABEL_SIZE_FACTOR labelLeading = labelSize * LEADING w, h, = pageSize padding = w / 14 doc = Document(w=w, h=h) for Theme in AllThemes: for mood in (DARK, LIGHT): theme = Theme(mood=mood) page = doc.newPage() page.padding = padding cw = page.pw / len(theme.colors[0]) # Column width ch = page.ph / len(theme.colors) # Column height for shade in range(len(theme.colors[0])): for base in range(len(theme.colors)): # Get the color from the theme color matrix and add as rectangle # This is the extened example, instead of using the ColorCell element. c = theme.colors[base][shade] # If textColor not defined, then get it from the theme, based on the # darkness of the current color. if textColor is None: tc = theme.textColor(base, shade) else: tc = textColor labelStyle = dict(font=FONT_NAME, fontSize=labelSize, lineHeight=labelLeading, fill=tc, align=CENTER) # The ColorCell element takes care of showing the color as rectangle # and the lines of various recipes on top. e = ColorCell(c, x=page.pl + shade * cw, y=page.pb + base * ch, w=cw, h=ch, layout=layout, labels=labels, style=labelStyle, pb=labelLeading) page.addElement(e) # Add background rectangle on top with theme name and mood. getColor(shade, base) e = Rect(x=page.pl, y=page.h - page.pt, w=page.pw, h=page.pt, fill=theme.getColor(0, 2)) page.addElement(e) titleStyle = dict(font=FONT_NAME, fontSize=fontSize, fill=theme.getColor(-2, 2)) bs = BabelString('%s – %s' % (theme.name, mood), titleStyle) tw, th = bs.textSize e = Text(bs, x=page.pl + fontSize / 2, y=page.h - page.pt * 2 / 3, w=page.pw) page.addElement(e) footNoteStyle = dict(font=FONT_NAME, fontSize=labelSize, lineHeight=labelLeading, fill=theme.colors[0][4], align=LEFT) bs = BabelString( 'Colors with (parenthesis) are approximated to the closest recipe.', footNoteStyle) tw, th = bs.textSize e = Text(bs, x=page.pl, y=page.pb - th, w=page.pw) page.addElement(e) footNoteStyle = dict(font=FONT_NAME, fontSize=labelSize, lineHeight=labelLeading, fill=theme.colors[0][4], align=RIGHT) bs = BabelString('Generated by PageBotNano', footNoteStyle) tw, th = bs.textSize e = Text(bs, x=page.pl + page.pw, y=page.pb - th, w=page.pw) page.addElement(e) doc.export('_export/ThemeSpecimen-%s.%s' % (fileName, extension), multipage=True)
def compose(self): """This is the core of a publication, composing the specific content of the document. The compose method gets called before building and exporting the self.doc document. """ fontSize = 11 headSize = fontSize * 1.5 titleSize = 36 subTitleSize = titleSize * 0.5 pad = 48 self.theme.styles['h1'] = dict( font='Georgia-Bold', lineHeight=titleSize * 1.1, fontSize=titleSize, align=CENTER, fill=1, # White title on dark cover background language=EN, hyphenation=False, ) self.theme.styles['h2'] = dict( font='Georgia-Italic', paragraphTopSpacing=subTitleSize / 2, lineHeight=subTitleSize * 1.2, fontSize=subTitleSize, align=CENTER, fill=1, # White title on dark cover background language=EN, hyphenation=False, ) headStyle = dict( font='Georgia', lineHeight=headSize * 1.3, fontSize=headSize, fill=0, # Black text language=EN, hyphenation=False, ) subHeadStyle = dict( font='Georgia-Italic', lineHeight=headSize * 0.8 * 1.4, fontSize=headSize * 0.8, fill=0, # Black text language=EN, hyphenation=False, ) bodyStyle = dict( font='Georgia', lineHeight=fontSize * 1.4, fontSize=fontSize, fill=0, # Black text language=EN, hyphenation=True, ) pageNumberLeftStyle = dict( font='Georgia', fontSize=9, fill=0, # Black text align=LEFT, ) pageNumberRightStyle = copy(pageNumberLeftStyle) pageNumberRightStyle['align'] = RIGHT # Make the cover page. page = coverPage(self.theme, self.doc) # Make “French” “Voordehandse” page. page = self.doc.newPage() # No page number here. # CENTER text alignment overwrites the value in headStyle. # fontSize overwrites the value in headStyle bs = BabelString('AAAA' + '\n', headStyle, fontSize=fontSize, align=CENTER) e = Text(bs, x=page.w / 2, y=page.h * 4 / 5) page.addElement(e) # Make Title page. page = titlePage(self.theme, self.doc) page.compose(self.doc, page) bs = BabelString('VVVVV' + '\n', headStyle, align=CENTER) bs.append(BabelString('AUTHOR', subHeadStyle, align=CENTER)) page.find(MAIN).bs = bs # For all the elements that are collected in the galley, assume that # the TextBoxes are chapters, creating a new page for them. # If the TextBox does not fit on the page, keep adding new pages # until all of the BabelString overfill is processed. for ge in self.galley.elements: if isinstance(ge, TextBox): bs = ge.bs # Get the BabelString from the galley box. for n in range(self.MAX_PAGES): page = self.doc.newPage() # Add text element with page number self.addPageNumber(page, pad, pageNumberLeftStyle, pageNumberRightStyle) # Add text element with the main text column of this page e = TextBox(bs, x=pad, y=pad, w=page.w - 2 * pad, h=page.h - 2 * pad) page.addElement(e) # If there is overflow on this page, continue looping creating # as many pages as needed to fill all the text in self.content. # Otherwise break the loop, as we are done placing content. bs = e.getOverflow(bs, doc=self.doc) # Test on this “incomplete” BabelString, as it only has a cached FS if not bs.fs: break elif isinstance(ge, Image): # Images not supported yet page = self.doc.newPage() self.addPageNumber(page, pad, pageNumberLeftStyle, pageNumberRightStyle) page.addElement(ge) ge.w = page.w - pad iw, ih = ge.getSize(self.doc) ge.x = pad / 2 ge.y = page.h - pad - ih
def makeColorSpecimen(layoutData): pageSize, fontSize, labelSize, fileName, layout, textColor, labels, extensions = layoutData labelLeading = labelSize * LEADING w, h, = pageSize padding = w / 14 doc = Document(w=w, h=h) for Theme in AllThemes: for mood in (LIGHT, DARK): theme = Theme(mood=mood) page = doc.newPage() page.padding = padding cw = page.pw / len(theme.colors[0]) # Column width ch = page.ph / len(theme.colors) # Column height for col in range(len(theme.colors[0])): for row in range(len(theme.colors)): # Get the color from the theme color matrix and add as rectangle # This is the extened example, instead of using the ColorCell element. c = theme.colors[row][col] # If textColor not defined, then get it from the theme, based on the # darkness of the current color. if textColor is None: tc = theme.textColor(row, col) else: tc = textColor labelStyle = dict(font=FONT_NAME, fontSize=labelSize, lineHeight=labelLeading, fill=tc.rgb, align=CENTER) # The ColorCell element takes care of showing the color as rectangle # and the lines of various recipes on top. e = ColorCell(c, x=page.pl + col * cw, y=page.pb + row * ch, w=cw, h=ch, rowCol=(row, col), layout=layout, labels=labels, style=labelStyle, pb=labelLeading) page.addElement(e) # Add background rectangle on top with theme name and mood. getColor(shade, base) e = Rect(x=page.pl, y=page.h - page.pt, w=page.pw, h=page.pt, fill=theme.getColor('main back').rgb) page.addElement(e) titleStyle = dict(font=FONT_NAME, fontSize=fontSize, fill=theme.getColor('main front').rgb) bs = BabelString('%s – %s' % (theme.name, mood), titleStyle) tw, th = bs.textSize e = Text(bs, x=page.pl + fontSize / 2, y=page.h - page.pt * 2 / 3, w=page.pw) page.addElement(e) footNoteColor = theme.getColor('main middle') footNoteStyle = dict(font=FONT_NAME, fontSize=labelSize, lineHeight=labelLeading, fill=footNoteColor.rgb, align=LEFT) bs = BabelString( 'Colors with (parenthesis) are approximated to the closest recipe.', footNoteStyle) tw, th = bs.textSize e = Text(bs, x=page.pl, y=page.pb - th, w=page.pw) page.addElement(e) footNoteStyle = dict(font=FONT_NAME, fontSize=labelSize, lineHeight=labelLeading, fill=footNoteColor.rgb, align=RIGHT) bs = BabelString('Generated by PageBotNano', footNoteStyle) tw, th = bs.textSize e = Text(bs, x=page.pl + page.pw, y=page.pb - th, w=page.pw) page.addElement(e) if not isinstance(extensions, (list, tuple)): extensions = [extensions] for extension in extensions: filePath = '_export/ThemeSpecimen-%s.%s' % (fileName, extension) print('Exporting', filePath) doc.export(filePath, multipage=True)
def textBox(self, bs, r): # Set the cache from the overflow, we don't have the source anymore overFlow = BabelString(hyphenation=bs.hyphenation) overFlow.fs = drawBot.textBox(bs.fs, r) return overFlow # Return this “incomplete” BabelString.