Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/SharpVectorRenderingWpf/Texts/WpfHorzTextRenderer.cs @ 13834

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

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

File size: 22.7 KB
Line 
1using System;
2using System.Xml;
3using System.Linq;
4using System.Text;
5using System.Collections.Generic;
6
7using System.Windows;
8using System.Windows.Media;
9
10using SharpVectors.Dom.Css;
11using SharpVectors.Dom.Svg;
12
13using SharpVectors.Renderers.Wpf;
14
15namespace SharpVectors.Renderers.Texts
16{
17    public sealed class WpfHorzTextRenderer : WpfTextRenderer
18    {
19        #region Private Fields
20
21        #endregion
22
23        #region Constructors and Destructor
24
25        public WpfHorzTextRenderer(SvgTextElement textElement, WpfTextRendering textRendering)
26            : base(textElement, textRendering)
27        {
28        }
29
30        #endregion
31
32        #region Public Methods
33
34        public override void RenderSingleLineText(SvgTextContentElement element, ref Point ctp,
35            string text, double rotate, WpfTextPlacement placement)
36        {
37            if (String.IsNullOrEmpty(text))
38                return;
39
40            double emSize         = GetComputedFontSize(element);
41            FontFamily fontFamily = GetTextFontFamily(element, emSize);
42
43            FontStyle fontStyle   = GetTextFontStyle(element);
44            FontWeight fontWeight = GetTextFontWeight(element);
45
46            FontStretch fontStretch = GetTextFontStretch(element);
47
48            WpfTextStringFormat stringFormat = GetTextStringFormat(element);
49
50            // Fix the use of Postscript fonts...
51            WpfFontFamilyVisitor fontFamilyVisitor = _drawContext.FontFamilyVisitor;
52            if (!String.IsNullOrEmpty(_actualFontName) && fontFamilyVisitor != null)
53            {
54                WpfFontFamilyInfo currentFamily = new WpfFontFamilyInfo(fontFamily, fontWeight,
55                    fontStyle, fontStretch);
56                WpfFontFamilyInfo familyInfo = fontFamilyVisitor.Visit(_actualFontName,
57                    currentFamily, _drawContext);
58                if (familyInfo != null && !familyInfo.IsEmpty)
59                {
60                    fontFamily  = familyInfo.Family;
61                    fontWeight  = familyInfo.Weight;
62                    fontStyle   = familyInfo.Style;
63                    fontStretch = familyInfo.Stretch;
64                }
65            }
66
67            WpfSvgPaint fillPaint   = new WpfSvgPaint(_drawContext, element, "fill");
68            Brush textBrush = fillPaint.GetBrush();
69
70            WpfSvgPaint strokePaint = new WpfSvgPaint(_drawContext, element, "stroke");
71            Pen textPen = strokePaint.GetPen();
72
73            if (textBrush == null && textPen == null)
74            {
75                return;
76            }
77            else if (textBrush == null)
78            {
79                // If here, then the pen is not null, and so the fill cannot be null.
80                // We set this to transparent for stroke only text path...
81                textBrush = Brushes.Transparent;
82            }
83
84            TextDecorationCollection textDecors = GetTextDecoration(element);
85            TextAlignment alignment = stringFormat.Alignment;
86
87            bool hasWordSpacing  = false;
88            string wordSpaceText = element.GetAttribute("word-spacing");
89            double wordSpacing   = 0;
90            if (!String.IsNullOrEmpty(wordSpaceText) &&
91                Double.TryParse(wordSpaceText, out wordSpacing) && (float)wordSpacing != 0)
92            {
93                hasWordSpacing = true;
94            }
95
96            bool hasLetterSpacing = false;
97            string letterSpaceText = element.GetAttribute("letter-spacing");
98            double letterSpacing = 0;
99            if (!String.IsNullOrEmpty(letterSpaceText) &&
100                Double.TryParse(letterSpaceText, out letterSpacing) && (float)letterSpacing != 0)
101            {
102                hasLetterSpacing = true;
103            }
104
105            bool isRotatePosOnly = false;
106
107            IList<WpfTextPosition> textPositions = null;
108            int textPosCount = 0;
109            if ((placement != null && placement.HasPositions))
110            {
111                textPositions = placement.Positions;
112                textPosCount = textPositions.Count;
113                isRotatePosOnly = placement.IsRotateOnly;
114            }
115
116            if (hasLetterSpacing || hasWordSpacing || textPositions != null)
117            {   
118                for (int i = 0; i < text.Length; i++)
119                {
120                    FormattedText formattedText = new FormattedText(new string(text[i], 1),
121                        _drawContext.CultureInfo, stringFormat.Direction,
122                        new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
123                        emSize, textBrush);
124
125                    formattedText.TextAlignment = stringFormat.Alignment;
126                    formattedText.Trimming      = stringFormat.Trimming;
127
128                    if (textDecors != null && textDecors.Count != 0)
129                    {
130                        formattedText.SetTextDecorations(textDecors);
131                    }
132
133                    WpfTextPosition? textPosition = null;
134                    if (textPositions != null && i < textPosCount)
135                    {
136                        textPosition = textPositions[i];
137                    }
138
139                    //float xCorrection = 0;
140                    //if (alignment == TextAlignment.Left)
141                    //    xCorrection = emSize * 1f / 6f;
142                    //else if (alignment == TextAlignment.Right)
143                    //    xCorrection = -emSize * 1f / 6f;
144
145                    double yCorrection = formattedText.Baseline;
146
147                    float rotateAngle = (float)rotate;
148                    if (textPosition != null)
149                    {
150                        if (!isRotatePosOnly)
151                        {
152                            Point pt = textPosition.Value.Location;
153                            ctp.X = pt.X;
154                            ctp.Y = pt.Y;
155                        }
156                        rotateAngle = (float)textPosition.Value.Rotation;
157                    }
158                    Point textStart = ctp;
159
160                    RotateTransform rotateAt = null;
161                    if (rotateAngle != 0)
162                    {
163                        rotateAt = new RotateTransform(rotateAngle, textStart.X, textStart.Y);
164                        _textContext.PushTransform(rotateAt);
165                    }
166
167                    Point textPoint = new Point(textStart.X, textStart.Y - yCorrection);
168
169                    if (textPen != null || _drawContext.TextAsGeometry)
170                    {
171                        Geometry textGeometry = formattedText.BuildGeometry(textPoint);
172                        if (textGeometry != null && !textGeometry.IsEmpty())
173                        {
174                            _textContext.DrawGeometry(textBrush, textPen,
175                                ExtractTextPathGeometry(textGeometry));
176
177                            this.IsTextPath = true;
178                        }
179                        else
180                        {
181                            _textContext.DrawText(formattedText, textPoint);
182                        }
183                    }
184                    else
185                    {
186                        _textContext.DrawText(formattedText, textPoint);
187                    }
188
189                    //float bboxWidth = (float)formattedText.Width;
190                    double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
191                    if (alignment == TextAlignment.Center)
192                        bboxWidth /= 2f;
193                    else if (alignment == TextAlignment.Right)
194                        bboxWidth = 0;
195
196                    //ctp.X += bboxWidth + emSize / 4 + spacing;
197                    if (hasLetterSpacing)
198                    {
199                        ctp.X += bboxWidth + letterSpacing;
200                    }
201                    if (hasWordSpacing && Char.IsWhiteSpace(text[i]))
202                    {
203                        if (hasLetterSpacing)
204                        {
205                            ctp.X += wordSpacing;
206                        }
207                        else
208                        {
209                            ctp.X += bboxWidth + wordSpacing;
210                        }
211                    }
212                    else
213                    {
214                        if (!hasLetterSpacing)
215                        {
216                            ctp.X += bboxWidth;
217                        }
218                    }
219
220                    if (rotateAt != null)
221                    {
222                        _textContext.Pop();
223                    }
224                }
225            }
226            else
227            {   
228                FormattedText formattedText = new FormattedText(text, _drawContext.CultureInfo,
229                    stringFormat.Direction, new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
230                    emSize, textBrush);
231
232                formattedText.TextAlignment = stringFormat.Alignment;
233                formattedText.Trimming      = stringFormat.Trimming;
234
235                if (textDecors != null && textDecors.Count != 0)
236                {
237                    formattedText.SetTextDecorations(textDecors);
238                }
239
240                //float xCorrection = 0;
241                //if (alignment == TextAlignment.Left)
242                //    xCorrection = emSize * 1f / 6f;
243                //else if (alignment == TextAlignment.Right)
244                //    xCorrection = -emSize * 1f / 6f;
245
246                double yCorrection = formattedText.Baseline;
247
248                float rotateAngle = (float)rotate;
249                Point textPoint = new Point(ctp.X, ctp.Y - yCorrection);
250
251                RotateTransform rotateAt = null;
252                if (rotateAngle != 0)
253                {
254                    rotateAt = new RotateTransform(rotateAngle, ctp.X, ctp.Y);
255                    _textContext.PushTransform(rotateAt);
256                }
257
258                if (textPen != null || _drawContext.TextAsGeometry)
259                {
260                    Geometry textGeometry = formattedText.BuildGeometry(textPoint);
261                    if (textGeometry != null && !textGeometry.IsEmpty())
262                    {
263                        _textContext.DrawGeometry(textBrush, textPen,
264                            ExtractTextPathGeometry(textGeometry));
265
266                        this.IsTextPath = true;
267                    }
268                    else
269                    {
270                        _textContext.DrawText(formattedText, textPoint);
271                    }
272                }
273                else
274                {
275                    _textContext.DrawText(formattedText, textPoint);
276                }
277
278                //float bboxWidth = (float)formattedText.Width;
279                double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
280                if (alignment == TextAlignment.Center)
281                    bboxWidth /= 2f;
282                else if (alignment == TextAlignment.Right)
283                    bboxWidth = 0;
284
285                //ctp.X += bboxWidth + emSize / 4;
286                ctp.X += bboxWidth;
287
288                if (rotateAt != null)
289                {
290                    _textContext.Pop();
291                }
292            }
293        }
294
295        public override void RenderTextRun(SvgTextContentElement element, ref Point ctp,
296            string text, double rotate, WpfTextPlacement placement)
297        {
298            if (String.IsNullOrEmpty(text))
299                return;
300
301            double emSize         = GetComputedFontSize(element);
302            FontFamily fontFamily = GetTextFontFamily(element, emSize);
303
304            FontStyle fontStyle   = GetTextFontStyle(element);
305            FontWeight fontWeight = GetTextFontWeight(element);
306
307            FontStretch fontStretch = GetTextFontStretch(element);
308
309            WpfTextStringFormat stringFormat = GetTextStringFormat(element);
310
311            // Fix the use of Postscript fonts...
312            WpfFontFamilyVisitor fontFamilyVisitor = _drawContext.FontFamilyVisitor;
313            if (!String.IsNullOrEmpty(_actualFontName) && fontFamilyVisitor != null)
314            {
315                WpfFontFamilyInfo currentFamily = new WpfFontFamilyInfo(fontFamily, fontWeight,
316                    fontStyle, fontStretch);
317                WpfFontFamilyInfo familyInfo = fontFamilyVisitor.Visit(_actualFontName,
318                    currentFamily,_drawContext);
319                if (familyInfo != null && !familyInfo.IsEmpty)
320                {
321                    fontFamily  = familyInfo.Family;
322                    fontWeight  = familyInfo.Weight;
323                    fontStyle   = familyInfo.Style;
324                    fontStretch = familyInfo.Stretch;
325                }
326            }
327
328            WpfSvgPaint fillPaint = new WpfSvgPaint(_drawContext, element, "fill");
329            Brush textBrush = fillPaint.GetBrush();
330
331            WpfSvgPaint strokePaint = new WpfSvgPaint(_drawContext, element, "stroke");
332            Pen textPen = strokePaint.GetPen();
333
334            if (textBrush == null && textPen == null)
335            {
336                return;
337            }
338            else if (textBrush == null)
339            {
340                // If here, then the pen is not null, and so the fill cannot be null.
341                // We set this to transparent for stroke only text path...
342                textBrush = Brushes.Transparent;
343            }
344
345            TextDecorationCollection textDecors = GetTextDecoration(element);
346            if (textDecors == null)
347            {
348                SvgTextElement textElement = element.ParentNode as SvgTextElement;
349
350                if (textElement != null)
351                {
352                    textDecors = GetTextDecoration(textElement);
353                }
354            }
355
356            TextAlignment alignment = stringFormat.Alignment;
357
358            bool hasWordSpacing  = false;
359            string wordSpaceText = element.GetAttribute("word-spacing");
360            double wordSpacing = 0;
361            if (!String.IsNullOrEmpty(wordSpaceText) &&
362                Double.TryParse(wordSpaceText, out wordSpacing) && (float)wordSpacing != 0)
363            {
364                hasWordSpacing = true;
365            }
366
367            bool hasLetterSpacing = false;
368            string letterSpaceText = element.GetAttribute("letter-spacing");
369            double letterSpacing = 0;
370            if (!String.IsNullOrEmpty(letterSpaceText) &&
371                Double.TryParse(letterSpaceText, out letterSpacing) && (float)letterSpacing != 0)
372            {
373                hasLetterSpacing = true;
374            }
375
376            bool isRotatePosOnly = false;
377
378            IList<WpfTextPosition> textPositions = null;
379            int textPosCount = 0;
380            if ((placement != null && placement.HasPositions))
381            {
382                textPositions   = placement.Positions;
383                textPosCount    = textPositions.Count;
384                isRotatePosOnly = placement.IsRotateOnly;
385            }
386
387            if (hasLetterSpacing || hasWordSpacing || textPositions != null)
388            {
389                double spacing = Convert.ToDouble(letterSpacing);
390                for (int i = 0; i < text.Length; i++)
391                {
392                    FormattedText formattedText = new FormattedText(new string(text[i], 1),
393                        _drawContext.CultureInfo, stringFormat.Direction,
394                        new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
395                        emSize, textBrush);
396
397                    if (this.IsMeasuring)
398                    {
399                        this.AddTextWidth(formattedText.WidthIncludingTrailingWhitespace);
400                        continue;
401                    }
402
403                    formattedText.Trimming      = stringFormat.Trimming;
404                    formattedText.TextAlignment = stringFormat.Alignment;
405
406                    if (textDecors != null && textDecors.Count != 0)
407                    {
408                        formattedText.SetTextDecorations(textDecors);
409                    }
410
411                    WpfTextPosition? textPosition = null;
412                    if (textPositions != null && i < textPosCount)
413                    {
414                        textPosition = textPositions[i];
415                    }
416
417                    //float xCorrection = 0;
418                    //if (alignment == TextAlignment.Left)
419                    //    xCorrection = emSize * 1f / 6f;
420                    //else if (alignment == TextAlignment.Right)
421                    //    xCorrection = -emSize * 1f / 6f;
422
423                    double yCorrection = formattedText.Baseline;
424
425                    float rotateAngle = (float)rotate;
426                    if (textPosition != null)
427                    {
428                        if (!isRotatePosOnly)
429                        {
430                            Point pt = textPosition.Value.Location;
431                            ctp.X = pt.X;
432                            ctp.Y = pt.Y;
433                        }
434                        rotateAngle = (float)textPosition.Value.Rotation;
435                    }
436                    Point textStart = ctp;
437
438                    RotateTransform rotateAt = null;
439                    if (rotateAngle != 0)
440                    {
441                        rotateAt = new RotateTransform(rotateAngle, textStart.X, textStart.Y);
442                        _textContext.PushTransform(rotateAt);
443                    }
444
445                    Point textPoint = new Point(ctp.X, ctp.Y - yCorrection);
446
447                    if (textPen != null || _drawContext.TextAsGeometry)
448                    {
449                        Geometry textGeometry = formattedText.BuildGeometry(textPoint);
450                        if (textGeometry != null && !textGeometry.IsEmpty())
451                        {
452                            _textContext.DrawGeometry(textBrush, textPen,
453                                ExtractTextPathGeometry(textGeometry));
454
455                            this.IsTextPath = true;
456                        }
457                        else
458                        {
459                            _textContext.DrawText(formattedText, textPoint);
460                        }
461                    }
462                    else
463                    {
464                        _textContext.DrawText(formattedText, textPoint);
465                    }
466
467                    //float bboxWidth = (float)formattedText.Width;
468                    double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
469                    if (alignment == TextAlignment.Center)
470                        bboxWidth /= 2f;
471                    else if (alignment == TextAlignment.Right)
472                        bboxWidth = 0;
473
474                    //ctp.X += bboxWidth + emSize / 4 + spacing;
475                    if (hasLetterSpacing)
476                    {
477                        ctp.X += bboxWidth + letterSpacing;
478                    }
479                    if (hasWordSpacing && Char.IsWhiteSpace(text[i]))
480                    {
481                        if (hasLetterSpacing)
482                        {
483                            ctp.X += wordSpacing;
484                        }
485                        else
486                        {
487                            ctp.X += bboxWidth + wordSpacing;
488                        }
489                    }
490                    else
491                    {
492                        if (!hasLetterSpacing)
493                        {
494                            ctp.X += bboxWidth;
495                        }
496                    }
497
498                    if (rotateAt != null)
499                    {
500                        _textContext.Pop();
501                    }
502                }
503            }
504            else
505            {   
506                FormattedText formattedText = new FormattedText(text, _drawContext.CultureInfo,
507                    stringFormat.Direction, new Typeface(fontFamily, fontStyle, fontWeight, fontStretch),
508                    emSize, textBrush);
509
510                if (this.IsMeasuring)
511                {
512                    this.AddTextWidth(formattedText.WidthIncludingTrailingWhitespace); 
513                    return;
514                }
515
516                if (alignment == TextAlignment.Center && this.TextWidth > 0)
517                {
518                    alignment = TextAlignment.Left;
519                }
520
521                formattedText.TextAlignment = alignment;
522                formattedText.Trimming      = stringFormat.Trimming;
523
524                if (textDecors != null && textDecors.Count != 0)
525                {
526                    formattedText.SetTextDecorations(textDecors);
527                }
528
529                //float xCorrection = 0;
530                //if (alignment == TextAlignment.Left)
531                //    xCorrection = emSize * 1f / 6f;
532                //else if (alignment == TextAlignment.Right)
533                //    xCorrection = -emSize * 1f / 6f;
534
535                double yCorrection = formattedText.Baseline;
536
537                float rotateAngle  = (float)rotate;
538                Point textPoint    = new Point(ctp.X, ctp.Y - yCorrection);
539
540                RotateTransform rotateAt = null;
541                if (rotateAngle != 0)
542                {
543                    rotateAt = new RotateTransform(rotateAngle, ctp.X, ctp.Y);
544                    _textContext.PushTransform(rotateAt);
545                }
546
547                if (textPen != null || _drawContext.TextAsGeometry)
548                {
549                    Geometry textGeometry = formattedText.BuildGeometry(textPoint);
550                    if (textGeometry != null && !textGeometry.IsEmpty())
551                    {
552                        _textContext.DrawGeometry(textBrush, textPen,
553                            ExtractTextPathGeometry(textGeometry));
554
555                        this.IsTextPath = true;
556                    }
557                    else
558                    {
559                        _textContext.DrawText(formattedText, textPoint);
560                    }
561                }
562                else
563                {
564                    _textContext.DrawText(formattedText, textPoint);
565                }
566
567                //float bboxWidth = (float)formattedText.Width;
568                double bboxWidth = formattedText.WidthIncludingTrailingWhitespace;
569                if (alignment == TextAlignment.Center)
570                    bboxWidth /= 2f;
571                else if (alignment == TextAlignment.Right)
572                    bboxWidth = 0;
573
574                //ctp.X += bboxWidth + emSize / 4;
575                ctp.X += bboxWidth;
576
577                if (rotateAt != null)
578                {
579                    _textContext.Pop();
580                }
581            }
582        }
583
584        #endregion
585    }
586}
Note: See TracBrowser for help on using the repository browser.