reportlab/platypus/paragraph.py
author rgbecker
Tue, 16 May 2000 16:15:16 +0000
changeset 221 3d71b66b14c6
parent 220 3b27693ac273
child 250 a1bcf9c6c21e
permissions -rw-r--r--
Changes related to removal of SimpleFlowDocument
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
     1
###############################################################################
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
     2
#
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
     3
#	ReportLab Public License Version 1.0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
     4
#
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
     5
#   Except for the change of names the spirit and intention of this
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
     6
#   license is the same as that of Python
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
     7
#
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
     8
#	(C) Copyright ReportLab Inc. 1998-2000.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
     9
#
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    10
#
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    11
# All Rights Reserved
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    12
#
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    13
# Permission to use, copy, modify, and distribute this software and its
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    14
# documentation for any purpose and without fee is hereby granted, provided
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    15
# that the above copyright notice appear in all copies and that both that
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    16
# copyright notice and this permission notice appear in supporting
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    17
# documentation, and that the name of ReportLab not be used
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    18
# in advertising or publicity pertaining to distribution of the software
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    19
# without specific, written prior permission. 
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    20
# 
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    21
#
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    22
# Disclaimer
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    23
#
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    24
# ReportLab Inc. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    25
# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    26
# IN NO EVENT SHALL ReportLab BE LIABLE FOR ANY SPECIAL, INDIRECT
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    27
# OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    28
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    29
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    30
# PERFORMANCE OF THIS SOFTWARE. 
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    31
#
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    32
###############################################################################
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    33
#	$Log: paragraph.py,v $
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 220
diff changeset
    34
#	Revision 1.9  2000/05/16 16:15:16  rgbecker
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 220
diff changeset
    35
#	Changes related to removal of SimpleFlowDocument
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 220
diff changeset
    36
#
220
3b27693ac273 Fixed font setting bug
rgbecker
parents: 218
diff changeset
    37
#	Revision 1.8  2000/05/16 15:58:27  rgbecker
3b27693ac273 Fixed font setting bug
rgbecker
parents: 218
diff changeset
    38
#	Fixed font setting bug
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 220
diff changeset
    39
#	
218
274db2129c04 Fixes/Changes to get testplatypus to work with new framework
rgbecker
parents: 212
diff changeset
    40
#	Revision 1.7  2000/05/16 14:28:55  rgbecker
274db2129c04 Fixes/Changes to get testplatypus to work with new framework
rgbecker
parents: 212
diff changeset
    41
#	Fixes/Changes to get testplatypus to work with new framework
220
3b27693ac273 Fixed font setting bug
rgbecker
parents: 218
diff changeset
    42
#	
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
    43
#	Revision 1.6  2000/05/15 13:36:11  rgbecker
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
    44
#	Splitting changes
218
274db2129c04 Fixes/Changes to get testplatypus to work with new framework
rgbecker
parents: 212
diff changeset
    45
#	
208
4351d6038a4f Fix extraspace calculation
rgbecker
parents: 202
diff changeset
    46
#	Revision 1.5  2000/05/13 16:03:23  rgbecker
4351d6038a4f Fix extraspace calculation
rgbecker
parents: 202
diff changeset
    47
#	Fix extraspace calculation
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
    48
#	
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    49
#	Revision 1.4  2000/05/12 15:13:41  rgbecker
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    50
#	Fixes to alignment handling
208
4351d6038a4f Fix extraspace calculation
rgbecker
parents: 202
diff changeset
    51
#	
191
c4907a8ee681 Removed usage of spaceBefore/After in wrap methods
rgbecker
parents: 143
diff changeset
    52
#	Revision 1.3  2000/05/11 14:04:34  rgbecker
c4907a8ee681 Removed usage of spaceBefore/After in wrap methods
rgbecker
parents: 143
diff changeset
    53
#	Removed usage of spaceBefore/After in wrap methods
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    54
#	
143
cc003e0530ce Fixed repeated breaklines bug
rgbecker
parents: 131
diff changeset
    55
#	Revision 1.2  2000/04/19 13:14:06  rgbecker
cc003e0530ce Fixed repeated breaklines bug
rgbecker
parents: 131
diff changeset
    56
#	Fixed repeated breaklines bug
191
c4907a8ee681 Removed usage of spaceBefore/After in wrap methods
rgbecker
parents: 143
diff changeset
    57
