[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
DPScomposite behaviour, was Coordinate transformations
From: |
Willem Rein Oudshoorn |
Subject: |
DPScomposite behaviour, was Coordinate transformations |
Date: |
03 Feb 2002 00:27:21 +0100 |
User-agent: |
Gnus/5.09 (Gnus v5.9.0) Emacs/21.1 |
As I wrote before the current fix for the problems with
images of non-integral width, is just that, a fix.
Now I am investigating what the correct fix should be.
Let me first describe what happens in the current
composite method.
The parameters that are important are:
from rectangle: A rectangle in the user space
of the `soure' gstate.
toPoint: A point in the user space of
the destination gstate.
Now both source and destination have a CTM
(current transformation matrix) that map the
user space to device space. So the basic picture
is:
Source Destination
+------------------+
| |
| from rectangle | -- composite --> * toPoint [USER SPACE]
| |
| |
+------------------+
| |
| |
CTM source CTM dest
| |
v v
+---------------------+ +----------------+
| | | |
| source `window' | | destination | [DEVICE SPACE]
| | | window |
| | | |
+---------------------+ +----------------+
[NOTE: I do not assume here that the from rectangle maps exactly
at the source window, it is just a situation sketch]
Now the `from rect', `toPoint' and the CTM's are used
to calculate the device space areas that are actually
involved.
They are determined as follows (I leave out all
the window clipping because it is not relevant to
my question).
XDestRect: Origin = `CTM dest' * toPoint
Size = `CTM dest' * `from rect size'.
XSrcRect: Origin = `CTM source' * `from rect origin'
Size = `CTM dest' * `from rect size'.
[actually it is just XDestRect.Size]
And here I have to say that I am not sure that this is
the right thing. It seems that the XSrcRect's size is wrong.
Now it seems that there are a few possibilities:
(A) It is correct, the CTM in the destination determines the size
of the area and no scaling whatsoever etcetera is involved.
(B) Composite is only allows to be called when CTM dest == CTM source
(C) It is wrong, we should implement the mapping
CTM dest * (CTM source)^{-1} Device source ---> Device destination.
The size calculation is the reason for the crash with images that have
non integer coordinates. Because the non-integral translation
in `CTM dest' can lead to an XDestRect.Size that is slightly
larger than the `from rect size' and this slightly larger
size is used to determine the XSrcRect.
The composite code assumes that the `from rect' is completely
backed by the device, and this goes wrong.
So the crash can be fixed quite simply by adding some clipping.
However, this will lead to some upainteted pixels if the
source clipping really occurs.
I will make a patch which will do this additional clipping and
remove the rounding in setSize in NSImage.
But I am curious of which transformation matrices should be
applied and if we have to implement scaling here.
NOTE: This clipping should be rarely needed, and if it
is needed it will lead to a crash in the current implementation.
Wim Oudshoorn.
- DPScomposite behaviour, was Coordinate transformations,
Willem Rein Oudshoorn <=