protected virtual void GetFontSelection([NotNull] SvgTextBase svgTextBase,
                                         float fontSize,
                                         out int fontSelection,
                                         out int horizontalMultiplier,
                                         out int verticalMultiplier)
 {
     this.EplTransformer.GetFontSelection(svgTextBase,
                                          fontSize,
                                          out fontSelection,
                                          out horizontalMultiplier,
                                          out verticalMultiplier);
 }
Beispiel #2
0
            public TextDrawingState(TextDrawingState parent, SvgTextBase element)
            {
                this.Element      = element;
                this.Renderer     = parent.Renderer;
                this.Parent       = parent;
                this.Current      = parent.Current;
                this.TextBounds   = parent.TextBounds;
                this.BaselinePath = element.GetBaselinePath(parent.Renderer) ?? parent.BaselinePath;
                var currPathLength = element.GetAuthorPathLength();

                _authorPathLength = currPathLength == 0 ? parent._authorPathLength : currPathLength;
            }
Beispiel #3
0
 protected virtual void GetFontSelection([NotNull] SvgTextBase svgTextBase,
                                         float fontSize,
                                         out string fontName,
                                         out int characterHeight,
                                         out int slant)
 {
     this.FingerPrintTransformer.GetFontSelection(svgTextBase,
                                                  fontSize,
                                                  out fontName,
                                                  out characterHeight,
                                                  out slant);
 }
        public void Transform([NotNull] SvgTextBase svgTextBase,
                              [NotNull] Matrix sourceMatrix,
                              [NotNull] Matrix viewMatrix,
                              out float startX,
                              out float startY,
                              out float fontSize,
                              out Direction direction)
        {
            if (svgTextBase == null)
            {
                throw new ArgumentNullException(nameof(svgTextBase));
            }
            if (sourceMatrix == null)
            {
                throw new ArgumentNullException(nameof(sourceMatrix));
            }
            if (viewMatrix == null)
            {
                throw new ArgumentNullException(nameof(viewMatrix));
            }

            startX = this.SvgUnitReader.GetValue(svgTextBase,
                                                 svgTextBase.X.FirstOrDefault());
            startY = this.SvgUnitReader.GetValue(svgTextBase,
                                                 svgTextBase.Y.FirstOrDefault());
            fontSize = this.SvgUnitReader.GetValue(svgTextBase,
                                                   svgTextBase.FontSize);

            direction = this.GetDirection(sourceMatrix,
                                          viewMatrix);

            if ((int)direction % 2 > 0)
            {
                var lineHeightFactor = this.GetLineHeightFactor(svgTextBase);
                if (lineHeightFactor >= float.Epsilon)
                {
                    startX -= fontSize / lineHeightFactor;
                }
                else
                {
                    startX -= fontSize;
                }
            }

            this.ApplyMatrixOnPoint(startX,
                                    startY,
                                    sourceMatrix,
                                    viewMatrix,
                                    out startX,
                                    out startY);
        }
        public virtual void GetFontSelection([NotNull] SvgTextBase svgTextBase,
                                             float fontSize,
                                             [NotNull] out string fontName,
                                             out int characterHeight,
                                             out int width)
        {
            if (svgTextBase == null)
            {
                throw new ArgumentNullException(nameof(svgTextBase));
            }

            fontName        = "0";
            characterHeight = (int)Math.Max(fontSize,
                                            10f);
            width = 0;
        }
