reportlab/platypus/paragraph.py
author rgbecker
Wed, 25 Oct 2000 08:57:46 +0000
changeset 494 54257447cfe9
parent 488 a270e8b45200
child 496 bb47cf5c2739
permissions -rw-r--r--
Changed to indirect copyright
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
494
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 488
diff changeset
     1
#copyright ReportLab Inc. 2000
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 488
diff changeset
     2
#see license.txt for license details
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 488
diff changeset
     3
#history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/platypus/paragraph.py?cvsroot=reportlab
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 488
diff changeset
     4
#$Header: /tmp/reportlab/reportlab/platypus/paragraph.py,v 1.25 2000/10/25 08:57:45 rgbecker Exp $
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 488
diff changeset
     5
__version__=''' $Id: paragraph.py,v 1.25 2000/10/25 08:57:45 rgbecker Exp $ '''
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
     6
import string
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
     7
from types import StringType, ListType
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
     8
from reportlab.pdfbase.pdfmetrics import stringWidth
279
e7d8b3631d5c Global sequencer put in the 'story builder'.
andy_robinson
parents: 268
diff changeset
     9
from reportlab.platypus.paraparser import ParaParser, ParaFrag
e7d8b3631d5c Global sequencer put in the 'story builder'.
andy_robinson
parents: 268
diff changeset
    10
from reportlab.platypus.flowables import Flowable
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    11
from reportlab.lib.colors import Color
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    12
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
449
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 438
diff changeset
    13
from reportlab.lib.utils import _className
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
    14
from copy import deepcopy
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    15
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    16
#our one and only parser
268
8414113fa500 more documentation changes
aaron_watters
parents: 253
diff changeset
    17
# XXXXX if the parser has any internal state using only one is probably a BAD idea!
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    18
_parser=ParaParser()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    19
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
    20
