示例#1
0
        public override void Execute(EpsInterpreter interpreter)
        {
            var operandStack = interpreter.OperandStack;

            var dy3 = operandStack.PopRealValue();
            var dx3 = operandStack.PopRealValue();
            var dy2 = operandStack.PopRealValue();
            var dx2 = operandStack.PopRealValue();
            var dy1 = operandStack.PopRealValue();
            var dx1 = operandStack.PopRealValue();

            GraphicsState graphicState = interpreter.GraphicState;
            var           currentPoint = graphicState.CurrentPoint;

            var x1 = currentPoint.X + dx1;
            var y1 = currentPoint.Y + dy1;
            var x2 = currentPoint.X + dx2;
            var y2 = currentPoint.Y + dy2;
            var x3 = currentPoint.X + dx3;
            var y3 = currentPoint.Y + dy3;

            var ctm = graphicState.CurrentTransformationMatrix;

            var bezier = new GraphicCubicBezierSegment();

            graphicState.CurrentGeometry.Segments.Add(bezier);

            bezier.ControlPoint1 = MatrixUtilities.TransformPoint(x1, y1, ctm);
            bezier.ControlPoint2 = MatrixUtilities.TransformPoint(x2, y2, ctm);
            bezier.EndPoint      = MatrixUtilities.TransformPoint(x3, y3, ctm);

            graphicState.CurrentPoint = new Point(x3, y3);
        }
示例#2
0
        public override void Execute(EpsInterpreter interpreter)
        {
            var operandStack = interpreter.OperandStack;

            var y = operandStack.PopRealValue();
            var x = operandStack.PopRealValue();

            GraphicsState graphicState = interpreter.GraphicState;

            if (graphicState.CurrentGeometry == null)
            {
                graphicState.CurrentGeometry = new GraphicPathGeometry();
            }

            var point = MatrixUtilities.TransformPoint(x, y, graphicState.CurrentTransformationMatrix);

            var move = new GraphicMoveSegment {
                StartPoint = point
            };

            graphicState.CurrentGeometry.Segments.Add(move);

            graphicState.LastMove     = move;
            graphicState.CurrentPoint = new Point(x, y);
        }
示例#3
0
        private void AddRectangle(GraphicPathGeometry geometry, double x, double y, double width, double height, Matrix ctm)
        {
            var point1 = MatrixUtilities.TransformPoint(x, y, ctm);
            var point2 = MatrixUtilities.TransformPoint(x + width, y + height, ctm);

            var move = new GraphicMoveSegment {
                StartPoint = point1
            };

            geometry.Segments.Add(move);

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

            geometry.Segments.Add(lineTo);

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

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

            move.IsClosed = true;
        }
示例#4
0
        private List <GraphicPathSegment> TransformSegments(List <GraphicPathSegment> segments)
        {
            var transformedSegments = new List <GraphicPathSegment>();

            foreach (var segment in segments)
            {
                switch (segment)
                {
                case GraphicMoveSegment graphicMove:
                {
                    var normalizedMove = new GraphicMoveSegment();
                    transformedSegments.Add(normalizedMove);

                    normalizedMove.StartPoint = MatrixUtilities.TransformPoint(graphicMove.StartPoint, transformMatrix);
                    normalizedMove.IsClosed   = graphicMove.IsClosed;
                    break;
                }

                case GraphicLineSegment graphicLineTo:
                {
                    var normalizedLineTo = new GraphicLineSegment();
                    transformedSegments.Add(normalizedLineTo);

                    normalizedLineTo.To = MatrixUtilities.TransformPoint(graphicLineTo.To, transformMatrix);
                    break;
                }

                case GraphicCubicBezierSegment graphicCubicBezier:
                {
                    var normalizedCubicBezier = new GraphicCubicBezierSegment();
                    transformedSegments.Add(normalizedCubicBezier);

                    normalizedCubicBezier.ControlPoint1 = MatrixUtilities.TransformPoint(graphicCubicBezier.ControlPoint1, transformMatrix);
                    normalizedCubicBezier.ControlPoint2 = MatrixUtilities.TransformPoint(graphicCubicBezier.ControlPoint2, transformMatrix);
                    normalizedCubicBezier.EndPoint      = MatrixUtilities.TransformPoint(graphicCubicBezier.EndPoint, transformMatrix);
                    break;
                }

                case GraphicQuadraticBezierSegment graphicQuadraticBezier:
                {
                    var normalizedQuadraticBezier = new GraphicQuadraticBezierSegment();
                    transformedSegments.Add(normalizedQuadraticBezier);

                    normalizedQuadraticBezier.ControlPoint = MatrixUtilities.TransformPoint(graphicQuadraticBezier.ControlPoint, transformMatrix);
                    normalizedQuadraticBezier.EndPoint     = MatrixUtilities.TransformPoint(graphicQuadraticBezier.EndPoint, transformMatrix);
                    break;
                }

                default:
                    break;
                }
            }

            return(transformedSegments);
        }
