11# -*- coding: iso-8859-1 -*-
22
33"""
4- A PDF matplotlib backend (not yet complete)
4+ A PDF matplotlib backend
55Author: Jouni K Seppänen <[email protected] > 66"""
77from __future__ import division , print_function
@@ -290,6 +290,29 @@ def pdfRepr(self):
290290Op = Bunch (** dict ([(name , Operator (value ))
291291 for name , value in _pdfops .iteritems ()]))
292292
293+ def _paint_path (closep , fillp , strokep ):
294+ """Return the PDF operator to paint a path in the following way:
295+ closep: close the path before painting
296+ fillp: fill the path with the fill color
297+ strokep: stroke the outline of the path with the line color"""
298+ if strokep :
299+ if closep :
300+ if fillp :
301+ return Op .close_fill_stroke
302+ else :
303+ return Op .close_stroke
304+ else :
305+ if fillp :
306+ return Op .fill_stroke
307+ else :
308+ return Op .stroke
309+ else :
310+ if fillp :
311+ return Op .fill
312+ else :
313+ return Op .endpath
314+ Op .paint_path = _paint_path
315+
293316class Stream (object ):
294317 """PDF stream object.
295318
@@ -1190,10 +1213,22 @@ def writeImages(self):
11901213
11911214 img .flipud_out ()
11921215
1193- def markerObject (self , path , trans , fillp , lw ):
1216+ def markerObject (self , path , trans , fillp , strokep , lw ):
11941217 """Return name of a marker XObject representing the given path."""
1218+ # self.markers used by markerObject, writeMarkers, close:
1219+ # mapping from (path operations, fill?, stroke?) to
1220+ # [name, object reference, bounding box, linewidth]
1221+ # This enables different draw_markers calls to share the XObject
1222+ # if the gc is sufficiently similar: colors etc can vary, but
1223+ # the choices of whether to fill and whether to stroke cannot.
1224+ # We need a bounding box enclosing all of the XObject path,
1225+ # but since line width may vary, we store the maximum of all
1226+ # occurring line widths in self.markers.
1227+ # close() is somewhat tightly coupled in that it expects the
1228+ # first two components of each value in self.markers to be the
1229+ # name and object reference.
11951230 pathops = self .pathOperations (path , trans , simplify = False )
1196- key = (tuple (pathops ), bool (fillp ))
1231+ key = (tuple (pathops ), bool (fillp ), bool ( strokep ) )
11971232 result = self .markers .get (key )
11981233 if result is None :
11991234 name = Name ('M%d' % len (self .markers ))
@@ -1207,17 +1242,15 @@ def markerObject(self, path, trans, fillp, lw):
12071242 return name
12081243
12091244 def writeMarkers (self ):
1210- for (pathops , fillp ),(name , ob , bbox , lw ) in self .markers .iteritems ():
1245+ for ((pathops , fillp , strokep ),
1246+ (name , ob , bbox , lw )) in self .markers .iteritems ():
12111247 bbox = bbox .padded (lw * 0.5 )
12121248 self .beginStream (
12131249 ob .id , None ,
12141250 {'Type' : Name ('XObject' ), 'Subtype' : Name ('Form' ),
12151251 'BBox' : list (bbox .extents ) })
12161252 self .output (* pathops )
1217- if fillp :
1218- self .output (Op .fill_stroke )
1219- else :
1220- self .output (Op .stroke )
1253+ self .output (Op .paint_path (False , fillp , strokep ))
12211254 self .endStream ()
12221255
12231256 @staticmethod
@@ -1436,11 +1469,12 @@ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None)
14361469 return
14371470
14381471 self .check_gc (gc , rgbFace )
1439- fillp = rgbFace is not None
1472+ fillp = gc .fillp ()
1473+ strokep = gc .strokep ()
14401474
14411475 output = self .file .output
14421476 marker = self .file .markerObject (
1443- marker_path , marker_trans , fillp , self .gc ._linewidth )
1477+ marker_path , marker_trans , fillp , strokep , self .gc ._linewidth )
14441478
14451479 output (Op .gsave )
14461480 lastx , lasty = 0 , 0
@@ -1869,16 +1903,18 @@ def __repr__(self):
18691903 del d ['parent' ]
18701904 return repr (d )
18711905
1872- def _strokep (self ):
1906+ def strokep (self ):
18731907 """
18741908 Predicate: does the path need to be stroked (its outline drawn)?
18751909 This tests for the various conditions that disable stroking
18761910 the path, in which case it would presumably be filled.
18771911 """
1912+ # _linewidth > 0: in pdf a line of width 0 is drawn at minimum
1913+ # possible device width, but e.g. agg doesn't draw at all
18781914 return (self ._linewidth > 0 and self ._alpha > 0 and
18791915 (len (self ._rgb ) <= 3 or self ._rgb [3 ] != 0.0 ))
18801916
1881- def _fillp (self ):
1917+ def fillp (self ):
18821918 """
18831919 Predicate: does the path need to be filled?
18841920 """
@@ -1891,32 +1927,14 @@ def close_and_paint(self):
18911927 Return the appropriate pdf operator to close the path and
18921928 cause it to be stroked, filled, or both.
18931929 """
1894- if self ._strokep ():
1895- if self ._fillp ():
1896- return Op .close_fill_stroke
1897- else :
1898- return Op .close_stroke
1899- else :
1900- if self ._fillp ():
1901- return Op .fill
1902- else :
1903- return Op .endpath
1930+ return Op .paint_path (True , self .fillp (), self .strokep ())
19041931
19051932 def paint (self ):
19061933 """
19071934 Return the appropriate pdf operator to cause the path to be
19081935 stroked, filled, or both.
19091936 """
1910- if self ._strokep ():
1911- if self ._fillp ():
1912- return Op .fill_stroke
1913- else :
1914- return Op .stroke
1915- else :
1916- if self ._fillp ():
1917- return Op .fill
1918- else :
1919- return Op .endpath
1937+ return Op .paint_path (False , self .fillp (), self .strokep ())
19201938
19211939 capstyles = { 'butt' : 0 , 'round' : 1 , 'projecting' : 2 }
19221940 joinstyles = { 'miter' : 0 , 'round' : 1 , 'bevel' : 2 }
0 commit comments