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); }
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); }
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; }
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); }
/// <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); }
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; }
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); }