示例#1
0
        /// <summary>
        /// Set the clipping of the group
        /// </summary>
        public static void SetClipPath(GraphicGroup group,
                                       Matrix currentTransformationMatrix,
                                       CssStyleCascade cssStyleCascade,
                                       Dictionary <string, XElement> globalDefinitions)
        {
            var clipPath = cssStyleCascade.GetPropertyFromTop("clip-path");

            if (string.IsNullOrEmpty(clipPath))
            {
                return;
            }

            if (!clipPath.StartsWith("url(", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            int endUri = clipPath.IndexOf(")", StringComparison.OrdinalIgnoreCase);
            var uri    = clipPath.Substring(4, endUri - 4);

            uri = uri.Trim();
            var id = uri.Substring(1);

            if (!globalDefinitions.ContainsKey(id))
            {
                return;
            }

            var clipElem = globalDefinitions[id];

            // richt now we support only a single path for the clip geometry
            var shapeElement = clipElem.Elements().First();

            if (shapeElement == null)
            {
                return;
            }

            var clipGeometry = GeometryParser.Parse(shapeElement, currentTransformationMatrix);

            clipGeometry.FillRule = GraphicFillRule.NoneZero;

            var clipRule = cssStyleCascade.GetProperty("clip-rule");

            if (!string.IsNullOrEmpty(clipRule))
            {
                switch (clipRule)
                {
                case "evenodd":
                    clipGeometry.FillRule = GraphicFillRule.EvenOdd;
                    break;

                case "nonzero":
                    clipGeometry.FillRule = GraphicFillRule.NoneZero;
                    break;
                }
            }

            group.Clip = clipGeometry;
        }
示例#2
0
 public Group(Guid guid, String tag, Box box, bool visible, GraphicGroup graphicGroup)
 {
     this.guid         = guid;
     this.tag          = tag;
     this.box          = box;
     this.visible      = visible;
     this.graphicGroup = graphicGroup;
 }
示例#3
0
 public Group(Guid guid, String tag, Box box, bool visible, GraphicGroup graphicGroup)
 {
   this.guid = guid;
   this.tag = tag;
   this.box = box;
   this.visible = visible;
   this.graphicGroup = graphicGroup;
 }
示例#4
0
        public static void SetClip(EpsInterpreter interpreter, GraphicPathGeometry geometry)
        {
            interpreter.GraphicState.ClippingPath = geometry;

            var graphicGroup = new GraphicGroup();

            interpreter.GraphicGroup      = graphicGroup;
            interpreter.GraphicGroup.Clip = geometry;
            interpreter.ReturnGraphicGroup.Childreen.Add(graphicGroup);
        }
示例#5
0
        /// <summary>
        /// Parse all graphic elements
        /// </summary>
        private GraphicGroup ParseGroup(XNamespace ns, XElement groupElement, Matrix matrix)
        {
            var group = new GraphicGroup();

            cssStyleCascade.PushStyles(groupElement);

            Matrix currentTransformationMatrix = matrix;

            var transform = cssStyleCascade.GetPropertyFromTop("transform");

            if (!string.IsNullOrEmpty(transform))
            {
                var transformMatrix = TransformMatrixParser.GetTransformMatrix(transform);
                currentTransformationMatrix = transformMatrix * currentTransformationMatrix;
            }

            Clipping.SetClipPath(group, currentTransformationMatrix, cssStyleCascade, globalDefinitions);
            group.Opacity = cssStyleCascade.GetDoubleFromTop("opacity", 1);

            var shapeParser = new ShapeParser();

            foreach (var element in groupElement.Elements())
            {
                switch (element.Name.LocalName)
                {
                case "defs":
                case "style":
                    // already read, ignore
                    break;

                case "g":
                case "svg":
                {
                    var childGroup = ParseGroup(ns, element, currentTransformationMatrix);
                    group.Childreen.Add(childGroup);
                    break;
                }

                default:
                {
                    var shape = shapeParser.Parse(element, ns, currentTransformationMatrix, cssStyleCascade, globalDefinitions);

                    if (shape != null)
                    {
                        group.Childreen.Add(shape);
                    }
                    break;
                }
                }
            }

            cssStyleCascade.Pop();

            return(group);
        }
示例#6
0
        /// <summary>
        /// Parse a single SVG shape
        /// </summary>
        public GraphicVisual Parse(XElement shape,
                                   XNamespace svgNamespace,
                                   Matrix currentTransformationMatrix,
                                   CssStyleCascade cssStyleCascade,
                                   Dictionary <string, XElement> globalDefinitions)
        {
            GraphicVisual graphicVisual = null;

            cssStyleCascade.PushStyles(shape);

            var transform = cssStyleCascade.GetPropertyFromTop("transform");

            if (!string.IsNullOrEmpty(transform))
            {
                var transformMatrix = TransformMatrixParser.GetTransformMatrix(transform);
                currentTransformationMatrix = transformMatrix * currentTransformationMatrix;
            }

            var geometry = GeometryParser.Parse(shape, currentTransformationMatrix);

            if (geometry != null)
            {
                var graphicPath = new GraphicPath();
                graphicPath.Geometry = geometry;
                graphicVisual        = graphicPath;

                this.svgNamespace                = svgNamespace;
                this.globalDefinitions           = globalDefinitions;
                this.currentTransformationMatrix = currentTransformationMatrix;
                this.cssStyleCascade             = cssStyleCascade;

                SetFillAndStroke(shape, graphicPath);

                if (Clipping.IsClipPathSet(cssStyleCascade))
                {
                    // shapes don't support clipping, create a group around it
                    var group = new GraphicGroup();
                    graphicVisual = group;
                    group.Childreen.Add(graphicPath);

                    Clipping.SetClipPath(group, currentTransformationMatrix, cssStyleCascade, globalDefinitions);
                }

                cssStyleCascade.Pop();
            }

            return(graphicVisual);
        }
示例#7
0
        /// <summary>
        /// Parse the given file
        /// </summary>
        GraphicVisual IFileParser.Parse(string filename)
        {
            colorManager = new ColorSpaceManager();
            var group = new GraphicGroup();

            using (PsdDocument document = PsdDocument.Create(filename))
            {
                Size size = new Size(document.Width, document.Height);

                PrepareIccProfile(document);
                ParseLayers(document, size, group);
            }

            CommonHelper.CleanUpTempDir();
            return(group);
        }
示例#8
0
        /// <summary>
        /// Initialize all about graphic
        /// </summary>
        private void InitGraphic()
        {
            ReturnGraphicGroup = new GraphicGroup();
            GraphicGroup       = ReturnGraphicGroup;

            graphicsStateStack = new Stack <GraphicsState>();

            GraphicState = new GraphicsState();
            GraphicState.TransformationMatrix = Matrix.Identity;
            GraphicState.ColorSpace           = ColorSpaceActivator.CreateColorSpace(this, EpsKeys.DeviceGray);

            var values = new List <Operand> {
                new RealOperand(0)
            };                                                      // black

            GraphicState.FillBrush = GraphicState.ColorSpace.GetBrushDescriptor(values,
                                                                                GraphicState.CurrentTransformationMatrix);
        }
示例#9
0
        /// <summary>
        /// Parse the given file and convert it to a list of graphic paths
        /// </summary>
        GraphicVisual IFileParser.Parse(string filename)
        {
            var         group         = new GraphicGroup();
            PdfDocument inputDocument = PdfReader.Open(filename);

            for (int i = 0; i < inputDocument.Pages.Count; i++)
            {
                var page     = inputDocument.Pages[i];
                var geometry = Parse(page);
                group.Childreen.Add(geometry);
            }

            var visual = OptimizeVisual.Optimize(group);

            CommonHelper.CleanUpTempDir();

            return(visual);
        }
示例#10
0
        /// <summary>
        /// Parse all graphic elements
        /// </summary>
        private GraphicGroup ParseChildren(XElement groupElement, Matrix matrix)
        {
            var group = new GraphicGroup();

            foreach (var element in groupElement.Elements())
            {
                if (!PresentationAttribute.IsElementVisible(element) || !PresentationAttribute.IsElementDisplayed(element))
                {
                    continue;
                }

                GraphicVisual graphicVisual = ParseElement(element, matrix);

                if (graphicVisual != null)
                {
                    group.Children.Add(graphicVisual);
                }
            }

            return(group);
        }
        /// <summary>
        /// Builds the selected drawing recursively
        /// </summary>
        private GraphicVisual BuildSelectedGeometry(GraphicVisual visual, List <GraphicPath> selectedPaths)
        {
            GraphicVisual graphicVisual = null;

            switch (visual)
            {
            case GraphicGroup group:
            {
                var graphicGroup = new GraphicGroup();
                graphicVisual        = graphicGroup;
                graphicGroup.Opacity = group.Opacity;
                graphicGroup.Clip    = group.Clip;

                foreach (var childVisual in group.Children)
                {
                    var selectedGeometry = BuildSelectedGeometry(childVisual, selectedPaths);

                    if (selectedGeometry != null)
                    {
                        graphicGroup.Children.Add(selectedGeometry);
                    }
                }

                break;
            }

            case GraphicPath graphicPath:
            {
                if (selectedPaths.Contains(graphicPath))
                {
                    graphicVisual = graphicPath;
                }

                break;
            }
            }

            return(graphicVisual);
        }
示例#12
0
        /// <summary>
        /// The transformation engine
        /// </summary>
        /// <returns></returns>
        private GraphicVisual Transform(GraphicVisual visual)
        {
            GraphicVisual graphicGeometry = null;

            switch (visual)
            {
            case GraphicGroup group:
            {
                var graphicGroup = new GraphicGroup();
                graphicGeometry      = graphicGroup;
                graphicGroup.Opacity = group.Opacity;

                if (group.Clip != null)
                {
                    graphicGroup.Clip = TransformGeometry(group.Clip);
                }

                foreach (var childVisual in group.Children)
                {
                    var normalizedVisual = Transform(childVisual);
                    graphicGroup.Children.Add(normalizedVisual);
                }

                break;
            }

            case GraphicPath graphicPath:
            {
                var transformedPath = new GraphicPath();
                graphicGeometry = transformedPath;

                transformedPath.Geometry = TransformGeometry(graphicPath.Geometry);
                SetShapeAttributes(graphicPath, transformedPath);
                break;
            }
            }

            return(graphicGeometry);
        }
示例#13
0
        /// <summary>
        /// Parse a single SVG shape
        /// </summary>
        public GraphicVisual Parse(XElement shape,
                                   Matrix currentTransformationMatrix)
        {
            GraphicVisual graphicVisual = null;

            cssStyleCascade.PushStyles(shape);

            var transformMatrix = cssStyleCascade.GetTransformMatrixFromTop();

            currentTransformationMatrix = transformMatrix * currentTransformationMatrix;

            var geometry = geometryParser.Parse(shape, currentTransformationMatrix);

            if (geometry != null)
            {
                var graphicPath = new GraphicPath();
                graphicPath.Geometry = geometry;
                graphicVisual        = graphicPath;

                brushParser.SetFillAndStroke(shape, graphicPath, currentTransformationMatrix);

                if (clipping.IsClipPathSet())
                {
                    // shapes don't support clipping, create a group around it
                    var group = new GraphicGroup();
                    graphicVisual = group;
                    group.Children.Add(graphicPath);

                    clipping.SetClipPath(group, currentTransformationMatrix);
                }
            }

            cssStyleCascade.Pop();

            return(graphicVisual);
        }
示例#14
0
        /// <summary>
        /// Parse all layers recursively
        /// </summary>
        void ParseLayers(IPsdLayer layer, Size size, GraphicGroup group)
        {
            if (!layer.IsVisible)
            {
                return;
            }

            if (layer.Childreen.Length > 0)
            {
                foreach (var child in layer.Childreen)
                {
                    ParseLayers(child, size, group);
                }
            }
            else
            {
                var graphicPath = ParseLayer(layer, size);

                if (graphicPath != null)
                {
                    group.Childreen.Add(graphicPath);
                }
            }
        }
示例#15
0
        /// <summary>
        /// Parse a text
        /// </summary>
        private GraphicVisual ParseText(XElement textElement,
                                        Matrix currentTransformationMatrix)
        {
            GraphicGroup graphicGroup = new GraphicGroup();


            var colorBlocks    = new List <ColorBlock>();
            var positionBlocks = new List <PositionBlock>();
            var position       = new CharacterPositions();

            var textColorBlock = new ColorBlock();

            colorBlocks.Add(textColorBlock);
            textColorBlock.Characters         = new List <PositionBlockCharacter>();
            textColorBlock.AdjustFillGlobal   = true;
            textColorBlock.AdjustStrokeGlobal = true;

            var xList = GetLengthPercentList(textElement, "x", PercentBaseSelector.ViewBoxWidth);

            if (xList == null)
            {
                xList = new List <double> {
                    0.0
                };
            }

            var dxList = GetLengthPercentList(textElement, "dx", PercentBaseSelector.ViewBoxWidth);

            position.X.SetParentValues(xList, dxList);

            var yList = GetLengthPercentList(textElement, "y", PercentBaseSelector.ViewBoxHeight);

            if (yList == null)
            {
                yList = new List <double> {
                    0.0
                };
            }

            var dyList = GetLengthPercentList(textElement, "dy", PercentBaseSelector.ViewBoxHeight);

            position.Y.SetParentValues(yList, dyList);

            var fontSize   = GetFontSize();
            var typeface   = GetTypeface();
            var textAnchor = GetTextAnchor();

            var rotation = new ParentChildPriorityList();

            rotation.ParentValues = GetRotate(textElement);

            var textOpacity       = cssStyleCascade.GetNumberPercentFromTop("opacity", 1);
            var textFillOpacity   = cssStyleCascade.GetNumberPercentFromTop("fill-opacity", 1);
            var textStrokeOpacity = cssStyleCascade.GetNumberPercentFromTop("stroke-opacity", 1);

            if (false && !textElement.HasElements)
            {
                var geometry = ParseTextGeometry(textElement, currentTransformationMatrix);

                var graphicPath = new GraphicPath();
                graphicPath.Geometry          = geometry;
                graphicPath.Geometry.FillRule = GraphicFillRule.NoneZero;

                brushParser.SetFillAndStroke(textElement, graphicPath, currentTransformationMatrix);

                return(graphicPath);
            }

            XNode node        = textElement.FirstNode;
            bool  beginOfLine = true;

            while (node != null)
            {
                var nextNode     = node.NextNode;
                var hasSuccessor = nextNode != null;

                switch (node)
                {
                case XElement embededElement:
                {
                    if (!PresentationAttribute.IsElementVisible(embededElement))
                    {
                        continue;
                    }

                    switch (embededElement.Name.LocalName)
                    {
                    case "tspan":
                    {
                        var tspanElement     = embededElement;
                        var isTspanDisplayed = PresentationAttribute.IsElementDisplayed(tspanElement);

                        cssStyleCascade.PushStyles(tspanElement);

                        var xChildList  = GetLengthPercentList(tspanElement, "x", PercentBaseSelector.ViewBoxWidth);
                        var dxChildList = GetLengthPercentList(tspanElement, "dx", PercentBaseSelector.ViewBoxWidth);
                        position.X.SetChildValues(xChildList, dxChildList);

                        var yChildList  = GetLengthPercentList(tspanElement, "y", PercentBaseSelector.ViewBoxHeight);
                        var dyChildList = GetLengthPercentList(tspanElement, "dy", PercentBaseSelector.ViewBoxHeight);
                        position.Y.SetChildValues(yChildList, dyChildList);

                        var hasOwnFill   = ExistsAttributeOnTop("fill");
                        var hasOwnStroke = ExistsAttributeOnTop("stroke");

                        var tspanFontSize = GetFontSize();
                        var tspanTypeface = GetTypeface();
                        var tspanAnchor   = GetTextAnchor();
                        rotation.ChildValues = GetRotate(tspanElement);

                        var charBlock = Vectorize(positionBlocks,
                                                  tspanElement.Value,
                                                  tspanAnchor,
                                                  position,
                                                  beginOfLine,
                                                  hasSuccessor,
                                                  tspanTypeface,
                                                  tspanFontSize,
                                                  rotation,
                                                  currentTransformationMatrix);

                        rotation.ChildValues = null;
                        position.X.SetChildValues(null, null);
                        position.Y.SetChildValues(null, null);

                        if (isTspanDisplayed)
                        {
                            ColorBlock colorBlock;

                            if (hasOwnFill || hasOwnStroke)
                            {
                                colorBlock = new ColorBlock();
                                colorBlocks.Add(colorBlock);
                                colorBlock.Characters         = charBlock;
                                colorBlock.AdjustFillGlobal   = !hasOwnFill;
                                colorBlock.AdjustStrokeGlobal = !hasOwnStroke;
                            }
                            else
                            {
                                colorBlock = textColorBlock;
                                textColorBlock.Characters.AddRange(charBlock);
                            }

                            for (int i = 0; i < charBlock.Count; i++)
                            {
                                var path = new GraphicPath();
                                colorBlock.Paths.Add(path);

                                brushParser.SetFillAndStroke(tspanElement, path, currentTransformationMatrix, textOpacity, textFillOpacity, textStrokeOpacity);
                            }
                        }

                        cssStyleCascade.Pop();
                    }
                    break;

                    case "textpath":
                    {
                        break;
                    }
                    }

                    break;
                }

                case XText textContentElement:
                {
                    var charBlock = Vectorize(positionBlocks,
                                              textContentElement.Value,
                                              textAnchor,
                                              position,
                                              beginOfLine,
                                              hasSuccessor,
                                              typeface,
                                              fontSize,
                                              rotation,
                                              currentTransformationMatrix);
                    textColorBlock.Characters.AddRange(charBlock);

                    for (int i = 0; i < charBlock.Count; i++)
                    {
                        var path = new GraphicPath();
                        textColorBlock.Paths.Add(path);

                        brushParser.SetFillAndStroke(textElement, path, currentTransformationMatrix);
                    }
                    break;
                }
                }

                beginOfLine = false;
                node        = nextNode;
            }

            AdjustPosition(positionBlocks);

            if (GetTextLength(textElement, out double textLength))
            {
                textLength = MatrixUtilities.TransformScale(textLength, currentTransformationMatrix);
                AdjustLength(positionBlocks, textLength, GetTextAdjust(textElement));
            }

            UpdateColorBlockPathGeometry(colorBlocks);
            AdjustGradients(colorBlocks);

            foreach (var block in colorBlocks)
            {
                graphicGroup.Children.AddRange(block.Paths);
            }

            if (clipping.IsClipPathSet())
            {
                clipping.SetClipPath(graphicGroup, currentTransformationMatrix);
            }

            return(graphicGroup);
        }
示例#16
0
        /// <summary>
        /// Run the interpreter and dispose everything
        /// </summary>
        private bool Run(StreamReader stream, List <IDisposable> disposables, int postscriptVersion, out GraphicGroup graph)
        {
            bool success = true;

            graph = null;

            try
            {
                var interpreter = new EpsInterpreter();
                graph = interpreter.Run(stream, postscriptVersion);
            }
            catch
            {
                success = false;
            }
            finally
            {
                foreach (var disposable in disposables)
                {
                    disposable.Dispose();
                }
            }

            return(success);
        }
示例#17
0
        /// <summary>
        /// Parse a single PDF page
        /// </summary>
        public GraphicGroup Run(PdfDictionary form, CSequence sequence, GraphicsState graphicsState)
        {
            this.returnGraphicGroup = new GraphicGroup();
            graphicGroup            = returnGraphicGroup;

            graphicsStateStack = new Stack <GraphicsState>();

            fontState            = new FontState();
            textVectorizer       = new TextVectorizer();
            currentGraphicsState = graphicsState;

            Init(form);
            InitColor();

            Point currentPoint          = new Point(0, 0);
            GraphicMoveSegment lastMove = null;

            ResetCurrentGeometry();

            for (int index = 0; index < sequence.Count; index++)
            {
                var contentOperator = sequence[index] as COperator;

                switch (contentOperator.OpCode.OpCodeName)
                {
                // path construction operators
                // rectangle
                case OpCodeName.re:
                {
                    if (currentGeometry == null)
                    {
                        currentGeometry = new GraphicPathGeometry();
                    }

                    var x      = PdfUtilities.GetDouble(contentOperator.Operands[0]);
                    var y      = PdfUtilities.GetDouble(contentOperator.Operands[1]);
                    var width  = PdfUtilities.GetDouble(contentOperator.Operands[2]);
                    var height = PdfUtilities.GetDouble(contentOperator.Operands[3]);

                    var point1 = MatrixUtilities.TransformPoint(x, y, currentGraphicsState.CurrentTransformationMatrix);
                    var point2 = MatrixUtilities.TransformPoint(x + width, y + height, currentGraphicsState.CurrentTransformationMatrix);

                    var move = new GraphicMoveSegment {
                        StartPoint = point1
                    };
                    currentGeometry.Segments.Add(move);

                    var lineTo = new GraphicLineSegment {
                        To = new Point(point2.X, point1.Y)
                    };
                    currentGeometry.Segments.Add(lineTo);

                    lineTo = new GraphicLineSegment {
                        To = new Point(point2.X, point2.Y)
                    };
                    currentGeometry.Segments.Add(lineTo);

                    lineTo = new GraphicLineSegment {
                        To = new Point(point1.X, point2.Y)
                    };
                    currentGeometry.Segments.Add(lineTo);

                    move.IsClosed = true;

                    lastMove     = move;
                    currentPoint = point1;
                    break;
                }

                // move to
                case OpCodeName.m:
                {
                    if (currentGeometry == null)
                    {
                        currentGeometry = new GraphicPathGeometry();
                    }

                    var x     = PdfUtilities.GetDouble(contentOperator.Operands[0]);
                    var y     = PdfUtilities.GetDouble(contentOperator.Operands[1]);
                    var point = MatrixUtilities.TransformPoint(x, y, currentGraphicsState.CurrentTransformationMatrix);

                    var move = new GraphicMoveSegment {
                        StartPoint = point
                    };
                    currentGeometry.Segments.Add(move);

                    lastMove     = move;
                    currentPoint = point;
                    break;
                }

                // line to
                case OpCodeName.l:
                {
                    var x     = PdfUtilities.GetDouble(contentOperator.Operands[0]);
                    var y     = PdfUtilities.GetDouble(contentOperator.Operands[1]);
                    var point = MatrixUtilities.TransformPoint(x, y, currentGraphicsState.CurrentTransformationMatrix);

                    var lineTo = new GraphicLineSegment {
                        To = point
                    };
                    currentGeometry.Segments.Add(lineTo);

                    currentPoint = point;
                    break;
                }

                // cubic bezier
                case OpCodeName.c:
                {
                    var bezier = new GraphicCubicBezierSegment();
                    currentGeometry.Segments.Add(bezier);

                    var x = PdfUtilities.GetDouble(contentOperator.Operands[0]);
                    var y = PdfUtilities.GetDouble(contentOperator.Operands[1]);
                    bezier.ControlPoint1 = MatrixUtilities.TransformPoint(x, y, currentGraphicsState.CurrentTransformationMatrix);

                    x = PdfUtilities.GetDouble(contentOperator.Operands[2]);
                    y = PdfUtilities.GetDouble(contentOperator.Operands[3]);
                    bezier.ControlPoint2 = MatrixUtilities.TransformPoint(x, y, currentGraphicsState.CurrentTransformationMatrix);

                    x = PdfUtilities.GetDouble(contentOperator.Operands[4]);
                    y = PdfUtilities.GetDouble(contentOperator.Operands[5]);
                    bezier.EndPoint = MatrixUtilities.TransformPoint(x, y, currentGraphicsState.CurrentTransformationMatrix);

                    currentPoint = bezier.EndPoint;
                    break;
                }

                // quadratic bezier
                case OpCodeName.v:
                {
                    var bezier = new GraphicCubicBezierSegment();
                    currentGeometry.Segments.Add(bezier);

                    bezier.ControlPoint1 = currentPoint;

                    var x = PdfUtilities.GetDouble(contentOperator.Operands[0]);
                    var y = PdfUtilities.GetDouble(contentOperator.Operands[1]);
                    bezier.ControlPoint2 = MatrixUtilities.TransformPoint(x, y, currentGraphicsState.CurrentTransformationMatrix);

                    x = PdfUtilities.GetDouble(contentOperator.Operands[2]);
                    y = PdfUtilities.GetDouble(contentOperator.Operands[3]);
                    bezier.EndPoint = MatrixUtilities.TransformPoint(x, y, currentGraphicsState.CurrentTransformationMatrix);

                    currentPoint = bezier.EndPoint;
                    break;
                }

                // quadratic bezier
                case OpCodeName.y:
                {
                    var bezier = new GraphicCubicBezierSegment();
                    currentGeometry.Segments.Add(bezier);

                    var x = PdfUtilities.GetDouble(contentOperator.Operands[0]);
                    var y = PdfUtilities.GetDouble(contentOperator.Operands[1]);
                    bezier.ControlPoint1 = MatrixUtilities.TransformPoint(x, y, currentGraphicsState.CurrentTransformationMatrix);

                    x = PdfUtilities.GetDouble(contentOperator.Operands[2]);
                    y = PdfUtilities.GetDouble(contentOperator.Operands[3]);
                    bezier.ControlPoint2 = MatrixUtilities.TransformPoint(x, y, currentGraphicsState.CurrentTransformationMatrix);
                    bezier.EndPoint      = bezier.ControlPoint2;

                    currentPoint = bezier.EndPoint;
                    break;
                }

                // path painting operators
                // end the path without filling and stroking
                case OpCodeName.n:
                {
                    ResetCurrentGeometry();
                    break;
                }

                // set clipping path
                case OpCodeName.W:
                case OpCodeName.Wx:
                {
                    currentGraphicsState.ClippingPath = currentGeometry;

                    graphicGroup      = new GraphicGroup();
                    graphicGroup.Clip = currentGeometry;
                    returnGraphicGroup.Children.Add(graphicGroup);
                    break;
                }

                // close path
                case OpCodeName.h:
                    lastMove.IsClosed = true;
                    break;

                // close and fill the path
                case OpCodeName.s:
                {
                    lastMove.IsClosed = true;
                    var path = GetCurrentPathFilled();
                    graphicGroup.Children.Add(path);
                    ResetCurrentGeometry();
                    break;
                }

                // stroke the path
                case OpCodeName.S:
                {
                    var path = GetCurrentPathStroked();
                    graphicGroup.Children.Add(path);
                    ResetCurrentGeometry();
                    break;
                }

                // close, fill and stroke the path
                case OpCodeName.b:
                case OpCodeName.bx:
                {
                    lastMove.IsClosed = true;
                    var path = GetCurrentPathFilledAndStroked();
                    graphicGroup.Children.Add(path);
                    ResetCurrentGeometry();
                    break;
                }

                // fill and stroke the path
                case OpCodeName.B:
                {
                    var path = GetCurrentPathFilledAndStroked();
                    currentGeometry.FillRule = GraphicFillRule.NoneZero;
                    graphicGroup.Children.Add(path);
                    ResetCurrentGeometry();
                    break;
                }

                // fill and stroke the path
                case OpCodeName.Bx:
                {
                    var path = GetCurrentPathFilledAndStroked();
                    currentGeometry.FillRule = GraphicFillRule.NoneZero;
                    currentGeometry.FillRule = GraphicFillRule.EvenOdd;
                    graphicGroup.Children.Add(path);
                    ResetCurrentGeometry();
                    break;
                }

                // fill the path
                case OpCodeName.F:
                case OpCodeName.f:
                {
                    var path = GetCurrentPathFilled();
                    currentGeometry.FillRule = GraphicFillRule.NoneZero;
                    graphicGroup.Children.Add(path);
                    ResetCurrentGeometry();
                    break;
                }

                // fill the path
                case OpCodeName.fx:
                {
                    var path = GetCurrentPathFilled();
                    currentGeometry.FillRule = GraphicFillRule.EvenOdd;
                    graphicGroup.Children.Add(path);
                    ResetCurrentGeometry();
                    break;
                }

                // set color space for stroking operations
                case OpCodeName.CS:
                {
                    var colorSpaceName = ((CName)contentOperator.Operands[0]).Name;
                    currentGraphicsState.StrokeColorSpace = colorSpaceManager.GetColorSpace(colorSpaceName);
                    break;
                }

                // set color space for nonstroking operations
                case OpCodeName.cs:
                {
                    var colorSpaceName = ((CName)contentOperator.Operands[0]).Name;
                    currentGraphicsState.ColorSpace = colorSpaceManager.GetColorSpace(colorSpaceName);
                    break;
                }

                // set /DeviceRGB and non-stroked color
                case OpCodeName.rg:
                {
                    currentGraphicsState.ColorSpace = colorSpaceManager.GetColorSpace(PdfKeys.DeviceRGB);
                    currentGraphicsState.FillBrush  =
                        currentGraphicsState.ColorSpace.GetBrushDescriptor(contentOperator.Operands,
                                                                           currentGraphicsState.CurrentTransformationMatrix,
                                                                           currentGraphicsState.FillAlpha.Current);
                    break;
                }

                // set /DeviceCMYK and non-stroked color
                case OpCodeName.k:
                {
                    currentGraphicsState.ColorSpace = colorSpaceManager.GetColorSpace(PdfKeys.DeviceCMYK);
                    currentGraphicsState.FillBrush  =
                        currentGraphicsState.ColorSpace.GetBrushDescriptor(contentOperator.Operands,
                                                                           currentGraphicsState.CurrentTransformationMatrix,
                                                                           currentGraphicsState.FillAlpha.Current);
                    break;
                }

                // set /DeviceGray and non-stroked color
                case OpCodeName.g:
                {
                    currentGraphicsState.ColorSpace = colorSpaceManager.GetColorSpace(PdfKeys.DeviceGray);
                    currentGraphicsState.FillBrush  =
                        currentGraphicsState.ColorSpace.GetBrushDescriptor(contentOperator.Operands,
                                                                           currentGraphicsState.CurrentTransformationMatrix,
                                                                           currentGraphicsState.FillAlpha.Current);
                    break;
                }

                // non-stroked color
                case OpCodeName.sc:
                {
                    currentGraphicsState.FillBrush =
                        currentGraphicsState.ColorSpace.GetBrushDescriptor(contentOperator.Operands,
                                                                           currentGraphicsState.CurrentTransformationMatrix,
                                                                           currentGraphicsState.FillAlpha.Current);
                    break;
                }

                // ICC based non-stroked color
                case OpCodeName.scn:
                {
                    currentGraphicsState.FillBrush =
                        currentGraphicsState.ColorSpace.GetBrushDescriptor(contentOperator.Operands,
                                                                           currentGraphicsState.CurrentTransformationMatrix,
                                                                           currentGraphicsState.FillAlpha.Current);
                    break;
                }

                // ICC based stroked color
                case OpCodeName.SCN:
                {
                    currentGraphicsState.StrokeBrush =
                        currentGraphicsState.StrokeColorSpace.GetBrushDescriptor(contentOperator.Operands,
                                                                                 currentGraphicsState.CurrentTransformationMatrix,
                                                                                 currentGraphicsState.StrokeAlpha.Current);
                    break;
                }

                // set /DeviceRGB and stroked color
                case OpCodeName.RG:
                {
                    currentGraphicsState.StrokeColorSpace = colorSpaceManager.GetColorSpace(PdfKeys.DeviceRGB);
                    currentGraphicsState.StrokeBrush      =
                        currentGraphicsState.StrokeColorSpace.GetBrushDescriptor(contentOperator.Operands,
                                                                                 currentGraphicsState.CurrentTransformationMatrix,
                                                                                 currentGraphicsState.StrokeAlpha.Current);
                    break;
                }

                // set /DeviceGray and stroked color
                case OpCodeName.G:
                {
                    currentGraphicsState.StrokeColorSpace = colorSpaceManager.GetColorSpace(PdfKeys.DeviceGray);
                    currentGraphicsState.StrokeBrush      =
                        currentGraphicsState.StrokeColorSpace.GetBrushDescriptor(contentOperator.Operands,
                                                                                 currentGraphicsState.CurrentTransformationMatrix,
                                                                                 currentGraphicsState.StrokeAlpha.Current);
                    break;
                }

                // set /DeviceCMYK and stroked color
                case OpCodeName.K:
                {
                    currentGraphicsState.StrokeColorSpace = colorSpaceManager.GetColorSpace(PdfKeys.DeviceCMYK);
                    currentGraphicsState.StrokeBrush      =
                        currentGraphicsState.StrokeColorSpace.GetBrushDescriptor(contentOperator.Operands,
                                                                                 currentGraphicsState.CurrentTransformationMatrix,
                                                                                 currentGraphicsState.StrokeAlpha.Current);
                    break;
                }

                // set stroked color
                case OpCodeName.SC:
                {
                    currentGraphicsState.StrokeBrush =
                        currentGraphicsState.StrokeColorSpace.GetBrushDescriptor(contentOperator.Operands,
                                                                                 currentGraphicsState.CurrentTransformationMatrix,
                                                                                 currentGraphicsState.StrokeAlpha.Current);
                    break;
                }

                // shading
                case OpCodeName.sh:
                {
                    var graphicPath       = new GraphicPath();
                    var shadingDescriptor = shadingManager.GetShading(contentOperator.Operands);

                    graphicPath.Geometry  = currentGraphicsState.ClippingPath;
                    graphicPath.FillBrush = shadingDescriptor.GetBrush(currentGraphicsState.CurrentTransformationMatrix,
                                                                       currentGraphicsState.ClippingPath.Bounds,
                                                                       currentGraphicsState.FillAlpha.Current,
                                                                       currentGraphicsState.SoftMask);
                    graphicPath.ColorPrecision = shadingDescriptor.ColorPrecision;

                    graphicGroup.Children.Add(graphicPath);
                    break;
                }

                // begin text
                case OpCodeName.BT:
                {
                    fontState.TextLineMatrix = Matrix.Identity;
                    fontState.TextMatrix     = Matrix.Identity;
                    break;
                }

                // set current font
                case OpCodeName.Tf:
                {
                    var fontName = ((CName)contentOperator.Operands[0]).Name;
                    fontState.FontSize       = PdfUtilities.GetDouble(contentOperator.Operands[1]);
                    fontState.FontDescriptor = fontManager.GetFont(fontName);
                    break;
                }

                // set rendering mode
                case OpCodeName.Tr:
                {
                    fontState.RenderingMode = PdfUtilities.GetRenderingMode(contentOperator.Operands[0]);
                    break;
                }

                // set font transformation matrix
                case OpCodeName.Tm:
                {
                    var matrix = PdfUtilities.GetMatrix(contentOperator.Operands);
                    fontState.TextMatrix     = matrix;
                    fontState.TextLineMatrix = matrix;
                    break;
                }

                // translate line matrix
                case OpCodeName.Td:
                {
                    var x = PdfUtilities.GetDouble(contentOperator.Operands[0]);
                    var y = PdfUtilities.GetDouble(contentOperator.Operands[1]);

                    // for some unknown reason the simple next statement doesn't
                    // work, do it in small steps instead
                    //fontState.TextLineMatrix.TranslatePrepend(x, y);
                    var m = fontState.TextLineMatrix;
                    m.TranslatePrepend(x, y);
                    fontState.TextLineMatrix = m;

                    fontState.TextMatrix = fontState.TextLineMatrix;
                    break;
                }

                case OpCodeName.TD:
                {
                    var x = PdfUtilities.GetDouble(contentOperator.Operands[0]);
                    var y = PdfUtilities.GetDouble(contentOperator.Operands[1]);

                    //fontState.TextLineMatrix.Translate(x, y);
                    var m = fontState.TextLineMatrix;
                    m.TranslatePrepend(x, y);
                    fontState.TextLineMatrix = m;

                    fontState.Leading    = -y;
                    fontState.TextMatrix = fontState.TextLineMatrix;
                    break;
                }

                case OpCodeName.TL:
                {
                    fontState.Leading = PdfUtilities.GetDouble(contentOperator.Operands[0]);
                    break;
                }

                case OpCodeName.Tx:
                {
                    var m = fontState.TextLineMatrix;
                    m.TranslatePrepend(0, -fontState.Leading);
                    fontState.TextLineMatrix = m;

                    fontState.TextMatrix = fontState.TextLineMatrix;
                    break;
                }

                case OpCodeName.QuoteSingle:
                {
                    break;
                }

                case OpCodeName.QuoteDbl:
                {
                    break;
                }

                // a single string
                case OpCodeName.Tj:
                {
                    var text        = (CString)contentOperator.Operands[0];
                    var textGraphic = textVectorizer.Vectorize(text.Value, currentGraphicsState, fontState);
                    graphicGroup.Children.AddRange(textGraphic);
                    break;
                }

                // multiple strings plus formatting
                case OpCodeName.TJ:
                {
                    var array = (CArray)contentOperator.Operands[0];
                    HandleMultipleTextCommand(array);
                    break;
                }

                // graphics state operators
                // push state onto the stack
                case OpCodeName.q:
                {
                    var clone = currentGraphicsState.Clone();
                    graphicsStateStack.Push(clone);
                    break;
                }

                // pop state from the stack
                case OpCodeName.Q:
                {
                    currentGraphicsState = graphicsStateStack.Pop();
                    break;
                }

                // current transform matrix
                case OpCodeName.cm:
                {
                    var matrix = PdfUtilities.GetMatrix(contentOperator.Operands);
                    currentGraphicsState.TransformationMatrix *= matrix;
                    break;
                }

                case OpCodeName.J:
                {
                    currentGraphicsState.LineCap = GetLineCap(((CInteger)contentOperator.Operands[0]).Value);
                    break;
                }

                case OpCodeName.j:
                {
                    currentGraphicsState.LineJoin = GetLineJoin(((CInteger)contentOperator.Operands[0]).Value);
                    break;
                }

                case OpCodeName.M:
                {
                    currentGraphicsState.MiterLimit = PdfUtilities.GetDouble(contentOperator.Operands[0]);
                    break;
                }

                case OpCodeName.d:
                {
                    SetDashPattern(contentOperator.Operands);
                    break;
                }

                // line width
                case OpCodeName.w:
                {
                    currentGraphicsState.LineWidth = MatrixUtilities.TransformScale(PdfUtilities.GetDouble(contentOperator.Operands[0]), currentGraphicsState.CurrentTransformationMatrix);
                    break;
                }

                // set parameters in the current graphic state of the given state name
                case OpCodeName.gs:
                {
                    var name = contentOperator.Operands[0] as CName;
                    extendedStatesManager.SetExtendedGraphicState(currentGraphicsState, fontState, name.Name);
                    break;
                }

                case OpCodeName.Do:
                {
                    var xObjectName = ((CName)contentOperator.Operands[0]).Name;
                    RunXObject(xObjectName);
                    break;
                }

                default:
                    break;
                }
            }

            return(this.returnGraphicGroup);
        }