Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move origin to left-top and draw from top left to bottom right #72

Closed
pieterclaerhout opened this issue Feb 2, 2021 · 13 comments
Closed

Comments

@pieterclaerhout
Copy link

From what I understand, the coordinate system is designed in such a way that the origin is in the lower left corner of canvas and that you draw from left to right and bottom to top, correct?

Is there a way to change it so that the 0,0 point is in the upper left corner (like most design programs do) and draw from left to right and top to bottom?

@kpym
Copy link
Contributor

kpym commented Feb 2, 2021

You can apply ReflectY.

@pieterclaerhout
Copy link
Author

That doesn't do the trick unfortunately. It does make it draw from top to bottom, but it keeps the 0, 0 point in the lower left corner (rendering everything outside the viewport).

I've then tried added Translate(0, -c.H) after the ReflectY call. This did move the 0,0 point to the upper left corner, but I then figured out that all the text is mirrored along the Y-axis…

Any other ideas?

@kpym
Copy link
Contributor

kpym commented Feb 3, 2021

There is SetCoordSystem that is supposed to do this (the code is equivalent to what you do, symmetry by the middle of the canvas), but if you say that the text is inverted (and probably the images too in this case, I haven't checked) then may be this should be considered as a bug?

@kpym
Copy link
Contributor

kpym commented Feb 3, 2021

It looks like that the coordinate transforms here in canvas are over simplistic. In PGF/TikZ, for example, there are two kind of transforms : coordinate transforms (that do not affect the line widths, the shapes, the text orientation...) and the canvas transforms (that transform everything). And there is actually a third option : when we apply a coordinate transform to some node (containing text or image) and we use transform shape the global coordinate changes are applied to the node, but this do not change for example the line widths.
All this to conclude that having only one transformation matrix, without additional flags to what this matrix should apply, is probably not enough.

@pieterclaerhout
Copy link
Author

OK, good to know.

I'll keep on using the extra calculations I've setup to get everything on the right location…

@tdewolff
Copy link
Owner

tdewolff commented Feb 5, 2021

There are two transformations though, much like PGF/TikZ. A coordinate transform and a path/image/text transform. You can set the former using ctx.SetCoordView(matrix) or ctx.SetCoordSystem(canvas.CartesianIV) in this case. This will not transform the actual path/stroke/text/image. The latter can be set using ctx.SetView(matrix), this will not transform the coordinates (but perhaps it should?).

Please let me know if setting ctx.SetCoordSystem(canvas.CartesianIV) works for you!

@kpym
Copy link
Contributor

kpym commented Feb 5, 2021

@tdewolff Sorry, I didn't see that Context has separate view and coordView. Very good news! Thanks.

@tdewolff
Copy link
Owner

tdewolff commented Feb 5, 2021

No worries! You think the view should also apply to coordinates as well, and coordView only to coordinates? I'm unaware of how other implementation have handled this.

@kpym
Copy link
Contributor

kpym commented Feb 5, 2021

I know only PGF/TikZ well : there transform canvas applies to the canvas after everything is drawn, so it transform really everything, and this looks probably as yours view. And when you apply a "standard" transform it applies before drawing, so only to coordinates (but not to objects put at some coordinates by default, except if you say transform shape), and this is probably like yours coordViews. Sorry if I'm not clear.

@tdewolff
Copy link
Owner

I've incorporated implementing view to work for coordinates as well in the roadmap from where it will be tracked: #74

@carbocation
Copy link
Contributor

Looping back to this, in case I am misunderstanding the docs and the discussion, the pieterclaerhout solution of

ctx.ReflectY()
ctx.Translate(0, -c.H)

is still the only solution that works for me. Other suggested approaches such as

ctx.SetCoordSystem(canvas.CartesianIII)
ctx.ReflectY()

do not cause the drawing to render within the viewport.

@tdewolff
Copy link
Owner

I think in the second approach you should not call ReflectY. In any case I think coordinate systems should be implemented differently to make it easier to use top-left as the origin, or perhaps use non-Cartesian coordinate systems. I will come back to this!

@tdewolff
Copy link
Owner

tdewolff commented Apr 27, 2022

I've added a change that adds better support for CartesianIV (i.e. origin is top-left). It differs from CartesianI (i.e. origin is bottom-left) in that it anchors differently to images (anchors top-left vs bottom-left) and that text has always been anchored to the baseline (TextLine) or to top-left (TextBox) and remains so. This means that switching to CartesianIV may change the position of text and images.

You can change to CartesianIV using:

ctx.SetCoordSystem(canvas.CartesianIV)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants