@@ -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
158176struct 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
256277impl 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
812926fn x0 ( info : & RenderInfo ) -> f64 {
0 commit comments