Пример #1
0
        /// <summary>
        /// Replaces the current content of the page with the specified content sequence.
        /// </summary>
        public PdfContent ReplaceContent(CSequence cseq)
        {
            if (cseq == null)
            {
                throw new ArgumentNullException(nameof(cseq));
            }

            return(ReplaceContent(cseq.ToContent()));
        }
Пример #2
0
        /// <summary>
        /// Get a matrix out of a sequence fof operands
        /// </summary>
        public static Matrix GetMatrix(CSequence operands)
        {
            var matrix = new Matrix(PdfUtilities.GetDouble(operands[0]),
                                    PdfUtilities.GetDouble(operands[1]),
                                    PdfUtilities.GetDouble(operands[2]),
                                    PdfUtilities.GetDouble(operands[3]),
                                    PdfUtilities.GetDouble(operands[4]),
                                    PdfUtilities.GetDouble(operands[5]));

            return(matrix);
        }
Пример #3
0
        /// <summary>
        /// Convert a operands array to a simple double array
        /// </summary>
        public static List <double> CreateDoubleArray(CSequence operands)
        {
            int           num    = operands.Count;
            List <double> values = new List <double>();

            for (int i = 0; i < num; i++)
            {
                values.Add(GetDouble(operands[i]));
            }

            return(values);
        }
Пример #4
0
        /// <summary>
        /// Get a brush descriptor
        /// </summary>
        public IBrushDescriptor GetBrushDescriptor(CSequence operands, Matrix matrix, double alpha)
        {
            float[] colorValues = new float[numberColorComponents];

            for (int i = 0; i < numberColorComponents; i++)
            {
                colorValues[i] = (float)PdfUtilities.GetDouble(operands[i]);
            }

            Color color = Color.FromAValues((float)alpha, colorValues, GetProfileUri());

            return(new ICCBasedBrushDescriptor(color));
        }
Пример #5
0
        public StreamDecoder(PdfPage page)
        {
            _page = page;
            // https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/pdf_reference_archives/PDFReference.pdf
            // Chapters 4, 5, 9. Start at page 134 (pdf154), table 4.1 - operator categories; 156 (table 4.7) and page 163 (table 4.9 - paths)
            // https://stackoverflow.com/questions/29467539/encoding-of-pdf-text-string
            _content = ContentReader.ReadContent(page);

            // Uncomment to spew the page into stdout

            /*foreach (var c in _content)
             * {
             *  if (c is not COperator op) Console.WriteLine($"####???{c.GetType().Name} - {c}");
             *  else Console.WriteLine($"{op.GetType().FullName} => {op.Name} ({op.OpCode.Description}) - {ShortDesc(op.Operands)}");
             * }*/
        }
Пример #6
0
        /// <summary>
        /// Get a brush descriptor
        /// </summary>
        public IBrushDescriptor GetBrushDescriptor(CSequence operands, Matrix matrix, double alpha)
        {
            CSequence newSequence       = new CSequence();
            var       numberColorValues = baseColorSpace.GetNumberOfValuesPerColor();
            int       index             = LimitIndexToBoundaries(PdfUtilities.GetInteger(operands[0])) * numberColorValues;

            for (int i = 0; i < numberColorValues; i++)
            {
                var real = new CReal();
                real.Value = lookup[index + i];
                newSequence.Add(real);
            }

            var brushDescriptor = baseColorSpace.GetBrushDescriptor(newSequence, matrix, alpha);

            return(new IndexedBrushDescriptor(brushDescriptor));
        }
Пример #7
0
        /// <summary>
        /// Set the initial color space and color
        /// </summary>
        private void InitColor()
        {
            var seq  = new CSequence();
            var real = new CReal {
                Value = 0.0
            };

            seq.Add(real);

            currentGraphicsState.ColorSpace = colorSpaceManager.GetColorSpace(PdfKeys.DeviceGray);
            currentGraphicsState.FillBrush  =
                currentGraphicsState.ColorSpace.GetBrushDescriptor(seq,
                                                                   currentGraphicsState.CurrentTransformationMatrix,
                                                                   currentGraphicsState.FillAlpha.Current);
            currentGraphicsState.StrokeBrush =
                currentGraphicsState.ColorSpace.GetBrushDescriptor(seq,
                                                                   currentGraphicsState.CurrentTransformationMatrix,
                                                                   currentGraphicsState.FillAlpha.Current);
        }
