Arnd Baecker venit, vidit, dixit 2006-06-30 20:35:
> On Fri, 30 Jun 2006, Michael J Gruber wrote:
> 
>> Joerg Lehmann venit, vidit, dixit 2006-06-29 18:54:
>>>>     # need help here
>>>>     def processPDF(self, file, writer, context, registry, bbox):
>>>>         raise NotImplementedError("ref canvasitem not implemented for PDF")
>>> This goes along the lines of the PS case.
>> Along the lines, well - I don't speak PDF ;)
>> 2 questions before I get myself into unnecessary trouble:
>>
>> 1) PDF is no programming language. Doing the equivalent of the PS stuff
>> would require deriving an XObject class PDFXObject(pdfwriter.PDFobject)
>> and using the "Do" operator on the XObject/Form instead of a procedure,
>> right?
>>
>> 2) Is there interest in it/a place in PyX for it anyway? zlib compresses
>> repeated stuff nicely anyways.
> 
> First many thanks for the re-newed translateablecanvas - it works
> very well!!

Thanks!

> (and sorry for the late response, today was quite hectic and I had
> to leave a little bit earlier than usual ;-).

This is happening to me quite often these days, too - amazing coincidence ;)

I'm attaching a version which implements translatable canvasses for the
PDF writer, too. PS stuff is unchanged. Note that the savings aren't
that dramatic for compressed PDF since zlib compresses repeated
sequences well. It still depends on the "code size" of the repeated
canvas, of course.

I had to implement that Form XObject thingy for the PDF version, and
since I have almost no clue of (PS and) PDF I don't know if I handled
all necessary cases (spell: resources for the XObject, such as fonts).
It works for the original example, though.

Cheers,
Michael
import zlib, cStringIO
from pyx import *
from pyx import pswriter,pdfwriter
 

class ref(canvas.canvasitem):
    """a stupid object insertable into a canvas; it needs to get all the
    information in the constructor"""

    def __init__(self, bbox, x_pt, y_pt, insertcanvas):
        self._bbox = bbox
        self._x_pt = x_pt
        self._y_pt = y_pt
        self._insertcanvas = insertcanvas

    def bbox(self):
        return self._bbox

    def processPS(self, file, writer, context, registry, bbox):
        bbox += self._bbox
        stringfile = cStringIO.StringIO()
        canvas._canvas.processPS(self._insertcanvas, stringfile, writer, 
context, registry, bbox)
        canvasproc = "gsave\nmatrix translate concat\n%sgrestore\n" % 
stringfile.getvalue()
        stringfile.close()
        registry.add(pswriter.PSdefinition(self._insertcanvas.id, "{\n" + 
canvasproc + "}"))
        file.write("%g %g %s\n" % (self._x_pt, self._y_pt, 
self._insertcanvas.id))

    # need help here
    def processPDF(self, file, writer, context, registry, bbox): 
        bbox += self._bbox
        ## the following just inserts the canvas again and again (zlib 
compresses this nicely)
        # c = canvas.canvas([trafo.translate_pt(self._x_pt, self._y_pt)])
        # c.insert(self._insertcanvas)
        # c.processPDF(file, writer, context, registry, bbox)
        ## or use Form XObjects:
        stringfile = cStringIO.StringIO()
        canvas._canvas.processPDF(self._insertcanvas, stringfile, writer, 
context, registry, bbox)
        canvasproc = stringfile.getvalue()
        stringfile.close()
        registry.add(PDFXForm(canvasproc, self._insertcanvas.bbox(), writer, 
registry, self._insertcanvas.id)) 
        file.write("q 1 0 0 1 %f %f cm /%s Do Q\n" % (self._x_pt, self._y_pt, 
self._insertcanvas.id))

class PDFXForm(pdfwriter.PDFobject):

    def __init__(self, content, bbox, writer, registry, _id=None):
        """create a Form XObject and register it as resource
          - content is the PDF content
          - _id is the resource name
        """
        pdfwriter.PDFobject.__init__(self, "xform", _id)
        self.bbox = bbox
        self.content = content
        registry.addresource("XObject", _id, self, "PDF")

    def write(self, file, writer, registry):
        if writer.compress:
            content = zlib.compress(self.content)
        else:
            content = self.content
        file.write("<<\n"
                   "/Length %i\n" % len(content)) 
        file.write("/Type /XObject /Subtype /Form /FormType 1\n"
                   "/BBox [%f %f %f %f]\n"
                   "/Resources << /ProcSet [/PDF] >>\n" % 
self.bbox.highrestuple_pt())
        if writer.compress:
            file.write("/Filter /FlateDecode\n")
        file.write(">>\n"
                   "stream\n")
        file.write(content)
        file.write("endstream\n")
 
class translateablecanvas(canvas._canvas):
    "a canvas which is efficiently translateable"
     
    def __init__(self, *args, **kwargs):
        canvas._canvas.__init__(self, *args, **kwargs)
        self.id = "symbol%d" % id(self)
 
    def translate_pt(self, x_pt, y_pt):
        """returns an insertable object which stores only the position and
        a reference to a prolog definition"""
        return ref(self.bbox().transformed(trafo.translate_pt(x_pt, y_pt)), 
x_pt, y_pt, self)
 
class insertstyle(graph.style.symbol):
    """a graph style which calls a translate_pt method of the symbol to insert
    the result instead of calling the symbol to get a path to be drawn"""

    def selectstyle(self, privatedata, sharedata, graph, selectindex, 
selecttotal):
        privatedata.symbol = attr.selectattr(self.symbol, selectindex, 
selecttotal)
        privatedata.size_pt = unit.topt(attr.selectattr(self.size, selectindex, 
selecttotal))
        privatedata.insertcanvas = translateablecanvas()
        if self.symbolattrs is not None:
            privatedata.symbolattrs = attr.selectattrs(self.defaultsymbolattrs 
+ self.symbolattrs, selectindex, selecttotal)
        else:
            privatedata.symbolattrs = None
        # stroke symbol on insertcanvas instead of symbolcanvas
        privatedata.symbol(privatedata.insertcanvas, 0, 0, privatedata.size_pt, 
privatedata.symbolattrs)

    def drawpoint(self, privatedata, sharedata, graph, point):
        if sharedata.vposvalid and privatedata.symbolattrs is not None:
            x_pt, y_pt = graph.vpos_pt(*sharedata.vpos)
            # use more efficient version of 
privatedata.symbolcanvas.insert(privatedata.insertcanvas,[trafo.translate_pt(x_pt,
 y_pt)])
            
privatedata.symbolcanvas.insert(privatedata.insertcanvas.translate_pt(x_pt, 
y_pt))

    # key_pt is inherited from graph.style.symbol because reimplementing would 
save only one instance


 
g = graph.graphxy(width=8)
#g.plot(graph.data.function("y(x)=x*x", min=-1, max=1, points=1000),
#       [graph.style.symbol(graph.style.symbol.circle, 
symbolattrs=[deco.filled,color.rgb.blue])])
#g.plot(graph.data.function("y(x)=x*x", min=-1, max=1, points=1000),
#       [graph.style.symbol(graph.style.symbol.circle, 
symbolattrs=[deco.filled,color.rgb.blue, deco.stroked.clear])])
g.plot(graph.data.function("y(x)=x*x", min=-1, max=1, points=1000),
        [insertstyle(graph.style.symbol.circle, 
symbolattrs=[deco.filled,color.rgb.blue, deco.stroked.clear])])
g.writeEPSfile("translateablecanvas")
g.writePDFfile("translateablecanvas")
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
PyX-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pyx-user

Reply via email to