On Fri, 14 Jun 2019 at 13:07, Eli Zaretskii <
address@hidden> wrote:
> From: Richard Copley <
address@hidden>
> Date: Fri, 14 Jun 2019 12:21:19 +0100
> Cc: Stefan Monnier <
address@hidden>, Emacs Development <
address@hidden>
>
> Firstly, all the 2D graphics libraries (XRender and NS, as we have
> seen, GDI, Direct2D, HTML5 Canvas, Cairo) specify the transformation
> with a homogeneous matrix. (The same goes for 3D graphics
> libraries.) It's fundamental to graphics programming. Why make up
> our own, inferior, system?
Two reasons: (a) Emacs is not a system for graphics programming, and
doesn't target programmers in that domain; (2) an API based on
transformation matrices is IMO too low-level, unlike anything else in
Emacs.
> (The Windows API documentation is no longer very good for finding out about
> previous versions of Windows. Is GM_ADVANCED not supported on some GDI
> versions we're interested in? If so, is it important to provide image
> support there?)
I'm using this site when I need information about older versions of
Windows:
http://winapi.freetechsecrets.com/win32 According to it, GM_ADVANCED is not supported on Windows 9X.
Is it important to support such advanced features there?
> Secondly, for users who want to specify a scale, translation and
> rotation, it's easy to construct the matrix from that
> information.
"Easy"? For those with background in graphics programming, sure. For
others, not so sure.
The point I was making is that it is easy compared with going in the opposite
direction.
> (All the graphics libraries provide helper functions for this, and
> so should we.)
So you are saying that we should accept the attributes and convert
them to a matrix in Lisp?
Sure. And we shouldn't allow users to access the attributes afterwards.
That might work, and doesn't really
contradict what I say above, but we should first make sure that all
the toolkits we support interpret the matrix the same.
They don't, but the differences are small platform-specific fixups (possibly
inverting and/or transposing the matrix, as well as converting the values to the
appropriate types). The mathematical fundamentals are the same for all the
platforms.
We are still
arguing about the meaning we ourselves assign to the matrix (see the
recent clockwise vs counter-clockwise rotation issue), which somehow
doesn't increase my confidence that exposing the transformation
through a Lisp API would be a good/useful idea.
It's not so important that everybody gets everything correct every time in this
discussion. The important thing is that the implementation is correct in the
end.
> On the other hand for users who want to specify the homogeneous
> matrix, it's not easy to decompose the matrix into scale, shear,
> rotation and translation and rotation.
I still don't understand why users would want to specify
transformations via a matrix.
Most won't.
> Thirdly, the homogeneous matrix is compact and uniform, and makes
> it easy to compose and invert (undo) transformations.
So are/do the attributes.
I think you're underestimating the difficulty of that part. Here's a concrete
example. Suppose the user wants to apply two transformations,
1. Stretch by factor 2 in the x direction, then rotate clockwise by 45 degrees,
then translate to the right by 100 pixels.
2. Stretch by factor 0.5 in the x direction, then rotate clockwise by 90 degrees,
then translate left by 100 pixels.
Calculating the resulting matrix might be a little tricky to get right, but with
some experimentation you'll get there. Calculating the resulting shear,
rotation, scale and translation is much more difficult to conceptualize. You
would first have to calculate the matrix in any case. Then you would need to do
Singular Value Decomposition. I can help you with the equations, if it comes to
it, but I don't think it's needed for this. We just shouldn't expose the
individual parameters to the users in the first place.
Which representation is more compact is
arguable: for example, the matrix representation of a rotation is much
more wasteful than just a single angle of rotation parameter.
I didn't say "more compact".
But I think this is a tangent, because my proposal doesn't preclude
providing a matrix-based API in the future.
It will make it difficult to preserve backward compatibility. Constructing
the :crop, :rotate, etc., from the matrix, is hard.