Skip to content

Commit e9aa01e

Browse files
committed
Renovate tunnel markers.
1 parent b0b21cd commit e9aa01e

File tree

1 file changed

+149
-35
lines changed

1 file changed

+149
-35
lines changed

src/railway/feature/marker.rs

Lines changed: 149 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,7 @@ pub struct Marker {
3636
extent: Option<Position>,
3737

3838
/// Orientation of the marker.
39-
///
40-
/// If this in `None` the marker doesn’t need to be oriented at all.
41-
/// Otherwise the value is the angle to be added to rotation from the
42-
/// position.
43-
orientation: f64,
39+
orientation: Orientation,
4440

4541
/// Are we drawing casing?
4642
casing: bool,
@@ -60,7 +56,7 @@ impl Marker {
6056
scope: &Scope,
6157
err: &mut EvalErrors,
6258
) -> Result<AnyFeature, Failed> {
63-
let orientation = Self::rotation_from_symbols(&mut symbols, err)?;
59+
let orientation = Orientation::from_symbols(&mut symbols, err)?;
6460
let class = Railway::from_symbols(&mut symbols, scope);
6561
let casing = symbols.take("casing");
6662
let pos = symbols.pos();
@@ -90,35 +86,10 @@ impl Marker {
9086

9187
// Didn’t find anything. Try the old marker for now.
9288
super::oldmarker::StandardMarker::new(
93-
position, orientation, class, marker, pos, err
89+
position, orientation.into_rotation(), class, marker, pos, err
9490
)
9591
}
9692

97-
fn rotation_from_symbols(
98-
symbols: &mut SymbolSet,
99-
_err: &mut EvalErrors
100-
) -> Result<f64, Failed> {
101-
if symbols.take("top") {
102-
Ok(1.5 * PI)
103-
}
104-
else if symbols.take("left") {
105-
Ok(PI)
106-
}
107-
else if symbols.take("bottom") {
108-
Ok(0.5 * PI)
109-
}
110-
else if symbols.take("right") {
111-
Ok(0.)
112-
}
113-
else {
114-
Ok(0.)
115-
/*
116-
err.add(pos, "missing orientation");
117-
Err(Failed)
118-
*/
119-
}
120-
}
121-
12293
fn find_marker(
12394
marker: &ShortString,
12495
collection: &[(&str, &'static dyn RenderMarker)]
@@ -147,12 +118,59 @@ impl Feature for Marker {
147118
) -> AnyShape<'_> {
148119
MarkerShape {
149120
marker: self,
150-
info: RenderInfo::from_style(style, &self.class),
121+
info: RenderInfo::new(self.orientation, style, &self.class),
151122
}.into()
152123
}
153124
}
154125

155126

127+
//------------ Orientation ---------------------------------------------------
128+
129+
#[derive(Clone, Copy, Debug)]
130+
enum Orientation {
131+
Left,
132+
Right,
133+
Top,
134+
Bottom,
135+
}
136+
137+
impl Orientation {
138+
fn from_symbols(
139+
symbols: &mut SymbolSet,
140+
_err: &mut EvalErrors
141+
) -> Result<Self, Failed> {
142+
if symbols.take("top") {
143+
Ok(Self::Top)
144+
}
145+
else if symbols.take("left") {
146+
Ok(Self::Left)
147+
}
148+
else if symbols.take("bottom") {
149+
Ok(Self::Bottom)
150+
}
151+
else if symbols.take("right") {
152+
Ok(Self::Right)
153+
}
154+
else {
155+
Ok(Self::Right)
156+
/*
157+
err.add(pos, "missing orientation");
158+
Err(Failed)
159+
*/
160+
}
161+
}
162+
163+
fn into_rotation(self) -> f64 {
164+
match self {
165+
Self::Left => PI,
166+
Self::Right => 0.,
167+
Self::Top => 1.5 * PI,
168+
Self::Bottom => 0.5 * PI,
169+
}
170+
}
171+
}
172+
173+
156174
//------------ MarkerShape ---------------------------------------------------
157175

158176
struct MarkerShape<'a> {
@@ -168,7 +186,7 @@ impl MarkerShape<'_> {
168186
let (point, angle) = self.marker.position.resolve(style);
169187
let matrix = Matrix::identity().translate(
170188
point
171-
).rotate(angle + self.marker.orientation);
189+
).rotate(angle + self.marker.orientation.into_rotation());
172190
let extent = self.marker.extent.as_ref().map(|extent| {
173191
let (extent, _) = extent.resolve(style);
174192
matrix.clone().invert().transform_point(extent)
@@ -231,6 +249,9 @@ struct RenderInfo {
231249
/// The detail level.
232250
detail: u8,
233251

252+
/// The orientation.
253+
orientation: Orientation,
254+
234255
/// The measures according to the style.
235256
m: Measures,
236257

@@ -254,9 +275,10 @@ struct RenderInfo {
254275
}
255276

256277
impl RenderInfo {
257-
fn from_style(style: &Style, class: &Railway) -> Self {
278+
fn new(orientation: Orientation, style: &Style, class: &Railway) -> Self {
258279
RenderInfo {
259280
detail: style.detail(),
281+
orientation,
260282
m: style.measures(),
261283
ct: style.measures().class_track(class),
262284
cd: style.measures().class_double(class),
@@ -382,6 +404,9 @@ const MARKERS: &[(&str, &'static dyn RenderMarker)] = &[
382404
("opbound", &OperatorBoundary),
383405
("st", &Station),
384406
("sst", &ServiceStation),
407+
("tuna", &TunnelStart),
408+
("tunf", &TunnelEnd),
409+
("tuno", &TunnelOffset),
385410

386411
("de.abzw", &Junction),
387412
("de.bbf", &ServiceStation),
@@ -807,6 +832,95 @@ impl OperatorBoundary {
807832
}
808833

809834

835+
//------------ TunnelStart ---------------------------------------------------
836+
837+
pub struct TunnelStart;
838+
839+
impl TunnelStart {
840+
fn s(info: &RenderInfo) -> f64 {
841+
info.m.sh() * 0.25
842+
}
843+
}
844+
845+
impl RenderMarker for TunnelStart {
846+
fn base(
847+
&self, info: &RenderInfo, _extent: Option<Point>, canvas: &mut Group
848+
) {
849+
let s = TunnelStart::s(info);
850+
canvas.apply(info.color);
851+
match info.orientation {
852+
Orientation::Top | Orientation::Bottom => {
853+
canvas.move_to(-0.5 * info.ct, 0.);
854+
canvas.line_to(0.5 * info.ct, 0.);
855+
}
856+
Orientation::Right => {
857+
canvas.move_to(0., -0.5 * info.ct);
858+
canvas.line_to(0., s + 0.5 * info.ct);
859+
canvas.line_to(-s, 2. * s + 0.5 * info.ct);
860+
}
861+
Orientation::Left => {
862+
canvas.move_to(0., -0.5 * info.ct);
863+
canvas.line_to(0., s + 0.5 * info.ct);
864+
canvas.line_to(s, 2. * s + 0.5 * info.ct);
865+
}
866+
}
867+
canvas.apply_line_width(w(info));
868+
canvas.stroke();
869+
}
870+
}
871+
872+
873+
//------------ TunnelEnd -----------------------------------------------------
874+
875+
pub struct TunnelEnd;
876+
877+
impl RenderMarker for TunnelEnd {
878+
fn base(
879+
&self, info: &RenderInfo, _extent: Option<Point>, canvas: &mut Group
880+
) {
881+
let s = TunnelStart::s(info);
882+
canvas.apply(info.color);
883+
match info.orientation {
884+
Orientation::Top | Orientation::Bottom => {
885+
canvas.move_to(-0.5 * info.ct, 0.);
886+
canvas.line_to(0.5 * info.ct, 0.);
887+
}
888+
Orientation::Right => {
889+
canvas.move_to(0., -0.5 * info.ct);
890+
canvas.line_to(0., s + 0.5 * info.ct);
891+
canvas.line_to(s, 2. * s + 0.5 * info.ct);
892+
}
893+
Orientation::Left => {
894+
canvas.move_to(0., -0.5 * info.ct);
895+
canvas.line_to(0., s + 0.5 * info.ct);
896+
canvas.line_to(-s, 2. * s + 0.5 * info.ct);
897+
}
898+
}
899+
canvas.apply_line_width(w(info));
900+
canvas.stroke();
901+
}
902+
}
903+
904+
905+
//------------ TunnelOffset --------------------------------------------------
906+
907+
pub struct TunnelOffset;
908+
909+
impl RenderMarker for TunnelOffset {
910+
fn base(
911+
&self, info: &RenderInfo, _extent: Option<Point>, canvas: &mut Group
912+
) {
913+
let co = info.ct + info.cs;
914+
canvas.apply(info.color);
915+
canvas.move_to(0., -0.5 * co);
916+
canvas.line_to(0., 0.5 * co);
917+
canvas.apply_line_width(w(info));
918+
canvas.stroke();
919+
}
920+
}
921+
922+
923+
810924
//------------ Helper Functions ----------------------------------------------
811925

812926
fn x0(info: &RenderInfo) -> f64 {

0 commit comments

Comments
 (0)