示例#5
0
        /// <summary>
        /// Normalize a brush
        /// </summary>
        private GraphicBrush TransformBrush(GraphicBrush graphicBrush)
        {
            GraphicBrush retBrush;

            switch (graphicBrush)
            {
            case GraphicLinearGradientBrush linearGradientBrush:
            {
                if (linearGradientBrush.MappingMode == GraphicBrushMappingMode.Absolute)
                {
                    var newlinearGradientBrush = new GraphicLinearGradientBrush();
                    retBrush = newlinearGradientBrush;

                    newlinearGradientBrush.StartPoint    = MatrixUtilities.TransformPoint(linearGradientBrush.StartPoint, transformMatrix);
                    newlinearGradientBrush.EndPoint      = MatrixUtilities.TransformPoint(linearGradientBrush.EndPoint, transformMatrix);
                    newlinearGradientBrush.MappingMode   = linearGradientBrush.MappingMode;
                    newlinearGradientBrush.GradientStops = linearGradientBrush.GradientStops;
                }
                else
                {
                    retBrush = linearGradientBrush;
                }

                break;
            }

            case GraphicRadialGradientBrush radialGradientBrush:
            {
                if (radialGradientBrush.MappingMode == GraphicBrushMappingMode.Absolute)
                {
                    var newlinearGradientBrush = new GraphicRadialGradientBrush();
                    retBrush = newlinearGradientBrush;

                    newlinearGradientBrush.StartPoint = MatrixUtilities.TransformPoint(radialGradientBrush.StartPoint, transformMatrix);
                    newlinearGradientBrush.EndPoint   = MatrixUtilities.TransformPoint(radialGradientBrush.EndPoint, transformMatrix);
                    (newlinearGradientBrush.RadiusX, newlinearGradientBrush.RadiusY) = MatrixUtilities.TransformSize(radialGradientBrush.RadiusX, radialGradientBrush.RadiusY, transformMatrix);
                    newlinearGradientBrush.MappingMode   = radialGradientBrush.MappingMode;
                    newlinearGradientBrush.GradientStops = radialGradientBrush.GradientStops;
                }
                else
                {
                    retBrush = radialGradientBrush;
                }

                break;
            }

            default:
                retBrush = graphicBrush;
                break;
            }

            return(retBrush);
        }
示例#6
0
        public static void CreateArc(EpsInterpreter interpreter, bool sweepDirection)
        {
            var           operandStack = interpreter.OperandStack;
            GraphicsState graphicState = interpreter.GraphicState;

            var angle2 = operandStack.PopRealValue();
            var angle1 = operandStack.PopRealValue();
            var r      = operandStack.PopRealValue();
            var y      = operandStack.PopRealValue();
            var x      = operandStack.PopRealValue();

            // be aware the segment converter returns coordinates in user space
            var(segments, startPoint, currentPoint) = ArcToPathSegmentConverter.ArcToPathSegments(new Point(x, y), r, angle1, angle2, sweepDirection);

            if (graphicState.CurrentGeometry == null)
            {
                graphicState.CurrentGeometry = new GraphicPathGeometry();

                var point = MatrixUtilities.TransformPoint(startPoint, graphicState.CurrentTransformationMatrix);
                var move  = new GraphicMoveSegment {
                    StartPoint = point
                };
                graphicState.CurrentGeometry.Segments.Add(move);

                graphicState.LastMove = move;
            }
            else
            {
                var point       = MatrixUtilities.TransformPoint(startPoint, graphicState.CurrentTransformationMatrix);
                var lineSegment = new GraphicLineSegment {
                    To = point
                };
                graphicState.CurrentGeometry.Segments.Add(lineSegment);
            }

            var transformVisual     = new TransformVisual();
            var transformedSegments = transformVisual.TransformSegments(segments, graphicState.CurrentTransformationMatrix);

            graphicState.CurrentGeometry.Segments.AddRange(transformedSegments);

            graphicState.CurrentPoint = currentPoint;
        }
示例#7
0
        public override void Execute(EpsInterpreter interpreter)
        {
            var operandStack = interpreter.OperandStack;

            var y = operandStack.PopRealValue();
            var x = operandStack.PopRealValue();

            GraphicsState graphicState = interpreter.GraphicState;
            var           ctm          = graphicState.CurrentTransformationMatrix;

            var point = MatrixUtilities.TransformPoint(x, y, ctm);

            var lineTo = new GraphicLineSegment {
                To = point
            };

            graphicState.CurrentGeometry.Segments.Add(lineTo);

            graphicState.CurrentPoint = new Point(x, y);
        }
        /// <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);
        }