reportlab: add support for strike through
authorrgbecker
Mon, 05 Jun 2006 13:55:03 +0000
changeset 2644 e762ad1c8909
parent 2643 602a93f33528
child 2645 ba65582b2f3f
reportlab: add support for strike through
reportlab/platypus/paragraph.py
reportlab/platypus/paraparser.py
reportlab/test/test_platypus_paragraphs.py
--- a/reportlab/platypus/paragraph.py	Mon Jun 05 13:43:08 2006 +0000
+++ b/reportlab/platypus/paragraph.py	Mon Jun 05 13:55:03 2006 +0000
@@ -138,6 +138,20 @@
                     xtraState.underlines.append( (xtraState.underline_x, cur_x, xtraState.underlineColor) )
                     xtraState.underlineColor = xtraState.textColor
                     xtraState.underline_x = cur_x
+            if not xtraState.strike and f.strike:
+                xtraState.strike = 1
+                xtraState.strike_x = cur_x
+                xtraState.strikeColor = f.textColor
+            elif xtraState.strike:
+                if not f.strike:
+                    xtraState.strike = 0
+                    spacelen = tx._canvas.stringWidth(' ', tx._fontname, tx._fontsize)
+                    xtraState.strikes.append( (xtraState.strike_x, cur_x-spacelen, xtraState.strikeColor) )
+                    xtraState.strikeColor = None
+                elif xtraState.textColor!=xtraState.strikeColor:
+                    xtraState.strikes.append( (xtraState.strike_x, cur_x, xtraState.strikeColor) )
+                    xtraState.strikeColor = xtraState.textColor
+                    xtraState.strike_x = cur_x
             if not xtraState.link and f.link:
                 xtraState.link = f.link
                 xtraState.link_x = cur_x
@@ -148,6 +162,8 @@
             cur_x += txtlen
     if xtraState.underline:
         xtraState.underlines.append( (xtraState.underline_x, cur_x, xtraState.underlineColor) )
+    if xtraState.strike:
+        xtraState.strikes.append( (xtraState.strike_x, cur_x, xtraState.strikeColor) )
     if xtraState.link:
         xtraState.links.append( (xtraState.link_x, cur_x, xtraState.link) )
 
@@ -193,10 +209,11 @@
     try:
         from reportlab.lib._rl_accel import _sameFrag
     except ImportError:
+        #if you modify this you need to modify _rl_accel RGB
         def _sameFrag(f,g):
             'returns 1 if two ParaFrags map out the same'
             if hasattr(f,'cbDefn') or hasattr(g,'cbDefn'): return 0
-            for a in ('fontName', 'fontSize', 'textColor', 'rise', 'underline', 'link'):
+            for a in ('fontName', 'fontSize', 'textColor', 'rise', 'underline', 'strike', 'link'):
                 if getattr(f,a)!=getattr(g,a): return 0
             return 1
 
@@ -366,24 +383,12 @@
             if j==lim:
                 i += 1
 
-def _do_under_line(i, t_off, tx):
-    y = tx.XtraState.cur_y - i*tx.XtraState.style.leading - tx.XtraState.f.fontSize/8.0 # 8.0 factor copied from para.py
+def _do_under_line(i, t_off, tx, lm=-0.125):
+    y = tx.XtraState.cur_y - i*tx.XtraState.style.leading + lm*tx.XtraState.f.fontSize
     text = join(tx.XtraState.lines[i][1])
     textlen = tx._canvas.stringWidth(text, tx._fontname, tx._fontsize)
     tx._canvas.line(t_off, y, t_off+textlen, y)
 
-def _do_under(i, t_off, tx):
-    xtraState = tx.XtraState
-    y = xtraState.cur_y - i*xtraState.style.leading - xtraState.f.fontSize/8.0 # 8.0 factor copied from para.py
-    ulc = None
-    for x1,x2,c in xtraState.underlines:
-        if c!=ulc:
-            tx._canvas.setStrokeColor(c)
-            ulc = c
-        tx._canvas.line(t_off+x1, y, t_off+x2, y)
-    xtraState.underlines = []
-    xtraState.underline=0
-    xtraState.underlineColor=None
 
 _scheme_re = re.compile('^[a-zA-Z][-+a-zA-Z0-9]+$')
 def _doLink(tx,link,rect):
