class MathSubSuperscript(MultiItem): """An item with a subscript""" def __init__(self, base, subscript = None, superscript = None): MultiItem.__init__(self) self.appendItem(base) self.base = base self.subscript = subscript self.superscript = superscript if subscript: subscript.scaleFont(0.8) self.appendItem(subscript) if superscript: superscript.scaleFont(0.8) self.appendItem(superscript) def resizePDF(self, pdf, x = 0, y = 0): self.resizeItemsPDF(pdf, x, y) dx = pdf.get_string_width(' ') * self.style[1] self.rect = Rect(x,y,x,y) h = self.base.rect.height() w = self.base.rect.width() + dx if self.subscript: self.subscript.rect.translate(w, h*0.5) self.rect.unite(self.subscript.rect) if self.superscript: self.superscript.rect.translate(w, - h*0.5) self.rect.unite(self.superscript.rect) self.refit()
class MathPower(MultiItem): """Container for inline maths""" def __init__(self): MultiItem.__init__(self) self.style = 'math-var', 1 def resizePDF(self, pdf, x = 0, y = 0): if len(self.items) < 2 or not self.items[0] or not self.items[1]: raise Exception('MathPower must have two items.') self.rect = Rect(x,y,x,y) dx = pdf.get_string_width(' ') * self.style[1] base = self.items[0] if hasattr(base,'style'): setFontPDF(pdf, base.style, self.styles) base.resizePDF(pdf,x,y) index = self.items[1] index.scaleFont(0.8) if hasattr(index,'style'): setFontPDF(pdf, index.style, self.styles) index.resizePDF(pdf, base.rect.x1() + dx, y - base.rect.height() * 0.4) self.rect.unite(base.rect) self.rect.unite(index.rect) self.refit()
class InlineMathBlock(MultiItem): """Container for inline maths""" def __init__(self, *items): MultiItem.__init__(self) self.style = ('math-var',1) for item in items: self.appendItem(item) def resizePDF(self, pdf, x = 0, y = 0): self.rect = Rect(x,y,x,y) dx = pdf.get_string_width(' ') dx *= self.style[1] rectList = [] width = 0.0 style = '' for item in self.items: if item: if hasattr(item,'style') and item.style != style: setFontPDF(pdf, item.style, self.styles) item.resizePDF(pdf,x,y) rectList.append(item.rect) width += item.rect.width() + dx rect.alignLeft(rectList, x, x+width, dx) for r in rectList: self.rect.unite(r) self.refit()
class MathFrac(MultiItem): """Container for inline maths""" def __init__(self, num = None, denom = None): MultiItem.__init__(self) self.style = 'math-var', 1 if num: if not denom: denom = MathNumber('1') self.appendItem(num) self.appendItem(denom) def resizePDF(self, pdf, x = 0, y = 0): if len(self.items) < 2 or not self.items[0] or not self.items[1]: raise Exception('MathFrac must have two items.') self.rect = Rect(x,y,x,y) dx = pdf.get_string_width(' ') * self.style[1] self.margins.set(dx, 0.0) setFontPDF(pdf, self.style, self.styles) lineHeight = pdf.font_size_pt / pdf.k numerator = self.items[0] if hasattr(numerator,'style'): setFontPDF(pdf, numerator.style, self.styles) numerator.resizePDF(pdf,x + dx, y - lineHeight * 0.5) denominator = self.items[1] if hasattr(denominator,'style'): setFontPDF(pdf, denominator.style, self.styles) denominator.resizePDF(pdf, x + dx, numerator.rect.y1()) if numerator.rect.width() > denominator.rect.width(): denominator.rect.alignXCenter(numerator.rect) else: numerator.rect.alignXCenter(denominator.rect) self.rect.unite(numerator.rect) self.rect.unite(denominator.rect) self.rect.adjust(rect.Point(0,0),rect.Point(dx,0)) def cellPDF(self, pdf, r = None): MultiItem.cellPDF(self, pdf, r) y = self.items[0].rect.y1() pdf.set_line_width(0.2) if r: x_shift = r.x0() y_shift = r.y0() else: x_shift = 0.0 y_shift = 0.0 pdf.line(self.rect.x0() - x_shift, y - y_shift, self.rect.x1() - x_shift, y - y_shift)
class MathColumn(MultiItem): """Container for inline maths""" def __init__(self, *items): MultiItem.__init__(self) self.style = ('math-var',1) for item in items: self.appendItem(item) def resizePDF(self, pdf, x = 0, y = 0): self.rect = Rect(x,y,x,y) for item in self.items: self.setFontPDF(pdf, item) item.resizePDF(pdf,x,y) item.rect.translate(0,self.rect.height()) self.rect.unite(item.rect) self.refit()
class MathBelowAndAbove(MultiItem): """Can have up to 3 items: first is placed inline with the text, if there is a second item it's placed below the first, if there is a third item it's placed above the first. """ def __init__(self,base = None, below = None, above = None): MultiItem.__init__(self) self.style = 'math-var', 1 if base: self.appendItem(base) if below: self.appendItem(below) if above: self.appendItem(above) else: if above: self.appendItem(None) self.appendItem(above) def resizePDF(self, pdf, x = 0, y = 0): if len(self.items) == 0: raise Exception('MathAboveAndBelow must have at least one item.') self.rect = Rect(x,y,x,y) base = self.items[0] self.setFontPDF(pdf, base) base.resizePDF(pdf,x,y) self.rect.unite(base.rect) if len(self.items) > 1 and self.items[1]: below = self.items[1] self.setFontPDF(pdf, below) below.resizePDF(pdf,x,y) below.rect.translate(0, base.rect.height()) below.rect.alignXCenter( base.rect ) self.rect.unite(below.rect) if len(self.items) > 2 and self.items[2]: above = self.items[2] self.setFontPDF(pdf, above) above.resizePDF(pdf,x,y) above.rect.translate(0, - above.rect.height()) above.rect.alignXCenter( base.rect ) self.rect.unite(above.rect) self.refit()