reportlab/platypus/paragraph.py
changeset 2664 c9faa3a99e93
parent 2663 927cc273c5a5
child 2670 3fdd642a7b76
equal deleted inserted replaced
2663:927cc273c5a5 2664:c9faa3a99e93
   210         from reportlab.lib._rl_accel import _sameFrag
   210         from reportlab.lib._rl_accel import _sameFrag
   211     except ImportError:
   211     except ImportError:
   212         #if you modify this you need to modify _rl_accel RGB
   212         #if you modify this you need to modify _rl_accel RGB
   213         def _sameFrag(f,g):
   213         def _sameFrag(f,g):
   214             'returns 1 if two ParaFrags map out the same'
   214             'returns 1 if two ParaFrags map out the same'
   215             if hasattr(f,'cbDefn') or hasattr(g,'cbDefn'): return 0
   215             if (hasattr(f,'cbDefn') or hasattr(g,'cbDefn')
       
   216                     or hasattr(f,'lineBreak') or hasattr(g,'lineBreak')): return 0
   216             for a in ('fontName', 'fontSize', 'textColor', 'rise', 'underline', 'strike', 'link'):
   217             for a in ('fontName', 'fontSize', 'textColor', 'rise', 'underline', 'strike', 'link'):
   217                 if getattr(f,a)!=getattr(g,a): return 0
   218                 if getattr(f,a)!=getattr(g,a): return 0
   218             return 1
   219             return 1
   219 
   220 
   220 def _getFragWords(frags):
   221 def _getFragWords(frags):
   255                 R.append(W)
   256                 R.append(W)
   256                 W = []
   257                 W = []
   257                 n = 0
   258                 n = 0
   258         elif hasattr(f,'cbDefn'):
   259         elif hasattr(f,'cbDefn'):
   259             W.append((f,''))
   260             W.append((f,''))
   260         elif getattr(f, 'lineBreak', False) == True:
   261         elif hasattr(f, 'lineBreak'):
   261             #pass the frag through.  The line breaker will scan for it.
   262             #pass the frag through.  The line breaker will scan for it.
   262             W.append((f,''))
   263             if W!=[]:
   263             
   264                 W.insert(0,n)
       
   265                 R.append(W)
       
   266                 W = []
       
   267                 n = 0
       
   268             R.append([0,(f,'')])
   264 
   269 
   265     if W!=[]:
   270     if W!=[]:
   266         W.insert(0,n)
   271         W.insert(0,n)
   267         R.append(W)
   272         R.append(W)
   268 
   273 
   636             currentWidth = - spaceWidth   # hack to get around extra space for word 1
   641             currentWidth = - spaceWidth   # hack to get around extra space for word 1
   637             for word in words:
   642             for word in words:
   638                 #this underscores my feeling that Unicode throughout would be easier!
   643                 #this underscores my feeling that Unicode throughout would be easier!
   639                 wordWidth = stringWidth(word, fontName, fontSize, self.encoding)
   644                 wordWidth = stringWidth(word, fontName, fontSize, self.encoding)
   640                 newWidth = currentWidth + spaceWidth + wordWidth
   645                 newWidth = currentWidth + spaceWidth + wordWidth
   641                 if newWidth <= maxWidth or len(cLine) == 0: 
   646                 if newWidth <= maxWidth or len(cLine) == 0:
   642                     # fit one more on this line
   647                     # fit one more on this line
   643                     cLine.append(word)
   648                     cLine.append(word)
   644                     currentWidth = newWidth
   649                     currentWidth = newWidth
   645                 else:
   650                 else:
   646                     if currentWidth > self.width: self.width = currentWidth
   651                     if currentWidth > self.width: self.width = currentWidth
   668                 #NB this is an utter hack that awaits the proper information
   673                 #NB this is an utter hack that awaits the proper information
   669                 #preserving splitting algorithm
   674                 #preserving splitting algorithm
   670                 return self.blPara
   675                 return self.blPara
   671             n = 0
   676             n = 0
   672             nSp = 0
   677             nSp = 0
       
   678             lineBreakPrev = False
   673             for w in _getFragWords(frags):
   679             for w in _getFragWords(frags):
   674                 spaceWidth = stringWidth(' ',w[-1][0].fontName, w[-1][0].fontSize)
   680                 spaceWidth = stringWidth(' ',w[-1][0].fontName, w[-1][0].fontSize)
   675 
   681 
   676                 if n==0:
   682                 if n==0:
   677                     currentWidth = -spaceWidth   # hack to get around extra space for word 1
   683                     currentWidth = -spaceWidth   # hack to get around extra space for word 1
   682                 f = w[1][0]
   688                 f = w[1][0]
   683                 if wordWidth>0:
   689                 if wordWidth>0:
   684                     newWidth = currentWidth + spaceWidth + wordWidth
   690                     newWidth = currentWidth + spaceWidth + wordWidth
   685                 else:
   691                 else:
   686                     newWidth = currentWidth
   692                     newWidth = currentWidth
   687                 #if (not getattr(f, 'lineBreak','False')) and (newWidth<=maxWidth or n==0):
   693 
   688                 if newWidth<=maxWidth or n==0:
   694                 #text to see if this frag is a line break. If it is and we will only act on it
   689                     # fit one more word on this line
   695                 #if the current width is non-negative or the previous thing was a deliberate lineBreak
       
   696                 lineBreak = hasattr(f,'lineBreak')
       
   697                 endLine = (newWidth>maxWidth and n>0) or (lineBreak and (currentWidth>0 or lineBreakPrev))
       
   698                 if not endLine:
       
   699                     lineBreakPrev = lineBreak
       
   700                     if lineBreak: continue      #throw it away
   690                     n += 1
   701                     n += 1
   691                     maxSize = max(maxSize,f.fontSize)
   702                     maxSize = max(maxSize,f.fontSize)
   692                     nText = w[1][1]
   703                     nText = w[1][1]
   693                     if words==[]:
   704                     if words==[]:
   694                         g = f.clone()
   705                         g = f.clone()
   716                         words.append(g)
   727                         words.append(g)
   717                         maxSize = max(maxSize,g.fontSize)
   728                         maxSize = max(maxSize,g.fontSize)
   718 
   729 
   719                     currentWidth = newWidth
   730                     currentWidth = newWidth
   720                 else:  #either it won't fit, or it's a lineBreak tag
   731                 else:  #either it won't fit, or it's a lineBreak tag
       
   732                     if lineBreak and not len(words):
       
   733                         g = f.clone()
       
   734                         del g.lineBreak
       
   735                         words.append(g)
       
   736 
   721                     if currentWidth>self.width: self.width = currentWidth
   737                     if currentWidth>self.width: self.width = currentWidth
   722                     #end of line
   738                     #end of line
   723                     lines.append(FragLine(extraSpace=(maxWidth - currentWidth),wordCount=n,
   739                     lines.append(FragLine(extraSpace=(maxWidth - currentWidth),wordCount=n,
   724                                         words=words, fontSize=maxSize))
   740                                         words=words, fontSize=maxSize))
   725 
   741 
   727                     lineno += 1
   743                     lineno += 1
   728                     try:
   744                     try:
   729                         maxWidth = maxWidths[lineno]
   745                         maxWidth = maxWidths[lineno]
   730                     except IndexError:
   746                     except IndexError:
   731                         maxWidth = maxWidths[-1]  # use the last one
   747                         maxWidth = maxWidths[-1]  # use the last one
       
   748 
       
   749                     lineBreakPrev = lineBreak
       
   750                     if lineBreak:
       
   751                         n = 0
       
   752                         continue
       
   753 
   732                     currentWidth = wordWidth
   754                     currentWidth = wordWidth
   733                     n = 1
   755                     n = 1
   734                     maxSize = f.fontSize
   756                     maxSize = f.fontSize
   735                     g = f.clone()
   757                     g = f.clone()
   736                     words = [g]
   758                     words = [g]