Пример #8
0
        /// <summary>
        /// Get a brush descriptor
        /// </summary>
        public IBrushDescriptor GetBrushDescriptor(CSequence operands, Matrix matrix, double alpha)
        {
            IBrushDescriptor altColorSpaceDescriptor = null;

            var values = PdfUtilities.CreateDoubleArray(operands);
            var altColorSpaceValues = function.Calculate(values);

            if (altColorSpaceValues != null)
            {
                var altColorOperands = new CSequence();

                foreach (var val in altColorSpaceValues)
                {
                    var real = new CReal();
                    real.Value = val;
                    altColorOperands.Add(real);
                }

                altColorSpaceDescriptor = alternateColorSpace.GetBrushDescriptor(altColorOperands, matrix, alpha);
            }

            return(new DeviceNBrushDescriptor(altColorSpaceDescriptor));
        }
Пример #9
0
        /// <summary>
        /// Sets the dash pattern
        /// </summary>
        private void SetDashPattern(CSequence operands)
        {
            var dashArray = (CArray)operands[0];
            var dashPhase = PdfUtilities.GetDouble(operands[1]);

            if (dashArray.Count == 0)
            {
                currentGraphicsState.Dashes     = null;
                currentGraphicsState.DashOffset = 0;
                return;
            }

            var dashes = new List <double>();

            foreach (var val in dashArray)
            {
                var dbl = MatrixUtilities.TransformScale(PdfUtilities.GetDouble(val), currentGraphicsState.CurrentTransformationMatrix);
                dashes.Add(dbl);
            }

            currentGraphicsState.Dashes     = dashes;
            currentGraphicsState.DashOffset = dashPhase;
        }
Пример #10
0
        /// <summary>
        /// Get an extended graphics state from the given state name
        /// </summary>
        public IShading GetShading(CSequence operands)
        {
            var shadingName = operands[0] as CName;

            return(shadings[shadingName.Name]);
        }
Пример #11
0
 private string ShortDesc(CSequence opOperands)
 {
     return(string.Join("; ", opOperands.Select(Describe)));
 }
Пример #12
0
        /// <summary>
        /// Parses whatever comes until the specified stop symbol is reached.
        /// </summary>
        void ParseObject(CSequence sequence, CSymbol stop)
        {
            CSymbol symbol;

            while ((symbol = ScanNextToken()) != CSymbol.Eof)
            {
                if (symbol == stop)
                {
                    return;
                }

                switch (symbol)
                {
                case CSymbol.Comment:
                    // ignore comments
                    break;

                case CSymbol.Integer:
                    CInteger n = new CInteger();
                    n.Value = lexer.TokenToInteger;
                    operands.Add(n);
                    break;

                case CSymbol.Real:
                    CReal r = new CReal();
                    r.Value = lexer.TokenToReal;
                    operands.Add(r);
                    break;

                case CSymbol.String:
                case CSymbol.HexString:
                case CSymbol.UnicodeString:
                case CSymbol.UnicodeHexString:
                    CString s = new CString();
                    s.Value = lexer.Token;
                    operands.Add(s);
                    break;

                case CSymbol.Name:
                    CName name = new CName();
                    name.Name = lexer.Token;
                    operands.Add(name);
                    break;

                case CSymbol.Operator:
                    COperator op = CreateOperator();
                    operands.Clear();
                    sequence.Add(op);
                    break;

                case CSymbol.BeginArray:
                    CArray array = new CArray();
                    Debug.Assert(operands.Count == 0, "Array within array...");
                    ParseObject(array, CSymbol.EndArray);
                    array.Add(operands);
                    operands.Clear();
                    operands.Add((CObject)array);
                    break;

                case CSymbol.EndArray:
                    throw new ContentReaderException("Unexpected: ']'");
                }
            }
        }
Пример #13
0
 /// <summary>
 /// Get a brush descriptor
 /// </summary>
 public IBrushDescriptor GetBrushDescriptor(CSequence operands, Matrix matrix, double alpha)
 {
     return(new UnknownBrushDescriptor(GetColor(null, alpha)));
 }
Пример #14
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);
        }
Пример #15
0
 /// <summary>
 /// Reads the specified content.
 /// </summary>
 /// <param name="content">The content.</param>
 static public CSequence ReadContent(MemoryStream content)
 {
     CParser parser = new CParser(content);
     CSequence sequence = parser.ReadContent();
     return sequence;
 }
Пример #16
0
        /// <summary>
        /// Get a brush descriptor
        /// </summary>
        public IBrushDescriptor GetBrushDescriptor(CSequence operands, Matrix matrix, double alpha)
        {
            var values = PdfUtilities.CreateDoubleArray(operands);

            return(new CMYKDeviceBrushDescriptor(GetColor(values, alpha)));
        }
