5 __doc__='''The standard paragraph implementation''' |
5 __doc__='''The standard paragraph implementation''' |
6 from string import whitespace |
6 from string import whitespace |
7 from operator import truth |
7 from operator import truth |
8 from unicodedata import category |
8 from unicodedata import category |
9 from reportlab.pdfbase.pdfmetrics import stringWidth, getFont, getAscentDescent |
9 from reportlab.pdfbase.pdfmetrics import stringWidth, getFont, getAscentDescent |
10 from reportlab.platypus.paraparser import ParaParser, _PCT |
10 from reportlab.platypus.paraparser import ParaParser, _PCT, _num as _parser_num, _re_us_value |
11 from reportlab.platypus.flowables import Flowable |
11 from reportlab.platypus.flowables import Flowable |
12 from reportlab.lib.colors import Color |
12 from reportlab.lib.colors import Color |
13 from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY |
13 from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY |
14 from reportlab.lib.geomutils import normalizeTRBL |
14 from reportlab.lib.geomutils import normalizeTRBL |
15 from reportlab.lib.textsplit import wordSplit, ALL_CANNOT_START |
15 from reportlab.lib.textsplit import wordSplit, ALL_CANNOT_START |
16 from copy import deepcopy |
16 from copy import deepcopy |
17 from reportlab.lib.abag import ABag |
17 from reportlab.lib.abag import ABag |
18 from reportlab.rl_config import platypus_link_underline, decimalSymbol, _FUZZ, paraFontSizeHeightOffset |
18 from reportlab.rl_config import platypus_link_underline, decimalSymbol, _FUZZ, paraFontSizeHeightOffset, \ |
19 from reportlab.lib.utils import _className, isBytes, unicodeT, bytesT, strTypes |
19 strikeGap, underlineGap |
|
20 from reportlab.lib.utils import _className, isBytes, unicodeT, bytesT, isStr |
20 from reportlab.lib.rl_accel import sameFrag |
21 from reportlab.lib.rl_accel import sameFrag |
21 from reportlab import xrange |
22 from reportlab import xrange |
22 import re |
23 import re |
23 from types import MethodType |
24 from types import MethodType |
24 |
25 |
58 u'\u3000', # IDEOGRAPHIC SPACE |
59 u'\u3000', # IDEOGRAPHIC SPACE |
59 )) |
60 )) |
60 _wsc_re_split=re.compile('[%s]+'% re.escape(_wsc)).split |
61 _wsc_re_split=re.compile('[%s]+'% re.escape(_wsc)).split |
61 _wsc_end_search=re.compile('[%s]+$'% re.escape(_wsc)).search |
62 _wsc_end_search=re.compile('[%s]+$'% re.escape(_wsc)).search |
62 |
63 |
|
64 def _usConv(s, vMap, default=None): |
|
65 '''convert a strike/underline distance to a number''' |
|
66 if isStr(s): |
|
67 s = s.strip() |
|
68 if s: |
|
69 m = _re_us_value.match(s) |
|
70 if m: |
|
71 return float(m.group(1))*vMap[m.group(2)] |
|
72 else: |
|
73 return _parser_num(s,allowRelative=False) |
|
74 elif default: |
|
75 return default |
|
76 return s |
|
77 |
63 def split(text, delim=None): |
78 def split(text, delim=None): |
64 if isBytes(text): text = text.decode('utf8') |
79 if isBytes(text): text = text.decode('utf8') |
65 if delim is not None and isBytes(delim): delim = delim.decode('utf8') |
80 if delim is not None and isBytes(delim): delim = delim.decode('utf8') |
66 return [uword for uword in (_wsc_re_split(text) if delim is None and u'\xa0' in text else text.split(delim))] |
81 return [uword for uword in (_wsc_re_split(text) if delim is None and u'\xa0' in text else text.split(delim))] |
67 |
82 |
262 tx.setFont(xs.style.fontName,xs.style.fontSize) |
281 tx.setFont(xs.style.fontName,xs.style.fontSize) |
263 tx._textOut('',1) |
282 tx._textOut('',1) |
264 else: |
283 else: |
265 cur_x_s = cur_x + nSpaces*ws |
284 cur_x_s = cur_x + nSpaces*ws |
266 end_x = cur_x_s |
285 end_x = cur_x_s |
|
286 fontSize = f.fontSize |
|
287 textColor = f.textColor |
|
288 rise = f.rise |
267 if i > 0: |
289 if i > 0: |
268 end_x = cur_x_s - _trailingSpaceLength(words[i-1].text, tx) |
290 end_x = cur_x_s - _trailingSpaceLength(words[i-1].text, tx) |
269 if (tx._fontname,tx._fontsize)!=(f.fontName,f.fontSize): |
291 if (tx._fontname,tx._fontsize)!=(f.fontName,fontSize): |
270 tx._setFont(f.fontName, f.fontSize) |
292 tx._setFont(f.fontName, fontSize) |
271 if xs.textColor!=f.textColor: |
293 if xs.textColor!=textColor: |
272 xs.textColor = f.textColor |
294 xs.textColor = textColor |
273 tx.setFillColor(f.textColor) |
295 tx.setFillColor(textColor) |
274 if xs.rise!=f.rise: |
296 if xs.rise!=rise: |
275 xs.rise=f.rise |
297 xs.rise=rise |
276 tx.setRise(f.rise) |
298 tx.setRise(rise) |
277 text = f.text |
299 text = f.text |
278 tx._textOut(text,f is words[-1]) # cheap textOut |
300 tx._textOut(text,f is words[-1]) # cheap textOut |
279 if not xs.underline and f.underline: |
301 if LL != f.us_lines: |
280 xs.underline = 1 |
302 S = set(LL) |
281 xs.underline_x = cur_x_s |
303 NS = set(f.us_lines) |
282 xs.underlineColor = f.textColor |
304 nL = NS - S #new lines |
283 elif xs.underline: |
305 eL = S - NS #ending lines |
284 if not f.underline: |
306 for l in eL: |
285 xs.underline = 0 |
307 us_lines[l] = us_lines[l],end_x |
286 xs.underlines.append( (xs.underline_x, end_x, xs.underlineColor) ) |
308 for l in nL: |
287 xs.underlineColor = None |
309 us_lines[l] = (l,fontSize,textColor,cur_x),fontSize |
288 elif xs.textColor!=xs.underlineColor: |
310 LL = f.us_lines |
289 xs.underlines.append( (xs.underline_x, end_x, xs.underlineColor) ) |
311 if LL: |
290 xs.underlineColor = xs.textColor |
312 for l in LL: |
291 xs.underline_x = cur_x_s |
313 l0, fsmax = us_lines[l] |
292 if not xs.strike and f.strike: |
314 if fontSize>fsmax: |
293 xs.strike = 1 |
315 us_lines[l] = l0, fontSize |
294 xs.strike_x = cur_x_s |
316 |
295 xs.strikeColor = f.textColor |
317 nlo = rise - 0.2*fontSize |
296 elif xs.strike: |
318 nhi = rise + fontSize |
297 if not f.strike: |
319 if AL != f.link: |
298 xs.strike = 0 |
320 S = set(AL) |
299 xs.strikes.append( (xs.strike_x, end_x, xs.strikeColor) ) |
321 NS = set(f.link) |
300 xs.strikeColor = None |
322 nL = NS - S #new linkis |
301 elif xs.textColor!=xs.strikeColor: |
323 eL = S - NS #ending links |
302 xs.strikes.append( (xs.strike_x, end_x, xs.strikeColor) ) |
324 for l in eL: |
303 xs.strikeColor = xs.textColor |
325 links[l] = links[l],end_x |
304 xs.strike_x = cur_x_s |
326 for l in nL: |
305 if f.link and not xs.link: |
327 links[l] = (l,cur_x),nlo,nhi |
306 if not xs.link: |
328 AL = f.link |
307 xs.link = f.link |
329 if AL: |
308 xs.link_x = cur_x_s |
330 for l in AL: |
309 xs.linkColor = xs.textColor |
331 l0, lo, hi = links[l] |
310 elif xs.link: |
332 if nlo<lo or nhi>hi: |
311 if not f.link: |
333 links[l] = l0,min(nlo,lo),max(nhi,hi) |
312 xs.links.append( (xs.link_x, end_x, xs.link, xs.linkColor) ) |
334 |
313 xs.link = None |
|
314 xs.linkColor = None |
|
315 elif f.link!=xs.link or xs.textColor!=xs.linkColor: |
|
316 xs.links.append( (xs.link_x, end_x, xs.link, xs.linkColor) ) |
|
317 xs.link = f.link |
|
318 xs.link_x = cur_x_s |
|
319 xs.linkColor = xs.textColor |
|
320 bg = getattr(f,'backColor',None) |
335 bg = getattr(f,'backColor',None) |
321 if bg and not xs.backColor: |
336 if bg and not xs.backColor: |
322 xs.backColor = bg |
337 xs.backColor = bg |
323 xs.backColor_x = cur_x_s |
338 xs.backColor_x = cur_x_s |
324 elif xs.backColor: |
339 elif xs.backColor: |
330 xs.backColor = bg |
345 xs.backColor = bg |
331 xs.backColor_x = cur_x_s |
346 xs.backColor_x = cur_x_s |
332 txtlen = tx._canvas.stringWidth(text, tx._fontname, tx._fontsize) |
347 txtlen = tx._canvas.stringWidth(text, tx._fontname, tx._fontsize) |
333 cur_x += txtlen |
348 cur_x += txtlen |
334 nSpaces += text.count(' ')+_nbspCount(text) |
349 nSpaces += text.count(' ')+_nbspCount(text) |
|
350 |
335 cur_x_s = cur_x+(nSpaces-1)*ws |
351 cur_x_s = cur_x+(nSpaces-1)*ws |
336 if last and pKind!='right' and xs.style.endDots: |
352 if last and pKind!='right' and xs.style.endDots: |
337 _do_dots_frag(cur_x,cur_x_s,line.maxWidth,xs,tx) |
353 _do_dots_frag(cur_x,cur_x_s,line.maxWidth,xs,tx) |
338 if xs.underline: |
354 |
339 xs.underlines.append( (xs.underline_x, cur_x_s, xs.underlineColor) ) |
355 if LL: |
340 if xs.strike: |
356 for l in LL: |
341 xs.strikes.append( (xs.strike_x, cur_x_s, xs.strikeColor) ) |
357 us_lines[l] = us_lines[l], cur_x_s |
342 if xs.link: |
358 |
343 xs.links.append( (xs.link_x, cur_x_s, xs.link,xs.linkColor) ) |
359 if AL: |
|
360 for l in AL: |
|
361 links[l] = links[l], cur_x_s |
|
362 |
344 if xs.backColor: |
363 if xs.backColor: |
345 xs.backColors.append( (xs.backColor_x, cur_x_s, xs.backColor) ) |
364 xs.backColors.append( (xs.backColor_x, cur_x_s, xs.backColor) ) |
346 if tx._x0!=x0: |
365 if tx._x0!=x0: |
347 setXPos(tx,x0-tx._x0) |
366 setXPos(tx,x0-tx._x0) |
348 |
367 |
706 def _drawBullet(canvas, offset, cur_y, bulletText, style, rtl): |
725 def _drawBullet(canvas, offset, cur_y, bulletText, style, rtl): |
707 '''draw a bullet text could be a simple string or a frag list''' |
726 '''draw a bullet text could be a simple string or a frag list''' |
708 bulletAnchor = style.bulletAnchor |
727 bulletAnchor = style.bulletAnchor |
709 if rtl or style.bulletAnchor!='start': |
728 if rtl or style.bulletAnchor!='start': |
710 numeric = bulletAnchor=='numeric' |
729 numeric = bulletAnchor=='numeric' |
711 if isinstance(bulletText,strTypes): |
730 if isStr(bulletText): |
712 t = bulletText |
731 t = bulletText |
713 q = numeric and decimalSymbol in t |
732 q = numeric and decimalSymbol in t |
714 if q: t = t[:t.index(decimalSymbol)] |
733 if q: t = t[:t.index(decimalSymbol)] |
715 bulletWidth = stringWidth(t, style.bulletFontName, style.bulletFontSize) |
734 bulletWidth = stringWidth(t, style.bulletFontName, style.bulletFontSize) |
716 if q: bulletWidth += 0.5 * stringWidth(decimalSymbol, style.bulletFontName, style.bulletFontSize) |
735 if q: bulletWidth += 0.5 * stringWidth(decimalSymbol, style.bulletFontName, style.bulletFontSize) |
736 width = rtl[0] |
755 width = rtl[0] |
737 bulletStart = width+style.rightIndent-(style.bulletIndent+bulletWidth) |
756 bulletStart = width+style.rightIndent-(style.bulletIndent+bulletWidth) |
738 tx2 = canvas.beginText(bulletStart, cur_y) |
757 tx2 = canvas.beginText(bulletStart, cur_y) |
739 tx2.setFont(style.bulletFontName, style.bulletFontSize) |
758 tx2.setFont(style.bulletFontName, style.bulletFontSize) |
740 tx2.setFillColor(getattr(style,'bulletColor',style.textColor)) |
759 tx2.setFillColor(getattr(style,'bulletColor',style.textColor)) |
741 if isinstance(bulletText,strTypes): |
760 if isStr(bulletText): |
742 tx2.textOut(bulletText) |
761 tx2.textOut(bulletText) |
743 else: |
762 else: |
744 for f in bulletText: |
763 for f in bulletText: |
745 tx2.setFont(f.fontName, f.fontSize) |
764 tx2.setFont(f.fontName, f.fontSize) |
746 tx2.setFillColor(f.textColor) |
765 tx2.setFillColor(f.textColor) |
830 g = (f,start,j) |
849 g = (f,start,j) |
831 line.append(g) |
850 line.append(g) |
832 if j==lim: |
851 if j==lim: |
833 i += 1 |
852 i += 1 |
834 |
853 |
835 def _old_do_line(tx, x1, y1, x2, y2): |
854 def _do_line(tx, x1, y1, x2, y2, nlw, nsc): |
836 tx._canvas.line(x1, y1, x2, y2) |
855 canv = tx._canvas |
837 |
856 olw = canv._lineWidth |
838 def _do_line(tx, x1, y1, x2, y2): |
|
839 olw = tx._canvas._lineWidth |
|
840 nlw = tx._underlineProportion*tx._fontsize |
|
841 if nlw!=olw: |
857 if nlw!=olw: |
842 tx._canvas.setLineWidth(nlw) |
858 canv.setLineWidth(nlw) |
843 tx._canvas.line(x1, y1, x2, y2) |
859 osc = canv._strokeColorObj |
844 tx._canvas.setLineWidth(olw) |
860 if nsc!=osc: |
845 else: |
861 canv.setStrokeColor(nsc) |
846 tx._canvas.line(x1, y1, x2, y2) |
862 canv.line(x1, y1, x2, y2) |
847 |
863 |
848 def _do_under_line(i, t_off, ws, tx, lm=-0.125): |
864 def _do_under_line(i, x1, ws, tx, us_lines): |
849 y = tx.XtraState.cur_y - i*tx.XtraState.style.leading + lm*tx.XtraState.f.fontSize |
865 xs = tx.XtraState |
850 textlen = tx._canvas.stringWidth(' '.join(tx.XtraState.lines[i][1]), tx._fontname, tx._fontsize) |
866 style = xs.style |
851 tx._do_line(t_off, y, t_off+textlen, y) |
867 y0 = xs.cur_y - i*style.leading |
|
868 f = xs.f |
|
869 fs = f.fontSize |
|
870 tc = f.textColor |
|
871 values = dict(L=fs,F=fs,f=fs) |
|
872 dw = tx._defaultLineWidth |
|
873 x2 = x1 + tx._canvas.stringWidth(' '.join(tx.XtraState.lines[i][1]), tx._fontname, fs) |
|
874 for n,k,c,w,o,r,m,g in us_lines: |
|
875 underline = k=='underline' |
|
876 lw = _usConv(w,values,default=tx._defaultLineWidth) |
|
877 lg = _usConv(g,values,default=1) |
|
878 dy = lg+lw |
|
879 if not underline: dy = -dy |
|
880 y = y0 + r + _usConv(('-0.125*L' if underline else '0.25*L') if o=='' else o,values) |
|
881 if not c: c = tc |
|
882 while m>0: |
|
883 tx._do_line(x1, y, x2, y, lw, c) |
|
884 y -= dy |
|
885 m -= 1 |
852 |
886 |
853 _scheme_re = re.compile('^[a-zA-Z][-+a-zA-Z0-9]+$') |
887 _scheme_re = re.compile('^[a-zA-Z][-+a-zA-Z0-9]+$') |
854 def _doLink(tx,link,rect): |
888 def _doLink(tx,link,rect): |
855 parts = link.split(':',1) |
889 parts = link.split(':',1) |
856 scheme = len(parts)==2 and parts[0].lower() or '' |
890 scheme = len(parts)==2 and parts[0].lower() or '' |
857 if _scheme_re.match(scheme) and scheme!='document': |
891 if _scheme_re.match(scheme) and scheme!='document': |
858 kind=scheme.lower()=='pdf' and 'GoToR' or 'URI' |
892 kind=scheme.lower()=='pdf' and 'GoToR' or 'URI' |
859 if kind=='GoToR': link = parts[1] |
893 if kind=='GoToR': link = parts[1] |
860 tx._canvas.linkURL(link, rect, relative=1, kind=kind) |
894 tx._canvas.linkURL(link, rect, relative=1, kind=kind) |
861 else: |
895 else: |
|
896 if not link: return |
862 if link[0]=='#': |
897 if link[0]=='#': |
863 link = link[1:] |
898 link = link[1:] |
864 scheme='' |
899 scheme='' |
865 tx._canvas.linkRect("", scheme!='document' and link or parts[1], rect, relative=1) |
900 tx._canvas.linkRect("", scheme!='document' and link or parts[1], rect, relative=1) |
866 |
901 |
868 xs = tx.XtraState |
903 xs = tx.XtraState |
869 leading = xs.style.leading |
904 leading = xs.style.leading |
870 y = xs.cur_y - i*leading - xs.f.fontSize/8.0 # 8.0 factor copied from para.py |
905 y = xs.cur_y - i*leading - xs.f.fontSize/8.0 # 8.0 factor copied from para.py |
871 text = ' '.join(xs.lines[i][1]) |
906 text = ' '.join(xs.lines[i][1]) |
872 textlen = tx._canvas.stringWidth(text, tx._fontname, tx._fontsize) |
907 textlen = tx._canvas.stringWidth(text, tx._fontname, tx._fontsize) |
873 _doLink(tx, xs.link, (t_off, y, t_off+textlen, y+leading)) |
908 for n, link in xs.link: |
|
909 _doLink(tx, link, (t_off, y, t_off+textlen, y+leading)) |
874 |
910 |
875 def _do_post_text(tx): |
911 def _do_post_text(tx): |
876 xs = tx.XtraState |
912 xs = tx.XtraState |
|
913 y0 = xs.cur_y |
|
914 f = xs.f |
877 leading = xs.style.leading |
915 leading = xs.style.leading |
878 autoLeading = xs.autoLeading |
916 autoLeading = xs.autoLeading |
879 y0 = xs.cur_y |
917 fontSize = f.fontSize |
880 f = xs.f |
|
881 ff = 0.125*f.fontSize |
|
882 yl = y0 + f.fontSize |
|
883 if autoLeading=='max': |
918 if autoLeading=='max': |
884 leading = max(leading,1.2*f.fontSize) |
919 leading = max(leading,1.2*fontSize) |
885 elif autoLeading=='min': |
920 elif autoLeading=='min': |
886 leading = 1.2*f.fontSize |
921 leading = 1.2*fontSize |
887 ydesc = yl - leading |
922 |
888 |
923 if xs.backColors: |
889 for x1,x2,c in xs.backColors: |
924 yl = y0 + fontSize |
890 tx._canvas.setFillColor(c) |
925 ydesc = yl - leading |
891 tx._canvas.rect(x1,ydesc,x2-x1,leading,stroke=0,fill=1) |
926 |
892 xs.backColors=[] |
927 for x1,x2,c in xs.backColors: |
893 xs.backColor=None |
928 tx._canvas.setFillColor(c) |
894 |
929 tx._canvas.rect(x1,ydesc,x2-x1,leading,stroke=0,fill=1) |
895 y = y0 - ff |
930 xs.backColors=[] |
896 csc = None |
931 xs.backColor=None |
897 for x1,x2,c in xs.underlines: |
932 |
898 if c!=csc: |
933 for (((n,link),x1),lo,hi),x2 in sorted(xs.links.values()): |
899 tx._canvas.setStrokeColor(c) |
934 _doLink(tx, link, (x1, y0+lo, x2, y0+hi)) |
900 csc = c |
935 xs.links = {} |
901 tx._do_line(x1, y, x2, y) |
936 |
902 xs.underlines = [] |
937 if xs.us_lines: |
903 xs.underline=0 |
938 #print 'lines' |
904 xs.underlineColor=None |
939 dw = tx._defaultLineWidth |
905 |
940 values = dict(L=fontSize) |
906 ys = y0 + 2*ff |
941 for (((n,k,c,w,o,r,m,g),fs,tc,x1),fsmax),x2 in sorted(xs.us_lines.values()): |
907 for x1,x2,c in xs.strikes: |
942 underline = k=='underline' |
908 if c!=csc: |
943 values['f'] = fs |
909 tx._canvas.setStrokeColor(c) |
944 values['F'] = fsmax |
910 csc = c |
945 lw = _usConv(w,values,default=tx._defaultLineWidth) |
911 tx._do_line(x1, ys, x2, ys) |
946 lg = _usConv(g,values,default=1) |
912 xs.strikes = [] |
947 dy = lg+lw |
913 xs.strike=0 |
948 if not underline: dy = -dy |
914 xs.strikeColor=None |
949 y = y0 + r + _usConv(o if o!='' else ('-0.125*L' if underline else '0.25*L'),values) |
915 |
950 #print 'n=%s k=%s x1=%s x2=%s r=%s c=%s w=%r o=%r fs=%r tc=%s y=%s lW=%r offs=%r' % (n,k,x1,x2,r,(c.hexval() if c else ''),w,o,fs,tc.hexval(),y,lW,y-y0-r) |
916 for x1,x2,link,c in xs.links: |
951 if not c: c = tc |
917 if platypus_link_underline: |
952 while m>0: |
918 if c!=csc: |
953 tx._do_line(x1, y, x2, y, lw, c) |
919 tx._canvas.setStrokeColor(c) |
954 y -= dy |
920 csc = c |
955 m -= 1 |
921 tx._do_line(x1, y, x2, y) |
956 xs.us_lines = {} |
922 _doLink(tx, link, (x1, ydesc, x2, yl)) |
|
923 xs.links = [] |
|
924 xs.link=None |
|
925 xs.linkColor=None |
|
926 |
957 |
927 xs.cur_y -= leading |
958 xs.cur_y -= leading |
928 |
959 |
929 def textTransformFrags(frags,style): |
960 def textTransformFrags(frags,style): |
930 tt = style.textTransform |
961 tt = style.textTransform |
1100 This class is a flowable that can format a block of text |
1131 This class is a flowable that can format a block of text |
1101 into a paragraph with a given style. |
1132 into a paragraph with a given style. |
1102 |
1133 |
1103 The paragraph Text can contain XML-like markup including the tags: |
1134 The paragraph Text can contain XML-like markup including the tags: |
1104 <b> ... </b> - bold |
1135 <b> ... </b> - bold |
|
1136 < u [color="red"] [width="pts"] [offset="pts"]> < /u > - underline |
|
1137 width and offset can be empty meaning use existing canvas line width |
|
1138 or with an f/F suffix regarded as a fraction of the font size |
|
1139 < strike > < /strike > - strike through has the same parameters as underline |
1105 <i> ... </i> - italics |
1140 <i> ... </i> - italics |
1106 <u> ... </u> - underline |
1141 <u> ... </u> - underline |
1107 <strike> ... </strike> - strike through |
1142 <strike> ... </strike> - strike through |
1108 <super> ... </super> - superscript |
1143 <super> ... </super> - superscript |
1109 <sub> ... </sub> - subscript |
1144 <sub> ... </sub> - subscript |
1110 <font name=fontfamily/fontname color=colorname size=float> |
1145 <font name=fontfamily/fontname color=colorname size=float> |
1111 <span name=fontfamily/fontname color=colorname backcolor=colorname size=float style=stylename> |
1146 <span name=fontfamily/fontname color=colorname backcolor=colorname size=float style=stylename> |
1112 <onDraw name=callable label="a label"/> |
1147 <onDraw name=callable label="a label"/> |
1113 <index [name="callablecanvasattribute"] label="a label"/> |
1148 <index [name="callablecanvasattribute"] label="a label"/> |
1114 <link>link text</link> |
1149 <link>link text</link> |
1115 attributes of links |
1150 attributes of links |
1116 size/fontSize=num |
1151 size/fontSize/uwidth/uoffset=num |
1117 name/face/fontName=name |
1152 name/face/fontName=name |
1118 fg/textColor/color=color |
1153 fg/textColor/color/ucolor=color |
1119 backcolor/backColor/bgcolor=color |
1154 backcolor/backColor/bgcolor=color |
1120 dest/destination/target/href/link=target |
1155 dest/destination/target/href/link=target |
|
1156 underline=bool turn on underline |
1121 <a>anchor text</a> |
1157 <a>anchor text</a> |
1122 attributes of anchors |
1158 attributes of anchors |
1123 fontSize=num |
1159 size/fontSize/uwidth/uoffset=num |
1124 fontName=name |
1160 fontName=name |
1125 fg/textColor/color=color |
1161 fg/textColor/color/ucolor=color |
1126 backcolor/backColor/bgcolor=color |
1162 backcolor/backColor/bgcolor=color |
1127 href=href |
1163 href=href |
|
1164 underline="yes|no" |
1128 <a name="anchorpoint"/> |
1165 <a name="anchorpoint"/> |
1129 <unichar name="unicode character name"/> |
1166 <unichar name="unicode character name"/> |
1130 <unichar value="unicode code point"/> |
1167 <unichar value="unicode code point"/> |
1131 <img src="path" width="1in" height="1in" valign="bottom"/> |
1168 <img src="path" width="1in" height="1in" valign="bottom"/> |
1132 width="w%" --> fontSize*w/100 idea from Roberto Alsina |
1169 width="w%" --> fontSize*w/100 idea from Roberto Alsina |
1764 words = lines[0][1] |
1795 words = lines[0][1] |
1765 lastLine = noJustifyLast and nLines==1 |
1796 lastLine = noJustifyLast and nLines==1 |
1766 if lastLine and jllwc and len(words)>jllwc: |
1797 if lastLine and jllwc and len(words)>jllwc: |
1767 lastLine=False |
1798 lastLine=False |
1768 t_off = dpl( tx, offset, ws, words, lastLine) |
1799 t_off = dpl( tx, offset, ws, words, lastLine) |
1769 if f.underline or f.link or f.strike or style.endDots: |
1800 if f.us_lines or f.link or style.endDots: |
1770 xs = tx.XtraState = ABag() |
1801 tx._do_line = MethodType(_do_line,tx) |
|
1802 tx.xs = xs = tx.XtraState = ABag() |
|
1803 tx._defaultLineWidth = canvas._lineWidth |
1771 xs.cur_y = cur_y |
1804 xs.cur_y = cur_y |
1772 xs.f = f |
1805 xs.f = f |
1773 xs.style = style |
1806 xs.style = style |
1774 xs.lines = lines |
1807 xs.lines = lines |
1775 xs.underlines=[] |
|
1776 xs.underlineColor=None |
|
1777 xs.strikes=[] |
|
1778 xs.strikeColor=None |
|
1779 xs.links=[] |
|
1780 xs.link=f.link |
1808 xs.link=f.link |
1781 xs.textColor = f.textColor |
1809 xs.textColor = f.textColor |
1782 xs.backColors = [] |
1810 xs.backColors = [] |
1783 canvas.setStrokeColor(f.textColor) |
|
1784 dx = t_off+leftIndent |
1811 dx = t_off+leftIndent |
1785 if dpl!=_justifyDrawParaLine: ws = 0 |
1812 if dpl!=_justifyDrawParaLine: ws = 0 |
1786 underline = f.underline or (f.link and platypus_link_underline) |
1813 if f.us_lines: |
1787 strike = f.strike |
1814 _do_under_line(0, t_off, ws, tx, f.us_lines) |
1788 link = f.link |
1815 if f.link: _do_link_line(0, dx, ws, tx) |
1789 if underline: _do_under_line(0, dx, ws, tx) |
|
1790 if strike: _do_under_line(0, dx, ws, tx, lm=0.125) |
|
1791 if link: _do_link_line(0, dx, ws, tx) |
|
1792 if lastLine and style.endDots and dpl!=_rightDrawParaLine: _do_dots(0, dx, ws, xs, tx, dpl) |
1816 if lastLine and style.endDots and dpl!=_rightDrawParaLine: _do_dots(0, dx, ws, xs, tx, dpl) |
1793 |
1817 |
1794 #now the middle of the paragraph, aligned with the left margin which is our origin. |
1818 #now the middle of the paragraph, aligned with the left margin which is our origin. |
1795 for i in xrange(1, nLines): |
1819 for i in xrange(1, nLines): |
1796 ws = lines[i][0] |
1820 ws = lines[i][0] |
1799 if lastLine and jllwc and len(words)>jllwc: |
1823 if lastLine and jllwc and len(words)>jllwc: |
1800 lastLine=False |
1824 lastLine=False |
1801 t_off = dpl( tx, _offsets[i], ws, words, lastLine) |
1825 t_off = dpl( tx, _offsets[i], ws, words, lastLine) |
1802 dx = t_off+leftIndent |
1826 dx = t_off+leftIndent |
1803 if dpl!=_justifyDrawParaLine: ws = 0 |
1827 if dpl!=_justifyDrawParaLine: ws = 0 |
1804 if underline: _do_under_line(i, dx, ws, tx) |
1828 if f.us_lines: |
1805 if strike: _do_under_line(i, dx, ws, tx, lm=0.125) |
1829 _do_under_line(i, t_off, ws, tx, f.us_lines) |
1806 if link: _do_link_line(i, dx, ws, tx) |
1830 if f.link: _do_link_line(i, dx, ws, tx) |
1807 if lastLine and style.endDots and dpl!=_rightDrawParaLine: _do_dots(i, dx, ws, xs, tx, dpl) |
1831 if lastLine and style.endDots and dpl!=_rightDrawParaLine: _do_dots(i, dx, ws, xs, tx, dpl) |
1808 else: |
1832 else: |
1809 for i in xrange(1, nLines): |
1833 for i in xrange(1, nLines): |
1810 words = lines[i][1] |
1834 words = lines[i][1] |
1811 lastLine = noJustifyLast and i==lim |
1835 lastLine = noJustifyLast and i==lim |
1837 else: |
1861 else: |
1838 raise ValueError("bad align %s" % repr(alignment)) |
1862 raise ValueError("bad align %s" % repr(alignment)) |
1839 |
1863 |
1840 #set up the font etc. |
1864 #set up the font etc. |
1841 tx = self.beginText(cur_x, cur_y) |
1865 tx = self.beginText(cur_x, cur_y) |
1842 if style.underlineProportion: |
1866 tx._defaultLineWidth = canvas._lineWidth |
1843 tx._underlineProportion = style.underlineProportion |
1867 tx._underlineWidth = getattr(style,'underlineWidth','') |
1844 tx._do_line = _do_line |
1868 tx._underlineOffset = getattr(style,'underlineOffset','') or '-0.125f' |
1845 else: |
1869 tx._strikeWidth = getattr(style,'strikeWidth','') |
1846 tx._do_line = _old_do_line |
1870 tx._strikeOffset = getattr(style,'strikeOffset','') or '0.25f' |
1847 tx._do_line = MethodType(tx._do_line,tx) |
1871 tx._do_line = MethodType(_do_line,tx) |
1848 # set the paragraph direction |
1872 # set the paragraph direction |
1849 tx.direction = self.style.wordWrap |
1873 tx.direction = self.style.wordWrap |
1850 |
1874 |
1851 xs = tx.XtraState=ABag() |
1875 xs = tx.XtraState=ABag() |
1852 xs.textColor=None |
1876 xs.textColor=None |
1853 xs.backColor=None |
1877 xs.backColor=None |
1854 xs.rise=0 |
1878 xs.rise=0 |
1855 xs.underline=0 |
|
1856 xs.underlines=[] |
|
1857 xs.underlineColor=None |
|
1858 xs.strike=0 |
|
1859 xs.strikes=[] |
|
1860 xs.strikeColor=None |
|
1861 xs.backColors=[] |
1879 xs.backColors=[] |
1862 xs.links=[] |
1880 xs.us_lines = {} |
1863 xs.link=None |
1881 xs.links = {} |
|
1882 xs.link={} |
1864 xs.leading = style.leading |
1883 xs.leading = style.leading |
1865 xs.leftIndent = leftIndent |
1884 xs.leftIndent = leftIndent |
1866 tx._leading = None |
1885 tx._leading = None |
1867 tx._olb = None |
1886 tx._olb = None |
1868 xs.cur_y = cur_y |
1887 xs.cur_y = cur_y |