def buildFamilySpecimenPage(self, page, family): box = page[self.specimenBoxId][0] fontSize = 500 while not box.getOverflow(): sportsHeadline = ' '.join( blurb.getBlurb('news_headline').split(' ')[:choice( (2, 2, 3, 3, 4))]) + '\n' styleKey = choice(('Regular', 'Bold', 'Italic', 'BoldItalic')) fs = newFS(sportsHeadline, self, style=dict(font=family[styleKey].installedName, fontSize=fontSize)) fsWidth = fs.size()[0] fittingFontSize = fontSize * box.w / fsWidth # Make new formatted string with fitting font size. fs = newFS(sportsHeadline, self, style=dict(font=family[styleKey].installedName, leading=0, fontSize=fittingFontSize, textColor=0)) box.append(fs) print '###', page, family, sportsHeadline
def drawFigures(): W, H = 860, 451 newPage(W, H) LEADING = 0.9 fs = newFS('ABC0123456789\n', style=dict(textFill=0, rLeading=1, font='BitcountPropSingle-RegularCircle', fontSize=90)) fs += newFS('abc0123456789\n', style=dict(textFill=0, font='BitcountPropSingle-RegularCircle', rLeading=LEADING, fontSize=90, openTypeFeatures=dict(smcp=True))) fs += newFS('ABCabc0123456789\n', style=dict(textFill=0, font='BitcountPropSingle-RegularCircle', rLeading=LEADING, fontSize=90, openTypeFeatures=dict(onum=True, ss07=True))) fs += newFS('ABCabc0123456789\n', style=dict(textFill=0, font='BitcountPropSingle-RegularCircle', rLeading=LEADING, fontSize=90, openTypeFeatures=dict(ss07=True))) fs += newFS('Fraction 1/2 12345/67890\n', style=dict(textFill=0, font='BitcountPropSingle-RegularCircle', rLeading=LEADING, fontSize=90, openTypeFeatures=dict(frac=True))) M = 30 textBox(fs, (M + 10, -10, W - 2 * M, H)) saveImage( '_export/figures.png') # Save the sample as file or animated gif.
def getFittingString(t, fontName, layerIndex, fontSize=None): # Make formatted string of large type. # Then see if it fits and calculate the fitting size. # First guess, to see if constructed formatted string fits. initialFontSize = 500 glb = globals() colorLabel = 'Layer_Color_%d' % layerIndex layerColor = getColor(layerIndex) if glb.get(colorLabel) is None: glb[colorLabel] = NSColor.whiteColor() try: r, g, b, opacity = layerColor.getRed_green_blue_alpha_( None, None, None, None) except ValueError: r = random() g = random() b = random() opacity = 0.4 + 0.6 * random() # Not totally opaque. glb[colorLabel] = NSColor.colorWithCalibratedRed_green_blue_alpha_( r, g, b, opacity) if not color: r = g = b = random() * 0.8 if fontSize is None: # Calculate the size for the given string for the selected font/spacing. # Then use the resulting with as source to calculate the fitting fontSize. fs = newFS(Sample_Text, None, dict(font=fontName, fontSize=initialFontSize)) fsWidth, fsHeight = fs.size() fontSize = initialFontSize * (W - 2 * M) / fsWidth # Make new formatted string in fitting fontSize fs = newFS( t, None, dict(font=fontName, fontSize=fontSize, textFill=(r, g, b, opacity))) return fontSize, fs
def makeDocument(): # Create new document with (w,h) and fixed amount of pages. # Make number of pages with default document size. # Initially make all pages default with template rootStyle = getRootStyle() doc = Document(rootStyle, originTop=OriginTop, w=W, h=H, autoPages=1) page = doc[0] # Get the first/single page of the document. page.size = W, H print page.originTop if OriginTop: s = 'Origin on top' conditions = (Center2Center(), Top2Top()) else: s = 'Origin on bottom' conditions = (Center2Center(), Bottom2Bottom()) fs = newFS(s, style=dict(fontSize=30, textFill=(1, 0, 0), xTextAlign=CENTER)) nt = newText(fs, y=100, xxconditions=conditions, parent=page, fill=(1, 1, 0)) print nt.x, nt.y, nt.w, nt.h score = page.solve() if score.fails: print score.fails print nt.x, nt.y, nt.w, nt.h # Set the view parameters for the required output. view = doc.getView() view.w = view.h = W, H view.padding = 100 # Make view padding to show crop marks and frame view.showPageFrame = True view.showPageCropMarks = True view.showElementOrigin = False view.showElementDimensions = True return doc
def drawElementOrigin(self, e, origin): px, py, _ = pointOffset(e.oPoint, origin) S = self.css('viewInfoOriginMarkerSize', 4) if self.showElementOrigin: # Draw origin of the element setFillColor( (0.5, 0.5, 0.5, 0.1) ) # Transparant fill, so we can see the marker on dark backgrounds. setStrokeColor(0, 0.25) oval(px - S, py - S, 2 * S, 2 * S) line((px - S, py), (px + S, py)) line((px, py - S), (px, py + S)) if self.showElementDimensions: fs = newFS(point2S(e.point3D), style=dict(font=self.css('viewInfoFont'), fontSize=self.css('viewInfoFontSize'), leading=self.css('viewInfoLeading'), textFill=0.1)) w, h = textSize(fs) text(fs, (px - w / 2, py + S * 1.5))
def getExtendedBlurb(doc): blurb = Blurb() fs = newFS(blurb.getBlurb('news_headline', noTags=True) + '\n', style=doc.styles['h1']) for n in range(ARTICLE_CNT): fs += newFS(blurb.getBlurb('design_headline', noTags=True) + '\n', style=doc.styles['h2']) fs += newFS(blurb.getBlurb('design_headline', noTags=True) + '\n', style=doc.styles['h3']) fs += newFS(blurb.getBlurb('article', noTags=True) + '\n', style=doc.styles['p']) fs += newFS(blurb.getBlurb('design_headline', noTags=True) + '\n', style=doc.styles['h3']) fs += newFS(blurb.getBlurb('article', noTags=True) + '\n', style=doc.styles['p']) return fs
def __init__(self, fs, html=None, minW=None, w=DEFAULT_WIDTH, h=None, showBaselines=False, **kwargs): Element.__init__(self, **kwargs) u"""Default is the storage of self.fs (DrawBot FormattedString), but optional can be ts (tagged basestring) if output is mainly through build and HTML/CSS. Since both strings cannot be conversted lossless one into the other, it is safer to keep them both if they are available.""" # Make sure that this is a formatted string. Otherwise create it with the current style. # Note that in case there is potential clash in the double usage of fill and stroke. self.minW = max(minW or 0, MIN_WIDTH, self.TEXT_MIN_WIDTH) self._textLines = self._baseLines = None # Force initiaize upon first usage. self.size = w, h if isinstance(fs, basestring): fs = newFS(fs, self) self.fs = fs # Keep as plain string, in case parent is not set yet. self.html = html or '' # Parallel storage of html content. self.showBaselines = showBaselines # Force showing of baseline if view.showBaselines is False.
def drawBaselineGrid(self, e, origin): u"""Draw baseline grid if line color is set in the style. TODO: Make fixed values part of calculation or part of grid style. Normally px and py will be 0, but it's possible to give them a fixed offset.""" if not self.showBaselineGrid: return p = pointOffset(self.oPoint, origin) p = self._applyScale(p) px, py, _ = self._applyAlignment(p) # Ignore z-axis for now. M = 16 startY = e.css('baselineGridStart') if startY is None: startY = e.pt # Otherwise use the top padding as start Y. oy = e.h - startY #- py line = 0 # Format of line numbers. # TODO: DrawBot align and fill don't work properly now. fs = newFS( '', self, dict(font=e.css('fallbackFont', 'Verdana'), xTextAlign=RIGHT, fontSize=M / 2, stroke=None, textFill=e.css('gridStroke'))) while oy > e.pb or 0: setFillColor(None) setStrokeColor(e.css('baselineGridStroke', NO_COLOR), e.css('gridStrokeWidth')) newPath() moveTo((px + e.pl, py + oy)) lineTo((px + e.w - e.pr, py + oy)) drawPath() text(fs + repr(line), (px + e.pl - 2, py + oy - e.pl * 0.6)) text(fs + repr(line), (px + e.w - e.pr - 8, py + oy - e.pr * 0.6)) line += 1 # Increment line index. oy -= e.css('baselineGrid' ) # Next vertical line position of baseline grid.
def makeDocument(): doc = Document(originTop=False, w=W, h=H, autoPages=1) page = doc[0] # Get the first/single page of the document. page.padding = 40 # TODO: order if 4 values? # Make rect as page element centered with centered origin. conditions = (Center2Center(), Middle2Middle()) shadow = Shadow(offset=(ShadowOffset, -ShadowOffset), blur=ShadowBlur, color=(0.2, 0.2, 0.2, 0.5) ) textShadow = Shadow(offset=(ShadowTextOffset, -ShadowTextOffset), blur=ShadowTextBlur, color=(0.2, 0.2, 0.2, 0.5) ) fs = newFS('This is text with a shadow', style=dict(font='Verdana', fontSize=30, textFill=0, rLeading=1.2)) newTextBox(fs, fill=0.8, parent=page, w=RectSize, h=RectSize, shadow=shadow, textShadow=textShadow, conditions=conditions, xAlign=CENTER, yAlign=MIDDLE) # Solve the layout conditions of the red rectangle. # Show if one of the conditions failed to solve. score = page.solve() if score.fails: print 'Failed conditions', score.fails # Set the view parameters for the required output. view = doc.getView() view.padding = 0 # Make view padding to show crop marks and frame view.showPageFrame = True # Show frame of the page in blue #view.showPagePadding = True view.showPageCropMarks = True # Show crop marks return doc
def _drawElementsNeedingInfo(self): for e, origin in self.elementsNeedingInfo.values(): p = pointOffset(e.oPoint, origin) p = e._applyScale(p) px, py, _ = e._applyAlignment(p) # Ignore z-axis for now. if self.showElementInfo: # Draw box with element info. fs = newFS(e.getElementInfoString(), style=dict(font=self.css('viewInfoFont'), fontSize=self.css('viewInfoFontSize'), leading=self.css('viewInfoLeading'), textFill=0.1)) tw, th = textSize(fs) Pd = 4 # Padding in box and shadow offset. tpx = px - Pd / 2 # Make info box outdent the element. Keeping shadow on the element top left corner. tpy = py + e.h - th - Pd # Tiny shadow setFillColor((0.3, 0.3, 0.3, 0.5)) setStrokeColor(None) rect(tpx + Pd / 2, tpy, tw + 2 * Pd, th + 1.5 * Pd) # Frame setFillColor(self.css('viewInfoFill')) setStrokeColor(0.3, 0.25) rect(tpx, tpy, tw + 2.5 * Pd, th + 1.5 * Pd) text(fs, (tpx + Pd, tpy + th)) e._restoreScale() if self.showElementDimensions: # TODO: Make separate arrow functio and better positions # Draw width and height measures setFillColor(None) setStrokeColor(0, 0.25) S = self.css('viewInfoOriginMarkerSize', 4) x1, y1, x2, y2 = px + e.left, py + e.bottom, e.right, e.top # Horizontal measure line((x1, y1 - 0.5 * S), (x1, y1 - 3.5 * S)) line((x2, y1 - 0.5 * S), (x2, y1 - 3.5 * S)) line((x1, y1 - 2 * S), (x2, y1 - 2 * S)) # Arrow heads line((x1, y1 - 2 * S), (x1 + S, y1 - 1.5 * S)) line((x1, y1 - 2 * S), (x1 + S, y1 - 2.5 * S)) line((x2, y1 - 2 * S), (x2 - S, y1 - 1.5 * S)) line((x2, y1 - 2 * S), (x2 - S, y1 - 2.5 * S)) fs = newFS(asFormatted(x2 - x1), style=dict(font=self.css('viewInfoFont'), fontSize=self.css('viewInfoFontSize'), leading=self.css('viewInfoLeading'), textFill=0.1)) tw, th = textSize(fs) text(fs, ((x2 + x1) / 2 - tw / 2, y1 - 1.5 * S)) # Vertical measure line((x2 + 0.5 * S, y1), (x2 + 3.5 * S, y1)) line((x2 + 0.5 * S, y2), (x2 + 3.5 * S, y2)) line((x2 + 2 * S, y1), (x2 + 2 * S, y2)) # Arrow heads line((x2 + 2 * S, y2), (x2 + 2.5 * S, y2 - S)) line((x2 + 2 * S, y2), (x2 + 1.5 * S, y2 - S)) line((x2 + 2 * S, y1), (x2 + 2.5 * S, y1 + S)) line((x2 + 2 * S, y1), (x2 + 1.5 * S, y1 + S)) fs = newFS(asFormatted(y2 - y1), style=dict(font=self.css('viewInfoFont'), fontSize=self.css('viewInfoFontSize'), leading=self.css('viewInfoLeading'), textFill=0.1)) tw, th = textSize(fs) text(fs, (x2 + 2 * S - tw / 2, (y2 + y1) / 2))
def makeDocument(rs): u"""Demo Bitcount Reference composer.""" mainId = 'mainId' features = dict( kern=True, liga=Ligatures, zero=Slashed_Zero, frac=Fraction, smcp=Smallcaps, c2sc=Caps_As_Smallcaps, ss08=Italic_Shapes, ss07=Condensed, ss01=Extended_Ascenders, ss02=Extended_Capitals, ss03=Extended_Descenders, ss04=Contrast_Pixel, ss09=Alternative_g, onum=LC_Figures, ) if HeadlineTracking: headlineTracking = 0.1 else: headlineTracking = 0 if BodyTracking: bodyTracking = 0.1 else: bodyTracking = 0 if Monospaced: spacing = 'Mono' else: spacing = 'Prop' if Single: singleDouble = 'Single' else: singleDouble = 'Double' if Italic: italic = 'Italic' else: italic = '' BOOK = '%s%s%s-BookCircle%s' % (familyName, spacing, singleDouble, italic) MEDIUM = '%s%s%s-MediumCircle%s' % (familyName, spacing, singleDouble, italic) BOOK_ITALIC = '%s%s%s-BookCircle%s' % (familyName, spacing, singleDouble, italic) BOLD = '%s%s%s-MediumCircle%s' % (familyName, spacing, singleDouble, italic) SEMIBOLD = '%s%sProp%s-BoldCircle%s' % (familyName, spacing, singleDouble, italic) # Template 1 template1 = Template(rs) # Create template of main size. Front page only. # Show baseline grid if rs.showBaselineGrid is True template1.baselineGrid(rs) # Create linked text boxes. Note the "nextPage" to keep on the same page or to next. template1.cTextBox('', 1, 0, 6, 6, style=rs, eId=mainId) # Create new document with (w,h) and fixed amount of pages. # Make number of pages with default document size. # Initially make all pages default with template2 doc = Document(rs, aufoPages=1, template=template1) page = doc[1] # Index by element id, answers ([e1, ...], (x, y)) tuple. There can be multiple elements # with the same Id, and there can be multiple elements on the same position). #page[mainId] e = page.getElement(mainId) fs = newFS( Sample_Text + ' V.T.TeY.Yjy\n', e, dict(font=BOLD, fontSize=32, rTracking=headlineTracking, openTypeFeatures=features)) e.append(fs) fs = newFS( scriptGlobals.head, e, dict(font=BOOK, fontSize=32, rTracking=headlineTracking, openTypeFeatures=features)) e.append(fs) fs = newFS( scriptGlobals.subhead, e, dict(font=BOOK, fontSize=16, rTracking=headlineTracking, openTypeFeatures=features)) e.append(fs) fs = newFS( scriptGlobals.body, e, dict(font=BOOK, fontSize=12, rTracking=bodyTracking, openTypeFeatures=features)) e.append(fs) return doc
def fitVariableWidth(varFont, s, w, fontSize, condensedLocation, wideLocation, fixedSize=False, tracking=None, rTracking=None): u"""Answer the font instance that makes string s width on the given width *w* for the given *fontSize*. The *condensedLocation* dictionary defines the most condensed font instance (optionally including the opsz) and the *wideLocation* dictionary defines the most wide font instance (optionally including the opsz). The string width for s is calculated with both locations and then the [wdth] value is interpolated and iterated until the location is found where the string *s* fits width *w). Note that interpolation may not be enough, as the width axis may contain non-linear masters. If the requested w outside of what is possible with two locations, then interations are performed to change the size. Again this cannot be done by simple interpolation, as the [opsz] also changes the width. It one of the axes does not exist in the font, then use the default setting of the font. """ condensedFont = getVariableFont(varFont, condensedLocation) condensedFs = newFS(s, style=dict(font=condensedFont.installedName, fontSize=fontSize, tracking=tracking, rTracking=rTracking, textFill=0)) condensedWidth, _ = textSize(condensedFs) wideFont = getVariableFont(varFont, wideLocation) wideFs = newFS(s, style=dict(font=wideFont.installedName, fontSize=fontSize, tracking=tracking, rTracking=rTracking, textFill=0)) wideWidth, _ = textSize(wideFs) # Check if the requested with is inside the boundaries of the font width axis if w < condensedWidth: font = condensedFont fs = condensedFs location = condensedLocation elif w > wideWidth: font = wideFont fs = wideFs location = wideLocation else: # Now interpolation the fitting location widthRange = wideLocation['wdth'] - condensedLocation['wdth'] location = copy.copy(condensedLocation) location['wdth'] += widthRange * (w - condensedWidth) / ( wideWidth - condensedWidth) font = getVariableFont(varFont, location) fs = newFS(s, style=dict(font=font.installedName, fontSize=fontSize, tracking=tracking, rTracking=rTracking, textFill=0)) return dict(condensendFont=condensedFont, condensedFs=condensedFs, condensedWidth=condensedWidth, condensedLocation=condensedLocation, wideFont=wideFont, wideFs=wideFs, wideWidth=wideWidth, wideLocation=wideLocation, font=font, fs=fs, width=textSize(fs)[0], location=location)
def makeDocument(fontPath): u"""Create Document instance with a single page. Fill the page with elements and perform a conditional layout run, until all conditions are solved.""" f = Font(fontPath) # Get PageBot Font instance of Variable font. fHeader = getVariableFont(f, dict(wght=0.5)) fHeaderCondensed = getVariableFont(f, dict(wght=0.5, wdth=0.4)) doc = Document(w=PageWidth, h=PageHeight, originTop=False, autoPages=1) # Get default view from the document and set the viewing parameters. view = doc.getView() view.style['fill'] = 1 view.padding = 0 # To show cropmarks and such, make >40 or so. view.showPageCropMarks = True # Won't show if there is not padding in the view. view.showPageRegistrationMarks = True view.showPageFrame = True view.showPagePadding = True view.showPageNameInfo = True view.showElementOrigin = False view.showElementDimensions = False #ShowDimensions view.showElementInfo = False page = doc[0] # Get the single frint page from the document. # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding pageAreaW = PageWidth-pl-pr pageAreaH = PageHeight-pt-pb # Resources blockFill = None #(1, 1, 0) # Use color to debug page area gradient = Gradient(locations=[1,0], colors=((0, 0, 0), (0.8, 0.8, 0.8))) shadow = Shadow(offset=(6, -6), blur=10, color=(0.2, 0.2, 0.2, 0.5)) bookBorders = dict(stroke=(1, 1, 1, 0.5),strokeWidth=0.1,line=OUTLINE) bookPadding = (25, 30, 40, 30) # Styles titleStyle =dict(font=fHeader.installedName, fontSize=26, rLeading=1.4, xTextAlign=CENTER, textFill=1) authorStyle = dict(font='Georgia-Italic', textFill=1, fontSize=18, xTextAlign=CENTER) headStyle = dict(font=fHeader.installedName, textFill=0, fontSize=14, rLeading=1.4, xTextAlign=LEFT, paragraphTopSpacing=30, paragraphBottomSpacing=0) bodyStyle = dict(font='Verdana', textFill=0, fontSize=12, rLeading=1.4, xTextAlign=LEFT, paragraphTopSpacing=10, hyphenation=True) italicBodyStyle = copy.copy(bodyStyle) italicBodyStyle['font'] = 'Verdana-Italic' italicBodyStyle['paragraphTopSpacing'] = 0 fs = newFS(f.info.familyName + ' ' + f.info.styleName, style=titleStyle) _, th = textSize(fs) title = newTextBox(fs, conditions=[Top2Top(), Fit2Width()], parent=page, h=th*1.2) # Make new container for adding elements inside with alignment. newRect(z=10, w=pageAreaW, h=pageAreaH, fill=blockFill, parent=page, margin=0, padding=0, yAlign=MIDDLE, maxW=pageAreaW, maxH=pageAreaH, xAlign=CENTER, conditions=(Center2Center(), Middle2Middle())) t1 = newTextBox('Inside the Amstelvar', z=0, font=fHeader.installedName, fontSize=40, w=pageAreaW/2, parent=page, conditions=(Left2Left(), Top2Top())) w = pageAreaW*0.75 # Used as element width and relative font size. padding = PageHeight/24 fs = newFS('Variable Fonts ', style=dict(font=fHeader.installedName, textFill=0, fontSize=90)) fs += newFS('Explained', style=dict(font=fHeaderCondensed.installedName, textFill=0, fontSize=90)) t2 = newTextBox(fs, z=0, w=PageWidth*0.75, parent=page, conditions=(Left2Left(), Fit2Width(), Float2Top())) circle = VariableCircle(f, s=GLYPH_NAME, name='VariableCircleSpeciment', parent=page, padding=4, x=100, fontSize=150, maxW=PageWidth-2*PADDING, minW=100, showAxisName=True, # Conditions make the element move to top-left of the page. # And the condition that there should be no overflow, otherwise the text box # will try to solve it. #conditions=[Right2Right(), Float2Top()], conditions=[Left2Left(), Fit2Width(), Bottom2Bottom()], # Position of the origin of the element. Just to show where it is. # Has no effect on the position conditions. yAlign=BOTTOM, xAlign=LEFT, fill=CIRCLE_ELEMENT_FILL, borders=1, ) score = page.solve() if score.fails: print 'Condition fails', score.fails return doc # Answer the doc for further doing.
def makeDocument(rs): u"""Demo Bitcount Reference composer.""" # Set some values of the default template (as already generated by the document). # Make squential unique names for the flow boxes inside the templates coverTitleId = 'coverTitleId' # To find the placement of the cover title. coverAuthorId = 'coverAuthorId' # Find the placement for the author name. tocId = 'toc' # Id of target textBox, containing the table of content. flowId1 = MAIN_FLOW + '1' flowIds = [flowId1] # Names of boxes that contain footnote text in flow. footnotesId = 'footnotes' # Id of target textBox containing footnotes per page. literatureIndexId = 'literatureIndex' imageIndexId = 'imageIndex' pageNumberId = 'pageNumberId' # Template for Cover page templateCover = Template(rs) # Create new template templateCover.rect(0, 0, rs['w'], rs['h'], fill=(1, 0, 0)) # Placement of first <h1> in the Galley, holding the Thesis title. templateCover.cTextBox(FS, 1, 1, 6, 5, rs, coverTitleId, fill=BOX_COLOR) # Placement of first <h4> in the Galley, holding the author name(s) templateCover.cTextBox(FS, 1, 8, 6, 5, rs, coverAuthorId, fill=BOX_COLOR) # Template for Table of Content templateToc = Template(rs) # Create template for Table of Content # Show grid columns and paddngs if rootStyle.showGrid or rootStyle.showGridColumns are True templateToc.grid(rs) # Show baseline grid if rs.showBaselineGrid is True templateToc.baselineGrid(rs) templateToc.cTextBox('\nTable of Content', 3, 0, 4, 1, rs, fill=BOX_COLOR, fontSize=32) templateToc.cTextBox('', 3, 1, 4, 8, rs, tocId, fill=BOX_COLOR) # Template for literature reference index. templateLiteratureIndex = Template( rs) # Create template for Table of Content # Show grid columns and paddings if rootStyle.showGrid or rootStyle.showGridColumns are True templateLiteratureIndex.grid(rs) # Show baseline grid if rs.showBaselineGrid is True templateLiteratureIndex.baselineGrid(rs) templateLiteratureIndex.cTextBox('\nLiterature index', 3, 0, 4, 1, rs, fill=BOX_COLOR, fontSize=32) templateLiteratureIndex.cTextBox('', 3, 1, 4, 8, rs, literatureIndexId, fill=BOX_COLOR) # Template for image reference index. templateImageIndex = Template(rs) # Create template for Table of Content # Show grid columns and padding if rootStyle.showGrid or rootStyle.showGridColumns are True templateImageIndex.grid(rs) # Show baseline grid if rs.showBaselineGrid is True templateImageIndex.baselineGrid(rs) templateImageIndex.cTextBox('\nImage index', 3, 0, 4, 1, rs, fill=BOX_COLOR, fontSize=32) templateImageIndex.cTextBox('', 3, 1, 4, 8, rs, imageIndexId, fill=BOX_COLOR) # Template 1 template1 = Template(rs) # Create template of main size. Front page only. # Show grid columns and paddings if rootStyle.showGrid or rootStyle.showGridColumns are True template1.grid(rs) # Show baseline grid if rs.showBaselineGrid is True template1.baselineGrid(rs) # Create empty image place holders. To be filled by running content on the page. # In this templates the images fill the left column if there is a reference on the page. template1.cContainer(0, 0, 3, 3, rs) # Empty image element, cx, cy, cw, ch template1.cContainer(0, 3, 3, 3, rs) template1.cContainer(0, 6, 3, 3, rs) # Create linked text boxes. Note the "nextPage" to keep on the same page or to next. template1.cTextBox(FS, 3, 0, 4, 9, rs, flowId1, nextBox=flowId1, nextPage=1, fill=BOX_COLOR) template1.cTextBox('', 3, 9, 3, 2, rs, footnotesId, fill=BOX_COLOR) # Create page number box. Pattern pageNumberMarker is replaced by FormattedString of actual page number. # Mark the text box, so we can find it back later. template1.cTextBox(rs['pageIdMarker'], 6, 9, 1, 1, eId=pageNumberId, style=rs, font=BOOK, fontSize=12, fill=BOX_COLOR, xAlign=RIGHT) # Create new document with (w,h) and fixed amount of pages. # Make number of pages with default document size. # Initially make all pages default with template2 doc = Document(rs, autoPages=5, template=template1) # Cache some values from the root style that we need multiple time to create the tag styles. fontSize = rs['fontSize'] leading = rs['leading'] rLeading = rs['rLeading'] listIndent = rs['listIndent'] language = rs['language'] # Add styles for whole document and text flows. # Note that some values are defined here for clarity, even if their default root values # are the same. doc.newStyle(name='chapter', font=BOOK) doc.newStyle(name='title', fontSize=3 * fontSize, font=BOLD) doc.newStyle(name='subtitle', fontSize=2.6 * fontSize, font=BOOK_ITALIC) doc.newStyle(name='author', fontSize=2 * fontSize, font=BOOK, fill=(1, 0, 0)) doc.newStyle(name='h1', fontSize=7 * fontSize, font=SEMIBOLD_CONDENSED, fill=(1, 0, 0), leading=7.2 * fontSize, tracking=H1_TRACK, prefix='', postfix='\n') doc.newStyle(name='h2', fontSize=1.5 * fontSize, font=SEMIBOLD_CONDENSED, fill=0, leading=1.6 * fontSize, rLeading=0, rTracking=H2_TRACK, prefix='\n', postfix='\n', paragraphTopSpacing=U) doc.newStyle(name='h3', fontSize=1.1 * fontSize, font=MEDIUM, fill=0, paragraphTopSpacing=2 * U, paragraphBottomSpacing=U, leading=leading, rLeading=0, rNeedsBelow=2 * rLeading, rTracking=H3_TRACK, prefix='\n', postfix='\n') doc.newStyle(name='h4', fontSize=1.1 * fontSize, font=BOOK, fill=0, leading=leading, rLeading=0, rNeedsBelow=2 * rLeading, rTracking=H3_TRACK, paragraphTopSpacing=U, paragraphBottomSpacing=U, prefix='\n', postfix='\n') # Spaced paragraphs. doc.newStyle( name='p', fontSize=fontSize, font=BOOK, fill=0.1, prefix='', postfix='\n', rTracking=P_TRACK, leading=14, rLeading=0, xAlign=LEFT, hyphenation=True, indent=0, firstLineIndent=2 * U, firstParagraphIndent=0) # TODO: Make firstParagraphIndent to work. # Inline tags need to refined prefix and postfix as non-\n, otherwise they # will inherit these attributes from the parent <p> doc.newStyle(name='b', font=SEMIBOLD, prefix='', postfix='') doc.newStyle(name='em', font=BOOK_ITALIC, textFill=(1, 0, 0), prefix='', postfix='') doc.newStyle(name='hr', stroke=(1, 0, 0), strokeWidth=4) doc.newStyle(name='br', postfix='\n') # Simplest way to make <br/> show newline doc.newStyle(name='a', prefix='', postfix='') # Literature reference. doc.newStyle(name='literatureref', textFill=0.3, fontSize=fontSize - 1) # Footnote reference index. doc.newStyle(name='sup', font=MEDIUM, baselineShift=2, prefix='', postfix=' ', fontSize=fontSize - 2) doc.newStyle( name='li', fontSize=fontSize, font=BOOK, rTracking=P_TRACK, leading=leading, hyphenation=True, # Lists need to copy the listIndex over to the regalar style value. tabs=[(listIndent, LEFT)], indent=listIndent, firstLineIndent=1, postfix='\n') doc.newStyle(name='ul', prefix='', postfix='') doc.newStyle(name='footnote', fill=0, fontSize=0.9 * fontSize, font=BOOK, rTracking=P_TRACK, tabs=[(listIndent, LEFT)], indent=listIndent, firstLineIndent=1, postfix='\n') # Image & captions doc.newStyle( name='img', stroke=0.3, fill=None, rTracking=P_TRACK, language=language, textFill=0.2, strokeWidth=1, leading=leading * 0.8, fontSize=0.8 * fontSize, font=BOOK_ITALIC, hyphenation=True, indent=0, firstLineIndent=0, # Use style['fill'] = transparant color as overlay on image. ) # Generic document layout # Page 1 Cover # Page 2 Title # Page 3 Table of Content # Page 4+ Content (footnotes are shown on the page of their reference) # Page -1 Alphabetical literature reference. # Change template of cover page. # Create filtered Galley for cover page. # See https://docs.python.org/2/library/xml.etree.elementtree.html#xpath-support # for XPath filter syntax. gTitle = Galley() t = Typesetter(doc, gTitle) t.typesetFile(MD_PATH, rootStyle=dict(textFill=1, fontSize=80, font=MEDIUM, leading=84), xPath='h1') gAuthor = Galley() t = Typesetter(doc, gAuthor) t.typesetFile(MD_PATH, rootStyle=dict(textFill=1, fontSize=24, font=MEDIUM), xPath='h4') # First one is the author coverPage = doc[1] coverPage.setTemplate(templateCover) c = Composer(doc) c.compose(gTitle, coverPage, coverTitleId) c.compose(gAuthor, coverPage, coverAuthorId) # Change template of Table of Content page tocPage = doc[2] tocPage.setTemplate(templateToc) mainPage = doc[3] # Create main Galley for this page, for pasting the sequence of elements. g = Galley() t = Typesetter(doc, g) t.typesetFile(MD_PATH) # Fill the main flow of text boxes with the ML-->XHTML formatted text. c = Composer(doc) c.compose(g, mainPage, flowId1) # Now all text is composed on pages, scan for the pages that contain footnotes. # TODO: This will be implemented a function inside Composer in a later version. # Assume the tocBox (Table of Content) to be available on the first page. literatureRefs = {} tocBox, (_, _) = tocPage[tocId] for pageId, page in sorted(doc.pages.items()): if page in (tocPage, coverPage): # Skip these for toc collect and footnotes. continue # Get page box for footnotes fnBox, (_, _) = page[footnotesId] assert fnBox is not None # Otherwise there is a template error. Footnote box needs to exist. for flowId in flowIds: # BUG: Need to check if the marker was really found in the textbox area. # If it is part of the overflow, then it should not be found here. flow, _ = page[flowId] for marker, arguments in findMarkers(flow.fs): if marker == 'footnote': footNoteIsInOverflow = False # Process the foot note. footnoteId = int(arguments) # Footnode ids are numbers. # @@@ Hack to check if the marker is in the overflow text. # In that case, ignore it. for overFlowMarker, overFlowArguments in findMarkers( flow.getOverflow()): # If this marker is a footnote and one that we are looking for, # we can ignore it, because it is in the overflow part of the flow.fs if overFlowMarker == 'footnote' and footnoteId == int( overFlowArguments): footNoteIsInOverflow = True break if not footNoteIsInOverflow: # We found a footnote that is visible on this page and # not in one of the overflow texts. # Process the footnote id and content, usng the “footnote“ content style. # We are re-using the typesetter here. This may become a separate typesetter, if this code # becomes a method of the composer. # TODO: Make this into Galley, in case footnote <p> has child nodes. footnoteText = newFS( '%d\t%s\n' % (footnoteId, doc.footnotes[footnoteId]['p'].text), page, t.getCascadedStyle(doc.getStyle('footnote'))) # Add the footnote content to the box (it may not be the first to be added. fnBox.append(footnoteText) elif marker in ('h1', 'h2', 'h3', 'h4'): # For now we want them all in the TOC #doc.addToc(marker) pass elif marker == 'literature': # The "arguments" contains the refId, so we can find it in the collected literature references # and then add this page number. # @@@ TODO: check if reference marker is in overflow. Then ignore processing it. doc.literatureRefs[int(arguments)]['pageIds'].append( pageId) # Build the alphabetical literature reference page. # Scan the created pages for literature references and build an index on a new page. literatureIndexPage = doc.newPage(template=templateLiteratureIndex) # Make an alfabetic sorted list of name-->(reference, (pageNumber, ...)) references = {} for refIndex, item in doc.literatureRefs.items(): references[item['nodeId']] = item literatureRefBox = literatureIndexPage.getElement(literatureIndexId) for refId, item in sorted(references.items()): # Now we have a sorted list of reference items, we need to make it into a galley. # Several ways of doing it: Create MarkDown, HTML/XML or directly writing FormattedText. pageNumbers = [] for pageNumber in item['pageIds']: pageNumbers.append( ` pageNumber `) literatureRefBox.append(u'%s – %s\n' % (refId, ', '.join(pageNumbers))) print refId, item['nodeId'], item['node'], item['p'], item['pageIds'] # Build the alphabetical image reference page. # Scan the created pages for image references and build an index on a new page. imageIndexPage = doc.newPage(template=templateImageIndex) # Make an alfabetic sorted list of name-->(reference, (pageNumber, ...)) references = {} for refIndex, item in doc.imageRefs.items(): references[item['nodeId']] = item for imageRefId, item in sorted(references.items()): print imageRefId, item['nodeId'], item['node'], item['p'], item[ 'pageIds'] # Set all pagenumbers and other page-based info for pageId, page in sorted(doc.pages.items()): for e in page.elements: if e.eId == pageNumberId: e.setText('%s' % pageId) break return doc
def makeDocument(): u"""Make a new document.""" # Create a new document, default to the defined page size. doc = Document(w=W, h=H, originTop=False, title='Text Flow', autoPages=2) view = doc.getView() view.padding = 30 # Aboid showing of crop marks, etc. view.showPageCropMarks = True view.showPageRegistrationMarks = True view.showPageFrame = True view.showPagePadding = True view.showElementOrigin = True view.showElementDimensions = False view.showElementInfo = False # Get list of pages with equal y, then equal x. #page = doc[0][0] # Get the single page from te document. page0 = doc.getPage( 0) # Get page on pageNumber, first in row (this is only one now). page0.name = 'Page 1' page0.padding = PagePadding s = newFS('', style=dict(font='Verdana', fontSize=10, textFill=0)) for n in range(10): s += newFS('(Line %d) Volume of text defines the box height.' % (n + 1), style=dict(fontSize=10 + n * 2, textFill=0)) s += newFS('Volume', style=dict(textFill=(1, 0, 0), font='Verdana', fontSize=10 + n * 2)) s += newFS(' of text defines the box height. \n', style=dict(textFill=0, font='Verdana', fontSize=10 + n * 2)) e1 = newTextBox( s, parent=page0, padding=4, x=100, w=BoxWidth, font='Verdana', h=None, maxW=W - 2 * PagePadding, minW=100, mb=20, mr=10, # Conditions make the element move to top-left of the page. # And the condition that there should be no overflow, otherwise the text box # will try to solve it. conditions=[Left2Left(), Float2Top(), Overflow2Next()], # Position of the origin of the element. Just to show where it is. # Has no effect on the position conditions. yAlign=BOTTOM, xAlign=LEFT, leading=5, fontSize=9, textFill=0, strokeWidth=0.5, fill=0.9, stroke=None, ) """ for line in e1.textLines: print line, line.x, line.y for foundPattern in e1.findPattern('Line 5'): print foundPattern.x, foundPattern.y, foundPattern.line, foundPattern.line.runs """ font = getFontByName(e1.textLines[0].runs[1].displayName) c = 'hyphen' g = font[c] print g.pointContexts[0].p.x save() scale(0.3) path = font[c].path fill(1, 0, 0) drawPath(path) ga = GlyphAnalyzer(font, c) for x, vertical in ga.verticals.items(): stroke(0) strokeWidth(1) fill(None) line((x, 0), (x, 3000)) print ga.horizontals for y, horizontal in ga.horizontals.items(): stroke(0) strokeWidth(1) fill(None) line((0, y), (2000, y)) restore() """ for contour in ga.glyph.pointContexts: path = BezierPath() for index, pc in contour.items(): p = pc[3] if index == 0: path.moveTo((p.x/2, p.y/2)) else: path.lineTo((p.x/2, p.y/2)) path.closePath() fill(0) drawPath(path) #oval(p.x/2, p.y/2, 4, 4) #print index, pc """ score = doc.solve() # Try to solve all pages. if score.fails: print score.fails return doc # Answer the doc for further doing.
from pagebot import newFS from pagebot.fonttoolbox.objects.family import getFamilyFontPaths from pagebot.contributions.filibuster.blurb import blurb if __name__ == '__main__': #for k in getFamilyFontPaths('Bitpath'): # print k F = 50 x = y = 20 s = blurb.getBlurb('article_content', noTags=True) fs = newFS( s, None, dict(font='BitpathGridDouble-RegularLineSquare', fontSize=F, textFill=(1, 0, 0), rLeading=0.5)) textBox(fs, (x, y, 1000, 900)) s = blurb.getBlurb('article_content', noTags=True) fs = newFS( s, None, dict(font='BitpathGridDouble-RegularLineSquare', fontSize=F, textFill=(0, 1, 0), rLeading=0.5)) textBox(fs, (x, y, 1000, 900)) s = blurb.getBlurb('article_content', noTags=True) fs = newFS(
scriptGlobals.s4 = blurb.getBlurb('article_content', noTags=True) scriptGlobals.s5 = blurb.getBlurb('article_content', noTags=True) F = 50 R = 10 x = y = 20 rLeading = 0.6 for angle in range(0, 360, 10): newPage(1000, 1000) dx = sin(angle / 360 * 2 * pi) * R dy = cos(angle / 360 * 2 * pi) * R fs = newFS( scriptGlobals.s1, None, ict(font='BitpathGridDouble-RegularLineSquare', fontSize=F, textFill=(1, 0, 0), rLeading=rLeading)) textBox(fs, (x, y, 1000, 900)) fs = newFS( scriptGlobals.s2, None, dict(font='BitpathGridDouble-RegularLineSquare', fontSize=F, textFill=(0, 1, 0), rLeading=rLeading)) textBox(fs, (x + 7, y + 7, 1000, 900)) fs = newFS( scriptGlobals.s3, None, dict(font='BitpathGridDouble-RegularLineSquare',
def makeDocument(): u"""Demo page composer.""" tt = time() # Keep track of time, in case SHOW_TIMER is True # Set some values of the default template (as already generated by the document). # Make squential unique names for the flow boxes inside the templates flowId0 = MAIN_FLOW+'0' flowId1 = MAIN_FLOW+'1' flowId2 = MAIN_FLOW+'2' # Template 1 template1 = Template(rs) # Create template of main size. Front page only. # Show grid columns and margins if rootStyle.showGrid or rootStyle.showGridColumns are True template1.grid(rs) # Show baseline grid if rs.showBaselineGrid is True template1.baselineGrid(rs) # Create empty image place holders. To be filled by running content on the page. template1.cContainer(4, 0, 2, 4, rs) # Empty image element, cx, cy, cw, ch template1.cContainer(0, 5, 2, 3, rs) # Create linked text boxes. Note the "nextPage" to keep on the same page or to next. template1.cTextBox('', 0, 0, 2, 5, rs, flowId0, nextBox=flowId1, nextPage=0, fill=BOX_COLOR) template1.cTextBox('', 2, 0, 2, 8, rs, flowId1, nextBox=flowId2, nextPage=0, fill=BOX_COLOR) template1.cTextBox('', 4, 4, 2, 4, rs, flowId2, nextBox=flowId0, nextPage=1, fill=BOX_COLOR) # Create page number box. Pattern pageNumberMarker is replaced by actual page number. template1.cText(rs['pageNumberMarker'], 6, 0, rs, font=BOOK, fontSize=12, fill=BOX_COLOR) # Template 2 template2 = Template(rs) # Create second template. This is for the main pages. # Show grid columns and margins if rootStyle.showGrid or rootStyle.showGridColumns are True template2.grid(rs) # Show baseline grid if rs.showBaselineGrid is True template2.baselineGrid(rs) template2.cContainer(4, 0, 2, 3, style=rs) # Empty image element, cx, cy, cw, ch template2.cContainer(0, 5, 2, 3, style=rs) template2.cContainer(2, 2, 2, 2, style=rs) template2.cContainer(2, 0, 2, 2, style=rs) template2.cContainer(4, 6, 2, 2, style=rs) template2.cTextBox('', 0, 0, 2, 5, style=rs, flowId0, nextBox=flowId1, nextPage=0, fill=BOX_COLOR) template2.cTextBox('', 2, 4, 2, 4, style=rs, flowId1, nextBox=flowId2, nextPage=0, fill=BOX_COLOR) template2.cTextBox('', 4, 3, 2, 3, style=rs, flowId2, nextBox=flowId0, nextPage=1, fill=BOX_COLOR) # Create page number box. Pattern pageNumberMarker is replaced by actual page number. template2.cText(rs['pageNumberMarker'], 6, 0, style=rs, font=BOOK, fontSize=12, fill=BOX_COLOR) # Create new document with (w,h) and fixed amount of pages. # Make number of pages with default document size. # Initially make all pages default with template2 doc = Document(rs, autoPages=2, template=template2) # Cache some values from the root style that we need multiple time to create the tag styles. fontSize = rs['fontSize'] leading = rs['leading'] rLeading = rs['rLeading'] listIndent = rs['listIndent'] language = rs['language'] # Add styles for whole document and text flows. # Note that some values are defined here for clarity, even if their default root values # are the same. doc.newStyle(name='chapter', font=BOOK) doc.newStyle(name='title', fontSize=3*fontSize, font=BOLD) doc.newStyle(name='subtitle', fontSize=2*fontSize, font=BOOK_ITALIC) doc.newStyle(name='author', fontSize=2*fontSize, font=BOOK, fill=(1, 0, 0)) doc.newStyle(name='h1', fontSize=fontSize, font=SEMIBOLD, fill=(1, 0, 0), leading=2*fontSize, tracking=H1_TRACK, postfix='\n') doc.newStyle(name='h2', fontSize=fontSize, font=SEMIBOLD, fill=(0, 0.5, 1), leading=1*fontSize, rLeading=0, tracking=H2_TRACK, postfix='\n') doc.newStyle(name='h3', fontSize=fontSize, font=MEDIUM, fill=0, leading=1*fontSize, rLeading=0, rNeedsBelow=2*rLeading, tracking=H3_TRACK, postfix='\n') # Spaced paragraphs. doc.newStyle(name='p', fontSize=fontSize, font=BOOK, fill=0.1, prefix='', postfix='\n', rTracking=P_TRACK, leading=14, rLeading=0, align=LEFT, hyphenation=True) doc.newStyle(name='b', font=SEMIBOLD) doc.newStyle(name='em', font=BOOK_ITALIC) doc.newStyle(name='hr', stroke=(1, 0, 0), strokeWidth=4) doc.newStyle(name='br', postfix='\n') # Simplest way to make <br/> be newline doc.newStyle(name='img', leading=leading, fontSize=fontSize, font=BOOK,) # Footnote reference index. doc.newStyle(name='sup', font=MEDIUM, rBaselineShift=0.6, fontSize=0.65*fontSize) doc.newStyle(name='li', fontSize=fontSize, font=BOOK, tracking=P_TRACK, leading=leading, hyphenation=True, # Lists need to copy the listIndex over to the regalar style value. tabs=[(listIndent, LEFT)], indent=listIndent, firstLineIndent=1, postfix='\n') doc.newStyle(name='ul',) doc.newStyle(name='literatureref', fill=0.5, rBaselineShift=0.2, fontSize=0.8*fontSize) doc.newStyle(name='footnote', fill=(1, 0, 0), fontSize=0.8*U, font=BOOK) doc.newStyle(name='caption', tracking=P_TRACK, language=language, fill=0.2, leading=leading*0.8, fontSize=0.8*fontSize, font=BOOK_ITALIC, indent=U/2, tailIndent=-U/2, hyphenation=True) if SHOW_TIMER: print 'Time styles %0.3f' % (time()-tt) tt = time() # Change template of page 1 page0 = doc[0] page0.setTemplate(template1) ttt = '' for n in range(100): ttt += 'abcdefg%d\n' % n ttt = newFS(ttt, rs) ttt = page0.textBox(ttt, point(rs.get('pl'), rs.get('pt')), w=11*14, h=50*14, fill=(0.8, 0.8, 0.8, 0.5)) page0.textBox(ttt, point=(rs.get('pl')+11*14+14, rs.get('pt')), w=11*14, h=50*14, fill=(0.8, 0.8, 0.8, 0.5)) if SHOW_TIMER: print 'Time template %0.3f' % (time()-tt) tt = time() # Create main Galley for this page, for pasting the sequence of elements. g = Galley() t = Typesetter(doc, g) t.typesetFile(MD_PATH) if SHOW_TIMER: print 'Time typesetter %0.3f' % (time()-tt) tt = time() # Fill the main flow of text boxes with the ML-->XHTML formatted text. c = Composer(doc) c.compose(g, doc[0], flowId0) if SHOW_TIMER: print 'Time compose %0.3f' % (time()-tt) return doc
from pagebot import newFS W = 600 H = 300 HEAD_LINE = """When fonts started a new world""" TEXT = """The advent of variable fonts means doing nothing, or everything, or something in between for font users and type designers. """ newPage(W, H) fs = newFS(HEAD_LINE + '\n', style=dict(font='Verdana', fontSize=24, textFill=0)) fs += newFS(TEXT, style=dict(font='Verdana', fontSize=12, textFill=0)) tw, th = textSize(fs, width=200) print tw, th textBox(fs, (100, -th + H, 200, th))
print len(bitcounts) for c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz': #newPage(1200, 500) newPage(500, 500) s = 'Bitcount & Bitpath' s = c fonts = bitpaths + bitcounts print len(fonts) shuffle(fonts) for name in fonts: #if not 'Double' in name: # continue if not 'Single' in name: continue if not 'Mono' in name: continue fs = newFS( s, style=dict( font=name, fontSize=400, openTypeFeatures=dict(ss01=True, ss02=True, ss03=True), #textFill=None, textFill=(random(), random(), random(), 0.05), textStroke=(random(), random(), random(), 0.5), textStrokeWidth=0.5, )) text(fs, (130, 130)) saveImage('_export/CompareBitpath2Bitcount.pdf')
def makeDocument(): u"""Create Document instance with a single page. Fill the page with elements and perform a conditional layout run, until all conditions are solved.""" doc = Document(w=PageWidth, h=PageHeight, originTop=False, autoPages=1) # Get default view from the document and set the viewing parameters. view = doc.getView() view.style['fill'] = 1 view.padding = 40 # To show cropmarks and such, make >40 or so. view.showPageCropMarks = True # Won't show if there is not padding in the view. view.showPageRegistrationMarks = True view.showPageFrame = True view.showPageNameInfo = True view.showElementOrigin = False view.showElementDimensions = False #ShowDimensions view.showElementInfo = False view.showGridColumns = True view.showGrid = True #view.style['showGridCo page = doc[0] # Get the single frint page from the document. # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding pageAreaW = PageWidth - pl - pr pageAreaH = PageHeight - pt - pb # Resources blockFill = None #(1, 1, 0) # Use color to debug page area gradient = Gradient(locations=[1, 0], colors=((0, 0, 0), (0.8, 0.8, 0.8))) shadow = Shadow(offset=(6, -6), blur=10, color=(0.2, 0.2, 0.2, 0.5)) # Styles coverTitleStyle = dict(font='Georgia', fontSize=80, rLeading=1.4, xTextAlign=CENTER, textFill=(1, 0, 0)) titleStyle = dict(font='Georgia', fontSize=26, rLeading=1.4, xTextAlign=CENTER, textFill=1) authorStyle = dict(font='Georgia-Italic', textFill=1, fontSize=18, xTextAlign=CENTER) headStyle = dict(font='Verdana-Bold', textFill=0, fontSize=14, rLeading=1.4, xTextAlign=LEFT, paragraphTopSpacing=30, paragraphBottomSpacing=0) bodyStyle = dict(font='Verdana', textFill=0, fontSize=12, rLeading=1.4, xTextAlign=LEFT, paragraphTopSpacing=10, hyphenation=True) italicBodyStyle = copy.copy(bodyStyle) italicBodyStyle['font'] = 'Verdana-Italic' italicBodyStyle['paragraphTopSpacing'] = 0 # Adding width to formatted string request will scale fontSize of # style to force fit width. fs = newFS('Magazine', w=page.pw, style=coverTitleStyle) # Keep h=None, to make vertical elastic box, depending on content. tb = newTextBox(fs, parent=page, showBaselines=True, conditions=[Fit2Width(), Top2TopSide()]) score = page.solve() if score.fails: print 'Condition fails', score.fails return doc # Answer the doc for further doing.
def makeDocument(fontPath): u"""Make a new document.""" f = Font(fontPath) # Get PageBot Font instance of Variable font. W = H = PageSize # Create a new document, default to the defined page size. doc = Document(w=W, h=H, originTop=False, title='Text Flow', autoPages=1) view = doc.getView() view.padding = 0 # Aboid showing of crop marks, etc. view.showPageCropMarks = True view.showPageRegistrationMarks = True view.showPageFrame = True view.showPagePadding = True view.showElementOrigin = False view.showElementDimensions = False # Get list of pages with equal y, then equal x. #page = doc[0][0] # Get the single page from te document. page = doc.getPage( 0) # Get page on pageNumber, first in row (this is only one now). page.name = 'Page 1' page.padding = PagePadding fs = newFS(f.info.familyName + ' ' + f.info.styleName, style=dict(font=f.name, fontSize=18, textFill=0)) _, th = textSize(fs) title = newTextBox(fs, conditions=[Top2Top(), Fit2Width()], parent=page, h=th * 1.2) circle = VariableCircle( f, s=GLYPH_NAME, name='VariableCircleSpeciment', parent=page, padding=4, x=100, fontSize=84, maxW=W - 2 * PagePadding, minW=100, # Conditions make the element move to top-left of the page. # And the condition that there should be no overflow, otherwise the text box # will try to solve it. conditions=[Float2Top(), Fit2Bottom(), Center2Center()], # Position of the origin of the element. Just to show where it is. # Has no effect on the position conditions. yAlign=BOTTOM, xAlign=LEFT, fill=CIRCLE_ELEMENT_FILL, borders=0, ) print circle.w, circle.h score = doc.solve() # Try to solve all pages. if score.fails: print score.fails # To avoid circular dependent conditions, we correct the position of the title # on left to that the position of the circle has become. title.pl = circle.x - page.pl return doc # Answer the doc for further doing.
def makeDocument(): u"""Make a new document.""" #W = H = 120 # Get the standard a4 width and height in points. W = PageSize H = PageSize # Hard coded SQUARE and GUTTE, just for simple demo, instead of filling padding an columns in the root style. # Page size decides on the amount squares that is visible. # Page padding is centered then. sqx = int( W / (SQUARE + GUTTER)) # Whole amount of squares that fit on the page. sqy = int(H / (SQUARE + GUTTER)) # Calculate centered paddings for the amount of fitting squares. # Set values in the rootStyle, so we can compare with column calculated square position and sizes. #rs['colH'] = rs['colW'] = SQUARE # Make default colW and colH square. #padX = (W - sqx*(SQUARE + GUTTER) + GUTTER)/2 my = (H - sqy * (SQUARE + GUTTER) + GUTTER) / 2 doc = Document(w=W, h=H, originTop=False, title='Color Squares', autoPages=1) view = doc.getView() view.padding = 0 # Aboid showing of crop marks, etc. view.showElementOrigin = True # Get list of pages with equal y, then equal x. #page = doc[0][0] # Get the single page from te document. page = doc.getPage( 0) # Get page on pageNumber, first in row (this is only one now). page.name = 'This is a demo page for floating child elements' page.padding = PagePadding page.gutter3D = GUTTER # Set all 3 gutters to same value im = newImage('images/cookbot10.jpg', (50, 50, 10), padding=0, parent=page, w=200, h=300, conditions=(Top2Top(), Fit2Width(), SolveBlock(), Shrink2BlockBottom()), yAlign=BOTTOM, fill=(0, 1, 0, 0.3), stroke=(1, 0, 0)) # Give parent on creation, to have the css chain working. # Caption falls through the yr2 (with differnt z) and lands on yr1 by Float2BottomSide() fs = newFS('Captions float below the image', style=dict(font='Verdana', fontSize=20, textFill=1)) cap = newTextBox( fs, name='Caption', parent=im, z=0, conditions=[Fit2Width(), Float2Top()], padding=4, font='Verdana', yAlign=TOP, fontSize=9, textFill=1, strokeWidth=0.5, fill=(0, 0, 1, 0.3), stroke=(0, 0, 1), ) score = page.solve() if score.fails: print score.fails print im.h for e in im.elements: print e.h return doc # Answer the doc for further doing.
def makeDocument(): u"""Make a new document.""" doc = Document(w=PageSize, h=PageSize, originTop=False, autoPages=1) view = doc.getView() view.padding = 10 # Don't show cropmarks and such. view.showPageCropMarks = True view.showElementOrigin = ShowOrigin view.showElementDimensions = False view.showElementInfo = ShowElementInfo page = doc[0] # Get the single page from te document. # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = SQ pageArea = PageSize - 2 * SQ print PageSize, pageArea, SQ # Make new container for adding elements inside with alignment. newRect(z=10, w=pageArea, h=pageArea, fill=(0.8, 0.8, 0.8, 0.4), parent=page, margin=0, padding=0, yAlign=MIDDLE, maxW=pageArea, maxH=pageArea, xAlign=CENTER, stroke=None, conditions=(Center2Center(), Middle2Middle())) fontSize = RedHeight / 3 fs = newFS('Headline in red box.', style=dict(textFill=1, fontSize=fontSize, maxW=pageArea, maxH=pageArea, leading=fontSize, font='LucidaGrande')) newTextBox(fs, z=0, w=RedWidth, h=RedHeight, name='RedRect', parent=page, fill=(1, 0.1, 0.1), yAlign=TOP, maxW=pageArea, maxH=pageArea, padding=4, conditions=(Center2Center(), Top2Top())) if not hasattr(scriptGlobals, 'blurbText'): scriptGlobals.blurbText = blurb.getBlurb('article_summary', noTags=True) fs = newFS('Headline of formatted text.\n', style=dict(font='LucidaGrande-Bold', fontSize=12, leading=14, textFill=0)) fs += newFS(scriptGlobals.blurbText, style=dict(font='LucidaGrande', fontSize=10, leading=12, textFill=0)) newTextBox(fs, z=0, w=YellowWidth, h=YellowHeight, parent=page, padding=4, fill=0.7, maxW=pageArea, maxH=pageArea, conditions=(Left2Left(), Float2Top())) newImage('images/cookbot10.jpg', z=0, w=BlueWidth, parent=page, fill=0.7, padding=8, maxW=pageArea, maxH=pageArea, conditions=(Right2Right(), Float2Top())) newRect(z=0, w=BlueWidth, h=20, parent=page, fill=0.2, conditions=(Fit2Width(), Float2Top())) score = page.solve() if score.fails: print 'Condition fails', score.fails return doc # Answer the doc for further doing.
def makeDocument(): u"""Create Document instance with a single page. Fill the page with elements and perform a conditional layout run, until all conditions are solved.""" foundryName, bookName = findFont( (None, 'Book', 'Regular')) # Find these styles in order. _, mediumName = findFont(('Medium', 'Book', 'Regular')) mediumName = mediumName or bookName # In case medium weight does not exist. _, boldName = findFont(('Bold', 'Medium')) bookItalicName = italicName(bookName) mediumItalicName = italicName(mediumName) boldItalicName = italicName(boldName) # Get the fonts, so we can dig in the information. bookFont = getFontByName(bookName, install=False) mediumFont = getFontByName(mediumName, install=False) boldFont = getFontByName(boldName, install=False) bookItalicFont = getFontByName(bookItalicName, install=False) mediumItalicFont = getFontByName(mediumItalicName, install=False) boldItalicFont = getFontByName(boldItalicName, install=False) # Some parameters from the original book paperColor = int2Color( 0xF4EbC9) # Approximation of paper color of original specimen. redColor = int2Color(0xAC1E2B) # Red color used in the original specimen RedBoxY = 118 * MM # Vertical position of the Red Box, on Bodoni chapter. columnX = 80 * MM # Original 80MM, by we don't adjust, so optically a bit more. columnW = 60 * MM leftPadding = rightPadding = 52 * MM # Exception page padding for columns blurb = Blurb() # BLurb generator doc = Document(w=PageWidth, h=PageHeight, originTop=False, startPage=1, autoPages=10) # Get default view from the document and set the viewing parameters. view = SpreadView(parent=doc) view.style['fill'] = 1 # TODO: There is a bug that makes view page size grow, if there are multiple pages and padding > 0 # TODO: Add optional showing of mid-page line gradient, to suggest bended book pages. view.padding = 0 # 20*MM # To show cropmarks and such, make >=20*MM or INCH. view.showPageCropMarks = False # Won't show if there is not padding in the view. view.showPageRegistrationMarks = False view.showPageFrame = True view.showPageNameInfo = False view.showElementOrigin = False view.showElementDimensions = False #ShowDimensions view.showElementInfo = False view.showTextOverflowMarker = False # Don't show marker in case Filibuster blurb is too long. labelFont = boldFont padding = (3 * MM, 3 * MM, 3 * MM, 3 * MM) fontNameSize = 16 aboutSize = 10 glyphSetSize = 11 glyphSetLeading = 5 * MM captionSize = 7 pageNumberSize = 12 glyphTracking = 0.2 # Tracking of glyphset samples rt = 0.02 # Relative tracking capHeight = labelFont.info.capHeight / labelFont.info.unitsPerEm * fontNameSize border = dict(line=INLINE, dash=None, stroke=redColor, strokeWidth=1) # ----------------------------------------------------------------------------------- # Cover from image scan. pn = 1 page = doc[pn] # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding # Add image of cover scan. # TODO: Make other positions and scaling work on image element. newImage(path=COVER_IMAGE_PATH, parent=page, conditions=[Fit2Sides()]) page.solve() # ----------------------------------------------------------------------------------- # Empty left page. pn += 1 page = doc[pn] # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding # Fill with paper color # TODO: Just background color could be part of page fill instead of extra element. newRect(z=-1, parent=page, conditions=[Fit2Sides()], fill=paperColor) # ----------------------------------------------------------------------------------- # Full red page with white chapter title. pn += 1 page = doc[pn] # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding # Fill full page with red color # TODO: Just background color could be part of page fill instead of extra element. newRect(z=-1, parent=page, conditions=[Fit2Sides()], fill=redColor) fs = newFS('BOEKLETTER', style=dict(font=boldName, xTextAlign=RIGHT, textFill=paperColor, fontSize=24, rTracking=0.1)) #, xTextAlign=RIGHT)) newTextBox(fs, parent=page, y=page.h - 176 * MM, conditions=[Left2Left(), Fit2Right(), Fit2Bottom()]) page.solve() # ----------------------------------------------------------------------------------- # Empty left page. pn += 1 page = doc[pn] # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding # Fill with paper color # TODO: Just background color could be part of page fill instead of extra element. newRect(z=-1, parent=page, conditions=[Fit2Sides()], fill=paperColor) # ----------------------------------------------------------------------------------- # Title page of family. pn += 1 page = doc[pn] # Get the single front page from the document. # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding # Fill with paper color # TODO: Just background color could be part of page fill instead of extra element. newRect(z=-1, parent=page, conditions=[Fit2Sides()], fill=paperColor) fs = newFS(labelFont.info.familyName.upper(), style=dict(font=boldName, textFill=paperColor, fontSize=fontNameSize, tracking=0, rTracking=0.3)) tw, th = textSize(fs) # TODO: h is still bit of a guess with padding and baseline position. Needs to be solved more structured. tbName = newTextBox(fs, parent=page, h=capHeight + 3 * padding[0], w=tw + 2 * padding[1], conditions=[Right2RightSide()], fill=redColor, padding=padding) tbName.top = page.h - RedBoxY tbName.solve() # Make it go to right side of page. fs = newFS(foundryName.upper(), style=dict(font=boldName, textFill=0, fontSize=fontNameSize, tracking=0, rTracking=0.3)) tw, th = textSize(fs) # TODO: Something wrong with left padding or right padding. Should be symmetric. tbFoundry = newTextBox(fs, parent=page, h=capHeight + 3 * padding[0], w=tw + 2 * padding[1], fill=None, padding=padding, borders=border) tbFoundry.top = page.h - RedBoxY tbFoundry.right = tbName.left # Make blurb text about design and typography. aboutText = blurb.getBlurb('article_summary', noTags=True) fs = newFS(aboutText, style=dict(font=bookName, textFill=0, fontSize=aboutSize, tracking=0, rTracking=rt, rLeading=1.3, hyphenation='en')) # TODO: Something wrong with left padding or right padding. Should be symmetric. tbAbout = newTextBox(fs, parent=page, x=columnX, w=columnW, conditions=[Fit2Bottom()]) tbAbout.top = tbFoundry.bottom - 8 * MM # ----------------------------------------------------------------------------------- # Page 2 of a family chapter. Glyph overview and 3 columns. pn += 1 page = doc[pn] # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding # Fill with paper color # TODO: Just background color could be part of page fill instead of extra element. newRect(z=-1, parent=page, conditions=[Fit2Sides()], fill=paperColor) # Glyph set caps = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ\n' lc = caps.lower() figures = u'1234567890\n' capAccents = u'ÁÀÄÂÉÈËÊÇÍÌÏÎÓÒÖÔØÚÙÜÛÑ\n' lcAccents = capAccents.lower() punctuations = u',.;:?![]()-–—“”‘’' fs = newFS(caps, style=dict(font=bookName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) fs += newFS(lc, style=dict(font=bookName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) if bookName != bookItalicName: fs += newFS(caps, style=dict(font=bookItalicName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) fs += newFS(lc, style=dict(font=bookItalicName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) fs += newFS(figures, style=dict(font=bookName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) if bookName != bookItalicName: fs += newFS(figures, style=dict(font=bookItalicName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) fs += newFS(capAccents, style=dict(font=bookName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) fs += newFS(lcAccents, style=dict(font=bookName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) if bookName != bookItalicName: fs += newFS(capAccents, style=dict(font=bookItalicName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) fs += newFS(lcAccents, style=dict(font=bookItalicName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) fs += newFS(punctuations, style=dict(font=bookName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) if bookName != bookItalicName: fs += newFS(punctuations + '\n', style=dict(font=bookItalicName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) else: fs += '\n' if bookName != boldName: fs += newFS(caps + lc + figures + capAccents + lcAccents + punctuations, style=dict(font=boldName, textFill=0, fontSize=glyphSetSize, leading=glyphSetLeading, tracking=0, rTracking=glyphTracking)) tbGlyphSet = newTextBox(fs, parent=page, w=112 * MM, x=leftPadding, conditions=[Top2Top()]) fs = newFS(labelFont.info.familyName.upper(), style=dict(font=boldName, textFill=paperColor, fontSize=fontNameSize, tracking=0, rTracking=0.3)) tw, th = textSize(fs) # TODO: h is still bit of a guess with padding and baseline position. Needs to be solved more structured. tbName = newTextBox(fs, parent=page, h=capHeight + 3 * padding[0], w=tw + 2 * padding[1], conditions=[Left2LeftSide()], fill=redColor, padding=padding) tbName.top = page.h - RedBoxY tbName.solve() # Make it go to right side of page. fs = newFS(foundryName.upper(), style=dict(font=boldName, textFill=0, fontSize=fontNameSize, tracking=0, rTracking=0.3)) tw, th = textSize(fs) # TODO: Something wrong with left padding or right padding. Should be symmetric. tbFoundry = newTextBox(fs, parent=page, h=capHeight + 3 * padding[0], w=tw + 2 * padding[1], fill=None, padding=padding, borders=border) tbFoundry.top = page.h - RedBoxY tbFoundry.left = tbName.right # Make blurb text about design and typography. specText = blurb.getBlurb('article', noTags=True) fs = newFS(specText, style=dict(font=bookName, textFill=0, fontSize=6.5, tracking=0, rTracking=rt, leading=6.5, hyphenation='en')) # TODO: Last line of text blocks in original is bold. # TODO: Something wrong with left padding or right padding. Should be symmetric. tbSpec6 = newTextBox(fs, parent=page, x=leftPadding, w=50 * MM, h=30 * MM) tbSpec6.top = tbFoundry.bottom - 8 * MM fs = newFS('6 1/2 set\nop 6 pt gegoten (links)', style=dict(font=bookName, fontSize=captionSize, textFill=redColor, xTextAlign=RIGHT, rTracking=0.05, leading=8, openTypeFeatures=dict(frac=True))) # TODO: Something wrong with left padding or right padding. Should be symmetric. tbCaption6 = newTextBox(fs, parent=page, x=page.pl, w=leftPadding - page.pl - 3 * MM, h=30 * MM) tbCaption6.top = tbSpec6.top # Make blurb text about design and typography. specText = blurb.getBlurb('article', noTags=True) fs = newFS(specText, style=dict(font=bookName, textFill=0, fontSize=6.5, tracking=0, rTracking=rt, leading=7, hyphenation='en')) # TODO: Something wrong with left padding or right padding. Should be symmetric. tbSpec7 = newTextBox(fs, parent=page, x=leftPadding, w=50 * MM, h=35 * MM) tbSpec7.top = tbSpec6.bottom - 5 * MM fs = newFS('op 7 pt gegoten (links)', style=dict(font=bookName, fontSize=captionSize, textFill=redColor, xTextAlign=RIGHT, rTracking=0.05, leading=8)) # TODO: Something wrong with left padding or right padding. Should be symmetric. tbCaption7 = newTextBox(fs, parent=page, x=page.pl, w=leftPadding - page.pl - 3 * MM, h=30 * MM) tbCaption7.top = tbSpec7.top # TODO: Align with first baseline, instead of box top. # Make blurb text about design and typography. specText = blurb.getBlurb('article', noTags=True) fs = newFS(specText, style=dict(font=bookName, textFill=0, fontSize=6.5, tracking=0, rTracking=rt, leading=8, hyphenation='en')) # TODO: Something wrong with left padding or right padding. Should be symmetric. tbSpec8 = newTextBox(fs, parent=page, h=tbSpec6.top - tbSpec7.bottom) tbSpec8.top = tbSpec6.top tbSpec8.left = tbSpec6.right + 5 * MM tbSpec8.w = page.w - page.pr - tbSpec8.left fs = newFS('op 8 pt gegoten (rechts)', style=dict(font=bookName, fontSize=captionSize, textFill=redColor, xTextAlign=RIGHT, rTracking=0.05, leading=8)) # TODO: Something wrong with left padding or right padding. Should be symmetric. tbCaption8 = newTextBox(fs, parent=page, x=page.pl, w=leftPadding - page.pl - 3 * MM) tbCaption8.bottom = tbSpec8.bottom # TODO: Align with the position of the lowest base line. # TODO: Calculate the right amount fs = newFS( 'Corps 6 – per 100 aug.: romein 417, cursief 444, vet 426 letters', style=dict(font=bookName, fontSize=captionSize, textFill=redColor, xTextAlign=RIGHT, rTracking=rt, leading=8)) # TODO: Something wrong with left padding or right padding. Should be symmetric. tbCaptionTotal = newTextBox(fs, parent=page, x=page.pl, w=page.w - page.pl - page.pr) tbCaptionTotal.top = tbSpec8.bottom - MM # Page number fs = newFS( ` pn `, style=dict(font=bookName, fontSize=pageNumberSize, textFill=redColor, xTextAlign=LEFT, rTracking=rt, leading=8)) # TODO: Something wrong with left padding or right padding. Should be symmetric. tbPageNumber = newTextBox(fs, parent=page, x=leftPadding, w=10 * MM) tbPageNumber.bottom = 20 * MM # ----------------------------------------------------------------------------------- # Page 3, 3 columns. pn += 1 page = doc[pn] # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding # Fill with paper color # TODO: Just background color could be part of page fill instead of extra element. newRect(z=-1, parent=page, conditions=[Fit2Sides()], fill=paperColor) # Make blurb text about design and typography. specText = blurb.getBlurb('article', noTags=True) + ' ' + blurb.getBlurb( 'article', noTags=True) fs = newFS(specText, style=dict(font=bookName, textFill=0, fontSize=8.5, tracking=0, rTracking=rt, leading=8, hyphenation='en')) # TODO: Something wrong with left padding or right padding. Should be symmetric. tbText1 = newTextBox(fs, parent=page, h=110 * MM, w=50 * MM, conditions=[Top2Top(), Left2Left()]) page.solve() # Make blurb text about design and typography. specText = blurb.getBlurb('article', noTags=True) + ' ' + blurb.getBlurb( 'article', noTags=True) fs = newFS(specText, style=dict(font=bookName, textFill=0, fontSize=8.5, tracking=0, rTracking=rt, leading=9, hyphenation='en')) # TODO: Something wrong with left padding or right padding. Should be symmetric. x = tbText1.right + 5 * MM tbText2 = newTextBox(fs, parent=page, x=x, y=tbText1.y, h=tbText1.h, w=page.w - x - rightPadding) page.solve() # Make blurb text about design and typography. specText = blurb.getBlurb('article', noTags=True) + ' ' + blurb.getBlurb( 'article', noTags=True) fs = newFS(specText, style=dict(font=bookName, textFill=0, fontSize=8.5, tracking=0, rTracking=rt, leading=10, hyphenation='en')) x = tbText1.left tbText3 = newTextBox(fs, parent=page, x=x, h=64 * MM, w=page.w - x - rightPadding, mt=10 * MM, conditions=[Float2TopLeft()]) # TODO: Add red captions here. # Red label on the left fs = newFS(labelFont.info.styleName.upper(), style=dict(font=boldName, textFill=paperColor, fontSize=fontNameSize, tracking=0, rTracking=0.3)) tw, th = textSize(fs) # TODO: h is still bit of a guess with padding and baseline position. Needs to be solved more structured. tbName = newTextBox(fs, parent=page, h=capHeight + 3 * padding[0], w=tw + 2 * padding[1], conditions=[Right2RightSide()], fill=redColor, padding=padding) tbName.top = page.h - RedBoxY # Page number fs = newFS( ` pn `, style=dict(font=bookName, fontSize=pageNumberSize, textFill=redColor, xTextAlign=RIGHT, rTracking=rt, leading=8)) tbPageNumber = newTextBox(fs, parent=page, x=page.w - rightPadding - 10 * MM, w=10 * MM) tbPageNumber.bottom = 20 * MM # ----------------------------------------------------------------------------------- # Page 4, 3 columns. pn += 1 page = doc[pn] # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding # Fill with paper color # TODO: Just background color could be part of page fill instead of extra element. newRect(z=-1, parent=page, conditions=[Fit2Sides()], fill=paperColor) x = leftPadding # Make blurb text about design and typography. specText = blurb.getBlurb('article', noTags=True) + ' ' + blurb.getBlurb( 'article', noTags=True) fs = newFS(specText, style=dict(font=bookName, textFill=0, fontSize=10.5, tracking=0, rTracking=rt, leading=10, hyphenation='en')) # TODO: Something wrong with left padding or right padding. Should be symmetric. tbText1 = newTextBox(fs, parent=page, x=x, h=55 * MM, w=page.w - x - page.pl, conditions=[Top2Top()]) page.solve() # Make blurb text about design and typography. specText = blurb.getBlurb('article', noTags=True) + ' ' + blurb.getBlurb( 'article', noTags=True) fs = newFS(specText, style=dict(font=bookName, textFill=0, fontSize=10.5, tracking=0, rTracking=rt, leading=11, hyphenation='en')) # TODO: Something wrong with left padding or right padding. Should be symmetric. newTextBox(fs, parent=page, mt=5 * MM, x=x, h=60 * MM, w=page.w - x - page.pl, conditions=[Float2Top()]) page.solve() # Make blurb text about design and typography. specText = blurb.getBlurb('article', noTags=True) + ' ' + blurb.getBlurb( 'article', noTags=True) fs = newFS(specText, style=dict(font=bookName, textFill=0, fontSize=10.5, tracking=0, rTracking=rt, leading=12, hyphenation='en')) # TODO: Something wrong with left padding or right padding. Should be symmetric. newTextBox(fs, parent=page, mt=5 * MM, x=x, h=65 * MM, w=page.w - x - page.pl, conditions=[Float2Top()]) page.solve() # TODO: Add red captions here. # Red label on the right fs = newFS('10.5pt', style=dict(font=boldName, textFill=paperColor, fontSize=fontNameSize, tracking=0, rTracking=0.3)) tw, th = textSize(fs) # TODO: h is still bit of a guess with padding and baseline position. Needs to be solved more structured. tbName = newTextBox(fs, parent=page, h=capHeight + 3 * padding[0], w=tw + 2 * padding[1], conditions=[Left2LeftSide()], fill=redColor, padding=padding) tbName.top = page.h - RedBoxY # Page number, even on left side. fs = newFS( ` pn `, style=dict(font=bookName, fontSize=pageNumberSize, textFill=redColor, xTextAlign=LEFT, rTracking=rt, leading=8)) tbPageNumber = newTextBox(fs, parent=page, x=leftPadding, w=10 * MM) tbPageNumber.bottom = 20 * MM # ----------------------------------------------------------------------------------- # Page 5, 2 columns. pn += 1 page = doc[pn] # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding # Fill with paper color # TODO: Just background color could be part of page fill instead of extra element. newRect(z=-1, parent=page, conditions=[Fit2Sides()], fill=paperColor) # Make blurb text about design and typography. specText = blurb.getBlurb('article', noTags=True) + ' ' + blurb.getBlurb( 'article', noTags=True) fs = newFS(specText, style=dict(font=bookName, textFill=0, fontSize=12.5, tracking=0, rTracking=rt, leading=12, hyphenation='en')) newTextBox(fs, parent=page, x=x, h=64 * MM, w=page.w - page.pl - rightPadding, mt=10 * MM, conditions=[Top2Top(), Left2Left()]) # Make blurb text about design and typography. specText = blurb.getBlurb('article', noTags=True) + ' ' + blurb.getBlurb( 'article', noTags=True) fs = newFS(specText, style=dict(font=bookName, textFill=0, fontSize=12.5, tracking=0, rTracking=rt, leading=13, hyphenation='en')) newTextBox(fs, parent=page, x=x, h=64 * MM, w=page.w - page.pl - rightPadding, mt=10 * MM, conditions=[Float2TopLeft()]) # TODO: Add red captions here. # Red label on the left fs = newFS(labelFont.info.styleName.upper(), style=dict(font=boldName, textFill=paperColor, fontSize=fontNameSize, tracking=0, rTracking=0.3)) tw, th = textSize(fs) # TODO: h is still bit of a guess with padding and baseline position. Needs to be solved more structured. tbName = newTextBox(fs, parent=page, h=capHeight + 3 * padding[0], w=tw + 2 * padding[1], conditions=[Right2RightSide()], fill=redColor, padding=padding) tbName.top = page.h - RedBoxY # Page number fs = newFS( ` pn `, style=dict(font=bookName, fontSize=pageNumberSize, textFill=redColor, xTextAlign=RIGHT, rTracking=rt, leading=8)) tbPageNumber = newTextBox(fs, parent=page, x=page.w - rightPadding - 10 * MM, w=10 * MM) tbPageNumber.bottom = 20 * MM # Solve remaining layout and size conditions. score = doc.solve() if score.fails: print 'Condition fails', score.fails return doc # Answer the doc for further doing.
def draw(self, orgX, orgY): if not self.show: return w = self.w # Width of the icon h = self.ih # Height of the icon e = self.E * self.scale # Ear size l = self.L * self.scale # Line x = self.x + orgX y = self.y + orgY path = newPath() moveTo((0, 0)) lineTo((0, h)) lineTo((w - e, h)) lineTo((w, h - e)) lineTo((w, 0)) lineTo((0, 0)) closePath() moveTo((w - e, h)) lineTo((w - e, h - e)) lineTo((w, h - e)) save() fill(1) stroke(0) strokeWidth(self.line) translate(x, y) drawPath(path) labelSize = e fs = newFS(self.c, style=dict(font=self.f.installedName, textFill=0, fontSize=h * 2 / 3)) tw, th = textSize(fs) text(fs, (w / 2 - tw / 2, h / 2 - th / 3.2)) if self.title: fs = newFS(self.title, style=dict(font=self.labelFont.installedName, textFill=0, rTracking=self.LABEL_RTRACKING, fontSize=labelSize)) tw, th = textSize(fs) text(fs, (w / 2 - tw / 2, self.ih + th / 2)) y = -self.LABEL_RLEADING * labelSize if self.name: fs = newFS(self.name, style=dict(font=self.labelFont.installedName, textFill=0, rTracking=self.LABEL_RTRACKING, fontSize=labelSize)) tw, th = textSize(fs) text(fs, (w / 2 - tw / 2, y)) y -= self.LABEL_RLEADING * labelSize if self.label: fs = newFS(self.label, style=dict(font=self.labelFont.installedName, textFill=0, rTracking=self.LABEL_RTRACKING, fontSize=labelSize)) tw, th = textSize(fs) text(fs, (w / 2 - tw / 2, y)) restore()
def typesetNode(self, node, e=None): u"""Recursively typeset the etree *node*, using a reference to element *e* or the cascading *style*. If *e* is None, then the tag style is merged on top of the doc.rootStyle. If *e* is defined, then rootstyle of the stack starts with an empty dictionary, leaving root searching for the e.parent path.""" # Fills self.codeBlocks dictionary from node codeblocks. # Side effect is to update self.doc, self.page and self.box cid, codeResult = self.runCodeBlock(node) #if codeResult is not None: # return # Open the node in HTML export for this node self.htmlNode(node) # Add this tag to the tag-history line self.addHistory(node.tag) # If e is undefined, then we make sure that the stack contains the doc.rootStyle on top. # If e is defined then root queries for style should follow the e.parent path. if self.peekStyle() is None and e is not None: # Root of stack is empty style, to force searching on the e.parent line. self.pushStyle({}) # Define top level for styles. nodeStyle = self.getNodeStyle( node.tag) # Merge found tag style with current top of stack self.pushStyle(nodeStyle) # Push this merged style on the stack # XML-nodes are organized as: node - node.text - node.children - node.tail # If there is no text or if the node does not have tail text, these are None. # Still we want to be able to add the prefix to the node.text, so then the text is changed to an empty string. nodeText = self._strip(node.text) if nodeText: # Not None and still has content after stripping? fs = newFS(nodeText, e, nodeStyle) self.appendString(fs) self.appendHtml( nodeText ) # Export the plain text as parallel HTML output as well. # Type set all child node in the current node, by recursive call. for child in node: hook = 'node_' + child.tag # Method will handle the styled body of the element, but not the tail. if hasattr(self, hook): # There is a hook for this node, let this method do the work. getattr(self, hook)(child, e) # Hook must be able to derive styles from e. # We are in tail mode now, but we don't know what happened in the child block. else: # If no method hook defined, then just solve recursively. Child node will get the style. self.typesetNode(child, e) # XML-nodes are organized as: node - node.text - node.children - node.tail # If there is no text or if the node does not have tail text, these are None. # Still we want to be able to add the postfix to the tail, so then the tail is changed # to empty string? childTail = child.tail #self._strip(child.tail, postfix=self.getStyleValue('postfix', e, nodeStyle, '')) if childTail: # Any tail left after stripping, then append to the galley. fs = newFS(childTail, e, nodeStyle) self.appendString(fs) self.appendHtml( childTail ) # Export the plain text as parallel HTML output as well. # Close the HTML tag of this node. self._htmlNode(node) # Now restore the graphic state at the end of the element content processing to the # style of the parent in order to process the tail text. Back to the style of the parent, # which was in nodeStyle. self.popStyle() """
def makeDocument(): u"""Create Document instance with a single page. Fill the page with elements and perform a conditional layout run, until all conditions are solved.""" bookName = findFont(('Book', 'Regular')) # Find these styles in order. mediumName = findFont(('Medium', 'Book', 'Regular')) boldName = findFont(('Bold', 'Medium')) doc = Document(w=PageWidth, h=PageHeight, originTop=False, autoPages=1) # Get default view from the document and set the viewing parameters. view = doc.getView() view.style['fill'] = 1 view.padding = 0 # To show cropmarks and such, make >40 or so. view.showPageCropMarks = True # Won't show if there is not padding in the view. view.showPageRegistrationMarks = True view.showPageFrame = True view.showPageNameInfo = True view.showElementOrigin = False view.showElementDimensions = False #ShowDimensions view.showElementInfo = False page = doc[0] # Get the single frint page from the document. # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding pageAreaW = PageWidth - pl - pr pageAreaH = PageHeight - pt - pb # Resources blockFill = None #(1, 1, 0) # Use color to debug page area gradient = Gradient(locations=[1, 0], colors=((0.3, 0.3, 0.3), (0.6, 0.6, 0.6))) shadow = Shadow(offset=(6, -6), blur=10, color=(0.2, 0.2, 0.2, 0.5)) bookBorders = dict(stroke=(1, 1, 1, 0.5), strokeWidth=0.1, line=OUTLINE) bookPadding = (25, 30, 40, 30) # Styles titleStyle = dict(font=bookName, fontSize=26, rLeading=1.4, xTextAlign=CENTER, textFill=1) authorStyle = dict(font=bookName, textFill=1, fontSize=18, xTextAlign=CENTER) headStyle = dict(font=boldName, textFill=0, fontSize=62, rLeading=1.4, xTextAlign=LEFT, paragraphTopSpacing=30, openTypeFeatures=dict(liga=True), paragraphBottomSpacing=0) bodyStyle = dict(font=bookName, textFill=0, fontSize=12, rLeading=1.4, xTextAlign=LEFT, paragraphTopSpacing=10, hyphenation=True) # Make new container for adding elements inside with alignment. newRect(z=10, w=pageAreaW, h=pageAreaH, fill=blockFill, parent=page, margin=0, padding=0, yAlign=MIDDLE, maxW=pageAreaW, maxH=pageAreaH, xAlign=CENTER, conditions=(Center2Center(), Middle2Middle())) t1 = newTextBox('PageBot Educational Series', z=0, font=bookName, fontSize=42, w=pageAreaW * 0.75, parent=page, conditions=(Left2Left(), Top2Top())) w = pageAreaW * 0.75 # Used as element width and relative font size. padding = 24 t2 = newTextBox('Hot metal typesetting', z=0, font=mediumName, fontSize=w / 8, w=pageAreaW, parent=page, mt=14, conditions=(Left2Left(), Float2Top())) i1 = newRect(z=0, h=PageHeight / 2, pl=padding, pr=padding, gradient=gradient, borders=None, parent=page, conditions=(Fit2Width(), Float2Top(), Fit2Bottom())) i1.solve() fs = newFS(topT, style=bodyStyle) fs += newFS('\nPrepare for what comes next.', style=bookName) topText = newTextBox(fs, w=w / 3 - 16, parent=page, conditions=(Top2Top(), Right2Right())) # Review content. Hard coded ligatures. t = u'This is an example of hot metal typesetting, where every letter had a fixed shape and its own width as rectangular box.\nVariable Fonts could adjust, fit and decorate letters where it is most needed in a column of text. Not in this example.' fs = newFS(t, style=headStyle) t4 = newTextBox(fs, w=w / 2 - G, mt=10, parent=i1, gradient=None, drawBefore=drawBefore, conditions=(Fit2Width(), Float2Top())) # Font names if 'Proforma' in bookName or 'Productus' in bookName: fontNamesFeatures = 'Example featuring typefaces TypeNetwork TYPETR Productus and Proforma' else: fontNamesFeatures = 'Example featuring OSX system fonts %s' % ', '.join( sorted(set((bookName, mediumName, boldName)))) fs = newFS(fontNamesFeatures, style=dict(font=bookName, fontSize=14, textFill=0)) t5 = newTextBox(fs, w=w / 2 - G, mt=10, parent=page, gradient=None, conditions=(Fit2Width(), Float2Top())) score = page.solve() if score.fails: print 'Condition fails', score.fails return doc # Answer the doc for further doing.
print len(bitpaths) print len(bitcounts) for c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz': newPage(2400, 300) fonts = bitpaths + bitcounts print len(fonts) shuffle(fonts) for name in fonts: #if not 'Double' in name: # continue if not 'Single' in name: continue if not 'Mono' in name: continue fs = newFS( 'Claire Lindsey', style=dict( font=name, fontSize=200, openTypeFeatures=dict(ss01=True, ss02=True, ss03=True), tracking=40, #textFill=None, textFill=(random(), random(), random(), 0.1), textStroke=(random(), random(), random()), textStrokeWidth=0.5, )) text(fs, (50, 100)) saveImage('_export/CompareBitpath2Bitcount.pdf')
def makeDocument(): u"""Create Document instance with a single page. Fill the page with elements and perform a conditional layout run, until all conditions are solved.""" doc = Document(w=PageWidth, h=PageHeight, originTop=False, autoPages=1) # Get default view from the document and set the viewing parameters. view = doc.getView() view.style['fill'] = 1 view.padding = 40 # To show cropmarks and such, make >40 or so. view.showPageCropMarks = True # Won't show if there is not padding in the view. view.showPageRegistrationMarks = True view.showPageFrame = True view.showPageNameInfo = True view.showElementOrigin = False view.showElementDimensions = False #ShowDimensions view.showElementInfo = False page = doc[0] # Get the single frint page from the document. # Hard coded padding, just for simple demo, instead of filling padding an columns in the root style. page.margin = 0 page.padding = pagePadding pageAreaW = PageWidth-pl-pr pageAreaH = PageHeight-pt-pb # Resources blockFill = None #(1, 1, 0) # Use color to debug page area gradient = Gradient(locations=[1,0], colors=((0, 0, 0), (0.8, 0.8, 0.8))) shadow = Shadow(offset=(6, -6), blur=10, color=(0.2, 0.2, 0.2, 0.5)) bookBorders = dict(stroke=(1, 1, 1, 0.5),strokeWidth=0.1,line=OUTLINE) bookPadding = (25, 30, 40, 30) # Styles titleStyle =dict(font='Georgia', fontSize=26, rLeading=1.4, xTextAlign=CENTER, textFill=1) authorStyle = dict(font='Georgia-Italic', textFill=1, fontSize=18, xTextAlign=CENTER) headStyle = dict(font='Verdana-Bold', textFill=0, fontSize=14, rLeading=1.4, xTextAlign=LEFT, paragraphTopSpacing=30, paragraphBottomSpacing=0) bodyStyle = dict(font='Verdana', textFill=0, fontSize=12, rLeading=1.4, xTextAlign=LEFT, paragraphTopSpacing=10, hyphenation=True) sideBarStyle = dict(font='Verdana', textFill=0, fontSize=10, rLeading=1.4, xTextAlign=LEFT, paragraphTopSpacing=10, hyphenation=True) italicBodyStyle = copy.copy(bodyStyle) italicBodyStyle['font'] = 'Verdana-Italic' italicBodyStyle['paragraphTopSpacing'] = 0 # Make new container for adding elements inside with alignment. newRect(z=10, w=pageAreaW, h=pageAreaH, fill=blockFill, parent=page, margin=0, padding=0, yAlign=MIDDLE, maxW=pageAreaW, maxH=pageAreaH, xAlign=CENTER, conditions=(Center2Center(), Middle2Middle())) t1 = newTextBox('The PageBot Times', z=0, font='BlackmoorLetPlain', fontSize=40, w=pageAreaW/2, parent=page, conditions=(Left2Left(), Top2Top())) w = pageAreaW*0.75 # Used as element width and relative font size. padding = PageHeight/24 t2 = newTextBox('Book Review', z=0, font='NewOdanaLarge-Black', fontSize=w/7, w=PageWidth*0.75, parent=page, conditions=(Left2Left(), Float2Top())) i1 = newRect(z=0, h=PageHeight/2, padding=padding, gradient=gradient, borders=None, parent=page, conditions=(Fit2Width(), Float2Top())) i1.solve() m = i1.h/10 # Book 1 cover book1 = newRect(z=0, margin=m, w=(i1.w-3*m)/2, fill=(0.05, 0.05, 0.25), gradient=None, parent=i1, shadow=shadow, padding=bookPadding, conditions=(Fit2Height(), Top2Top(), Left2Left()), borders=bookBorders) fs = newFS('Educational series', style=authorStyle) fs += newFS('\n\nThrilling title\nfor my first book\nabout Design', style=titleStyle) fs += newFS('\n'*3 + 'John Smith', style=authorStyle) frame = newRect(margin=6, conditions=(Fit(),), title1 = newTextBox(fs, parent=book1, shadow=None, conditions=(Fit2Width(), Center2Center(), Top2Top()))) fs = newFS(u'¶', style=authorStyle) publisher1 = newTextBox(fs, parent=book1, shadow=None, conditions=(Fit2Width(), Bottom2Bottom())) # Book 2 cover book2 = newRect(z=0, margin=m, w=(i1.w-3*m)/2, fill=(0.1, 0.2, 0.45), gradient=None, parent=i1, shadow=shadow, padding=bookPadding, conditions=(Fit2Height(), Top2Top(), Right2Right()), borders=bookBorders) fs = newFS('Educational series', style=authorStyle) fs += newFS('\n\nPredictable title of my second book about Typography', style=titleStyle) fs += newFS('\n'*3 + 'John Smith', style=authorStyle) title2 = newTextBox(fs, parent=book2, marginTop=120, shadow=None, conditions=(Fit2Width(), Center2Center(), Top2Top())) fs = newFS(u'¶', style=authorStyle) publisher2 = newTextBox(fs, parent=book2, shadow=None, conditions=(Fit2Width(), Bottom2Bottom())) bottomContainer = newRect(parent=page, w=w, borderBottom=dict(strokeWidth=1), padding=0, conditions=(Left2Left(), Float2Top(), Fit2Bottom())) t3 = newTextBox('Reviewing 2017 score', z=0, font='BodoniSvtyTwoOSITCTT-Book', fontSize=w/8.5+3, w=w, stroke=NO_COLOR, pb=16, borderBottom=dict(strokeWidth=1), parent=bottomContainer, conditions=(Fit2Width(), Float2Top()), mt=20) # Review content fs = newFS('About the thrilling title\n', style=headStyle) fs += newFS(t, style=bodyStyle) t4 = newTextBox(fs, w=w/2-G, mt=10, parent=bottomContainer, conditions=(Left2Left(), Float2Top())) fs = newFS('Second column\n', style=headStyle) fs += newFS(t, style=bodyStyle) t5 = newTextBox(fs, w=w/2-G, mt=10, parent=bottomContainer, conditions=(Float2Right(), Float2Top())) # Text box on bottom right fs = newFS('This is a funny head.\n', style=headStyle) fs += newFS(t+t, style=sideBarStyle) t6 = newTextBox(fs, w=w/3-16, pt=34, parent=page, conditions=(Float2Right(), Float2Top(), Fit2Bottom())) fs = newFS(topT, style=bodyStyle) fs += newFS('\nAn addition italic line', style=italicBodyStyle) topText = newTextBox(fs, w=w/3-16, parent=page, conditions=(Top2Top(), Right2Right())) score = page.solve() if score.fails: print 'Condition fails', score.fails return doc # Answer the doc for further doing.