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