An important canvas use case that arose during the development of pdf.js[1] is 
implementing a "fill-to-current-clip" operation.  In PDF, the shading fill 
operator, "sh", requires this.  In the cairo library, cairo_paint() is this 
operation.  The operation can be implemented by tracking the current transform 
matrix (CTM) in script, then at paint time, inverting the CTM and filling the 
canvas bounds transformed by the inverse CTM.  However, tracking the CTM from 
script is cumbersome and not likely to be performant.  It's also not always 
possible for script to track the CTM; for example, if an external library is 
passed a canvas to draw to, the library doesn't know the initial CTM.  Another 
use case that requires the CTM is creating a minimal temporary surface for a 
fill operation that's bounded by user-space coordinates, for which canvas 
doesn't have native support for creating the contents of what's to be filled.  
This case also arose in pdf.js.

To that end, we propose a canvas interface that allows querying the CTM.  The 
concrete proposal is

  interface CanvasRenderingContext2D {
    //...
    attribute SVGMatrix currentTransform;  // default is the identity matrix
    //...
  };

The first use case above is satisfied by |inverseCtm = 
context.currentTransform.inverse();|.  This attribute also serves as a 
convenience attribute for updating the CTM.  The |currentTransform| attribute 
tracks updates made to the CTM through |setTransform()/scale()/translate()|.

Note: a similar API is implemented in Gecko as the sequence attributes 
|mozCurrentTransform/mozCurrentTransformInverse|.  This violates WebIDL rules 
and will be updated.  SVGMatrix was chosen as a replacement since it already 
has the |inverse()| method and so results in a smaller API surface area.  
Mozilla will update Gecko when this proposal stabilizes.

Cheers,
Chris

[1] https://github.com/mozilla/pdf.js

Reply via email to