def newDocument(self, w, h, units='pt'): """Create a new document. Store the (w, h) for the moment that pages are created.""" self.w = w self.h = h self.margin = 36 self.units = units # Creates a new document without showing the document window. The # first parameter (showingWindow) controls the visibility of the # document. Hidden documents are not minimized and will not appear # until you add a new window to the document. if self.title: self.comment('--- %s ---' % (self.title or 'Untitled')) self.addJs( 'var currentDocument = app.documents.add(%s);' % str(self.openDocument).lower()) # Make document in background self.addJs('var currentElement;') # Storage of current parent element #self.comment('-'*60) self.addJs('with(currentDocument.documentPreferences){') self.addJs(' pageWidth = "%s%s";' % (asFormatted(h), self.units)) self.addJs(' pageHeight = "%s%s";' % (asFormatted(w), self.units)) self.addJs(' pageOrientation = PageOrientation.%s;' % { False: 'landscape', True: 'portrait' }[w > h]) #self.addJs(' pagesPerDocument = %d;' % pageCount) self.addJs('}') self.addJs('var currentPage = currentDocument.pages.item(0);') self.addJs('var currentTextFrames = currentPage.textFrames;')
def buildTextBox(self, s1, s2, origin, x, y, w, h, fontSize, alignment=None, labelSize=None, label=None, Bwght=0, Bwdth=0, Rwght=0, Rwdth=0, useOpsz=True): """Makes a new instance for the bold and roman locations (if self.f is a Variable Font). Draws a textbox fitting the content ot otherwise forced to (w,h) size. Answers the (x, y) position of the next stacked block. If labelSize defined then show the defaul label: Font family name fontSize/leading. If label is defined, then use that label in the defined font font size. """ c = self.context ox, oy, _ = origin if useOpsz: # Using [opsz] then set to fontSize opsz = fontSize else: opsz = None # Otherwise ignore. # Construct the location location = self.getLocation(opsz=opsz) instance = self.getInstance(location) # Get Roman for labels, using default axis values. # Labels by default in default roman, showing font family name, fontSize and rounded leading. style = self.getTextStyle(instance, labelSize or self.DEFAULT_LABEL_SIZE, LEFT, 0.8) if labelSize is not None and label is None: label = '%s %s/%s\n\n' % (self.f.info.familyName, asFormatted(fontSize), asFormatted(self.css('leading', 0), format='%0.1f')) bs = c.newString(label or '', style=style) # Create BabelString/FormattedString if content. if s1: # In case s1 lead is defined, then use that for the bold version of # self.f Construct the location. location = self.getLocation(wght=Bwght, wdth=Bwdth, opsz=opsz) instance = self.getInstance(location) style = self.getTextStyle(instance, fontSize, alignment) bs += c.newString((s1 or '')+' ', style=style) # Create BabelString/FormattedString if content. # Make Roman style. Use font size of [opsz] axis, if it exists. # Construct the location location = self.getLocation(wght=Rwght, wdth=Rwdth, opsz=opsz) instance = self.getInstance(location) style = self.getTextStyle(instance, fontSize, alignment) # Add roman formatted string to what we already had. bs += c.newString(s2, style=style) # Get the text height for the request width. tw, th = bs.textSize(w=w) c.textBox(bs, (ox+x, oy+y-(h or th)-self.gh, w, h or th)) # Use h if defined, otherwise text height. # Answer the new position (x, y) for the next block, using self.gh # (gutter height) as distance. return x, y-(h or th)-self.gh
def _getCSV(self): csv = [] line = [self.familyName] lineName = ['Name'] lineMin = ['Minimum'] lineDef = ['Default'] lineMax = ['Maximum'] # Axis tags columns and some more for axis in self.axisList: line.append(axis.tag) lineName.append(axis.name) lineMin.append(asFormatted(axis.minimum)) lineDef.append(asFormatted(axis.default)) lineMax.append(asFormatted(axis.maximum)) line.append('name') line.append('path') line.append('copy') csv.append('\t'.join(line)) csv.append('[AXES]') csv.append('\t'.join(lineName)) csv.append('\t'.join(lineMin)) csv.append('\t'.join(lineDef)) csv.append('\t'.join(lineMax)) # Add master info csv.append('[MASTERS]') for master in self.masterList: lineMaster = [master.styleName] for axis in self.axisList: if axis.tag in master.location: lineMaster.append(asFormatted(master.location[axis.tag])) else: lineMaster.append('') lineMaster.append(master.name) lineMaster.append(master.path.split('/')[-1]) if master.info and master.info.get('copy'): lineMaster.append('True') csv.append('\t'.join(lineMaster)) # Add instances csv.append('[INSTANCES]') return '\n'.join(csv)
def _drawElementsNeedingInfo(self, e): b = self.b context = self.context for e, origin in self.elementsNeedingInfo.values(): p = pointOffset(e.origin, origin) p = e._applyScale(self, p) px, py, _ = e._applyAlignment(p) # Ignore z-axis for now. if (self.showElementInfo or e.isPage) or e.showElementInfo: # Draw box with element info. bs = context.newString( e.getElementInfoString(), style=dict(font=self.css('viewInfoFont'), fontSize=self.css('viewInfoFontSize'), leading=self.css('viewInfoLeading'), textFill=color(0.1))) tw, th = bs.size 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 context.fill(color(0.3, 0.3, 0.3, 0.5)) context.stroke(noColor) context.rect(tpx + Pd / 2, tpy, tw + 2 * Pd, th + 1.5 * Pd) # Frame context.fill(self.css('viewInfoFill')) context.stroke(color(0.3), w=0.25) context.rect(tpx, tpy, tw + 2.5 * Pd, th + 1.5 * Pd) context.text(bs, (tpx + Pd, tpy + th)) if (self.showDimensions or e.isPage) or e.showDimensions: # TODO: Make separate arrow functio and better positions # Draw width and height measures context.fill(noColor) context.stroke(blackColor, w=pt(0.25)) S = self.css('viewInfoOriginMarkerSize', pt(5)) x1, y1, x2, y2 = px + e.left, py + e.bottom, e.right, e.top # Horizontal measure context.line((x1, y1 - 0.5 * S), (x1, y1 - 3.5 * S)) context.line((x2, y1 - 0.5 * S), (x2, y1 - 3.5 * S)) context.line((x1, y1 - 2 * S), (x2, y1 - 2 * S)) # Arrow heads context.line((x1, y1 - 2 * S), (x1 + S, y1 - 1.5 * S)) context.line((x1, y1 - 2 * S), (x1 + S, y1 - 2.5 * S)) context.line((x2, y1 - 2 * S), (x2 - S, y1 - 1.5 * S)) context.line((x2, y1 - 2 * S), (x2 - S, y1 - 2.5 * S)) bs = context.newString( asFormatted(x2 - x1), style=dict(font=self.css('viewInfoFont'), fontSize=self.css('viewInfoFontSize'), leading=self.css('viewInfoLeading'), textFill=color(0.1))) tw, th = bs.size context.text(bs, ((x2 + x1) / 2 - tw / 2, y1 - 1.5 * S)) # Vertical measure context.line((x2 + 0.5 * S, y1), (x2 + 3.5 * S, y1)) context.line((x2 + 0.5 * S, y2), (x2 + 3.5 * S, y2)) context.line((x2 + 2 * S, y1), (x2 + 2 * S, y2)) # Arrow heads context.line((x2 + 2 * S, y2), (x2 + 2.5 * S, y2 - S)) context.line((x2 + 2 * S, y2), (x2 + 1.5 * S, y2 - S)) context.line((x2 + 2 * S, y1), (x2 + 2.5 * S, y1 + S)) context.line((x2 + 2 * S, y1), (x2 + 1.5 * S, y1 + S)) bs = context.newString( asFormatted(y2 - y1), style=dict(font=self.css('viewInfoFont'), fontSize=self.css('viewInfoFontSize'), leading=self.css('viewInfoLeading'), textFill=0.1)) tw, th = bs.size context.text(bs, (x2 + 2 * S - tw / 2, (y2 + y1) / 2)) e._restoreScale(self)
def __repr__(self): return '<%s %s min=%s def=%s max=%s>' % (self.__class__.__name__, self.tag, asFormatted(self.minimum), asFormatted(self.default), asFormatted(self.maximum))
def __repr__(self): return 'Cmp(%s, %s, %s)' % (self.baseGlyph, asFormatted(self.x), asFormatted(self.y))
def __init__(self, f, showLabel=True, labelSize=7, sampleText=None, factor=0.9, location=None, useOpsz=True, **kwargs): """ >>> from pagebot.fonttoolbox.objects.font import findFont >>> from pagebot.document import Document >>> from pagebot.constants import Letter, RIGHT >>> from pagebot.contexts.drawbotcontext import DrawBotContext >>> from pagebot.conditions import * >>> from pagebot.toolbox.color import color >>> c = DrawBotContext() >>> w, h = Letter >>> doc = Document(w=w, h=h, padding=80, originTop=False, autoPages=2, context=c) >>> style = dict(fill=color(0.95), leading=em(1.3), fontSize=48, xTextAlign=RIGHT) >>> conditions = [Fit()] # FIX: Does not seem to work for TextBox >>> page = doc[1] >>> font1 = findFont('AmstelvarAlpha-VF') >>> loc = dict(wght=1) >>> useOpsz = False >>> page.pw, page.w, 500 (6.28", 8.50", 500) >>> gs = Waterfall(font1, parent=page, conditions=conditions, padding=20, style=style, w=page.pw, h=page.ph, location=loc, useOpsz=useOpsz, context=c) >>> style = dict(stroke=0, strokeWidth=0.25, leading=em(1.3), fontSize=48, xTextAlign=RIGHT) >>> page = doc[2] >>> font2 = findFont('RobotoDelta-VF') >>> #font2 = findFont('Upgrade-Regular') >>> #font2 = findFont('Escrow-Bold') >>> gs = Waterfall(font2, parent=page, conditions=conditions, style=style, w=page.pw, h=page.ph, padding=20, location=loc, useOpsz=useOpsz, context=c) >>> #score = doc.solve() >>> doc.export('_export/%sWaterfall_opsz_%s.pdf' % (font1.info.familyName, useOpsz)) TODO: Make self.css('xTextAlign') work for CENTER """ TextBox.__init__(self, **kwargs) c = self.context self.useOpsz = useOpsz # Only for the sample lines. Labels always have opsz. self.f = f if not location: location = {} self.factor = factor # Decreasing multiplication factor for fontSize style = self.style.copy() labelStyle = self.style.copy() labelStyle['font'] = self.getInstance(f, dict(opsz=labelSize)).path labelStyle['fontSize'] = labelSize labelStyle['leading'] = em(1) w = self.pw # Initial with to fit top sample location['opsz'] = None style['font'] = self.getInstance(self.f, self.getLocation(self.f, location)).path sampleText = sampleText or self.SAMPLE matchingLine = c.newString(sampleText + '\n', style=style, w=w) style['fontSize'] = fontSize = matchingLine.fittingFontSize // 8 * 8 bs = c.newString('', style=style) while fontSize >= 12: # Still fitting? Otherwise stop the loop # TODO: Measure both lines (label + samleText) for fitting. tw, th = bs.size if th > self.ph: break # Make the optional label if showLabel: label = '%s %spt | opsz = %s\n' % ( self.f.info.familyName, asFormatted(fontSize, '%0.1f'), self.useOpsz) bs += c.newString(label, style=labelStyle) style['fontSize'] = fontSize = int(round(fontSize * self.factor)) location['opsz'] = {True: fontSize, False: None}[self.useOpsz] style['font'] = self.getInstance( self.f, self.getLocation(self.f, location)).path bs += c.newString(sampleText + '\n', style=style) self.bs = bs