def cleanBlockQuotedText(text,joiner=' '):
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    21
	"""This is an internal utility which takes triple-
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    22
	quoted text form within the document and returns
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    23
	(hopefully) the paragraph the user intended originally."""
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    24
	stripped = string.strip(text)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    25
	lines = string.split(stripped, '\n')
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    26
	trimmed_lines = map(string.lstrip, lines)
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
    27
	return string.join(trimmed_lines, joiner)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    28
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    29
def	_leftDrawParaLine( tx, offset, extraspace, words, last=0):
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
    30
	tx.setXPos(offset)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    31
	tx._textOut(string.join(words),1)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    32
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    33
def	_centerDrawParaLine( tx, offset, extraspace, words, last=0):
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    34
	m = offset + 0.5 * extraspace
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
    35
	tx.setXPos(m)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    36
	tx._textOut(string.join(words),1)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    37
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    38
def	_rightDrawParaLine( tx, offset, extraspace, words, last=0):
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    39
	m = offset + extraspace
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
    40
	tx.setXPos(m)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    41
	tx._textOut(string.join(words),1)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    42
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    43
def	_justifyDrawParaLine( tx, offset, extraspace, words, last=0):
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
    44
	tx.setXPos(offset)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    45
	text  = string.join(words)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    46
	if last:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    47
		#last one, left align
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    48
		tx._textOut(text,1)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    49
	else:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    50
		tx.setWordSpace(extraspace / float(len(words)-1))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    51
		tx._textOut(text,1)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    52
		tx.setWordSpace(0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    53
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    54
def	_putFragLine(tx,words):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    55
	for f in words:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    56
		if (tx._fontname,tx._fontsize)!=(f.fontName,f.fontSize):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    57
			tx._setFont(f.fontName, f.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    58
		if tx.XtraState.textColor!=f.textColor:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    59
			tx.XtraState.textColor = f.textColor
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    60
			tx.setFillColor(f.textColor)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    61
		if tx.XtraState.rise!=f.rise:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    62
			tx.XtraState.rise=f.rise
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    63
			tx.setRise(f.rise)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    64
		tx._textOut(f.text,f is words[-1])	# cheap textOut
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    65
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    66
def	_leftDrawParaLineX( tx, offset, line, last=0):
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
    67
	tx.setXPos(offset)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    68
	_putFragLine(tx, line.words)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    69
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    70
def	_centerDrawParaLineX( tx, offset, line, last=0):
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    71
	m = offset+0.5*line.extraSpace
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
    72
	tx.setXPos(m)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    73
	_putFragLine(tx, line.words)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    74
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    75
def	_rightDrawParaLineX( tx, offset, line, last=0):
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    76
	m = offset+line.extraSpace
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
    77
	tx.setXPos(m)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    78
	_putFragLine(tx, line.words)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    79
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    80
def	_justifyDrawParaLineX( tx, offset, line, last=0):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    81
	if last:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    82
		#last one, left align
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
    83
		tx.setXPos(offset)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    84
		_putFragLine(tx, line.words)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    85
	else:
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
    86
		tx.setXPos(offset)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    87
		tx.setWordSpace(line.extraSpace / float(line.wordCount-1))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    88
		_putFragLine(tx, line.words)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    89
		tx.setWordSpace(0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    90
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    91
def	_sameFrag(f,g):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    92
	'returns 1 if two frags map out the same'
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    93
	for a in ('fontName', 'fontSize', 'textColor', 'rise'):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    94
		if getattr(f,a)!=getattr(g,a): return 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    95
	return 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    96
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    97
def _getFragWords(frags):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    98
	'''	given a fragment list return a list of lists
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    99
		[[size, (f00,w00), ..., (f0n,w0n)],....,[size, (fm0,wm0), ..., (f0n,wmn)]]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   100
		each pair f,w represents a style and some string
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   101
		each sublist represents a word
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   102
	'''
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   103
	R = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   104
	W = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   105
	n = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   106
	for f in frags:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   107
		text = f.text
143
cc003e0530ce Fixed repeated breaklines bug
rgbecker
parents: 131
diff changeset
   108
		#del f.text	# we can't do this until we sort out splitting
cc003e0530ce Fixed repeated breaklines bug
rgbecker
parents: 131
diff changeset
   109
					# of paragraphs
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   110
		if text!='':
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   111
			S = string.split(text,' ')
302
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   112
			if S[-1]=='': del S[-1]
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   113
			if W!=[] and text[0] in [' ','\t']:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   114
				W.insert(0,n)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   115
				R.append(W)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   116
				W = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   117
				n = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   118
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   119
			for w in S[:-1]:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   120
				W.append((f,w))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   121
				n = n + stringWidth(w, f.fontName, f.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   122
				W.insert(0,n)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   123
				R.append(W)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   124
				W = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   125
				n = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   126
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   127
			w = S[-1]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   128
			W.append((f,w))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   129
			n = n + stringWidth(w, f.fontName, f.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   130
			if text[-1] in [' ','\t']:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   131
				W.insert(0,n)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   132
				R.append(W)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   133
				W = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   134
				n = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   135
	if W!=[]:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   136
		W.insert(0,n)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   137
		R.append(W)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   138
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   139
	return R
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   140
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   141
def	_split_bfragSimple(bfrag,start,stop):
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   142
	f = bfrag.clone()
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   143
	for a in ('lines', 'kind', 'text'):
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   144
		if hasattr(f,a): delattr(f,a)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   145
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   146
	f.words = []
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   147
	for l in bfrag.lines[start:stop]:
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   148
		for w in l[1]:
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   149
			f.words.append(w)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   150
	return [f]
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   151
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   152
def	_split_bfragHard(bfrag,start,stop):
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   153
	f = []
302
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   154
	lines = bfrag.lines[start:stop]
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   155
	for l in lines:
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   156
		for w in l.words:
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   157
			f.append(w)
302
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   158
		if l is not lines[-1]:
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   159
			f[-1].text = f[-1].text+' '
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   160
	return f
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   161
250
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   162
def _drawBullet(canvas, offset, cur_y, bulletText, style):
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   163
	'''draw a bullet text could be a simple string or a frag list'''
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   164
	tx2 = canvas.beginText(style.bulletIndent, cur_y)
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   165
	tx2.setFont(style.bulletFontName, style.bulletFontSize)
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   166
	tx2.setFillColor(hasattr(style,'bulletColor') and style.bulletColor or style.textColor)
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   167
	if type(bulletText) is StringType:
250
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   168
		tx2.textOut(bulletText)
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   169
	else:
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   170
		for f in bulletText:
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   171
			tx2.setFont(f.fontName, f.fontSize)
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   172
			tx2.setFillColor(f.textColor)
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   173
			tx2.textOut(f.text)
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   174
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   175
	bulletEnd = tx2.getX()
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   176
	offset = max(offset, bulletEnd - style.leftIndent)
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   177
	canvas.drawText(tx2)
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   178
	return offset
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   179
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   180
def _handleBulletWidth(bulletText,style,maxWidths):
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   181
	'''work out bullet width and adjust maxWidths[0] if neccessary
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   182
	'''
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   183
	if bulletText <> None:
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   184
		if type(bulletText) is StringType:
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   185
			bulletWidth = stringWidth(
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   186
				bulletText,
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   187
				style.bulletFontName, style.bulletFontSize)
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   188
		else:
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   189
			#it's a list of fragments
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   190
			bulletWidth = 0
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   191
			for f in bulletText:
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   192
				bulletWidth = bulletWidth + stringWidth(f.text, f.fontName, f.fontSize)
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   193
		bulletRight = style.bulletIndent + bulletWidth
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   194
		if bulletRight > style.firstLineIndent:
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   195
			#..then it overruns, and we have less space available on line 1
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   196
			maxWidths[0] = maxWidths[0] - (bulletRight - style.firstLineIndent)
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   197
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   198
class Paragraph(Flowable):
316
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   199
	"""	Paragraph(text, style, bulletText=None)
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   200
		text a string of stuff to go into the paragraph.
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   201
		style is a style definition as in reportlab.lib.styles.
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   202
		bulletText is an optional bullet defintion.
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   203
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   204
		This class is a flowable that can format a block of text
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   205
		into a paragraph with a given style.
268
8414113fa500 more documentation changes
aaron_watters
parents: 253
diff changeset
   206
	
316
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   207
		The paragraph Text can contain XML-like markup including the tags:
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   208
		<b> ... </b> - bold
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   209
		<i> ... </i> - italics
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   210
		<u> ... </u> - underline
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   211
		<super> ... </super> - superscript
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   212
		<sub> ... </sub> - subscript
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   213
		<font name=fontfamily/fontname color=colorname size=float>
268
8414113fa500 more documentation changes
aaron_watters
parents: 253
diff changeset
   214
8414113fa500 more documentation changes
aaron_watters
parents: 253
diff changeset
   215
		The whole may be surrounded by <para> </para> tags
8414113fa500 more documentation changes
aaron_watters
parents: 253
diff changeset
   216
316
e15cf6a28eb8 Documentation fixes
rgbecker
parents: 302
diff changeset
   217
		It will also be able to handle any MathML specified Greek characters.
268
8414113fa500 more documentation changes
aaron_watters
parents: 253
diff changeset
   218
	"""
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   219
	def __init__(self, text, style, bulletText = None, frags=None):
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   220
		self._setup(text, style, bulletText, frags, cleanBlockQuotedText)
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   221
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   222
	def _setup(self, text, style, bulletText, frags, cleaner):
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   223
		if frags is None:
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   224
			text = cleaner(text)
250
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   225
			style, frags, bFrags = _parser.parse(text,style)
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   226
			if frags is None:
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   227
				raise "xml parser error (%s) in paragraph beginning\n'%s'"\
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   228
					% (_parser.errors[0],text[:min(30,len(text))])
250
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   229
			if bFrags: bulletText = bFrags
279
e7d8b3631d5c Global sequencer put in the 'story builder'.
andy_robinson
parents: 268
diff changeset
   230
e7d8b3631d5c Global sequencer put in the 'story builder'.
andy_robinson
parents: 268
diff changeset
   231
		#AR hack
e7d8b3631d5c Global sequencer put in the 'story builder'.
andy_robinson
parents: 268
diff changeset
   232
		self.text = text
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   233
		self.frags = frags
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   234
		self.style = style
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   235
		self.bulletText = bulletText
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   236
		self.debug = 0	 #turn this on to see a pretty one with all the margins etc.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   237
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   238
	def wrap(self, availWidth, availHeight):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   239
		# work out widths array for breaking
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   240
		self.width = availWidth
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   241
		first_line_width = availWidth - self.style.firstLineIndent - self.style.rightIndent
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   242
		later_widths = availWidth - self.style.leftIndent - self.style.rightIndent
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   243
		self.bfrags = self.breakLines([first_line_width, later_widths])
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   244
		self.height = len(self.bfrags.lines) * self.style.leading
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   245
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   246
		#estimate the size
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   247
		return (self.width, self.height)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   248
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   249
	def _get_split_bFragFunc(self):
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   250
		return self.bfrags.kind==0 and _split_bfragSimple or _split_bfragHard
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   251
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   252
	def split(self,availWidth, availHeight):
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   253
		if len(self.frags)<=0: return []
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   254
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   255
		#the split information is all inside self.bfrags
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   256
		if not hasattr(self,'bfrags'):
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   257
			self.wrap(availWidth,availHeight)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   258
		bfrags = self.bfrags
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   259
		style = self.style
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   260
		leading = style.leading
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   261
		lines = bfrags.lines
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   262
		n = len(lines)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   263
		s = int(availHeight/leading)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   264
		if s<=1: return []
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   265
		if n<=s: return [self]
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   266
		func = self._get_split_bFragFunc()
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   267
467
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 450
diff changeset
   268
		P1=self.__class__(None,style,bulletText=self.bulletText,frags=func(bfrags,0,s))
471
2b882a518d05 Justified XPreformatteds are OK
rgbecker
parents: 467
diff changeset
   269
		P1._JustifyLast = 1
383
9a0af56bcfe1 The Paragraph.split method was wrongly assuming that the firstLineIndent
rgbecker
parents: 316
diff changeset
   270
		if style.firstLineIndent != style.leftIndent:
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   271
			style = deepcopy(style)
383
9a0af56bcfe1 The Paragraph.split method was wrongly assuming that the firstLineIndent
rgbecker
parents: 316
diff changeset
   272
			style.firstLineIndent = style.leftIndent
467
34593cc102de Splitting fixes. Mostly caused by XPreformatted not doing it right.
rgbecker
parents: 450
diff changeset
   273
		P2=self.__class__(None,style,bulletText=None,frags=func(bfrags,s,n))
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   274
		return [P1,P2]
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   275
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   276
	def draw(self):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   277
		#call another method for historical reasons.  Besides, I
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   278
		#suspect I will be playing with alternate drawing routines
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   279
		#so not doing it here makes it easier to switch.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   280
		self.drawPara(self.debug)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   281
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   282
	def breakLines(self, width):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   283
		"""
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   284
		Returns a broken line structure. There are two cases
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   285
		
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   286
		A) For the simple case of a single formatting input fragment the output is
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   287
			A fragment specifier with
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   288
				kind = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   289
				fontName, fontSize, leading, textColor
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   290
				lines=	A list of lines
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   291
						Each line has two items.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   292
						1) unused width in points
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   293
						2) word list
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   294
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   295
		B) When there is more than one input formatting fragment the out put is
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   296
			A fragment specifier with
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   297
				kind = 1
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   298
				lines=	A list of fragments each having fields
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   299
							extraspace (needed for justified)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   300
							fontSize
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   301
							words=word list
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   302
								each word is itself a fragment with
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   303
								various settings
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   304
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   305
		This structure can be used to easily draw paragraphs with the various alignments.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   306
		You can supply either a single width or a list of widths; the latter will have its
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   307
		last item repeated until necessary. A 2-element list is useful when there is a
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   308
		different first line indent; a longer list could be created to facilitate custom wraps
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   309
		around irregular objects."""
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   310
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   311
		if type(width) <> ListType: maxWidths = [width]
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   312
		else: maxWidths = width
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   313
		lines = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   314
		lineno = 0
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   315
		maxWidth = maxWidths[lineno]
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   316
		style = self.style
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   317
		fFontSize = float(style.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   318
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   319
		#for bullets, work out width and ensure we wrap the right amount onto line one
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   320
		_handleBulletWidth(self.bulletText,style,maxWidths)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   321
191
c4907a8ee681 Removed usage of spaceBefore/After in wrap methods
rgbecker
parents: 143
diff changeset
   322
		self.height = 0
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   323
		frags = self.frags
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   324
		nFrags= len(frags)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   325
		if nFrags==1:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   326
			f = frags[0]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   327
			fontSize = f.fontSize
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   328
			fontName = f.fontName
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   329
			words = hasattr(f,'text') and string.split(f.text, ' ') or f.words
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   330
			spaceWidth = stringWidth(' ', fontName, fontSize)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   331
			cLine = []
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   332
			currentWidth = - spaceWidth   # hack to get around extra space for word 1
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   333
			for word in words:
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   334
				wordWidth = stringWidth(word, fontName, fontSize)
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   335
				space_available = maxWidth - (currentWidth + spaceWidth + wordWidth)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   336
				if	space_available > 0:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   337
					# fit one more on this line
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   338
					cLine.append(word)
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   339
					currentWidth = currentWidth + spaceWidth + wordWidth
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   340
				else:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   341
					#end of line
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   342
					lines.append((maxWidth - currentWidth, cLine))
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   343
					cLine = [word]
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   344
					currentWidth = wordWidth
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   345
					lineno = lineno + 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   346
					try:
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   347
						maxWidth = maxWidths[lineno]
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   348
					except IndexError:
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   349
						maxWidth = maxWidths[-1]  # use the last one
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   350
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   351
			#deal with any leftovers on the final line
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   352
			if cLine!=[]: lines.append((maxWidth - currentWidth, cLine))
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   353
			return f.clone(kind=0, lines=lines)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   354
		elif nFrags<=0:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   355
			return ParaFrag(kind=0, fontSize=style.fontSize, fontName=style.fontName,
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   356
							textColor=style.textColor, lines=[])
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   357
		else:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   358
			n = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   359
			for w in _getFragWords(frags):
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   360
				spaceWidth = stringWidth(' ',w[-1][0].fontName, w[-1][0].fontSize)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   361
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   362
				if n==0:
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   363
					currentWidth = -spaceWidth	 # hack to get around extra space for word 1
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   364
					words = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   365
					maxSize = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   366
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   367
				wordWidth = w[0]
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   368
				f = w[1][0]
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   369
				space_available = maxWidth - (currentWidth + spaceWidth + wordWidth)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   370
				if	space_available > 0:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   371
					# fit one more on this line
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   372
					n = n + 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   373
					maxSize = max(maxSize,f.fontSize)
302
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   374
					nText = w[1][1]
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   375
					if words==[]:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   376
						words = [f.clone()]
302
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   377
						words[-1].text = nText
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   378
					elif not _sameFrag(words[-1],f):
302
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   379
						if nText!='' and nText[0]!=' ':
450
37919675ea28 Further tweaks of XPreformatted
rgbecker
parents: 449
diff changeset
   380
							words[-1].text = words[-1].text + ' '
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   381
						words.append(f.clone())
302
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   382
						words[-1].text = nText
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   383
					else:
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   384
						if nText!='' and nText[0]!=' ':
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   385
							words[-1].text = words[-1].text + ' ' + nText
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   386
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   387
					for i in w[2:]:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   388
						f = i[0].clone()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   389
						f.text=i[1]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   390
						words.append(f)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   391
						maxSize = max(maxSize,f.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   392
						
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   393
					currentWidth = currentWidth + spaceWidth + wordWidth
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   394
				else:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   395
					#end of line
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   396
					lines.append(ParaFrag(extraSpace=(maxWidth - currentWidth),wordCount=n,
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   397
										words=words, fontSize=maxSize))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   398
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   399
					#start new line
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   400
					lineno = lineno + 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   401
					try:
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   402
						maxWidth = maxWidths[lineno]
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   403
					except IndexError:
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   404
						maxWidth = maxWidths[-1]  # use the last one
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   405
					currentWidth = wordWidth
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   406
					n = 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   407
					maxSize = f.fontSize
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   408
					words = [f.clone()]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   409
					words[-1].text = w[1][1]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   410
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   411
					for i in w[2:]:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   412
						f = i[0].clone()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   413
						f.text=i[1]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   414
						words.append(f)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   415
						maxSize = max(maxSize,f.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   416
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   417
			#deal with any leftovers on the final line
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   418
			if words<>[]:
438
fa5d480207bc Preparing for cleanup
rgbecker
parents: 434
diff changeset
   419
				lines.append(ParaFrag(extraSpace=(maxWidth - currentWidth),wordCount=n,
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   420
									words=words, fontSize=maxSize))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   421
			return ParaFrag(kind=1, lines=lines)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   422
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   423
		return lines
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   424
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   425
	def drawPara(self,debug=0):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   426
		"""Draws a paragraph according to the given style.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   427
		Returns the final y position at the bottom. Not safe for
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   428
		paragraphs without spaces e.g. Japanese; wrapping
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   429
		algorithm will go infinite."""
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   430
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   431
		#stash the key facts locally for speed
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   432
		canvas = self.canv
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   433
		style = self.style
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   434
		bfrags = self.bfrags
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   435
		lines = bfrags.lines
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   436
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   437
		#work out the origin for line 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   438
		cur_x = style.leftIndent
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   439
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   440
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   441
		if debug:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   442
			# This boxes and shades stuff to show how the paragraph
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   443
			# uses its space.  Useful for self-documentation so
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   444
			# the debug code stays!
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   445
			# box the lot
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   446
			canvas.rect(0, 0, self.width, self.height)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   447
			#left and right margins
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   448
			canvas.saveState()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   449
			canvas.setFillColor(Color(0.9,0.9,0.9))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   450
			canvas.rect(0, 0, style.leftIndent, self.height)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   451
			canvas.rect(self.width - style.rightIndent, 0, style.rightIndent, self.height)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   452
			# shade above and below
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   453
			canvas.setFillColor(Color(1.0,1.0,0.0))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   454
			canvas.restoreState()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   455
			#self.drawLine(x + style.leftIndent, y, x + style.leftIndent, cur_y)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   456
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   457
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   458
		nLines = len(lines)
250
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   459
		bulletText = self.bulletText
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   460
		if nLines > 0:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   461
			canvas.saveState()
449
1ba0d6fb0f9e XPreformatted fixed empty lines and leading space
rgbecker
parents: 438
diff changeset
   462
			canvas.addLiteral('%% %s.drawPara' % _className(self))
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   463
			alignment = style.alignment
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   464
			offset = style.firstLineIndent - style.leftIndent
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   465
			lim = nLines-1
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   466
			noJustifyLast = not (hasattr(self,'_JustifyLast') and self._JustifyLast)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   467
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   468
			if bfrags.kind==0:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   469
				if alignment == TA_LEFT:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   470
					dpl = _leftDrawParaLine
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   471
				elif alignment == TA_CENTER:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   472
					dpl = _centerDrawParaLine
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   473
				elif self.style.alignment == TA_RIGHT:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   474
					dpl = _rightDrawParaLine
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   475
				elif self.style.alignment == TA_JUSTIFY:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   476
					dpl = _justifyDrawParaLine
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   477
				f = bfrags
191
c4907a8ee681 Removed usage of spaceBefore/After in wrap methods
rgbecker
parents: 143
diff changeset
   478
				cur_y = self.height - f.fontSize
250
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   479
				if bulletText <> None:
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   480
					offset = _drawBullet(canvas,offset,cur_y,bulletText,style)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   481
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   482
				#set up the font etc.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   483
				canvas._code.append('%s %s %s rg' % (f.textColor.red, f.textColor.green, f.textColor.blue))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   484
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   485
				tx = canvas.beginText(cur_x, cur_y)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   486
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   487
				#now the font for the rest of the paragraph
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   488
				tx.setFont(f.fontName, f.fontSize, style.leading)
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   489
				dpl( tx, offset, lines[0][0], lines[0][1], noJustifyLast and nLines==1)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   490
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   491
				#now the middle of the paragraph, aligned with the left margin which is our origin.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   492
				for i in range(1, nLines):
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   493
					dpl( tx, 0, lines[i][0], lines[i][1], noJustifyLast and i==lim)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   494
			else:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   495
				f = lines[0]
191
c4907a8ee681 Removed usage of spaceBefore/After in wrap methods
rgbecker
parents: 143
diff changeset
   496
				cur_y = self.height - f.fontSize
250
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   497
				if bulletText <> None:
a1bcf9c6c21e <bullet> xml tag added
rgbecker
parents: 221
diff changeset
   498
					offset = _drawBullet(canvas,offset,cur_y,bulletText,style)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   499
				if alignment == TA_LEFT:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   500
					dpl = _leftDrawParaLineX
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   501
				elif alignment == TA_CENTER:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   502
					dpl = _centerDrawParaLineX
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   503
				elif self.style.alignment == TA_RIGHT:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   504
					dpl = _rightDrawParaLineX
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   505
				elif self.style.alignment == TA_JUSTIFY:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   506
					dpl = _justifyDrawParaLineX
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   507
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   508
				#set up the font etc.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   509
				tx = canvas.beginText(cur_x, cur_y)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   510
				tx.XtraState=ParaFrag()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   511
				tx.XtraState.textColor=None
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   512
				tx.XtraState.rise=0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   513
				tx.setLeading(style.leading)
220
3b27693ac273 Fixed font setting bug
rgbecker
parents: 218
diff changeset
   514
				f = lines[0].words[0]
3b27693ac273 Fixed font setting bug
rgbecker
parents: 218
diff changeset
   515
				tx._setFont(f.fontName, f.fontSize)
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   516
				dpl( tx, offset, lines[0], noJustifyLast and nLines==1)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   517
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   518
				#now the middle of the paragraph, aligned with the left margin which is our origin.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   519
				for i in range(1, nLines):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   520
					f = lines[i]
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   521
					dpl( tx, 0, f, noJustifyLast and i==lim)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   522
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   523
			canvas.drawText(tx)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   524
			canvas.restoreState()
284
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   525
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   526
	def getPlainText(self):
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   527
		"""Convenience function for templates which want access
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   528
		to the raw text, without XML tags. """
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   529
		plains = []
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   530
		for frag in self.frags:
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   531
			plains.append(frag.text)
eabeb5f4e851 Added UserDocTemplate class, and paragraph.getPlainText()
andy_robinson
parents: 279
diff changeset
   532
		return string.join(plains, '')
302
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   533
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   534
if __name__=='__main__':	#NORUNTESTS
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   535
	def dumpParagraphLines(P):
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   536
		print 'dumpParagraphLines(%s)' % str(P)
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   537
		lines = P.bfrags.lines
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   538
		n =len(lines)
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   539
		for l in range(n):
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   540
			line = lines[l]
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   541
			words = line.words
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   542
			nwords = len(words)
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   543
			print 'line%d: %d(%d)\n  ' % (l,nwords,line.wordCount),
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   544
			for w in range(nwords):
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   545
				print "%d:'%s'"%(w,words[w].text),
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   546
			print
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   547
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   548
	def dumpParagraphFrags(P):
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   549
		print 'dumpParagraphLines(%s)' % str(P)
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   550
		frags = P.frags
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   551
		n =len(frags)
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   552
		for l in range(n):
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   553
			print "frag%d: '%s'" % (l, frags[l].text)
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   554
	
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   555
		l = 0
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   556
		for W in _getFragWords(frags):
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   557
			print "fragword%d: size=%d" % (l, W[0]),
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   558
			for w in W[1:]:
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   559
				print "'%s'" % w[1],
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   560
			print
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   561
			l = l + 1
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   562
302
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   563
	from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   564
	styleSheet = getSampleStyleSheet()
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   565
	B = styleSheet['BodyText']
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   566
	style = ParagraphStyle("discussiontext", parent=B)
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   567
	style.fontName= 'Helvetica'
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   568
	text='''The <font name=courier color=green>CMYK</font> or subtractive method follows the way a printer
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   569
mixes three pigments (cyan, magenta, and yellow) to form colors.
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   570
Because mixing chemicals is more difficult than combining light there
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   571
is a fourth parameter for darkness.  For example a chemical
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   572
combination of the <font name=courier color=green>CMY</font> pigments generally never makes a perfect
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   573
black -- instead producing a muddy color -- so, to get black printers
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   574
don't use the <font name=courier color=green>CMY</font> pigments but use a direct black ink.  Because
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   575
<font name=courier color=green>CMYK</font> maps more directly to the way printer hardware works it may
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   576
be the case that &amp;| &amp; | colors specified in <font name=courier color=green>CMYK</font> will provide better fidelity
302
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   577
and better control when printed.
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   578
'''
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   579
	P=Paragraph(text,style)
434
257af3109bf4 Various brutal changes to paragraph, canvas and textobject for speed/size
rgbecker
parents: 383
diff changeset
   580
	dumpParagraphFrags(P)
302
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   581
	aW, aH = 456.0, 42.8
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   582
	w,h = P.wrap(aW, aH)
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   583
	dumpParagraphLines(P)
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   584
	S = P.split(aW,aH)
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   585
	for s in S:
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   586
		s.wrap(aW,aH)
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   587
		dumpParagraphLines(s)
960659f9cb5c Fixes to splitting code
rgbecker
parents: 284
diff changeset
   588
		aH = 500
488
a270e8b45200 Added J Alet's bug case
rgbecker
parents: 471
diff changeset
   589
a270e8b45200 Added J Alet's bug case
rgbecker
parents: 471
diff changeset
   590
	P=Paragraph("""Price<super><font color="red">*</font></super>""", styleSheet['Normal'])
a270e8b45200 Added J Alet's bug case
rgbecker
parents: 471
diff changeset
   591
	dumpParagraphFrags(P)
a270e8b45200 Added J Alet's bug case
rgbecker
parents: 471
diff changeset
   592
	w,h = P.wrap(24, 200)
a270e8b45200 Added J Alet's bug case
rgbecker
parents: 471
diff changeset
   593
	dumpParagraphLines(P)