In preparation for CSS Writing Modes and porting all of our layout code, I started adding geometry primitives in abstract dimensions.

Permanent link as of this writing:
https://github.com/SimonSapin/servo/compare/d6caf26

Link tracking the branch:
https://github.com/SimonSapin/servo/compare/abstract-geometry

Relevant spec:
http://dev.w3.org/csswg/css-writing-modes/#abstract-box

AbstractSize and AbstractPoint are equivalent to rust-geom’s Size2D and Point2D, but in flow-relative dimensions rather than physical. I’ll add AbstractSideOffsets and AbstractRect when we’re happy with the design.

Like the physical ones, they are generic over the representation of a scalar, and so should be orthogonal to Matt’s work on typed units.

The two flow-relative axis are I and B, short of inline-direction and block-direction.

I put this in the util crate for now to avoid dealing with submodules, but it could be in rust-geom.

This is largely based on Gecko’s WritingModes.h file:
http://dxr.mozilla.org/mozilla-central/source/layout/generic/WritingModes.h

The addition on points is:
AbstractPoint + AbstractSize -> AbstractPoint
rather than
Point + Point -> Point
I find this makes more sense (a size is just a vector, whereas a point is a vector from an implied origin), but I don’t know yet how this used in practice.

The mapping between abstract and physical dimensions is determined by "the writing mode", which is based on the 'direction', 'writing-mode', and 'text-orientation' CSS properties.

The fields of abstract structs are private, and all method take the writing mode as a parameter. On debug builds (i.e. without --cfg ndebug), the writing mode is also stored in the struct and asserted at each method call. (Non-debug builds make this storage zero-size and the checks no-ops.) This has apparently caught several bugs in Gecko.

Unlike C++, Rust does not have method overloading so the accessors are much more verbose.
`nscoord ISize(WritingMode aWritingMode) const` overloaded with
`nscoord& ISize(WritingMode aWritingMode)` becomes
`get_i_size(&self, mode: WritingMode) -> T` and
`set_i_size(&mut self, mode: WritingMode, T)`.
The setter could be replaced with
`i_size_ref(&'a mut self, mode: WritingMode) -> &'a mut T`, but the getter would still be needed so that reading does not require `&mut`. Or perhaps we should have all three.

Is there a better way to do accessors in Rust?

--
Simon Sapin
_______________________________________________
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo

Reply via email to