protected internal override void DoDraw(SvgDrawContext context)
        {
            PdfCanvas cv = context.GetCurrentCanvas();

            cv.WriteLiteral("% rect\n");
            float x = 0.0f;
            float y = 0.0f;

            if (GetAttribute(SvgConstants.Attributes.X) != null)
            {
                x = CssUtils.ParseAbsoluteLength(GetAttribute(SvgConstants.Attributes.X));
            }
            if (GetAttribute(SvgConstants.Attributes.Y) != null)
            {
                y = CssUtils.ParseAbsoluteLength(GetAttribute(SvgConstants.Attributes.Y));
            }
            float width     = CssUtils.ParseAbsoluteLength(GetAttribute(SvgConstants.Attributes.WIDTH));
            float height    = CssUtils.ParseAbsoluteLength(GetAttribute(SvgConstants.Attributes.HEIGHT));
            bool  rxPresent = false;
            bool  ryPresent = false;
            float rx        = 0f;
            float ry        = 0f;

            if (attributesAndStyles.ContainsKey(SvgConstants.Attributes.RX))
            {
                rx        = CssUtils.ParseAbsoluteLength(GetAttribute(SvgConstants.Attributes.RX));
                rxPresent = true;
            }
            if (attributesAndStyles.ContainsKey(SvgConstants.Attributes.RY))
            {
                ry        = CssUtils.ParseAbsoluteLength(GetAttribute(SvgConstants.Attributes.RY));
                ryPresent = true;
            }
            bool singleValuePresent = (rxPresent && !ryPresent) || (!rxPresent && ryPresent);

            // these checks should happen in all cases
            rx = CheckRadius(rx, width);
            ry = CheckRadius(ry, height);
            if (!rxPresent && !ryPresent)
            {
                cv.Rectangle(x, y, width, height);
            }
            else
            {
                if (singleValuePresent)
                {
                    cv.WriteLiteral("% circle rounded rect\n");
                    // only look for radius in case of circular rounding
                    float radius = FindCircularRadius(rx, ry, width, height);
                    cv.RoundRectangle(x, y, width, height, radius);
                }
                else
                {
                    cv.WriteLiteral("% ellipse rounded rect\n");
                    // TODO (DEVSIX-1878): this should actually be refactored into PdfCanvas.roundRectangle()

                    /*
                     *
                     * y+h    ->    ____________________________
                     * /                            \
                     * /                              \
                     * y+h-ry -> /                                \
                     |                                |
                     |                                |
                     |                                |
                     |                                |
                     | y+ry   -> \                                /
                     \                              /
                     \ y      ->   \____________________________/
                     \ ^  ^                          ^  ^
                     \ x  x+rx                  x+w-rx  x+w
                     \
                     */
                    cv.MoveTo(x + rx, y);
                    cv.LineTo(x + width - rx, y);
                    Arc(x + width - 2 * rx, y, x + width, y + 2 * ry, -90, 90, cv);
                    cv.LineTo(x + width, y + height - ry);
                    Arc(x + width, y + height - 2 * ry, x + width - 2 * rx, y + height, 0, 90, cv);
                    cv.LineTo(x + rx, y + height);
                    Arc(x + 2 * rx, y + height, x, y + height - 2 * ry, 90, 90, cv);
                    cv.LineTo(x, y + ry);
                    Arc(x, y + 2 * ry, x + 2 * rx, y, 180, 90, cv);
                    cv.ClosePath();
                }
            }
        }
 /// <summary>
 /// Method that will set properties to be inherited by this branch renderer's
 /// children and will iterate over all children in order to draw them.
 /// </summary>
 /// <param name="context">
 /// the object that knows the place to draw this element and
 /// maintains its state
 /// </param>
 protected internal override void DoDraw(SvgDrawContext context)
 {
     if (GetChildren().Count > 0)
     {
         // if branch has no children, don't do anything
         PdfCanvas currentCanvas = context.GetCurrentCanvas();
         if (performRootTransformations)
         {
             currentCanvas.BeginText();
             //Current transformation matrix results in the character glyphs being mirrored, correct with inverse tf
             AffineTransform rootTf;
             if (this.ContainsAbsolutePositionChange())
             {
                 rootTf = GetTextTransform(this.GetAbsolutePositionChanges(), context);
             }
             else
             {
                 rootTf = new AffineTransform(TEXTFLIP);
             }
             currentCanvas.SetTextMatrix(rootTf);
             //Reset context of text move
             context.ResetTextMove();
             //Apply relative move
             if (this.ContainsRelativeMove())
             {
                 float[] rootMove = this.GetRelativeTranslation();
                 context.AddTextMove(rootMove[0], -rootMove[1]);
             }
             //-y to account for the text-matrix transform we do in the text root to account for the coordinates
             //handle white-spaces
             if (!whiteSpaceProcessed)
             {
                 SvgTextUtil.ProcessWhiteSpace(this, true);
             }
         }
         ApplyTextRenderingMode(currentCanvas);
         if (this.attributesAndStyles != null)
         {
             ResolveFontSize();
             ResolveFont(context);
             currentCanvas.SetFontAndSize(font, fontSize);
             foreach (ISvgTextNodeRenderer c in children)
             {
                 float childLength = c.GetTextContentLength(fontSize, font);
                 if (c.ContainsAbsolutePositionChange())
                 {
                     //TODO(DEVSIX-2507) support rotate and other attributes
                     float[][]       absolutePositions = c.GetAbsolutePositionChanges();
                     AffineTransform newTransform      = GetTextTransform(absolutePositions, context);
                     //overwrite the last transformation stored in the context
                     context.SetLastTextTransform(newTransform);
                     //Apply transformation
                     currentCanvas.SetTextMatrix(newTransform);
                     //Absolute position changes requires resetting the current text move in the context
                     context.ResetTextMove();
                 }
                 //Handle Text-Anchor declarations
                 float textAnchorCorrection = GetTextAnchorAlignmentCorrection(childLength);
                 if (!CssUtils.CompareFloats(0f, textAnchorCorrection))
                 {
                     context.AddTextMove(textAnchorCorrection, 0);
                 }
                 //Move needs to happen before the saving of the state in order for it to cascade beyond
                 if (c.ContainsRelativeMove())
                 {
                     float[] childMove = c.GetRelativeTranslation();
                     context.AddTextMove(childMove[0], -childMove[1]);
                 }
                 //-y to account for the text-matrix transform we do in the text root to account for the coordinates
                 currentCanvas.SaveState();
                 c.Draw(context);
                 context.AddTextMove(childLength, 0);
                 currentCanvas.RestoreState();
                 //Restore transformation matrix
                 if (!context.GetLastTextTransform().IsIdentity())
                 {
                     currentCanvas.SetTextMatrix(context.GetLastTextTransform());
                 }
             }
             if (performRootTransformations)
             {
                 currentCanvas.EndText();
             }
         }
     }
 }
        protected internal override void DoDraw(SvgDrawContext context)
        {
            ResourceResolver resourceResolver = context.GetResourceResolver();

            if (resourceResolver == null || this.attributesAndStyles == null)
            {
                return;
            }
            String     uri     = this.attributesAndStyles.Get(SvgConstants.Attributes.XLINK_HREF);
            PdfXObject xObject = resourceResolver.RetrieveImageExtended(uri);

            if (xObject == null)
            {
                return;
            }
            PdfCanvas currentCanvas = context.GetCurrentCanvas();
            float     x             = 0;

            if (attributesAndStyles.ContainsKey(SvgConstants.Attributes.X))
            {
                x = CssUtils.ParseAbsoluteLength(attributesAndStyles.Get(SvgConstants.Attributes.X));
            }
            float y = 0;

            if (attributesAndStyles.ContainsKey(SvgConstants.Attributes.Y))
            {
                y = CssUtils.ParseAbsoluteLength(attributesAndStyles.Get(SvgConstants.Attributes.Y));
            }
            float width = 0;

            if (attributesAndStyles.ContainsKey(SvgConstants.Attributes.WIDTH))
            {
                width = CssUtils.ParseAbsoluteLength(attributesAndStyles.Get(SvgConstants.Attributes.WIDTH));
            }
            float height = 0;

            if (attributesAndStyles.ContainsKey(SvgConstants.Attributes.HEIGHT))
            {
                height = CssUtils.ParseAbsoluteLength(attributesAndStyles.Get(SvgConstants.Attributes.HEIGHT));
            }
            String preserveAspectRatio = "";

            if (attributesAndStyles.ContainsKey(SvgConstants.Attributes.PRESERVE_ASPECT_RATIO))
            {
                preserveAspectRatio = attributesAndStyles.Get(SvgConstants.Attributes.PRESERVE_ASPECT_RATIO);
            }
            preserveAspectRatio = preserveAspectRatio.ToLowerInvariant();
            if (!SvgConstants.Values.NONE.Equals(preserveAspectRatio) && !(width == 0 || height == 0))
            {
                float normalizedWidth;
                float normalizedHeight;
                if (xObject.GetWidth() / width > xObject.GetHeight() / height)
                {
                    normalizedWidth  = width;
                    normalizedHeight = xObject.GetHeight() / xObject.GetWidth() * width;
                }
                else
                {
                    normalizedWidth  = xObject.GetWidth() / xObject.GetHeight() * height;
                    normalizedHeight = height;
                }
                switch (preserveAspectRatio.ToLowerInvariant())
                {
                case SvgConstants.Values.XMIN_YMIN: {
                    break;
                }

                case SvgConstants.Values.XMIN_YMID: {
                    y += Math.Abs(normalizedHeight - height) / 2;
                    break;
                }

                case SvgConstants.Values.XMIN_YMAX: {
                    y += Math.Abs(normalizedHeight - height);
                    break;
                }

                case SvgConstants.Values.XMID_YMIN: {
                    x += Math.Abs(normalizedWidth - width) / 2;
                    break;
                }

                case SvgConstants.Values.XMID_YMAX: {
                    x += Math.Abs(normalizedWidth - width) / 2;
                    y += Math.Abs(normalizedHeight - height);
                    break;
                }

                case SvgConstants.Values.XMAX_YMIN: {
                    x += Math.Abs(normalizedWidth - width);
                    break;
                }

                case SvgConstants.Values.XMAX_YMID: {
                    x += Math.Abs(normalizedWidth - width);
                    y += Math.Abs(normalizedHeight - height) / 2;
                    break;
                }

                case SvgConstants.Values.XMAX_YMAX: {
                    x += Math.Abs(normalizedWidth - width);
                    y += Math.Abs(normalizedHeight - height);
                    break;
                }

                case SvgConstants.Values.DEFAULT_ASPECT_RATIO:
                default: {
                    x += Math.Abs(normalizedWidth - width) / 2;
                    y += Math.Abs(normalizedHeight - height) / 2;
                    break;
                }
                }
                width  = normalizedWidth;
                height = normalizedHeight;
            }
            float v = y + height;

            currentCanvas.AddXObject(xObject, width, 0, 0, -height, x, v);
        }
