def wrap(self, availWidth, availHeight): """ If we need more width than we have, complain, keep a scale. """ self.pad = self.border_padding(True, 0.1) maxWidth = float(min( styles.adjustUnits(self.maxWidth, availWidth) or availWidth, availWidth)) self.maxWidth = maxWidth maxWidth -= (self.pad[1] + self.pad[3]) # Paragraphs always say they can fit, so check the dims instead dims = [] _listWrapOn(self.content, maxWidth, None, dims=dims) self.width, self.height = min(dims, key=lambda i: i[0]) if self.width > maxWidth: if self.mode != 'shrink': self.scale = 1.0 log.warning("BoundByWidth too wide to fit in frame (%s > %s): %s", self.width, maxWidth, self.identity()) if self.mode == 'shrink' and not self.scale: self.scale = ((maxWidth + self.pad[1] + self.pad[3]) / (self.width + self.pad[1] + self.pad[3])) else: self.scale = 1.0 self.height *= self.scale self.width *= self.scale return self.width, self.height + (self.pad[0] + self.pad[2]) * self.scale
def wrap(self, availWidth, availHeight): """If we need more width than we have, complain, keep a scale""" if self.style: bp = self.style.__dict__.get("borderPadding", 0) bw = self.style.__dict__.get("borderWidth", 0) if isinstance(bp,list): self.pad = [bp[0] + bw + .1, bp[1] + bw + .1, bp[2] + bw + .1, bp[3] + bw + .1] else: self.pad = [bp + bw + .1, bp + bw + .1, bp + bw + .1, bp + bw + .1] else: self.pad = [0,0,0,0] maxWidth = float(min( styles.adjustUnits(self.maxWidth, availWidth) or availWidth, availWidth)) self.maxWidth = maxWidth maxWidth -= (self.pad[1]+self.pad[3]) self.width, self.height = _listWrapOn(self.content, maxWidth, None) self.scale = 1.0 if self.width > maxWidth: if self.mode <> 'shrink': log.warning("BoundByWidth too wide to fit in frame (%s > %s): %s", self.width,maxWidth,self.identity()) if self.mode == 'shrink': self.scale = (maxWidth + self.pad[1]+self.pad[3])/\ (self.width + self.pad[1]+self.pad[3]) self.height *= self.scale return self.width, self.height + (self.pad[0]+self.pad[2])*self.scale
def split(self,aW,aH): dims = [] W,H = _listWrapOn(self._content,aW,self.canv,dims=dims) if self._state==0: if H<aH: return [flowables.Spacer(aW,aH-H)]+self._content else: S = self S._state = 1 return [self._makeBreak(aH), S] else: if H>aH: return self._content return [flowables.Spacer(aW,aH-H)]+self._content
def wrap(self, availWidth, availHeight): """If we need more width than we have, complain, keep a scale""" self.pad = self.border_padding(True, 0.1) maxWidth = float(min( styles.adjustUnits(self.maxWidth, availWidth) or availWidth, availWidth)) self.maxWidth = maxWidth maxWidth -= (self.pad[1]+self.pad[3]) self.width, self.height = _listWrapOn(self.content, maxWidth, None) if self.width > maxWidth: if self.mode <> 'shrink': self.scale = 1.0 log.warning("BoundByWidth too wide to fit in frame (%s > %s): %s", self.width,maxWidth,self.identity()) if self.mode == 'shrink' and not self.scale: self.scale = (maxWidth + self.pad[1]+self.pad[3])/\ (self.width + self.pad[1]+self.pad[3]) else: self.scale = 1.0 self.height *= self.scale self.width *= self.scale return self.width, self.height + (self.pad[0]+self.pad[2])*self.scale
def wrap(self, aW, aH): dims = [] W,H = _listWrapOn(self._content, aW, self.canv, dims=dims) self.height = H self.content_dims = dims return W, 0xffffff # force a split
def split(self,w,h): _w,_h=self.wrap(w, h) if _h > h: # Can't split! # The right column data mandates the split # Find which flowable exceeds the available height dw=self.colWidths[0]+self.padding[1]+self.padding[3] dh=self.padding[0]+self.padding[2] bullet=self.data[0][0] text=self.data[0][1] for l in range(0,len(text)): _,fh = _listWrapOn(text[:l+1],w-dw,None) if fh+dh > h: # The lth flowable is the guilty one # split it _,lh=_listWrapOn(text[:l],w-dw,None) # Workaround for Issue 180 text[l].wrap(w-dw,h-lh-dh) l2=text[l].split(w-dw,h-lh-dh) if l2==[]: # Not splittable, push some to next page if l==0: # Can't fit anything, push all to next page return l2 # We reduce the number of items we keep on the # page for two reasons: # 1) If an item is associated with the following # item (getKeepWithNext() == True), we have # to back up to a previous one. # 2) If we miscalculated the size required on # the first page (I dunno why, probably not # counting borders properly, but we do # miscalculate occasionally). Seems to # have to do with nested tables, so it might # be the extra space on the border on the # inner table. while l > 0: if not text[l-1].getKeepWithNext(): first_t = Table([ [bullet, text[:l]] ], colWidths=self.colWidths, style=self.style) _w,_h = first_t.wrap(w, h) if _h <= h: break l -= 1 if l>0: # Workaround for Issue 180 with wordaxe: #if wordaxe is not None: #l3=[Table([ #[bullet, #text[:l]] #], #colWidths=self.colWidths, #style=self.style), #Table([['',text[l:]]], #colWidths=self.colWidths, #style=self.style)] #else: l3=[first_t, SplitTable([['',text[l:]]], colWidths=self.colWidths, style=self.style, padding=self.padding)] else: # Everything flows l3=[] else: l3=[Table([[bullet,text[:l]+[l2[0]]]], colWidths=self.colWidths, rowHeights=[h], style=self.style)] if l2[1:]+text[l+1:]: ## Workaround for Issue 180 with wordaxe: #if wordaxe is not None: #l3.append( #Table([['',l2[1:]+text[l+1:]]], #colWidths=self.colWidths, #style=self.style)) #else: l3.append( SplitTable([['',l2[1:]+text[l+1:]]], colWidths=self.colWidths, style=self.style, padding=self.padding)) return l3 log.debug("Can't split splittable") return self.t.split(w, h) else: return DelayedTable.split(self,w,h)
def split(self,w,h): _w,_h=self.wrap(w, h) if _h > h: # Can't split! # The right column data mandates the split # Find which flowable exceeds the available height dw=self.colWidths[0]+self.padding[1]+self.padding[3] dh=self.padding[0]+self.padding[2] bullet=self.data[0][0] text=self.data[0][1] for l in range(0,len(text)): # The -12 here is a hack. I don't know why # If the table contents wrap to Y points, the # table wraps to Y+12 _,fh = _listWrapOn(text[:l+1],w-dw,None) if fh+dh > h: # The lth flowable is the guilty one # split it _,lh=_listWrapOn(text[:l],w-dw,None) # Workaround for Issue 180 text[l].wrap(w-dw,h-lh-dh) l2=text[l].split(w-dw,h-lh-dh) if l2==[] and l==0: # Can't fit anything return l2 elif l2==[]: # Not splittable, push to next page # If the previous one is keepwithnext, push # that one too while l>0 and text[l-1].getKeepWithNext(): l-=1 if l>0: # Workaround for Issue 180 with wordaxe: #if HAS_WORDAXE: #l3=[Table([ #[bullet, #text[:l]] #], #colWidths=self.colWidths, #style=self.style), #Table([['',text[l:]]], #colWidths=self.colWidths, #style=self.style)] #else: l3=[Table([ [bullet, text[:l]] ], colWidths=self.colWidths, style=self.style), SplitTable([['',text[l:]]], colWidths=self.colWidths, style=self.style, padding=self.padding)] else: # Everything flows l3=[] else: l3=[Table([[bullet,text[:l]+[l2[0]]]], colWidths=self.colWidths, rowHeights=[h], style=self.style)] if l2[1:]+text[l+1:]: ## Workaround for Issue 180 with wordaxe: #if HAS_WORDAXE: #l3.append( #Table([['',l2[1:]+text[l+1:]]], #colWidths=self.colWidths, #style=self.style)) #else: l3.append( SplitTable([['',l2[1:]+text[l+1:]]], colWidths=self.colWidths, style=self.style, padding=self.padding)) return l3 log.debug("Can't split splittable") return self.t.split(w, h) else: return DelayedTable.split(self,w,h)
def wrap (self, aW, aH): self.width, self.height = _listWrapOn(self.content, aW, None) return self.width, aH
def func(x): W, H = _listWrapOn(self._content,x*maxWidth,self.canv) if x: W /= x H /= x return W, H
def safe_wrap(self, availWidth, availHeight): """ safe version of reportlab method """ mode = self.mode maxWidth = float(min(self.maxWidth or availWidth,availWidth)) maxHeight = float(min(self.maxHeight or availHeight,availHeight)) W, H = _listWrapOn(self._content,maxWidth,self.canv) if (mode=='error' and (W>maxWidth+_FUZZ or H>maxHeight+_FUZZ)): ident = 'content %sx%s too large for %s' % (W,H,self.identity(30)) #leave to keep apart from the raise raise LayoutError(ident) elif W<=maxWidth+_FUZZ and H<=maxHeight+_FUZZ: self.width = W-_FUZZ #we take what we get self.height = H-_FUZZ elif mode in ('overflow','truncate'): #we lie self.width = min(maxWidth,W)-_FUZZ self.height = min(maxHeight,H)-_FUZZ else: def func(x): W, H = _listWrapOn(self._content,x*maxWidth,self.canv) if x: W /= x H /= x return W, H W0 = W H0 = H s0 = 1 if W>maxWidth+_FUZZ: #squeeze out the excess width and or Height s1 = W/maxWidth W, H = func(s1) if H<=maxHeight+_FUZZ: self.width = W-_FUZZ self.height = H-_FUZZ self._scale = s1 return W,H s0 = s1 H0 = H W0 = W s1 = H/maxHeight W, H = func(s1) self.width = W-_FUZZ self.height = H-_FUZZ self._scale = s1 if H<min(0.95*maxHeight,maxHeight-10) or H>=maxHeight+_FUZZ: #the standard case W should be OK, H is short we want #to find the smallest s with H<=maxHeight H1 = H for f in 0, 0.01, 0.05, 0.10, 0.15: #apply the quadratic model if not s0 or not s1: s = 0.0 else: s = _qsolve(maxHeight*(1-f),_hmodel(s0,s1,H0,H1)) W, H = func(s) if H<=maxHeight+_FUZZ and W<=maxWidth+_FUZZ: self.width = W-_FUZZ self.height = H-_FUZZ self._scale = s break return self.width, self.height