@@ -406,13 +411,37 @@
     textlen = tx._canvas.stringWidth(text, tx._fontname, tx._fontsize)
     _doLink(tx, xs.link, (t_off, y, t_off+textlen, y+leading))
 
-def _do_link(i, t_off, tx):
+def _do_post_text(i, t_off, tx):
     xs = tx.XtraState
     leading = xs.style.leading
-    y = xs.cur_y - i*leading - xs.f.fontSize/8.0 # 8.0 factor copied from para.py
+    ff = 0.125*xs.f.fontSize
+    y0 = xs.cur_y - i*leading
+    y = y0 - ff
+    ulc = None
+    for x1,x2,c in xs.underlines:
+        if c!=ulc:
+            tx._canvas.setStrokeColor(c)
+            ulc = c
+        tx._canvas.line(t_off+x1, y, t_off+x2, y)
+    xs.underlines = []
+    xs.underline=0
+    xs.underlineColor=None
+
+    ys = y0 + 2*ff
+    ulc = None
+    for x1,x2,c in xs.strikes:
+        if c!=ulc:
+            tx._canvas.setStrokeColor(c)
+            ulc = c
+        tx._canvas.line(t_off+x1, ys, t_off+x2, ys)
+    xs.strikes = []
+    xs.strike=0
+    xs.strikeColor=None
+
+    yl = y + leading
     for x1,x2,link in xs.links:
         tx._canvas.line(t_off+x1, y, t_off+x2, y)
-        _doLink(tx, link, (t_off+x1, y, t_off+x2, y+leading))
+        _doLink(tx, link, (t_off+x1, y, t_off+x2, yl))
     xs.links = []
     xs.link=None
 
@@ -430,6 +459,7 @@
         <b> ... </b> - bold
         <i> ... </i> - italics
         <u> ... </u> - underline
+        <strike> ... </strike> - strike through
         <super> ... </super> - superscript
         <sub> ... </sub> - subscript
         <font name=fontfamily/fontname color=colorname size=float>
@@ -846,7 +876,7 @@
                 #now the font for the rest of the paragraph
                 tx.setFont(f.fontName, f.fontSize, style.leading)
                 t_off = dpl( tx, offset, lines[0][0], lines[0][1], noJustifyLast and nLines==1)
-                if f.underline or f.link:
+                if f.underline or f.link or f.strike:
                     xs = tx.XtraState=ABag()
                     xs.cur_y = cur_y
                     xs.f = f
@@ -854,16 +884,20 @@
                     xs.lines = lines
                     xs.underlines=[]
                     xs.underlineColor=None
+                    xs.strikes=[]
+                    xs.strikeColor=None
                     xs.links=[]
                     xs.link=f.link
                     canvas.setStrokeColor(f.textColor)
                     if f.underline: _do_under_line(0, t_off+leftIndent, tx)
+                    if f.strike: _do_under_line(0, t_off+leftIndent, tx, lm=0.125)
                     if f.link: _do_link_line(0, t_off+leftIndent, tx)
 
                     #now the middle of the paragraph, aligned with the left margin which is our origin.
                     for i in xrange(1, nLines):
                         t_off = dpl( tx, _offsets[i], lines[i][0], lines[i][1], noJustifyLast and i==lim)
                         if f.underline: _do_under_line(i, t_off+leftIndent, tx)
+                        if f.strike: _do_under_line(i, t_off+leftIndent, tx, lm=0.125)
                         if f.link: _do_link_line(i, t_off+leftIndent, tx)
                 else:
                     for i in xrange(1, nLines):
@@ -894,6 +928,9 @@
                 xs.underline=0
                 xs.underlines=[]
                 xs.underlineColor=None
+                xs.strike=0
+                xs.strikes=[]
+                xs.strikeColor=None
                 xs.links=[]
                 xs.link=None
                 tx.setLeading(style.leading)