Пример #4
0
        public override Color CreateColor(SvgDrawContext context, Rectangle objectBoundingBox, float objectBoundingBoxMargin
                                          , float parentOpacity)
        {
            if (objectBoundingBox == null)
            {
                return(null);
            }
            LinearGradientBuilder builder = new LinearGradientBuilder();

            foreach (GradientColorStop stopColor in ParseStops(parentOpacity))
            {
                builder.AddColorStop(stopColor);
            }
            builder.SetSpreadMethod(ParseSpreadMethod());
            bool isObjectBoundingBox = IsObjectBoundingBoxUnits();

            Point[] coordinates = GetCoordinates(context, isObjectBoundingBox);
            builder.SetGradientVector(coordinates[0].GetX(), coordinates[0].GetY(), coordinates[1].GetX(), coordinates
                                      [1].GetY());
            AffineTransform gradientTransform = GetGradientTransformToUserSpaceOnUse(objectBoundingBox, isObjectBoundingBox
                                                                                     );

            builder.SetCurrentSpaceToGradientVectorSpaceTransformation(gradientTransform);
            return(builder.BuildColor(objectBoundingBox.ApplyMargins(objectBoundingBoxMargin, objectBoundingBoxMargin,
                                                                     objectBoundingBoxMargin, objectBoundingBoxMargin, true), context.GetCurrentCanvasTransform(), context.
                                      GetCurrentCanvas().GetDocument()));
        }