Пример #17
0
        /// <summary>
        /// Run the XObject with the given name
        /// </summary>
        private void RunXObject(string name)
        {
            var xobjectDict = xObjectManager.GetXObject(name);
            var subType     = xobjectDict.Elements.GetName(PdfKeys.Subtype);

            if (subType != PdfKeys.Form)
            {
                return;
            }

            var cloneCurrentGraphicsState = currentGraphicsState.Clone();

            var    matrixArray = xobjectDict.Elements.GetArray(PdfKeys.Matrix);
            Matrix matrix      = Matrix.Identity;

            if (matrixArray != null)
            {
                matrix = PdfUtilities.GetMatrix(matrixArray);
                cloneCurrentGraphicsState.TransformationMatrix *= matrix;
            }

            cloneCurrentGraphicsState.FillAlpha.Layer  = 1.0;
            cloneCurrentGraphicsState.FillAlpha.Object = 1.0;

            cloneCurrentGraphicsState.StrokeAlpha.Layer  = 1.0;
            cloneCurrentGraphicsState.StrokeAlpha.Object = 1.0;

            cloneCurrentGraphicsState.SoftMask = null;

            CSequence sequence = ContentReader.ReadContent(xobjectDict.Stream.UnfilteredValue);

            var interpreter = new ContentInterpreter();
            var group       = interpreter.Run(xobjectDict, sequence, cloneCurrentGraphicsState);

            // do some optimizations that the post-processor cannot do

            if (group.Children.Count == 1 && group.Clip == null && !DoubleUtilities.IsEqual(currentGraphicsState.FillAlpha.Object, 1.0))
            {
                // the layer has only 1 child and the layer has an opacity set other than 1 ->
                // recreate the layer but with the layer opacity set which gets "added" to each single object
                // on that layer. Because there is only 1 object the result is the same as if the object sits
                // on a semi transparent layer. That saves a group for a single object.

                cloneCurrentGraphicsState = currentGraphicsState.Clone();

                if (matrixArray != null)
                {
                    cloneCurrentGraphicsState.TransformationMatrix *= matrix;
                }

                cloneCurrentGraphicsState.FillAlpha.Layer   = currentGraphicsState.FillAlpha.Object;
                cloneCurrentGraphicsState.StrokeAlpha.Layer = currentGraphicsState.StrokeAlpha.Object;

                group = interpreter.Run(xobjectDict, sequence, cloneCurrentGraphicsState);
                graphicGroup.Children.Add(group.Children[0]);
            }
            else
            {
                group.Opacity = currentGraphicsState.FillAlpha.Object;
                graphicGroup.Children.Add(group);
            }
        }
Пример #18
0
        /// <summary>
        /// Parses whatever comes until the specified stop symbol is reached.
        /// </summary>
        void ParseObject(CSequence sequence, CSymbol stop)
        {
            CSymbol symbol;

            while ((symbol = ScanNextToken()) != CSymbol.Eof)
            {
                if (symbol == stop)
                {
                    return;
                }

                CString   s;
                COperator op;
                switch (symbol)
                {
                case CSymbol.Comment:
                    // ignore comments
                    break;

                case CSymbol.Integer:
                    CInteger n = new CInteger();
                    n.Value = _lexer.TokenToInteger;
                    _operands.Add(n);
                    break;

                case CSymbol.Real:
                    CReal r = new CReal();
                    r.Value = _lexer.TokenToReal;
                    _operands.Add(r);
                    break;

                case CSymbol.String:
                case CSymbol.HexString:
                case CSymbol.UnicodeString:
                case CSymbol.UnicodeHexString:
                    s       = new CString();
                    s.Value = _lexer.Token;
                    _operands.Add(s);
                    break;

                case CSymbol.Dictionary:
                    s             = new CString();
                    s.Value       = _lexer.Token;
                    s.CStringType = CStringType.Dictionary;
                    _operands.Add(s);
                    op = CreateOperator(OpCodeName.Dictionary);
                    //_operands.Clear();
                    sequence.Add(op);

                    break;

                case CSymbol.Name:
                    CName name = new CName();
                    name.Name = _lexer.Token;
                    _operands.Add(name);
                    break;

                case CSymbol.Operator:
                    op = CreateOperator();
                    //_operands.Clear();
                    sequence.Add(op);
                    break;

                case CSymbol.BeginArray:
                    CArray array = new CArray();
                    if (_operands.Count != 0)
                    {
                        ContentReaderDiagnostics.ThrowContentReaderException("Array within array...");
                    }

                    ParseObject(array, CSymbol.EndArray);
                    array.Add(_operands);
                    _operands.Clear();
                    _operands.Add((CObject)array);
                    break;

                case CSymbol.EndArray:
                    ContentReaderDiagnostics.HandleUnexpectedCharacter(']');
                    break;

#if DEBUG
                default:
                    Debug.Assert(false);
                    break;
#endif
                }
            }
        }
Пример #19
0
 /// <summary>
 /// Reads the specified content.
 /// </summary>
 /// <param name="content">The content.</param>
 static public CSequence ReadContent(byte[] content)
 {
     CParser parser = new CParser(content);
     CSequence sequence = parser.ReadContent();
     return sequence;
 }