@@ -906,15 +943,13 @@
 
                 tx._fontname,tx._fontsize = None, None
                 t_off = dpl( tx, offset, lines[0], noJustifyLast and nLines==1)
-                _do_under(0, t_off+leftIndent, tx)
-                _do_link(0, t_off+leftIndent, tx)
+                _do_post_text(0, t_off+leftIndent, tx)
 
                 #now the middle of the paragraph, aligned with the left margin which is our origin.
                 for i in range(1, nLines):
                     f = lines[i]
                     t_off = dpl( tx, _offsets[i], f, noJustifyLast and i==lim)
-                    _do_under(i, t_off+leftIndent, tx)
-                    _do_link(i, t_off+leftIndent, tx)
+                    _do_post_text(i, t_off+leftIndent, tx)
 
             canvas.drawText(tx)
             canvas.restoreState()
--- a/reportlab/platypus/paraparser.py	Mon Jun 05 13:43:08 2006 +0000
+++ b/reportlab/platypus/paraparser.py	Mon Jun 05 13:55:03 2006 +0000
@@ -312,6 +312,7 @@
 #       < /b > - bold
 #       < /i > - italics
 #       < u > < /u > - underline
+#       < strike > < /strike > - strike through
 #       < super > < /super > - superscript
 #       < sup > < /sup > - superscript
 #       < sub > < /sub > - subscript
@@ -382,6 +383,13 @@
     def end_u( self ):
         self._pop(underline=1)
 
+    #### strike
+    def start_strike( self, attributes ):
+        self._push(strike=1)
+
+    def end_strike( self ):
+        self._pop(strike=1)
+
     #### link
     def start_link(self, attributes):
         self._push(**self.getAttributes(attributes,_linkAttrMap))
@@ -486,6 +494,7 @@
         frag.super = 0
         frag.rise = 0
         frag.underline = 0
+        frag.strike = 0
         frag.greek = 0
         frag.link = None
         if bullet:
@@ -878,7 +887,7 @@
 Theban prophet Teiresias had told me, and how carefully Aeaean Circe
 had warned me to shun the island of the blessed sun-god. So being
 much troubled I said to the men, 'My men, I know you are hard pressed,
-but listen while I tell you the prophecy that Teiresias made me, and
+but listen while I <strike>tell you the prophecy that</strike> Teiresias made me, and
 how carefully Aeaean Circe warned me to shun the island of the blessed
 sun-god, for it was here, she said, that our worst danger would lie.
 Head the ship, therefore, away from the island.''')
--- a/reportlab/test/test_platypus_paragraphs.py	Mon Jun 05 13:43:08 2006 +0000
+++ b/reportlab/test/test_platypus_paragraphs.py	Mon Jun 05 13:55:03 2006 +0000
@@ -22,8 +22,7 @@
 from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
 from reportlab.platypus.paragraph import Paragraph
 from reportlab.platypus.frames import Frame
-from reportlab.platypus.doctemplate \
-     import PageTemplate, BaseDocTemplate
+from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
 from reportlab.platypus import tableofcontents
 from reportlab.platypus.tableofcontents import TableOfContents
 from reportlab.platypus.tables import TableStyle, Table
@@ -134,7 +133,7 @@
 u with a dieresis on top &lt;unichar code=0xfc/&gt;="<unichar code=0xfc/>" and this &amp;#xfc;="&#xfc;" and this \\xc3\\xbc="\xc3\xbc". On the other hand this
 should be a pound sign &amp;pound;="&pound;" and this an alpha &amp;alpha;="&alpha;". You can have links in the page <link href=http://www.reportlab.com color=blue>ReportLab</link>.
 Use scheme "pdf:" to indicate an external PDF link, "http:", "https:" to indicate an external link eg something to open in
-your browser. If an internal link begins with something that looks like a scheme, precede with "document:".
+your browser. If an internal link begins with something that looks like a scheme, precede with "document:". <strike>This text should have a strike through it.</strike>
 '''
         from reportlab.platypus.flowables import ImageAndFlowables, Image
         from reportlab.lib.utils import _RL_DIR