Пример #5
0
 /// <summary>Operations to perform before drawing an element.</summary>
 /// <remarks>
 /// Operations to perform before drawing an element.
 /// This includes setting stroke color and width, fill color.
 /// </remarks>
 /// <param name="context">the svg draw context</param>
 internal virtual void PreDraw(SvgDrawContext context)
 {
     if (this.attributesAndStyles != null)
     {
         PdfCanvas    currentCanvas        = context.GetCurrentCanvas();
         PdfExtGState opacityGraphicsState = new PdfExtGState();
         if (!partOfClipPath)
         {
             float generalOpacity = GetOpacity();
             {
                 // fill
                 String fillRawValue = GetAttribute(SvgConstants.Attributes.FILL);
                 this.doFill = !SvgConstants.Values.NONE.EqualsIgnoreCase(fillRawValue);
                 if (doFill && CanElementFill())
                 {
                     Color  rgbColor     = ColorConstants.BLACK;
                     float  fillOpacity  = generalOpacity;
                     String opacityValue = GetAttribute(SvgConstants.Attributes.FILL_OPACITY);
                     if (opacityValue != null && !SvgConstants.Values.NONE.EqualsIgnoreCase(opacityValue))
                     {
                         fillOpacity *= float.Parse(opacityValue, System.Globalization.CultureInfo.InvariantCulture);
                     }
                     if (fillRawValue != null)
                     {
                         fillOpacity *= GetAlphaFromRGBA(fillRawValue);
                         rgbColor     = WebColors.GetRGBColor(fillRawValue);
                     }
                     if (!CssUtils.CompareFloats(fillOpacity, 1f))
                     {
                         opacityGraphicsState.SetFillOpacity(fillOpacity);
                     }
                     currentCanvas.SetFillColor(rgbColor);
                 }
             }
             {
                 // stroke
                 String strokeRawValue = GetAttribute(SvgConstants.Attributes.STROKE);
                 if (!SvgConstants.Values.NONE.EqualsIgnoreCase(strokeRawValue))
                 {
                     if (strokeRawValue != null)
                     {
                         Color  rgbColor      = WebColors.GetRGBColor(strokeRawValue);
                         float  strokeOpacity = generalOpacity;
                         String opacityValue  = GetAttribute(SvgConstants.Attributes.STROKE_OPACITY);
                         if (opacityValue != null && !SvgConstants.Values.NONE.EqualsIgnoreCase(opacityValue))
                         {
                             strokeOpacity *= float.Parse(opacityValue, System.Globalization.CultureInfo.InvariantCulture);
                         }
                         strokeOpacity *= GetAlphaFromRGBA(strokeRawValue);
                         if (!CssUtils.CompareFloats(strokeOpacity, 1f))
                         {
                             opacityGraphicsState.SetStrokeOpacity(strokeOpacity);
                         }
                         currentCanvas.SetStrokeColor(rgbColor);
                         String strokeWidthRawValue = GetAttribute(SvgConstants.Attributes.STROKE_WIDTH);
                         // 1 px = 0,75 pt
                         float strokeWidth = 0.75f;
                         if (strokeWidthRawValue != null)
                         {
                             strokeWidth = CssUtils.ParseAbsoluteLength(strokeWidthRawValue);
                         }
                         currentCanvas.SetLineWidth(strokeWidth);
                         doStroke = true;
                     }
                 }
             }
             {
                 // opacity
                 if (!opacityGraphicsState.GetPdfObject().IsEmpty())
                 {
                     currentCanvas.SetExtGState(opacityGraphicsState);
                 }
             }
         }
     }
 }
