Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorRenderingWpf/Texts/WpfTextOnPathDrawing.cs @ 14040

Last change on this file since 14040 was 12762, checked in by aballeit, 9 years ago

#2283 GUI updates, Tree-chart, MCTS Version 2 (prune leaves)

File size: 13.2 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Globalization;
4using System.Windows;
5using System.Windows.Media;
6
7using SharpVectors.Dom.Svg;
8
9namespace SharpVectors.Renderers.Texts
10{
11    public sealed class WpfTextOnPathDrawing : WpfTextOnPathBase
12    {
13        #region Private Fields
14
15        private double _fontSize;
16
17        private double _pathLength;
18        private double _textLength;
19
20        private List<Point>         _formattedOrigins;
21        private List<FormattedText> _formattedChars;
22
23        #endregion
24
25        #region Constructors and Destructor
26
27        public WpfTextOnPathDrawing()
28        {
29            _fontSize         = 100;
30            _formattedChars   = new List<FormattedText>();
31            _formattedOrigins = new List<Point>();
32        }
33
34        #endregion
35
36        #region Public Properties
37
38        public double FontSize
39        {
40            get
41            {
42                return _fontSize;
43            }
44            set
45            {
46                if (value >= 6)
47                {
48                    _fontSize = value;
49                }
50            }
51        }
52
53        #endregion
54
55        #region Public Methods
56
57        public void BeginTextPath()
58        {
59            if (_formattedChars == null || _formattedChars.Count != 0)
60            {
61                _formattedChars   = new List<FormattedText>();
62                _formattedOrigins = new List<Point>();
63            }
64            _formattedChars.Clear();
65            _formattedOrigins.Clear();
66
67            _textLength = 0;
68            _pathLength = 0;
69
70            _fontSize = 100;
71
72            //typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);
73        }
74
75        public void AddTextPath(string text, Point origin)
76        {
77            if (String.IsNullOrEmpty(text))
78            {
79                return;
80            }
81            Typeface typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch);
82
83            foreach (char ch in text)
84            {
85                FormattedText formattedText =
86                    new FormattedText(ch.ToString(), CultureInfo.CurrentCulture,
87                            FlowDirection.LeftToRight, typeface, _fontSize, Foreground);
88
89                _formattedChars.Add(formattedText);
90                _formattedOrigins.Add(origin);
91
92                _textLength += formattedText.WidthIncludingTrailingWhitespace;
93            }
94        }
95       
96        public void EndTextPath()
97        {
98            if (_formattedChars != null)
99            {
100                _formattedChars.Clear();
101            }
102
103            if (_formattedOrigins != null)
104            {
105                _formattedOrigins.Clear();
106            }
107        }
108
109        public void DrawTextPath(DrawingContext dc, PathGeometry pathGeometry,
110            ISvgAnimatedLength startOffset, TextAlignment alignment, SvgTextPathMethod method,
111            SvgTextPathSpacing spacing)
112        {
113            if (alignment == TextAlignment.Right)
114            {
115                this.DrawEndAlignedTextPath(dc, pathGeometry, startOffset);
116            }
117            else
118            {
119                this.DrawStartAlignedTextPath(dc, pathGeometry, startOffset, alignment);
120            }
121        }
122
123        #endregion
124
125        #region Private Methods
126
127        private void DrawStartAlignedTextPath(DrawingContext dc, PathGeometry pathGeometry,
128            ISvgAnimatedLength startOffset, TextAlignment alignment)
129        {
130            if (pathGeometry == null || pathGeometry.Figures == null ||
131                pathGeometry.Figures.Count != 1)
132            {
133                return;
134            }
135
136            _pathLength = GetPathFigureLength(pathGeometry.Figures[0]);
137            if (_pathLength == 0 || _textLength == 0)
138                return;
139
140            //double scalingFactor = pathLength / textLength;
141            double scalingFactor   = 1.0; // Not scaling the text to fit...
142            double progress = 0;
143            if (startOffset != null)
144            {
145                ISvgLength offsetLength = startOffset.AnimVal;
146                if (offsetLength != null)
147                {
148                    switch (offsetLength.UnitType)
149                    {
150                        case SvgLengthType.Percentage:
151                            if ((float)offsetLength.ValueInSpecifiedUnits != 0)
152                            {
153                                progress += offsetLength.ValueInSpecifiedUnits / 100d;
154                            }
155                            break;
156                    }
157                }
158            }
159            //PathGeometry pathGeometry =
160            //    new PathGeometry(new PathFigure[] { PathFigure });
161
162            Point ptOld = new Point(0, 0);
163
164            for (int i = 0; i < _formattedChars.Count; i++)
165            {
166                FormattedText formText = _formattedChars[i];
167
168                double width = scalingFactor *
169                            formText.WidthIncludingTrailingWhitespace;
170                double baseline = scalingFactor * formText.Baseline;
171                progress += width / 2 / _pathLength;
172                Point point, tangent;
173
174                pathGeometry.GetPointAtFractionLength(progress,
175                                                out point, out tangent);
176
177                if (i != 0)
178                {
179                    if (point == ptOld)
180                    {
181                        break;
182                    }
183                }
184               
185                dc.PushTransform(
186                    new TranslateTransform(point.X - width / 2,
187                                           point.Y - baseline));
188                dc.PushTransform(
189                    new RotateTransform(Math.Atan2(tangent.Y, tangent.X)
190                            * 180 / Math.PI, width / 2, baseline));
191                //dc.PushTransform(
192                //    new ScaleTransform(scalingFactor, scalingFactor));
193
194                dc.DrawText(formText, _formattedOrigins[i]);
195                dc.Pop();
196                dc.Pop();
197                //dc.Pop();
198
199                progress += width / 2 / _pathLength;
200
201                ptOld = point;
202            }
203        }
204
205        private void DrawEndAlignedTextPath(DrawingContext dc, PathGeometry pathGeometry,
206            ISvgAnimatedLength startOffset)
207        {
208            if (pathGeometry == null || pathGeometry.Figures == null ||
209                pathGeometry.Figures.Count != 1)
210            {
211                return;
212            }
213
214            _pathLength = GetPathFigureLength(pathGeometry.Figures[0]);
215            if (_pathLength == 0 || _textLength == 0)
216                return;
217
218            //double scalingFactor = pathLength / textLength;
219            double scalingFactor   = 1.0; // Not scaling the text to fit...
220            double progress = 1.0;
221            //PathGeometry pathGeometry =
222            //    new PathGeometry(new PathFigure[] { PathFigure });
223
224            Point ptOld = new Point(0, 0);
225
226            int itemCount = _formattedChars.Count - 1;
227
228            for (int i = itemCount; i >= 0; i--)
229            {
230                FormattedText formText = _formattedChars[i];
231
232                double width = scalingFactor *
233                            formText.WidthIncludingTrailingWhitespace;
234                double baseline = scalingFactor * formText.Baseline;
235                progress -= width / 2 / _pathLength;
236                Point point, tangent;
237
238                pathGeometry.GetPointAtFractionLength(progress,
239                                                out point, out tangent);
240
241                if (i != itemCount)
242                {
243                    if (point == ptOld)
244                    {
245                        break;
246                    }
247                }
248
249                dc.PushTransform(
250                    new TranslateTransform(point.X - width / 2,
251                                           point.Y - baseline));
252                dc.PushTransform(
253                    new RotateTransform(Math.Atan2(tangent.Y, tangent.X)
254                            * 180 / Math.PI, width / 2, baseline));
255                //dc.PushTransform(
256                //    new ScaleTransform(scalingFactor, scalingFactor));
257
258                dc.DrawText(formText, _formattedOrigins[i]);
259                dc.Pop();
260                dc.Pop();
261                //dc.Pop();
262
263                progress -= width / 2 / _pathLength;
264
265                ptOld = point;
266            }
267        }
268
269        //protected override void OnPathPropertyChanged(DependencyPropertyChangedEventArgs args)
270        //{
271        //    pathLength = GetPathFigureLength(PathFigure);
272        //    //TransformVisualChildren();
273        //}
274
275        protected override void OnFontPropertyChanged(DependencyPropertyChangedEventArgs args)
276        {
277            //OnTextPropertyChanged(args);
278        }
279
280        protected override void OnForegroundPropertyChanged(DependencyPropertyChangedEventArgs args)
281        {
282            //OnTextPropertyChanged(args);
283        }
284
285        //protected override void OnTextPropertyChanged(DependencyPropertyChangedEventArgs args)
286        //{             
287        //    //GenerateVisualChildren();
288        //}
289
290        //protected virtual void GenerateVisualChildren()
291        //{
292        //    visualChildren.Clear();
293
294        //    foreach (FormattedText formText in formattedChars)
295        //    {
296        //        DrawingVisual drawingVisual = new DrawingVisual();
297
298        //        TransformGroup transformGroup = new TransformGroup();
299        //        transformGroup.Children.Add(new ScaleTransform());
300        //        transformGroup.Children.Add(new RotateTransform());
301        //        transformGroup.Children.Add(new TranslateTransform());
302        //        drawingVisual.Transform = transformGroup;
303
304        //        DrawingContext dc = drawingVisual.RenderOpen();
305        //        dc.DrawText(formText, new Point(0, 0));
306        //        dc.Close();
307
308        //        visualChildren.Add(drawingVisual);
309        //    }
310
311        //    TransformVisualChildren();
312        //}
313
314        //protected virtual void TransformVisualChildren()
315        //{
316        //    boundingRect = new Rect();
317
318        //    if (pathLength == 0 || textLength == 0)
319        //        return;
320
321        //    if (formattedChars.Count != visualChildren.Count)
322        //        return;
323
324        //    double scalingFactor = pathLength / textLength;
325        //    PathGeometry pathGeometry =
326        //        new PathGeometry(new PathFigure[] { PathFigure });
327        //    double progress = 0;
328        //    boundingRect = new Rect();
329
330        //    for (int index = 0; index < visualChildren.Count; index++)
331        //    {
332        //        FormattedText formText = formattedChars[index];
333        //        double width = scalingFactor *
334        //                    formText.WidthIncludingTrailingWhitespace;
335        //        double baseline = scalingFactor * formText.Baseline;
336        //        progress += width / 2 / pathLength;
337        //        Point point, tangent;
338        //        pathGeometry.GetPointAtFractionLength(progress,
339        //                                    out point, out tangent);
340
341        //        DrawingVisual drawingVisual =
342        //            visualChildren[index] as DrawingVisual;
343        //        TransformGroup transformGroup =
344        //            drawingVisual.Transform as TransformGroup;
345        //        ScaleTransform scaleTransform =
346        //            transformGroup.Children[0] as ScaleTransform;
347        //        RotateTransform rotateTransform =
348        //            transformGroup.Children[1] as RotateTransform;
349        //        TranslateTransform translateTransform =
350        //            transformGroup.Children[2] as TranslateTransform;
351
352        //        scaleTransform.ScaleX = scalingFactor;
353        //        scaleTransform.ScaleY = scalingFactor;
354        //        rotateTransform.Angle =
355        //            Math.Atan2(tangent.Y, tangent.X) * 180 / Math.PI;
356        //        rotateTransform.CenterX = width / 2;
357        //        rotateTransform.CenterY = baseline;
358        //        translateTransform.X = point.X - width / 2;
359        //        translateTransform.Y = point.Y - baseline;
360
361        //        Rect rect = drawingVisual.ContentBounds;
362        //        rect.Transform(transformGroup.Value);
363        //        boundingRect.Union(rect);
364
365        //        progress += width / 2 / pathLength;
366        //    }
367        //    InvalidateMeasure();
368        //}
369
370        //protected override int VisualChildrenCount
371        //{
372        //    get
373        //    {
374        //        return visualChildren.Count;
375        //    }
376        //}
377
378        //protected override Visual GetVisualChild(int index)
379        //{
380        //    if (index < 0 || index >= visualChildren.Count)
381        //        throw new ArgumentOutOfRangeException("index");
382
383        //    return visualChildren[index];
384        //}
385
386        //protected override Size MeasureOverride(Size availableSize)
387        //{
388        //    return (Size)boundingRect.BottomRight;
389        //}
390
391        #endregion
392    }
393}
Note: See TracBrowser for help on using the repository browser.