def test_sameFrag(self): from _rl_accel import _sameFrag class ABag: def __init__(self,**kwd): self.__dict__.update(kwd) def __str__(self): V=['%s=%r' % v for v in self.__dict__.items()] V.sort() return 'ABag(%s)' % ','.join(V) a=ABag(fontName='Helvetica',fontSize=12, textColor="red", rise=0, underline=0, strike=0, link="aaaa") b=ABag(fontName='Helvetica',fontSize=12, textColor="red", rise=0, underline=0, strike=0, link="aaaa") for name in ("fontName", "fontSize", "textColor", "rise", "underline", "strike", "link"): old = getattr(a,name) assert _sameFrag(a,b)==1, "_sameFrag(%s,%s)!=1" % (a,b) assert _sameFrag(b,a)==1, "_sameFrag(%s,%s)!=1" % (b,a) setattr(a,name,None) assert _sameFrag(a,b)==0, "_sameFrag(%s,%s)!=0" % (a,b) assert _sameFrag(b,a)==0, "_sameFrag(%s,%s)!=0" % (b,a) delattr(a,name) assert _sameFrag(a,b)==0, "_sameFrag(%s,%s)!=0" % (a,b) assert _sameFrag(b,a)==0, "_sameFrag(%s,%s)!=0" % (b,a) delattr(b,name) assert _sameFrag(a,b)==1, "_sameFrag(%s,%s)!=1" % (a,b) assert _sameFrag(b,a)==1, "_sameFrag(%s,%s)!=1" % (b,a) setattr(a,name,old) setattr(b,name,old)
def breakLines(self, width): """ Returns a broken line structure. There are two cases A) For the simple case of a single formatting input fragment the output is A fragment specifier with kind = 0 fontName, fontSize, leading, textColor lines= A list of lines Each line has two items. 1) unused width in points 2) word list B) When there is more than one input formatting fragment the output is A fragment specifier with kind = 1 lines= A list of fragments each having fields extraspace (needed for justified) fontSize words=word list each word is itself a fragment with various settings This structure can be used to easily draw paragraphs with the various alignments. You can supply either a single width or a list of widths; the latter will have its last item repeated until necessary. A 2-element list is useful when there is a different first line indent; a longer list could be created to facilitate custom wraps around irregular objects.""" if type(width) <> ListType: maxWidths = [width] else: maxWidths = width lines = [] lineno = 0 style = self.style fFontSize = float(style.fontSize) #for bullets, work out width and ensure we wrap the right amount onto line one _handleBulletWidth(self.bulletText, style, maxWidths) maxWidth = maxWidths[0] self.height = 0 frags = self.frags nFrags = len(frags) if nFrags == 1 and not hasattr(frags[0], 'cbDefn'): f = frags[0] fontSize = f.fontSize fontName = f.fontName words = hasattr(f, 'text') and split(f.text, ' ') or f.words spaceWidth = stringWidth(' ', fontName, fontSize, self.encoding) cLine = [] currentWidth = -spaceWidth # hack to get around extra space for word 1 for word in words: #this underscores my feeling that Unicode throughout would be easier! wordWidth = stringWidth(word, fontName, fontSize, self.encoding) newWidth = currentWidth + spaceWidth + wordWidth if newWidth <= maxWidth or not len(cLine): # fit one more on this line cLine.append(word) currentWidth = newWidth else: if currentWidth > self.width: self.width = currentWidth #end of line lines.append((maxWidth - currentWidth, cLine)) cLine = [word] currentWidth = wordWidth lineno += 1 try: maxWidth = maxWidths[lineno] except IndexError: maxWidth = maxWidths[-1] # use the last one #deal with any leftovers on the final line if cLine != []: if currentWidth > self.width: self.width = currentWidth lines.append((maxWidth - currentWidth, cLine)) return f.clone(kind=0, lines=lines) elif nFrags <= 0: return ParaLines(kind=0, fontSize=style.fontSize, fontName=style.fontName, textColor=style.textColor, lines=[]) else: if hasattr(self, 'blPara') and getattr(self, '_splitpara', 0): #NB this is an utter hack that awaits the proper information #preserving splitting algorithm return self.blPara n = 0 words = [] for w in _getFragWords(frags): spaceWidth = stringWidth(' ', w[-1][0].fontName, w[-1][0].fontSize) if n == 0: currentWidth = -spaceWidth # hack to get around extra space for word 1 maxSize = 0 wordWidth = w[0] f = w[1][0] if wordWidth > 0: newWidth = currentWidth + spaceWidth + wordWidth else: newWidth = currentWidth #test to see if this frag is a line break. If it is we will only act on it #if the current width is non-negative or the previous thing was a deliberate lineBreak lineBreak = hasattr(f, 'lineBreak') endLine = (newWidth > maxWidth and n > 0) or lineBreak if not endLine: if lineBreak: continue #throw it away nText = w[1][1] if nText: n += 1 maxSize = max(maxSize, f.fontSize) if words == []: g = f.clone() words = [g] g.text = nText elif not _sameFrag(g, f): if currentWidth > 0 and ( (nText != '' and nText[0] != ' ') or hasattr(f, 'cbDefn')): if hasattr(g, 'cbDefn'): i = len(words) - 1 while hasattr(words[i], 'cbDefn'): i -= 1 words[i].text += ' ' else: g.text += ' ' g = f.clone() words.append(g) g.text = nText else: if nText != '' and nText[0] != ' ': g.text += ' ' + nText for i in w[2:]: g = i[0].clone() g.text = i[1] words.append(g) maxSize = max(maxSize, g.fontSize) currentWidth = newWidth else: #either it won't fit, or it's a lineBreak tag if lineBreak: g = f.clone() #del g.lineBreak words.append(g) if currentWidth > self.width: self.width = currentWidth #end of line lines.append( FragLine(extraSpace=(maxWidth - currentWidth), wordCount=n, words=words, fontSize=maxSize)) #start new line lineno += 1 try: maxWidth = maxWidths[lineno] except IndexError: maxWidth = maxWidths[-1] # use the last one if lineBreak: n = 0 words = [] continue currentWidth = wordWidth n = 1 maxSize = f.fontSize g = f.clone() words = [g] g.text = w[1][1] for i in w[2:]: g = i[0].clone() g.text = i[1] words.append(g) maxSize = max(maxSize, g.fontSize) #deal with any leftovers on the final line if words != []: if currentWidth > self.width: self.width = currentWidth lines.append( ParaLines(extraSpace=(maxWidth - currentWidth), wordCount=n, words=words, fontSize=maxSize)) return ParaLines(kind=1, lines=lines) return lines
def breakLines(self, width): """ Returns a broken line structure. There are two cases A) For the simple case of a single formatting input fragment the output is A fragment specifier with kind = 0 fontName, fontSize, leading, textColor lines= A list of lines Each line has two items. 1) unused width in points 2) word list B) When there is more than one input formatting fragment the out put is A fragment specifier with kind = 1 lines= A list of fragments each having fields extraspace (needed for justified) fontSize words=word list each word is itself a fragment with various settings This structure can be used to easily draw paragraphs with the various alignments. You can supply either a single width or a list of widths; the latter will have its last item repeated until necessary. A 2-element list is useful when there is a different first line indent; a longer list could be created to facilitate custom wraps around irregular objects.""" if type(width) <> ListType: maxWidths = [width] else: maxWidths = width lines = [] lineno = 0 style = self.style fFontSize = float(style.fontSize) #for bullets, work out width and ensure we wrap the right amount onto line one _handleBulletWidth(self.bulletText,style,maxWidths) maxWidth = maxWidths[0] self.height = 0 frags = self.frags nFrags= len(frags) if nFrags==1: f = frags[0] fontSize = f.fontSize fontName = f.fontName words = hasattr(f,'text') and split(f.text, ' ') or f.words spaceWidth = stringWidth(' ', fontName, fontSize) cLine = [] currentWidth = - spaceWidth # hack to get around extra space for word 1 for word in words: wordWidth = stringWidth(word, fontName, fontSize) newWidth = currentWidth + spaceWidth + wordWidth if newWidth<=maxWidth or len(cLine)==0: # fit one more on this line cLine.append(word) currentWidth = newWidth else: if currentWidth>self.width: self.width = currentWidth #end of line lines.append((maxWidth - currentWidth, cLine)) cLine = [word] currentWidth = wordWidth lineno = lineno + 1 try: maxWidth = maxWidths[lineno] except IndexError: maxWidth = maxWidths[-1] # use the last one #deal with any leftovers on the final line if cLine!=[]: if currentWidth>self.width: self.width = currentWidth lines.append((maxWidth - currentWidth, cLine)) return f.clone(kind=0, lines=lines) elif nFrags<=0: return ParaLines(kind=0, fontSize=style.fontSize, fontName=style.fontName, textColor=style.textColor, lines=[]) else: if hasattr(self,'blPara'): #NB this is an utter hack that awaits the proper information #preserving splitting algorithm return self.blPara n = 0 nSp = 0 for w in _getFragWords(frags): spaceWidth = stringWidth(' ',w[-1][0].fontName, w[-1][0].fontSize) if n==0: currentWidth = -spaceWidth # hack to get around extra space for word 1 words = [] maxSize = 0 wordWidth = w[0] f = w[1][0] if wordWidth>0: newWidth = currentWidth + spaceWidth + wordWidth else: newWidth = currentWidth if newWidth<=maxWidth or n==0: # fit one more on this line n = n + 1 maxSize = max(maxSize,f.fontSize) nText = w[1][1] if words==[]: g = f.clone() words = [g] g.text = nText elif not _sameFrag(g,f): if currentWidth>0 and ((nText!='' and nText[0]!=' ') or hasattr(f,'cbDefn')): if hasattr(g,'cbDefn'): i = len(words)-1 while hasattr(words[i],'cbDefn'): i = i-1 words[i].text = words[i].text + ' ' else: g.text = g.text + ' ' nSp = nSp + 1 g = f.clone() words.append(g) g.text = nText else: if nText!='' and nText[0]!=' ': g.text = g.text + ' ' + nText for i in w[2:]: g = i[0].clone() g.text=i[1] words.append(g) maxSize = max(maxSize,g.fontSize) currentWidth = newWidth else: if currentWidth>self.width: self.width = currentWidth #end of line lines.append(FragLine(extraSpace=(maxWidth - currentWidth),wordCount=n, words=words, fontSize=maxSize)) #start new line lineno = lineno + 1 try: maxWidth = maxWidths[lineno] except IndexError: maxWidth = maxWidths[-1] # use the last one currentWidth = wordWidth n = 1 maxSize = f.fontSize g = f.clone() words = [g] g.text = w[1][1] for i in w[2:]: g = i[0].clone() g.text=i[1] words.append(g) maxSize = max(maxSize,g.fontSize) #deal with any leftovers on the final line if words<>[]: if currentWidth>self.width: self.width = currentWidth lines.append(ParaLines(extraSpace=(maxWidth - currentWidth),wordCount=n, words=words, fontSize=maxSize)) return ParaLines(kind=1, lines=lines) return lines