/// <summary> /// Realizes the CTM. /// </summary> public void RealizeCtm() { if (MustRealizeCtm) { Debug.Assert(!unrealizedCtm.IsIdentity, "mrCtm is unnecessarily set."); double[] matrix = unrealizedCtm.GetElements(); // Up to six decimal digits to prevent round up problems renderer.AppendFormat("{0:0.######} {1:0.######} {2:0.######} {3:0.######} {4:0.######} {5:0.######} cm\n", matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); realizedCtm.Prepend(unrealizedCtm); unrealizedCtm = new XMatrix(); //XMatrix.Identity; MustRealizeCtm = false; } }
/// <summary> /// Realizes the CTM. /// </summary> public void RealizeCtm() { //if (MustRealizeCtm) if (!UnrealizedCtm.IsIdentity) { Debug.Assert(!UnrealizedCtm.IsIdentity, "mrCtm is unnecessarily set."); const string format = Config.SignificantFigures7; double[] matrix = UnrealizedCtm.GetElements(); // Use up to six decimal digits to prevent round up problems. _renderer.AppendFormatArgs("{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "} {4:" + format + "} {5:" + format + "} cm\n", matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); RealizedCtm.Prepend(UnrealizedCtm); UnrealizedCtm = new XMatrix(); EffectiveCtm = RealizedCtm; InverseEffectiveCtm = EffectiveCtm; InverseEffectiveCtm.Invert(); } }
/// <summary> /// Renders the contents of the supplied Stream to the Page at the position specified by the provided Rectangle /// </summary> /// <param name="page"></param> /// <param name="stream"></param> /// <param name="rect"></param> protected virtual void RenderContentStream(PdfPage page, PdfStream stream, PdfRectangle rect) { if (stream == null || rect.IsEmpty) { return; } var content = ContentReader.ReadContent(stream.UnfilteredValue); var matrix = new XMatrix(); matrix.TranslateAppend(rect.X1, rect.Y1); var matElements = matrix.GetElements(); var matrixOp = OpCodes.OperatorFromName("cm"); foreach (var el in matElements) { matrixOp.Operands.Add(new CReal { Value = el }); } content.Insert(0, matrixOp); // Save and restore Graphics state content.Insert(0, OpCodes.OperatorFromName("q")); content.Add(OpCodes.OperatorFromName("Q")); var appendedContent = page.Contents.AppendContent(); using (var ms = new MemoryStream()) { var cw = new ContentWriter(ms); foreach (var obj in content) { obj.WriteObject(cw); } appendedContent.CreateStream(ms.ToArray()); } }
// -------------------------------------------------------------------------------------------- #region Realizing graphical state /// <summary> /// Initializes the default view transformation, i.e. the transformation from the user page /// space to the PDF page space. /// </summary> void BeginPage() { if (_gfxState.Level == GraphicsStackLevelInitial) { // TODO: Is PageOriging and PageScale (== Viewport) useful? Or just public DefaultViewMatrix (like Presentation Manager has had) // May be a BeginContainer(windows, viewport) is useful for userer that are not familar with maxtrix transformations. // Flip page horizontally and mirror text. // PDF uses a standard right-handed Cartesian coordinate system with the y axis directed up // and the rotation counterclockwise. Windows uses the opposite convertion with y axis // directed down and rotation clockwise. When I started with PDFsharp I flipped pages horizontally // and then mirrored text to compensate the effect that the fipping turns text upside down. // I found this technique during analysis of PDF documents generated with PDFlib. Unfortunately // this technique leads to several problems with programms that compose or view PDF documents // generated with PDFsharp. // In PDFsharp 1.4 I implement a revised technique that does not need text mirroring any more. DefaultViewMatrix = new XMatrix(); if (_gfx.PageDirection == XPageDirection.Downwards) { // Take TrimBox into account. PageHeightPt = Size.Height; XPoint trimOffset = new XPoint(); if (_page != null && _page.TrimMargins.AreSet) { PageHeightPt += _page.TrimMargins.Top.Point + _page.TrimMargins.Bottom.Point; trimOffset = new XPoint(_page.TrimMargins.Left.Point, _page.TrimMargins.Top.Point); } // Scale with page units. switch (_gfx.PageUnit) { case XGraphicsUnit.Point: // Factor is 1. // DefaultViewMatrix.ScalePrepend(XUnit.PointFactor); break; case XGraphicsUnit.Presentation: DefaultViewMatrix.ScalePrepend(XUnit.PresentationFactor); break; case XGraphicsUnit.Inch: DefaultViewMatrix.ScalePrepend(XUnit.InchFactor); break; case XGraphicsUnit.Millimeter: DefaultViewMatrix.ScalePrepend(XUnit.MillimeterFactor); break; case XGraphicsUnit.Centimeter: DefaultViewMatrix.ScalePrepend(XUnit.CentimeterFactor); break; } if (trimOffset != new XPoint()) { Debug.Assert(_gfx.PageUnit == XGraphicsUnit.Point, "With TrimMargins set the page units must be Point. Ohter cases nyi."); DefaultViewMatrix.TranslatePrepend(trimOffset.X, -trimOffset.Y); } // Save initial graphic state. SaveState(); // Set default page transformation, if any. if (!DefaultViewMatrix.IsIdentity) { Debug.Assert(_gfxState.RealizedCtm.IsIdentity); //_gfxState.RealizedCtm = DefaultViewMatrix; const string format = Config.SignificantFigures7; double[] cm = DefaultViewMatrix.GetElements(); AppendFormatArgs("{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "} {4:" + format + "} {5:" + format + "} cm ", cm[0], cm[1], cm[2], cm[3], cm[4], cm[5]); } // Set page transformation //double[] cm = DefaultViewMatrix.GetElements(); //AppendFormat("{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "} {4:" + format + "} {5:" + format + "} cm ", // cm[0], cm[1], cm[2], cm[3], cm[4], cm[5]); } else { // Scale with page units. switch (_gfx.PageUnit) { case XGraphicsUnit.Point: // Factor is 1. // DefaultViewMatrix.ScalePrepend(XUnit.PointFactor); break; case XGraphicsUnit.Presentation: DefaultViewMatrix.ScalePrepend(XUnit.PresentationFactor); break; case XGraphicsUnit.Inch: DefaultViewMatrix.ScalePrepend(XUnit.InchFactor); break; case XGraphicsUnit.Millimeter: DefaultViewMatrix.ScalePrepend(XUnit.MillimeterFactor); break; case XGraphicsUnit.Centimeter: DefaultViewMatrix.ScalePrepend(XUnit.CentimeterFactor); break; } // Save initial graphic state. SaveState(); // Set page transformation. const string format = Config.SignificantFigures7; double[] cm = DefaultViewMatrix.GetElements(); AppendFormat3Points("{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "} {4:" + format + "} {5:" + format + "} cm ", cm[0], cm[1], cm[2], cm[3], cm[4], cm[5]); } } }