Beispiel #6
0
        private void RenderFill(SvgTextBase txt, ISvgRenderer renderer)
        {
            if (txt.Fill != null)
            {
                var brush = txt.Fill.GetBrush(txt, renderer, 1f);
                using (var pen = new Pen(brush, 0f))
                {
                    pen.TextSize  = txt.FontSize.Value;
                    pen.TextAlign = FromAnchor(txt.TextAnchor);

                    var x = txt.X.Any() ? txt.X.FirstOrDefault().Value : 0f;
                    var y = txt.Y.Any() ? txt.Y.FirstOrDefault().Value : 0f;

                    pen.Paint.IsStroke = false;

                    DrawLines(txt, renderer, x, y, pen);
                }
            }
        }
        public virtual void GetFontSelection([NotNull] SvgTextBase svgTextBase,
                                             float fontSize,
                                             out int fontSelection,
                                             out int horizontalMultiplier,
                                             out int verticalMultiplier)
        {
            if (svgTextBase == null)
            {
                throw new ArgumentNullException(nameof(svgTextBase));
            }

            // VALUE    203dpi        300dpi
            // ==================================
            //  1       20.3cpi       25cpi
            //          6pts          4pts
            //          8x12 dots     12x20 dots
            //          1:1.5         1:1.66
            // ==================================
            //  2       16.9cpi       18.75cpi
            //          7pts          6pts
            //          10x16 dots    16x28 dots
            //          1:1.6         1:1.75
            // ==================================
            //  3       14.5cpi       15cpi
            //          10pts         8pts
            //          12x20 dots    20x36 dots
            //          1:1.66        1:1.8
            // ==================================
            //  4       12.7cpi       12.5cpi
            //          12pts         10pts
            //          14x24 dots    24x44 dots
            //          1:1.71        1:1.83
            // ==================================
            //  5       5.6cpi        6.25cpi
            //          24pts         21pts
            //          32x48 dots    48x80 dots
            //          1:1.5         1:1.6
            // ==================================
            // horizontal multiplier: Accepted Values: 1–6, 8
            // vertical multiplier: Accepted Values: 1–9

            var fontDefinitions = new SortedList <int, int>
            {
                {
                    12, 1
                },
                {
                    16, 2
                },
                {
                    20, 3
                },
                {
                    24, 4
                }
            };

            var lowerFontDefinitionCandidate = default(FontDefinitionCandidate);
            var upperFontDefinitionCandidate = default(FontDefinitionCandidate);

            foreach (var factor in new[]
            {
                1,
                2,
                3,
                4,
                5,
                6,
                8
            })
            {
                foreach (var fontDefinition in fontDefinitions)
                {
                    var actualFontSize = fontDefinition.Key * factor;

                    // TODO find a good TOLERANCE
                    if (Math.Abs(actualFontSize - fontSize) < 0.5f)
                    {
                        fontSelection        = fontDefinition.Value;
                        horizontalMultiplier = factor;
                        verticalMultiplier   = factor;
                        return;
                    }

                    if (actualFontSize < fontSize)
                    {
                        if (lowerFontDefinitionCandidate == null ||
                            actualFontSize > lowerFontDefinitionCandidate.ActualHeight)
                        {
                            lowerFontDefinitionCandidate = new FontDefinitionCandidate
                            {
                                FontSelection = fontDefinition.Value,
                                ActualHeight  = actualFontSize,
                                Multiplier    = factor
                            };
                        }
                    }
                    else if (actualFontSize <= fontSize + this.MaximumUpperFontSizeOverlap)
                    {
                        if (upperFontDefinitionCandidate == null ||
                            actualFontSize < upperFontDefinitionCandidate.ActualHeight)
                        {
                            upperFontDefinitionCandidate = new FontDefinitionCandidate
                            {
                                FontSelection = fontDefinition.Value,
                                ActualHeight  = actualFontSize,
                                Multiplier    = factor
                            };
                        }
                        break;
                    }
                }
            }

            if (lowerFontDefinitionCandidate == null &&
                upperFontDefinitionCandidate == null)
            {
                throw new ArgumentOutOfRangeException(nameof(fontSize),
                                                      fontSize,
                                                      $"Parameter {nameof(fontSize)} must be greater than {fontDefinitions.Keys.Min()}.");
            }

            if (lowerFontDefinitionCandidate == null)
            {
                fontSelection        = upperFontDefinitionCandidate.FontSelection;
                horizontalMultiplier = upperFontDefinitionCandidate.Multiplier;
                verticalMultiplier   = upperFontDefinitionCandidate.Multiplier;
            }
            else if (upperFontDefinitionCandidate == null)
            {
                fontSelection        = lowerFontDefinitionCandidate.FontSelection;
                horizontalMultiplier = lowerFontDefinitionCandidate.Multiplier;
                verticalMultiplier   = lowerFontDefinitionCandidate.Multiplier;
            }
            else
            {
                // :question: why dafuq are you doing it like this, and using no comparisons in the if-clause :question:
                // reason: idk if lower or upper is better, so I am leveling the playing field here
                // if I would add this to the if-clauses, the arithmetic behind it would be done
                // twice for the worst case. with this solution, the cost is stable for all scenarios
                var differenceLower = fontSize - lowerFontDefinitionCandidate.ActualHeight;
                var differenceUpper = upperFontDefinitionCandidate.ActualHeight - fontSize;
                if (differenceLower <= differenceUpper)
                {
                    fontSelection        = lowerFontDefinitionCandidate.FontSelection;
                    horizontalMultiplier = lowerFontDefinitionCandidate.Multiplier;
                    verticalMultiplier   = lowerFontDefinitionCandidate.Multiplier;
                }
                else
                {
                    fontSelection        = upperFontDefinitionCandidate.FontSelection;
                    horizontalMultiplier = upperFontDefinitionCandidate.Multiplier;
                    verticalMultiplier   = upperFontDefinitionCandidate.Multiplier;
                }
            }
        }
Beispiel #8
0
 internal string PrepareText(SvgTextBase svgTextBase, string value)
 {
     value = ApplyTransformation(svgTextBase, value);
     value = new StringBuilder(value).Replace("\r\n", " ").Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' ').ToString();
     return(svgTextBase.SpaceHandling == XmlSpaceHandling.preserve ? value : s_multipleSpaces.Replace(value.Trim(), " "));
 }
Beispiel #9
0
 internal virtual IEnumerable <ISvgNode> GetContentNodes(SvgTextBase svgTextBase)
 {
     return(svgTextBase.Nodes == null || svgTextBase.Nodes.Count < 1 ?
            svgTextBase.Children.OfType <ISvgNode>().Where(o => !(o is ISvgDescriptiveElement)) :
            svgTextBase.Nodes);
 }