Пример #6
0
 /// <summary>Operations to be performed after drawing the element.</summary>
 /// <remarks>
 /// Operations to be performed after drawing the element.
 /// This includes filling, stroking.
 /// </remarks>
 /// <param name="context">the svg draw context</param>
 internal virtual void PostDraw(SvgDrawContext context)
 {
     if (this.attributesAndStyles != null)
     {
         PdfCanvas currentCanvas = context.GetCurrentCanvas();
         // fill-rule
         if (partOfClipPath)
         {
             if (SvgConstants.Values.FILL_RULE_EVEN_ODD.EqualsIgnoreCase(this.GetAttribute(SvgConstants.Attributes.CLIP_RULE
                                                                                           )))
             {
                 currentCanvas.EoClip();
             }
             else
             {
                 currentCanvas.Clip();
             }
             currentCanvas.EndPath();
         }
         else
         {
             if (doFill && CanElementFill())
             {
                 String fillRuleRawValue = GetAttribute(SvgConstants.Attributes.FILL_RULE);
                 if (SvgConstants.Values.FILL_RULE_EVEN_ODD.EqualsIgnoreCase(fillRuleRawValue))
                 {
                     if (doStroke)
                     {
                         currentCanvas.EoFillStroke();
                     }
                     else
                     {
                         currentCanvas.EoFill();
                     }
                 }
                 else
                 {
                     if (doStroke)
                     {
                         currentCanvas.FillStroke();
                     }
                     else
                     {
                         currentCanvas.Fill();
                     }
                 }
             }
             else
             {
                 if (doStroke)
                 {
                     currentCanvas.Stroke();
                 }
                 else
                 {
                     if (!typeof(TextSvgBranchRenderer).IsInstanceOfType(this))
                     {
                         currentCanvas.EndPath();
                     }
                 }
             }
         }
         // Marker drawing
         if (this is IMarkerCapable)
         {
             // TODO (DEVSIX-3397) add processing of 'marker' property (shorthand for a joint using of all other properties)
             foreach (MarkerVertexType markerVertexType in MARKER_VERTEX_TYPES)
             {
                 if (attributesAndStyles.ContainsKey(markerVertexType.ToString()))
                 {
                     currentCanvas.SaveState();
                     ((IMarkerCapable)this).DrawMarker(context, markerVertexType);
                     currentCanvas.RestoreState();
                 }
             }
         }
     }
 }
