"Fossies" - the Fresh Open Source Software Archive

Member "reportlab-3.5.23/src/reportlab/pdfgen/pathobject.py" (6 Nov 2017, 4657 Bytes) of package /linux/privat/reportlab-3.5.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "pathobject.py" see the Fossies "Dox" file reference documentation.

    1 #Copyright ReportLab Europe Ltd. 2000-2017
    2 #see license.txt for license details
    3 #history https://bitbucket.org/rptlab/reportlab/history-node/tip/src/reportlab/pdfgen/pathobject.py
    4 __version__='3.3.0'
    5 __doc__="""
    6 PDFPathObject is an efficient way to draw paths on a Canvas. Do not
    7 instantiate directly, obtain one from the Canvas instead.
    8 
    9 Progress Reports:
   10 8.83, 2000-01-13, gmcm: created from pdfgen.py
   11 
   12 """
   13 
   14 from reportlab.pdfgen import pdfgeom
   15 from reportlab.lib.rl_accel import fp_str
   16 
   17 
   18 class PDFPathObject:
   19     """Represents a graphic path.  There are certain 'modes' to PDF
   20     drawing, and making a separate object to expose Path operations
   21     ensures they are completed with no run-time overhead.  Ask
   22     the Canvas for a PDFPath with getNewPathObject(); moveto/lineto/
   23     curveto wherever you want; add whole shapes; and then add it back
   24     into the canvas with one of the relevant operators.
   25 
   26     Path objects are probably not long, so we pack onto one line
   27 
   28     the code argument allows a canvas to get the operatiosn appended directly so
   29     avoiding the final getCode
   30     """
   31     def __init__(self,code=None):
   32         self._code = (code,[])[code is None]
   33         self._code_append = self._init_code_append
   34 
   35     def _init_code_append(self,c):
   36         assert c.endswith(' m') or c.endswith(' re'), 'path must start with a moveto or rect'
   37         code_append = self._code.append
   38         code_append('n')
   39         code_append(c)
   40         self._code_append = code_append
   41 
   42     def getCode(self):
   43         "pack onto one line; used internally"
   44         return ' '.join(self._code)
   45 
   46     def moveTo(self, x, y):
   47         self._code_append('%s m' % fp_str(x,y))
   48 
   49     def lineTo(self, x, y):
   50         self._code_append('%s l' % fp_str(x,y))
   51 
   52     def curveTo(self, x1, y1, x2, y2, x3, y3):
   53         self._code_append('%s c' % fp_str(x1, y1, x2, y2, x3, y3))
   54 
   55     def arc(self, x1,y1, x2,y2, startAng=0, extent=90):
   56         """Contributed to piddlePDF by Robert Kern, 28/7/99.
   57         Draw a partial ellipse inscribed within the rectangle x1,y1,x2,y2,
   58         starting at startAng degrees and covering extent degrees.   Angles
   59         start with 0 to the right (+x) and increase counter-clockwise.
   60         These should have x1<x2 and y1<y2.
   61 
   62         The algorithm is an elliptical generalization of the formulae in
   63         Jim Fitzsimmon's TeX tutorial <URL: http://www.tinaja.com/bezarc1.pdf>."""
   64 
   65         self._curves(pdfgeom.bezierArc(x1,y1, x2,y2, startAng, extent))
   66 
   67     def arcTo(self, x1,y1, x2,y2, startAng=0, extent=90):
   68         """Like arc, but draws a line from the current point to
   69         the start if the start is not the current point."""
   70         self._curves(pdfgeom.bezierArc(x1,y1, x2,y2, startAng, extent),'lineTo')
   71 
   72     def rect(self, x, y, width, height):
   73         """Adds a rectangle to the path"""
   74         self._code_append('%s re' % fp_str((x, y, width, height)))
   75 
   76     def ellipse(self, x, y, width, height):
   77         """adds an ellipse to the path"""
   78         self._curves(pdfgeom.bezierArc(x, y, x + width,y + height, 0, 360))
   79 
   80     def _curves(self,curves,initial='moveTo'):
   81         getattr(self,initial)(*curves[0][:2])
   82         for curve in curves:
   83             self.curveTo(*curve[2:])
   84 
   85     def circle(self, x_cen, y_cen, r):
   86         """adds a circle to the path"""
   87         x1 = x_cen - r
   88         y1 = y_cen - r
   89         width = height = 2*r
   90         self.ellipse(x1, y1, width, height)
   91 
   92     def roundRect(self, x, y, width, height, radius):
   93         """Draws a rectangle with rounded corners. The corners are
   94         approximately quadrants of a circle, with the given radius."""
   95         #use a precomputed set of factors for the bezier approximation
   96         #to a circle. There are six relevant points on the x axis and y axis.
   97         #sketch them and it should all make sense!
   98         t = 0.4472 * radius
   99 
  100         x0 = x
  101         x1 = x0 + t
  102         x2 = x0 + radius
  103         x3 = x0 + width - radius
  104         x4 = x0 + width - t
  105         x5 = x0 + width
  106 
  107         y0 = y
  108         y1 = y0 + t
  109         y2 = y0 + radius
  110         y3 = y0 + height - radius
  111         y4 = y0 + height - t
  112         y5 = y0 + height
  113 
  114         self.moveTo(x2, y0)
  115         self.lineTo(x3, y0) #bottom row
  116         self.curveTo(x4, y0, x5, y1, x5, y2) #bottom right
  117         self.lineTo(x5, y3) #right edge
  118         self.curveTo(x5, y4, x4, y5, x3, y5) #top right
  119         self.lineTo(x2, y5) #top row
  120         self.curveTo(x1, y5, x0, y4, x0, y3) #top left
  121         self.lineTo(x0, y2) #left edge
  122         self.curveTo(x0, y1, x1, y0, x2, y0) #bottom left
  123         self.close()
  124 
  125     def close(self):
  126         "draws a line back to where it started"
  127         self._code_append('h')