Beispiel #10
0
        public RectangleF GetBounds(SvgTextBase txt, ISvgRenderer renderer)
        {
            if (!txt.Visible || !txt.Displayable)
            {
                return(new RectangleF(0f, 0f, 0f, 0f));
            }

            bool textIsEmpty   = string.IsNullOrEmpty(txt.Text);
            bool hasNoChildren = !txt.Children.OfType <SvgTextBase>().Any();

            if (textIsEmpty && hasNoChildren)
            {
                return(new RectangleF(0f, 0f, 0f, 0f));
            }

            if (!textIsEmpty)
            {
                var brush = txt.Fill.GetBrush(txt, renderer, 1f);
                using (var pen = new Pen(brush, txt.StrokeWidth.Value))
                {
                    pen.TextSize  = txt.FontSize.Value;
                    pen.TextAlign = FromAnchor(txt.TextAnchor);

                    var x = txt.X.Any() ? txt.X.FirstOrDefault().Value : 0f;
                    var y = txt.Y.Any() ? txt.Y.FirstOrDefault().Value : 0f;

                    float width  = 0f;
                    float height = 0f;

                    bool   isFirstLineRect = true;
                    SKRect firstLineRect   = default(SKRect);
                    var    lines           = txt.Text.Split('\n');
                    var    lineCount       = lines.Length;

                    // as android does not know the sense of "lines", we need to split the text and measure ourselves
                    // see: http://stackoverflow.com/questions/6756975/draw-multi-line-text-to-canvas
                    foreach (var line in lines)
                    {
                        SKRect rect = new SKRect();
                        pen.Paint.MeasureText(line, ref rect);

                        if (isFirstLineRect)
                        {
                            firstLineRect   = rect;
                            isFirstLineRect = false;
                        }

                        var w = rect.Right - rect.Left;
                        if (width < w)
                        {
                            width = w;
                        }

                        var h = rect.Bottom - rect.Top;
                        if (height < h)
                        {
                            height = h;
                        }
                    }

                    var x1 = x + firstLineRect.Left;
                    var y1 = y + firstLineRect.Top;

                    SvgTextBase t      = txt;
                    var         anchor = t.TextAnchor;
                    while (t != null && anchor == SvgTextAnchor.Inherit)
                    {
                        t = t.Parent as SvgTextBase;
                        if (t == null)
                        {
                            anchor = SvgTextAnchor.Start;
                        }
                        else
                        {
                            anchor = t.TextAnchor;
                        }
                    }

                    // textanchor affects boundingbox:
                    // if "Middle" (aka Align.Center) then x is the center of the rectangle
                    if (anchor == SvgTextAnchor.Middle)
                    {
                        x1 -= width / 2;
                    }
                    // if "End" (aka Align.Right) then x is at the very right end of the text
                    else if (anchor == SvgTextAnchor.End)
                    {
                        x1 -= width;
                    }


                    return(new RectangleF(x1, y1, width,
                                          height * lineCount));
                }
            }
            else if (!hasNoChildren)
            {
                RectangleF r = null;

                foreach (var child in txt.Children.OfType <SvgTextBase>())
                {
                    var bounds = GetBounds(child, renderer);
                    if (r == null)
                    {
                        r = bounds;
                    }
                    else
                    {
                        r = r.UnionAndCopy(bounds);
                    }
                }

                return(r);
            }

            return(new RectangleF(0f, 0f, 0f, 0f));
        }
        public override void Transform(SvgTextBase svgTextBase,
                                       Matrix sourceMatrix,
                                       Matrix viewMatrix,
                                       out float startX,
                                       out float startY,
                                       out float fontSize)
        {
            if (svgTextBase == null)
            {
                throw new ArgumentNullException(nameof(svgTextBase));
            }
            if (sourceMatrix == null)
            {
                throw new ArgumentNullException(nameof(sourceMatrix));
            }
            if (viewMatrix == null)
            {
                throw new ArgumentNullException(nameof(viewMatrix));
            }

            base.Transform(svgTextBase,
                           sourceMatrix,
                           viewMatrix,
                           out startX,
                           out startY,
                           out fontSize);

            var lineHeightFactor = this.GetLineHeightFactor(svgTextBase);

            float offset;

            if (lineHeightFactor >= float.Epsilon)
            {
                offset = fontSize / lineHeightFactor;
            }
            else
            {
                offset = fontSize;
            }

            var rotationSector = this.GetRotationSector(sourceMatrix,
                                                        viewMatrix);
            var rotationQuotient = Math.DivRem(rotationSector,
                                               2,
                                               out var remainder);

            if (remainder == 0)
            {
                if (rotationQuotient % 2 == 0)
                {
                    startY += offset;
                }
                else
                {
                    startY -= offset;
                }
            }
            else
            {
                if (rotationQuotient % 2 == 0)
                {
                    startX -= offset;
                }
                else
                {
                    startX += offset;
                }
            }
        }