Пример #7
0
 /// <summary>Operations to be performed after drawing the element.</summary>
 /// <remarks>
 /// Operations to be performed after drawing the element.
 /// This includes filling, stroking.
 /// </remarks>
 /// <param name="context">the svg draw context</param>
 internal virtual void PostDraw(SvgDrawContext context)
 {
     if (this.attributesAndStyles != null)
     {
         PdfCanvas currentCanvas = context.GetCurrentCanvas();
         // fill-rule
         if (partOfClipPath)
         {
             if (SvgConstants.Values.FILL_RULE_EVEN_ODD.EqualsIgnoreCase(this.GetAttribute(SvgConstants.Attributes.CLIP_RULE
                                                                                           )))
             {
                 currentCanvas.EoClip();
             }
             else
             {
                 currentCanvas.Clip();
             }
             currentCanvas.EndPath();
         }
         else
         {
             if (doFill && CanElementFill())
             {
                 String fillRuleRawValue = GetAttribute(SvgConstants.Attributes.FILL_RULE);
                 if (SvgConstants.Values.FILL_RULE_EVEN_ODD.EqualsIgnoreCase(fillRuleRawValue))
                 {
                     if (doStroke)
                     {
                         currentCanvas.EoFillStroke();
                     }
                     else
                     {
                         currentCanvas.EoFill();
                     }
                 }
                 else
                 {
                     if (doStroke)
                     {
                         currentCanvas.FillStroke();
                     }
                     else
                     {
                         currentCanvas.Fill();
                     }
                 }
             }
             else
             {
                 if (doStroke)
                 {
                     currentCanvas.Stroke();
                 }
                 else
                 {
                     if (!typeof(TextSvgBranchRenderer).IsInstanceOfType(this))
                     {
                         currentCanvas.EndPath();
                     }
                 }
             }
         }
     }
 }
