Bug 28067

Summary: TransformationMatrix should have rectToRect convenience function
Product: WebKit Reporter: Adam Treat <manyoso>
Component: WebCore Misc.Assignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: darin
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: PC   
OS: OS X 10.5   
Attachments:
Description Flags
Adds method rectToRect
darin: review+
Adds asserts
staikos: review-
Fix assert as pointed out by staikos staikos: review+

Description Adam Treat 2009-08-07 07:32:20 PDT
The following patch adds rectToRect convenience function which returns the TransformationMatrix which maps the 'from' rectangle to the 'to' rectangle.

No tests as this would require binding the method to js and since it is static that doesn't seem possible.  Please check the math.
Comment 1 Adam Treat 2009-08-07 07:33:44 PDT
Created attachment 34271 [details]
Adds method rectToRect
Comment 2 Darin Adler 2009-08-07 08:05:50 PDT
Comment on attachment 34271 [details]
Adds method rectToRect

Does this have the desirable behavior when from.width() or from.height() is 0?

This does not match the pattern of other functions that manipulate the matrix. For example, we don't have a function to return the identity matrix. Instead we have a setter, makeIdentity(). Probably this should be makeRectToRect() or makeIdentity() should be changed.

We don't have any other static member functions to create new matrices. And in classes where we do have such functions we normally use the word "create" in the name of the function.

Seems OK to add it.

I'm going to say r=me, but I think the class's interface is a little weak and getting a little weaker.
Comment 3 Adam Treat 2009-08-07 08:11:35 PDT
Created attachment 34272 [details]
Adds asserts
Comment 4 Adam Treat 2009-08-07 08:14:39 PDT
makeRectToRect is ugly imo.  In this case, we want to create a transform from scratch, not modify an existing one.  I guess we could make a new constructor that takes to rects, but that seems ugly too.
Comment 5 Eric Seidel (no email) 2009-08-07 08:34:41 PDT
Comment on attachment 34272 [details]
Adds asserts

I think we should deploy this in at least one place to make sure it works and is tested.  I think this patch is OK as is, but I'd rather see it used in at least one of the places where we already do this by hand.  For example, the SVG viewport code does this kind of thing.

SVGPaintServerGradient:
    TransformationMatrix matrix;
    if (gradientServer->boundingBoxMode()) {
        matrix.translate(maskBBox.x(), maskBBox.y());
        matrix.scaleNonUniform(maskBBox.width(), maskBBox.height());
    }

TransformationMatrix SVGPreserveAspectRatio::getCTM(double logicX, double logicY,

There are many other examples in the code.  Not all of them would need to be deployed to for this to be tested. :)
Comment 6 George Staikos 2009-08-07 08:40:40 PDT
Comment on attachment 34272 [details]
Adds asserts

No reason to ASSERT(!to.isEmpty()), but from is fine.
Comment 7 Adam Treat 2009-08-07 08:45:15 PDT
Created attachment 34279 [details]
Fix assert as pointed out by staikos
Comment 8 George Staikos 2009-08-07 08:47:45 PDT
Comment on attachment 34279 [details]
Fix assert as pointed out by staikos

Patch on its own is fine now.  Would be a good idea to follow up with a usage somewhere as Eric pointed out.
Comment 9 Adam Treat 2009-08-07 08:52:42 PDT
Landed with r46893.
Comment 10 Darin Adler 2009-08-07 11:14:43 PDT
(In reply to comment #4)
> makeRectToRect is ugly imo.  In this case, we want to create a transform from
> scratch, not modify an existing one.

OK, that addresses one of my comments.

What about the comment that we normally use the name "create" in all of our named constructor names?

And what about changing makeIdentity?

It seems like you responded to one part of the comment and didn't address the rest. I'd really like to hear your thoughts.
Comment 11 Adam Treat 2009-08-07 11:28:09 PDT
(In reply to comment #10)
> (In reply to comment #4)
> > makeRectToRect is ugly imo.  In this case, we want to create a transform from
> > scratch, not modify an existing one.
> 
> OK, that addresses one of my comments.
> 
> What about the comment that we normally use the name "create" in all of our
> named constructor names?
> 
> And what about changing makeIdentity?
> 
> It seems like you responded to one part of the comment and didn't address the
> rest. I'd really like to hear your thoughts.

Ah, sorry Darin.  My eyes missed the "create" comment.  I can certainly change it to 'createRectToRect', but I've noticed that other implementations use the 'rectToRect' naming pattern or 'quadToQuad'.  This is true of Qt's API and OpenVG API for instance.  Given that we already use such substandard naming patterns for consistency with other standard API's (getCTM and concatCTM come to mind... *ugly*) I'm not sure what is best.  'createRectToRect' seems good to me, but if we do that then I think we should change 'getCTM' and 'concatCTM'.  Better names are better names :)

As for changing 'makeIdentity' I had looked at this, but forgot to comment.  If you want to create a new identity TransformationMatrix there is no reason to use 'makeIdentity' as the default ctor returns an identity matrix.  The only time someone would use 'makeIdentity' is if you wanted to reset an existing matrix.  To me, makeIdentity is strictly not necessary and should be private.  matrix = TransformationMatrix() accomplishes the same.  I can change this and refactor parts that use 'makeIdentity' if you like?
Comment 12 Darin Adler 2009-08-07 12:54:44 PDT
(In reply to comment #11)
> Ah, sorry Darin.  My eyes missed the "create" comment.  I can certainly change
> it to 'createRectToRect', but I've noticed that other implementations use the
> 'rectToRect' naming pattern or 'quadToQuad'.  This is true of Qt's API and
> OpenVG API for instance.  Given that we already use such substandard naming
> patterns for consistency with other standard API's (getCTM and concatCTM come
> to mind... *ugly*) I'm not sure what is best.  'createRectToRect' seems good to
> me, but if we do that then I think we should change 'getCTM' and 'concatCTM'. 
> Better names are better names :)

Yes, I think this class is currently not using good names across the board and is worth improving.

It seems a shame that this operation is unique at this point. The only named constructor in the class. But I guess we've discussed it sufficiently.

> As for changing 'makeIdentity' I had looked at this, but forgot to comment.  If
> you want to create a new identity TransformationMatrix there is no reason to
> use 'makeIdentity' as the default ctor returns an identity matrix.  The only
> time someone would use 'makeIdentity' is if you wanted to reset an existing
> matrix.  To me, makeIdentity is strictly not necessary and should be private. 
> matrix = TransformationMatrix() accomplishes the same.  I can change this and
> refactor parts that use 'makeIdentity' if you like?

I'm not sure it would be an improvement. I guess we can just leave it alone for now. The class's interface seems a little weak at the moment but I don't see an obvious change that will make things better.