#	
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    58
#	Revision 1.1  2000/04/14 13:21:52  rgbecker
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    59
#	Removed from layout.py
143
cc003e0530ce Fixed repeated breaklines bug
rgbecker
parents: 131
diff changeset
    60
#	
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 220
diff changeset
    61
__version__=''' $Id: paragraph.py,v 1.9 2000/05/16 16:15:16 rgbecker Exp $ '''
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    62
import string
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    63
import types
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    64
from reportlab.pdfbase.pdfmetrics import stringWidth
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    65
from reportlab.platypus.paraparser import ParaParser, ParaFrag
221
3d71b66b14c6 Changes related to removal of SimpleFlowDocument
rgbecker
parents: 220
diff changeset
    66
from layout import Flowable
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    67
from reportlab.lib.colors import Color
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    68
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
    69
from copy import deepcopy
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    70
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    71
#our one and only parser
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    72
_parser=ParaParser()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    73
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    74
def cleanBlockQuotedText(text):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    75
	"""This is an internal utility which takes triple-
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    76
	quoted text form within the document and returns
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    77
	(hopefully) the paragraph the user intended originally."""
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    78
	stripped = string.strip(text)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    79
	lines = string.split(stripped, '\n')
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    80
	trimmed_lines = map(string.lstrip, lines)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    81
	return string.join(trimmed_lines, ' ')
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    82
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    83
def	_leftDrawParaLine( tx, offset, extraspace, words, last=0):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    84
	tx.moveCursor(offset, 0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    85
	tx._textOut(string.join(words),1)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    86
	tx.moveCursor(-offset, 0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    87
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    88
def	_centerDrawParaLine( tx, offset, extraspace, words, last=0):
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    89
	m = offset + 0.5 * extraspace
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    90
	tx.moveCursor(m, 0)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    91
	tx._textOut(string.join(words),1)
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    92
	tx.moveCursor(-m, 0)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    93
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    94
def	_rightDrawParaLine( tx, offset, extraspace, words, last=0):
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    95
	m = offset + extraspace
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    96
	tx.moveCursor(m, 0)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    97
	tx._textOut(string.join(words),1)
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
    98
	tx.moveCursor(-m, 0)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
    99
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   100
def	_justifyDrawParaLine( tx, offset, extraspace, words, last=0):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   101
	tx.moveCursor(offset, 0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   102
	text  = string.join(words)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   103
	if last:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   104
		#last one, left align
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   105
		tx._textOut(text,1)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   106
	else:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   107
		tx.setWordSpace(extraspace / float(len(words)-1))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   108
		tx._textOut(text,1)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   109
		tx.setWordSpace(0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   110
	tx.moveCursor(-offset, 0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   111
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   112
def	_putFragLine(tx,words):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   113
	for f in words:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   114
		if (tx._fontname,tx._fontsize)!=(f.fontName,f.fontSize):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   115
			tx._setFont(f.fontName, f.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   116
		if tx.XtraState.textColor!=f.textColor:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   117
			tx.XtraState.textColor = f.textColor
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   118
			tx.setFillColor(f.textColor)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   119
		if tx.XtraState.rise!=f.rise:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   120
			tx.XtraState.rise=f.rise
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   121
			tx.setRise(f.rise)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   122
		tx._textOut(f.text,f is words[-1])	# cheap textOut
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   123
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   124
def	_leftDrawParaLineX( tx, offset, line, last=0):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   125
	tx.moveCursor(offset, 0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   126
	_putFragLine(tx, line.words)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   127
	tx.moveCursor(-offset, 0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   128
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   129
def	_centerDrawParaLineX( tx, offset, line, last=0):
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
   130
	m = offset+0.5*line.extraSpace
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
   131
	tx.moveCursor(m, 0)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   132
	_putFragLine(tx, line.words)
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
   133
	tx.moveCursor(-m, 0)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   134
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   135
def	_rightDrawParaLineX( tx, offset, line, last=0):
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
   136
	m = offset+line.extraSpace
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
   137
	tx.moveCursor(m, 0)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   138
	_putFragLine(tx, line.words)
202
9ab36770f445 Fixes to alignment handling
rgbecker
parents: 191
diff changeset
   139
	tx.moveCursor(-m, 0)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   140
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   141
def	_justifyDrawParaLineX( tx, offset, line, last=0):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   142
	tx.moveCursor(offset, 0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   143
	if last:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   144
		#last one, left align
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   145
		tx.moveCursor(offset, 0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   146
		_putFragLine(tx, line.words)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   147
		tx.moveCursor(-offset, 0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   148
	else:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   149
		tx.setWordSpace(line.extraSpace / float(line.wordCount-1))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   150
		_putFragLine(tx, line.words)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   151
		tx.setWordSpace(0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   152
	tx.moveCursor(-offset, 0)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   153
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   154
def	_sameFrag(f,g):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   155
	'returns 1 if two frags map out the same'
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   156
	for a in ('fontName', 'fontSize', 'textColor', 'rise'):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   157
		if getattr(f,a)!=getattr(g,a): return 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   158
	return 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   159
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   160
def _getFragWords(frags):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   161
	'''	given a fragment list return a list of lists
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   162
		[[size, (f00,w00), ..., (f0n,w0n)],....,[size, (fm0,wm0), ..., (f0n,wmn)]]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   163
		each pair f,w represents a style and some string
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   164
		each sublist represents a word
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   165
	'''
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   166
	R = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   167
	W = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   168
	n = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   169
	for f in frags:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   170
		text = f.text
143
cc003e0530ce Fixed repeated breaklines bug
rgbecker
parents: 131
diff changeset
   171
		#del f.text	# we can't do this until we sort out splitting
cc003e0530ce Fixed repeated breaklines bug
rgbecker
parents: 131
diff changeset
   172
					# of paragraphs
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   173
		if text!='':
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   174
			S = string.split(text,' ')
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   175
			if W!=[] and text[0] in [' ','\t']:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   176
				W.insert(0,n)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   177
				R.append(W)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   178
				W = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   179
				n = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   180
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   181
			for w in S[:-1]:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   182
				W.append((f,w))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   183
				n = n + stringWidth(w, f.fontName, f.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   184
				W.insert(0,n)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   185
				R.append(W)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   186
				W = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   187
				n = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   188
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   189
			w = S[-1]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   190
			W.append((f,w))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   191
			n = n + stringWidth(w, f.fontName, f.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   192
			if text[-1] in [' ','\t']:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   193
				W.insert(0,n)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   194
				R.append(W)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   195
				W = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   196
				n = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   197
	if W!=[]:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   198
		W.insert(0,n)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   199
		R.append(W)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   200
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   201
	for r in R:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   202
		f = r[1][0]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   203
	return R
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   204
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   205
def	_split_bfragSimple(bfrag,start,stop):
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   206
	f = bfrag.clone()
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   207
	for a in ('lines', 'kind', 'text'):
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   208
		if hasattr(f,a): delattr(f,a)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   209
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   210
	f.words = []
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   211
	for l in bfrag.lines[start:stop]:
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   212
		for w in l[1]:
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   213
			f.words.append(w)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   214
	return [f]
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   215
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   216
def	_split_bfragHard(bfrag,start,stop):
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   217
	f = []
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   218
	for l in bfrag.lines[start:stop-1]:
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   219
		for w in l.words:
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   220
			f.append(w)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   221
	return f
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   222
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   223
class Paragraph(Flowable):
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   224
	def __init__(self, text, style, bulletText = None, frags=None):
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   225
		if frags is None:
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   226
			text = cleanBlockQuotedText(text)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   227
			style, frags = _parser.parse(text,style)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   228
			if frags is None:
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   229
				raise "xml parser error (%s) in paragraph beginning\n'%s'"\
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   230
					% (_parser.errors[0],text[:min(30,len(text))])
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   231
		self.frags = frags
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   232
		self.style = style
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   233
		self.bulletText = bulletText
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   234
		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
   235
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   236
	def wrap(self, availWidth, availHeight):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   237
		# work out widths array for breaking
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   238
		self.width = availWidth
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   239
		first_line_width = availWidth - self.style.firstLineIndent - self.style.rightIndent
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   240
		later_widths = availWidth - self.style.leftIndent - self.style.rightIndent
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   241
		self.bfrags = self.breakLines([first_line_width, later_widths])
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   242
		self.height = len(self.bfrags.lines) * self.style.leading
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   243
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   244
		#estimate the size
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   245
		return (self.width, self.height)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   246
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   247
	def split(self,availWidth, availHeight):
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   248
		if len(self.frags)<=0: return []
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   249
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   250
		#the split information is all inside self.bfrags
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   251
		if not hasattr(self,'bfrags'):
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   252
			self.wrap(availWidth,availHeight)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   253
		bfrags = self.bfrags
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   254
		style = self.style
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   255
		leading = style.leading
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   256
		lines = bfrags.lines
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   257
		n = len(lines)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   258
		s = int(availHeight/leading)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   259
		if s<=1: return []
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   260
		if n<=s: return [self]
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   261
		func = bfrags.kind==0 and _split_bfragSimple or _split_bfragHard
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   262
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   263
		P1=Paragraph(None,style,bulletText=self.bulletText,frags=func(bfrags,0,s))
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   264
		P1._JustifyLast = 1
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   265
		if style.firstLineIndent != 0:
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   266
			style = deepcopy(style)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   267
			style.firstLineIndent = 0
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   268
		P2=Paragraph(None,style,bulletText=None,frags=func(bfrags,s,n))
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   269
		return [P1,P2]
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   270
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   271
	def draw(self):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   272
		#call another method for historical reasons.  Besides, I
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   273
		#suspect I will be playing with alternate drawing routines
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   274
		#so not doing it here makes it easier to switch.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   275
		self.drawPara(self.debug)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   276
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   277
	def breakLines(self, width):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   278
		"""
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   279
		Returns a broken line structure. There are two cases
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   280
		
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   281
		A) For the simple case of a single formatting input fragment the output is
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   282
			A fragment specifier with
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   283
				kind = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   284
				fontName, fontSize, leading, textColor
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   285
				lines=	A list of lines
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   286
						Each line has two items.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   287
						1) unused width in points
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   288
						2) word list
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   289
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   290
		B) When there is more than one input formatting fragment the out put is
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   291
			A fragment specifier with
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   292
				kind = 1
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   293
				lines=	A list of fragments each having fields
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   294
							extraspace (needed for justified)
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   295
							fontSize
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   296
							words=word list
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   297
								each word is itself a fragment with
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   298
								various settings
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   299
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   300
		This structure can be used to easily draw paragraphs with the various alignments.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   301
		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
   302
		last item repeated until necessary. A 2-element list is useful when there is a
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   303
		different first line indent; a longer list could be created to facilitate custom wraps
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   304
		around irregular objects."""
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   305
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   306
		if type(width) <> types.ListType: maxwidths = [width]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   307
		else: maxwidths = width
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   308
		lines = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   309
		lineno = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   310
		maxwidth = maxwidths[lineno]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   311
		style = self.style
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   312
		fFontSize = float(style.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   313
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   314
		#for bullets, work out width and ensure we wrap the right amount onto line one
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   315
		if self.bulletText <> None:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   316
			bulletWidth = stringWidth(
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   317
				self.bulletText,
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   318
				style.bulletFontName, style.bulletFontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   319
			bulletRight = style.bulletIndent + bulletWidth
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   320
			if bulletRight > style.firstLineIndent:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   321
				#..then it overruns, and we have less space available on line 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   322
				maxwidths[0] = maxwidths[0] - (bulletRight - style.firstLineIndent)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   323
191
c4907a8ee681 Removed usage of spaceBefore/After in wrap methods
rgbecker
parents: 143
diff changeset
   324
		self.height = 0
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   325
		frags = self.frags
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   326
		nFrags= len(frags)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   327
		if nFrags==1:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   328
			f = frags[0]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   329
			fontSize = f.fontSize
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   330
			fontName = f.fontName
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   331
			words = hasattr(f,'text') and string.split(f.text, ' ') or f.words
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   332
			spacewidth = stringWidth(' ', fontName, fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   333
			cLine = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   334
			currentwidth = - spacewidth   # hack to get around extra space for word 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   335
			for word in words:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   336
				wordwidth = stringWidth(word, fontName, fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   337
				space_available = maxwidth - (currentwidth + spacewidth + wordwidth)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   338
				if	space_available > 0:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   339
					# fit one more on this line
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   340
					cLine.append(word)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   341
					currentwidth = currentwidth + spacewidth + wordwidth
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   342
				else:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   343
					#end of line
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   344
					lines.append((maxwidth - currentwidth, cLine))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   345
					cLine = [word]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   346
					currentwidth = wordwidth
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   347
					lineno = lineno + 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   348
					try:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   349
						maxwidth = maxwidths[lineno]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   350
					except IndexError:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   351
						maxwidth = maxwidths[-1]  # use the last one
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   352
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   353
			#deal with any leftovers on the final line
208
4351d6038a4f Fix extraspace calculation
rgbecker
parents: 202
diff changeset
   354
			if cLine!=[]: lines.append((maxwidth - currentwidth, cLine))
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   355
			return f.clone(kind=0, lines=lines)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   356
		elif nFrags<=0:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   357
			return ParaFrag(kind=0, fontSize=style.fontSize, fontName=style.fontName,
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   358
							textColor=style.textColor, lines=[])
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   359
		else:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   360
			n = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   361
			for w in _getFragWords(frags):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   362
				spacewidth = stringWidth(' ',w[-1][0].fontName, w[-1][0].fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   363
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   364
				if n==0:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   365
					currentwidth = -spacewidth	 # hack to get around extra space for word 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   366
					words = []
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   367
					maxSize = 0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   368
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   369
				wordwidth = w[0]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   370
				f = w[1][0]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   371
				space_available = maxwidth - (currentwidth + spacewidth + wordwidth)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   372
				if	space_available > 0:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   373
					# fit one more on this line
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   374
					n = n + 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   375
					maxSize = max(maxSize,f.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   376
					if words==[]:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   377
						words = [f.clone()]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   378
						words[-1].text = w[1][1]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   379
					elif not _sameFrag(words[-1],f):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   380
						words[-1].text = words[-1].text+' '
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   381
						words.append(f.clone())
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   382
						words[-1].text = w[1][1]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   383
					else:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   384
						words[-1].text = words[-1].text + ' ' + w[1][1]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   385
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   386
					for i in w[2:]:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   387
						f = i[0].clone()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   388
						f.text=i[1]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   389
						words.append(f)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   390
						maxSize = max(maxSize,f.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   391
						
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   392
					currentwidth = currentwidth + spacewidth + wordwidth
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   393
				else:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   394
					#end of line
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   395
					lines.append(ParaFrag(extraSpace=(maxwidth - currentwidth),wordCount=n,
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   396
										words=words, fontSize=maxSize))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   397
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   398
					#start new line
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   399
					lineno = lineno + 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   400
					try:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   401
						maxwidth = maxwidths[lineno]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   402
					except IndexError:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   403
						maxwidth = maxwidths[-1]  # use the last one
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   404
					currentwidth = wordwidth
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   405
					n = 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   406
					maxSize = f.fontSize
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   407
					words = [f.clone()]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   408
					words[-1].text = w[1][1]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   409
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   410
					for i in w[2:]:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   411
						f = i[0].clone()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   412
						f.text=i[1]
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   413
						words.append(f)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   414
						maxSize = max(maxSize,f.fontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   415
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   416
			#deal with any leftovers on the final line
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   417
			if words<>[]:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   418
				lines.append(ParaFrag(extraSpace=(maxwidth - currentwidth),wordCount=n,
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   419
									words=words, fontSize=maxSize))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   420
			return ParaFrag(kind=1, lines=lines)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   421
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   422
		return lines
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   423
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   424
	def drawPara(self,debug=0):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   425
		"""Draws a paragraph according to the given style.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   426
		Returns the final y position at the bottom. Not safe for
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   427
		paragraphs without spaces e.g. Japanese; wrapping
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   428
		algorithm will go infinite."""
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   429
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   430
		#stash the key facts locally for speed
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   431
		canvas = self.canv
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   432
		style = self.style
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   433
		bfrags = self.bfrags
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   434
		lines = bfrags.lines
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   435
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   436
		#work out the origin for line 1
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   437
		cur_x = style.leftIndent
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   438
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   439
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   440
		if debug:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   441
			# This boxes and shades stuff to show how the paragraph
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   442
			# uses its space.  Useful for self-documentation so
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   443
			# the debug code stays!
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   444
			# box the lot
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   445
			canvas.rect(0, 0, self.width, self.height)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   446
			#left and right margins
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   447
			canvas.saveState()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   448
			canvas.setFillColor(Color(0.9,0.9,0.9))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   449
			canvas.rect(0, 0, style.leftIndent, self.height)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   450
			canvas.rect(self.width - style.rightIndent, 0, style.rightIndent, self.height)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   451
			# shade above and below
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   452
			canvas.setFillColor(Color(1.0,1.0,0.0))
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   453
			canvas.restoreState()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   454
			#self.drawLine(x + style.leftIndent, y, x + style.leftIndent, cur_y)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   455
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   456
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   457
		nLines = len(lines)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   458
		if nLines > 0:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   459
			canvas.saveState()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   460
			canvas.addLiteral('% textcanvas.drawParagraph()')
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   461
			alignment = style.alignment
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   462
			offset = style.firstLineIndent - style.leftIndent
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   463
			lim = nLines-1
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   464
			noJustifyLast = not (hasattr(self,'_JustifyLast') and self._JustifyLast)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   465
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   466
			if bfrags.kind==0:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   467
				if alignment == TA_LEFT:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   468
					dpl = _leftDrawParaLine
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   469
				elif alignment == TA_CENTER:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   470
					dpl = _centerDrawParaLine
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   471
				elif self.style.alignment == TA_RIGHT:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   472
					dpl = _rightDrawParaLine
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   473
				elif self.style.alignment == TA_JUSTIFY:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   474
					dpl = _justifyDrawParaLine
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   475
				f = bfrags
191
c4907a8ee681 Removed usage of spaceBefore/After in wrap methods
rgbecker
parents: 143
diff changeset
   476
				cur_y = self.height - f.fontSize
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   477
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   478
				if self.bulletText <> None:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   479
					tx2 = canvas.beginText(style.bulletIndent, cur_y)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   480
					tx2.setFont(style.bulletFontName, style.bulletFontSize)
218
274db2129c04 Fixes/Changes to get testplatypus to work with new framework
rgbecker
parents: 212
diff changeset
   481
					tx2.setFillColor(hasattr(style,'bulletColor') and style.bulletColor or style.textColor)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   482
					tx2.textOut(self.bulletText)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   483
					bulletEnd = tx2.getX()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   484
					offset = max(offset, bulletEnd - style.leftIndent)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   485
					canvas.drawText(tx2)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   486
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   487
				#set up the font etc.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   488
				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
   489
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   490
				tx = canvas.beginText(cur_x, cur_y)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   491
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   492
				#now the font for the rest of the paragraph
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   493
				tx.setFont(f.fontName, f.fontSize, style.leading)
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   494
				dpl( tx, offset, lines[0][0], lines[0][1], noJustifyLast and nLines==1)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   495
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   496
				#now the middle of the paragraph, aligned with the left margin which is our origin.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   497
				for i in range(1, nLines):
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   498
					dpl( tx, 0, lines[i][0], lines[i][1], noJustifyLast and i==lim)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   499
			else:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   500
				f = lines[0]
191
c4907a8ee681 Removed usage of spaceBefore/After in wrap methods
rgbecker
parents: 143
diff changeset
   501
				cur_y = self.height - f.fontSize
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   502
				if alignment == TA_LEFT:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   503
					dpl = _leftDrawParaLineX
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   504
				elif alignment == TA_CENTER:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   505
					dpl = _centerDrawParaLineX
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   506
				elif self.style.alignment == TA_RIGHT:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   507
					dpl = _rightDrawParaLineX
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   508
				elif self.style.alignment == TA_JUSTIFY:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   509
					dpl = _justifyDrawParaLineX
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   510
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   511
				if self.bulletText <> None:
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   512
					tx2 = canvas.beginText(style.bulletIndent, cur_y)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   513
					tx2.setFont(style.bulletFontName, style.bulletFontSize)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   514
					tx2.textOut(self.bulletText)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   515
					bulletEnd = tx2.getX()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   516
					offset = max(offset, bulletEnd - style.leftIndent)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   517
					canvas.drawText(tx2)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   518
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   519
				#set up the font etc.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   520
				tx = canvas.beginText(cur_x, cur_y)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   521
				tx.XtraState=ParaFrag()
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   522
				tx.XtraState.textColor=None
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   523
				tx.XtraState.rise=0
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   524
				tx.setLeading(style.leading)
220
3b27693ac273 Fixed font setting bug
rgbecker
parents: 218
diff changeset
   525
				f = lines[0].words[0]
3b27693ac273 Fixed font setting bug
rgbecker
parents: 218
diff changeset
   526
				tx._setFont(f.fontName, f.fontSize)
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   527
				dpl( tx, offset, lines[0], noJustifyLast and nLines==1)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   528
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   529
				#now the middle of the paragraph, aligned with the left margin which is our origin.
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   530
				for i in range(1, nLines):
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   531
					f = lines[i]
212
b04e22acb4fa Splitting changes
rgbecker
parents: 208
diff changeset
   532
					dpl( tx, 0, f, noJustifyLast and i==lim)
131
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   533
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   534
			canvas.drawText(tx)
72cb089e6fda Removed from layout.py
rgbecker
parents:
diff changeset
   535
			canvas.restoreState()