Пример #8
0
 protected internal override void DoDraw(SvgDrawContext context)
 {
     if (this.attributesAndStyles != null)
     {
         String elementToReUse = this.attributesAndStyles.Get(SvgConstants.Attributes.XLINK_HREF);
         if (elementToReUse == null)
         {
             elementToReUse = this.attributesAndStyles.Get(SvgConstants.Attributes.HREF);
         }
         if (elementToReUse != null && !String.IsNullOrEmpty(elementToReUse) && IsValidHref(elementToReUse))
         {
             String normalizedName = NormalizeName(elementToReUse);
             if (!context.IsIdUsedByUseTagBefore(normalizedName))
             {
                 ISvgNodeRenderer template = context.GetNamedObject(normalizedName);
                 //Clone template
                 ISvgNodeRenderer namedObject = template == null ? null : template.CreateDeepCopy();
                 //Resolve parent inheritance
                 SvgNodeRendererInheritanceResolver iresolver = new SvgNodeRendererInheritanceResolver();
                 iresolver.ApplyInheritanceToSubTree(this, namedObject);
                 if (namedObject != null)
                 {
                     if (namedObject is AbstractSvgNodeRenderer)
                     {
                         ((AbstractSvgNodeRenderer)namedObject).SetPartOfClipPath(partOfClipPath);
                     }
                     PdfCanvas currentCanvas = context.GetCurrentCanvas();
                     float     x             = 0f;
                     float     y             = 0f;
                     if (this.attributesAndStyles.ContainsKey(SvgConstants.Attributes.X))
                     {
                         x = CssUtils.ParseAbsoluteLength(this.attributesAndStyles.Get(SvgConstants.Attributes.X));
                     }
                     if (this.attributesAndStyles.ContainsKey(SvgConstants.Attributes.Y))
                     {
                         y = CssUtils.ParseAbsoluteLength(this.attributesAndStyles.Get(SvgConstants.Attributes.Y));
                     }
                     AffineTransform inverseMatrix = null;
                     if (!SvgMathUtils.CompareFloats(x, 0) || !SvgMathUtils.CompareFloats(y, 0))
                     {
                         AffineTransform translation = AffineTransform.GetTranslateInstance(x, y);
                         currentCanvas.ConcatMatrix(translation);
                         if (partOfClipPath)
                         {
                             try {
                                 inverseMatrix = translation.CreateInverse();
                             }
                             catch (NoninvertibleTransformException ex) {
                                 LogManager.GetLogger(typeof(UseSvgNodeRenderer)).Warn(SvgLogMessageConstant.NONINVERTIBLE_TRANSFORMATION_MATRIX_USED_IN_CLIP_PATH
                                                                                       , ex);
                             }
                         }
                     }
                     // setting the parent of the referenced element to this instance
                     namedObject.SetParent(this);
                     namedObject.Draw(context);
                     // unsetting the parent of the referenced element
                     namedObject.SetParent(null);
                     if (inverseMatrix != null)
                     {
                         currentCanvas.ConcatMatrix(inverseMatrix);
                     }
                 }
             }
         }
     }
 }