Beispiel #1
0
        PdfTilingPattern BuildPattern(ImageBrush brush, XMatrix transform)
        {
            // Bounding box lays always at (0,0)
            XRect   bbox   = new XRect(0, 0, brush.Viewport.Width, brush.Viewport.Height);
            XMatrix matrix = transform;

            matrix.Prepend(new XMatrix(1, 0, 0, 1, brush.Viewport.X, brush.Viewport.Y));
            if (brush.Transform != null)
            {
                matrix.Prepend(new XMatrix(brush.Transform.Matrix.m11, brush.Transform.Matrix.m12, brush.Transform.Matrix.m21,
                                           brush.Transform.Matrix.m22, brush.Transform.Matrix.offsetX, brush.Transform.Matrix.offsetY));
            }

            // HACK by [email protected]
            // Avoid extra thin lines at the right and at the bottom of original image
            double xStep = brush.Viewport.Width + 1;
            double yStep = brush.Viewport.Height + 1;

            PdfTilingPattern pattern = Context.PdfDocument.Internals.CreateIndirectObject <PdfTilingPattern>();

            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PatternType, 1); // Tiling
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PaintType, 1);   // Color
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.TilingType, 3);  // Constant spacing and faster tiling
            pattern.Elements.SetMatrix(PdfTilingPattern.Keys.Matrix, matrix);
            pattern.Elements.SetRectangle(PdfTilingPattern.Keys.BBox, new PdfRectangle(bbox));
            pattern.Elements.SetReal(PdfTilingPattern.Keys.XStep, xStep);
            pattern.Elements.SetReal(PdfTilingPattern.Keys.YStep, yStep);

            // Set extended graphic state like Acrobat do
            PdfExtGState pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();

            pdfExtGState.SetDefault1();

            PdfFormXObject pdfForm = BuildForm(brush);

            PdfContentWriter writer = new PdfContentWriter(Context, pattern);

            writer.BeginContentRaw();

            // Acrobat 8 clips to bounding box, so do we
            //writer.WriteClip(bbox);

            XMatrix transformation = new XMatrix();
            double  dx             = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            double  dy             = brush.Viewport.Height / brush.Viewbox.Height * 96 / pdfForm.DpiY;

            transformation = new XMatrix(dx, 0, 0, dy, 0, 0);
            writer.WriteMatrix(transformation);
            writer.WriteGraphicsState(pdfExtGState);

            string name = writer.Resources.AddForm(pdfForm);

            writer.WriteLiteral(name + " Do\n");

            writer.EndContent();

            return(pattern);
        }
Beispiel #2
0
        /// <summary>
        /// Creates an XForm from an image brush.
        /// </summary>
        public static XForm FromImageBrush(DocumentRenderingContext context, ImageBrush brush)
        {
            XPImage xpImage = ImageBuilder.FromImageBrush(context, brush);
            XImage  ximage  = xpImage.XImage;
            double  width   = ximage.PixelWidth;
            double  height  = ximage.PixelHeight;

            // view box in point
            // XRect box = new XRect(brush.Viewbox.X * 0.75, brush.Viewbox.Y * 0.75, brush.Viewbox.Width * 0.75, brush.Viewbox.Height * 0.75);
            XRect box   = new XRect(0, 0, width, height);
            XForm xform = new XForm(context.PdfDocument, box);

            PdfContentWriter formWriter = new PdfContentWriter(context, xform, RenderMode.Default);

            Debug.Assert(ximage != null);

            PdfFormXObject pdfForm = xform.PdfForm;

            pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix());

            //formWriter.Size = brush.Viewport.Size;
            formWriter.BeginContentRaw();

            string  imageID = formWriter.Resources.AddImage(new PdfImage(context.PdfDocument, ximage));
            XMatrix matrix  = new XMatrix();
            double  scaleX  = brush.Viewport.Width / brush.Viewbox.Width * 4 / 3 * ximage.PointWidth;
            double  scaleY  = brush.Viewport.Height / brush.Viewbox.Height * 4 / 3 * ximage.PointHeight;

            matrix.TranslatePrepend(-brush.Viewbox.X, -brush.Viewbox.Y);
            matrix.ScalePrepend(scaleX, scaleY);
            matrix.TranslatePrepend(brush.Viewport.X / scaleX, brush.Viewport.Y / scaleY);

            matrix = new XMatrix(width, 0, 0, -height, 0, height);
            formWriter.WriteLiteral("q\n");
            // TODO:WriteClip(path.Data);
            //formWriter.WriteLiteral("{0:0.###} 0 0 -{1:0.###} {2:0.###} {3:0.###} cm 100 Tz {4} Do Q\n",
            //  matrix.M11, matrix.M22, matrix.OffsetX, matrix.OffsetY + brush.Viewport.Height, imageID);
            formWriter.WriteMatrix(matrix);
            formWriter.WriteLiteral(imageID + " Do Q\n");

            formWriter.EndContent();

            return(xform);
        }
    /// <summary>
    /// Creates an XForm from an image brush.
    /// </summary>
    public static XForm FromImageBrush(DocumentRenderingContext context, ImageBrush brush)
    {
      XPImage xpImage = ImageBuilder.FromImageBrush(context, brush);
      XImage ximage = xpImage.XImage;
      double width = ximage.PixelWidth;
      double height = ximage.PixelHeight;

      // view box in point
      // XRect box = new XRect(brush.Viewbox.X * 0.75, brush.Viewbox.Y * 0.75, brush.Viewbox.Width * 0.75, brush.Viewbox.Height * 0.75);
      XRect box = new XRect(0, 0, width, height);
      XForm xform = new XForm(context.PdfDocument, box);

      PdfContentWriter formWriter = new PdfContentWriter(context, xform, RenderMode.Default);

      Debug.Assert(ximage != null);

      PdfFormXObject pdfForm = xform.PdfForm;
      pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix());

      //formWriter.Size = brush.Viewport.Size;
      formWriter.BeginContentRaw();

      string imageID = formWriter.Resources.AddImage(new PdfImage(context.PdfDocument, ximage));
      XMatrix matrix = new XMatrix();
      double scaleX = brush.Viewport.Width / brush.Viewbox.Width * 4 / 3 * ximage.PointWidth;
      double scaleY = brush.Viewport.Height / brush.Viewbox.Height * 4 / 3 * ximage.PointHeight;
      matrix.TranslatePrepend(-brush.Viewbox.X, -brush.Viewbox.Y);
      matrix.ScalePrepend(scaleX, scaleY);
      matrix.TranslatePrepend(brush.Viewport.X / scaleX, brush.Viewport.Y / scaleY);

      matrix = new XMatrix(width, 0, 0, -height, 0, height);
      formWriter.WriteLiteral("q\n");
      // TODO:WriteClip(path.Data);
      //formWriter.WriteLiteral("{0:0.###} 0 0 -{1:0.###} {2:0.###} {3:0.###} cm 100 Tz {4} Do Q\n",
      //  matrix.M11, matrix.M22, matrix.OffsetX, matrix.OffsetY + brush.Viewport.Height, imageID);
      formWriter.WriteMatrix(matrix);
      formWriter.WriteLiteral(imageID + " Do Q\n");

      formWriter.EndContent();

      return xform;
    }
Beispiel #4
0
        /// <summary>
        /// Builds the soft mask.
        /// </summary>
        PdfSoftMask BuildSoftMask(RadialGradientBrush brush)
        {
            Debug.Assert(brush.GradientStops.HasTransparency);

            XRect viewBox = new XRect(0, 0, 360, 480); // HACK
            //XForm xform = new XForm(Context.PdfDocument, viewBox);

            PdfFormXObject form = Context.PdfDocument.Internals.CreateIndirectObject <PdfFormXObject>();

#if DEBUG
            if (DevHelper.RenderComments)
            {
                form.Elements.SetString("/@comment", "This is the Form XObject of the soft mask");
            }
#endif
            form.Elements.SetRectangle(PdfFormXObject.Keys.BBox, new PdfRectangle(viewBox));


            // Transparency group of mask form
            //<<
            //  /CS /DeviceGray
            //  /I false
            //  /K false
            //  /S /Transparency
            //  /Type /Group
            //>>
            PdfTransparencyGroupAttributes tgAttributes = Context.PdfDocument.Internals.CreateIndirectObject <PdfTransparencyGroupAttributes>();
            tgAttributes.Elements.SetName(PdfTransparencyGroupAttributes.Keys.CS, "/DeviceGray");
            tgAttributes.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.I, false);
            tgAttributes.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.K, false);

            // ExtGState of mask form
            //<<
            //  /AIS false
            //  /BM /Normal
            //  /ca 1
            //  /CA 1
            //  /op false
            //  /OP false
            //  /OPM 1
            //  /SA true
            //  /SMask /None
            //  /Type /ExtGState
            //>>
            PdfExtGState pdfStateMaskFrom = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
            pdfStateMaskFrom.SetDefault1();

            // Shading of mask form
            PdfShading shadingFrom = BuildShadingForSoftMask(brush);

            ////// Set reference to transparency group attributes
            ////pdfForm.Elements.SetObject(PdfFormXObject.Keys.Group, tgAttributes);
            ////pdfForm.Elements[PdfFormXObject.Keys.Matrix] = new PdfLiteral("[1.001 0 0 1.001 0.001 0.001]");

            // Soft mask
            //<<
            //  /G 21 0 R   % form
            //  /S /Luminosity
            //  /Type /Mask
            //>>
            PdfSoftMask softmask = Context.PdfDocument.Internals.CreateIndirectObject <PdfSoftMask>(); // new PdfSoftMask(this.writer.Owner);
            //extGState.Elements.SetReference(PdfExtGState.Keys.SMask, softmask);
            //this.writer.Owner.Internals.AddObject(softmask);
#if DEBUG
            if (DevHelper.RenderComments)
            {
                softmask.Elements.SetString("/@comment", "This is the soft mask");
            }
#endif
            softmask.Elements.SetName(PdfSoftMask.Keys.S, "/Luminosity");
            softmask.Elements.SetReference(PdfSoftMask.Keys.G, form);

            // Create content of mask form
            //<<
            //  /BBox [200.118 369.142 582.795 -141.094]
            //  /Group 16 0 R
            //  /Length 121
            //  /Matrix [1 0 0 1 0 0]
            //  /Resources
            //  <<
            //    /ExtGState
            //    <<
            //      /GS0 20 0 R
            //    >>
            //    /Shading
            //    <<
            //      /Sh0 19 0 R
            //    >>
            //  >>
            //  /Subtype /Form
            //>>
            //stream
            //  q
            //    200.118 369.142 382.677 -510.236 re
            //    W n
            //  q
            //    0 g
            //    1 i
            //    GS0 gs
            //    0.75 0 0 -0.75 200.1181183 369.1417236 cm
            //   BX /Sh0 sh EX Q
            //  Q
            //endstream
            form.Elements.SetReference(PdfFormXObject.Keys.Group, tgAttributes);
            PdfContentWriter writer = new PdfContentWriter(Context, form);
            writer.BeginContentRaw();
            // Acrobat 8 clips to bounding box, so we should do
            // why   0 480 360 -480 re ??
            //writer.WriteClip(bbox);
            //writer.WriteGraphicsState(extGState);
            writer.WriteLiteral("1 i 0 g\n");
            writer.WriteLiteral(writer.Resources.AddExtGState(pdfStateMaskFrom) + " gs\n");

            XMatrix transform = new XMatrix(); //(brush.Viewport.Width / viewBoxForm.width, 0, 0, brush.Viewport.Height / viewBoxForm.height, 0, 0);
            writer.WriteMatrix(transform);
            writer.WriteLiteral("BX " + writer.Resources.AddShading(shadingFrom) + " sh EX\n");
            writer.EndContent();

            return(softmask);
        }
Beispiel #5
0
        PdfShadingPattern BuildPattern(RadialGradientBrush brush, XRect boundingBox, XMatrix transform)
        {
            //<<
            //  /BBox [0 0 600 760]
            //  /Length 123
            //  /Matrix [0.75 0 0 -0.75 0 480]
            //  /PaintType 1
            //  /PatternType 1
            //  /Resources
            //  <<
            //    /ColorSpace
            //    <<
            //      /CS0 12 0 R
            //      /CS1 12 0 R
            //    >>
            //    /ExtGState
            //    <<
            //      /GS0 10 0 R
            //      /GS1 16 0 R
            //    >>
            //    /Shading
            //    <<
            //      /Sh0 15 0 R
            //    >>
            //  >>
            //  /TilingType 3
            //  /Type /Pattern
            //  /XStep 600
            //  /YStep 1520
            //>>
            //stream
            //  /CS0 cs 1 0 0  scn
            //  1 i
            //  /GS0 gs
            //  0 0 600 759.999 re
            //  f
            //  q
            //  0 0 600 760 re
            //  W n
            //  q
            //  0 g
            //  /GS1 gs
            //  1 0 0 0.5 0 0 cm
            //  BX /Sh0 sh EX Q
            //  Q
            //endstream
            XRect   bbox   = new XRect(-600, -700, 1200, 1520); // HACK
            XMatrix matrix = transform;
            //matrix.Prepend(brush.Transform.Matrix);

            double xStep = 600;
            double yStep = 1520; // HACK

            PdfShadingPattern pattern = Context.PdfDocument.Internals.CreateIndirectObject <PdfShadingPattern>();

            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PatternType, 1); // Tiling
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PaintType, 1);   // Color
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.TilingType, 3);  // Constant spacing and faster tiling
            pattern.Elements.SetMatrix(PdfTilingPattern.Keys.Matrix, matrix);
            pattern.Elements.SetRectangle(PdfTilingPattern.Keys.BBox, new PdfRectangle(bbox));
            pattern.Elements.SetReal(PdfTilingPattern.Keys.XStep, xStep);
            pattern.Elements.SetReal(PdfTilingPattern.Keys.YStep, yStep);

            double dx       = 2 * brush.RadiusX;
            double dy       = 2 * brush.RadiusY;
            XRect  brushBox = new XRect(brush.Center.X - brush.RadiusX, brush.Center.Y - brush.RadiusY, dx, dy);

            Debug.Assert(dx * dy > 0, "Radius is 0.");
            double scaleX, scaleY;

            if (dx > dy)
            {
                scaleX = 1;
                scaleY = dy / dx;
            }
            else
            {
                scaleX = dx / dy;
                scaleY = 1;
            }

            PdfColorMode  colorMode = PdfColorMode.Rgb;
            PdfDictionary funcReflected;
            PdfDictionary funcRegular = BuildShadingFunction(brush.GradientStops, false, colorMode, true, out funcReflected);

            if (brush.SpreadMethod != SpreadMethod.Pad)
            {
                if (CanOptimizeForTwoColors(brush.GradientStops))
                {
                    PdfDictionary dummy;
                    funcReflected = BuildShadingFunction(brush.GradientStops, false, colorMode, false, out dummy);
                }
                else
                {
                    Context.PdfDocument.Internals.AddObject(funcRegular);
                }
            }

            //PdfShading shading = BuildShading(brush, scaleX, scaleY);

            int shadingCount = 1;

            if (brush.SpreadMethod != SpreadMethod.Pad)
            {
                // TODO: Calculate number of required shadings
                shadingCount = Convert.ToInt32(Math.Max(boundingBox.Width / (2 * brush.RadiusX), boundingBox.Height / (2 * brush.RadiusY)) + 1);

                // HACK: Rule of thumb, better than nothing
                shadingCount *= 2;
            }
            PdfShading[] shadings = new PdfShading[shadingCount];

            // Create the shadings
            for (int idx = 0; idx < shadingCount; idx++)
            {
                PdfShading shading = BuildShading2(brush, scaleX, scaleY, idx,
                                                   brush.SpreadMethod == SpreadMethod.Reflect && idx % 2 == 1 ? funcReflected : funcRegular);
                shadings[idx] = shading;
            }

            PdfContentWriter writer = new PdfContentWriter(Context, pattern);

            writer.BeginContentRaw();

            // Fill background (even if spread method is not pad)
            writer.WriteLiteral("q /DeviceRGB cs\n");
            //writer.WriteLiteral(PdfEncoders.ToString(clr0, colorMode) + " rg 1 i\n");
            writer.WriteLiteral(PdfEncoders.ToString(brush.GradientStops[brush.GradientStops.Count - 1].Color, PdfColorMode.Rgb) + " rg 1 i\n");
            writer.WriteLiteral("1 i\n");
            PdfExtGState gs = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();

            gs.SetDefault1();
            writer.WriteGraphicsState(gs);
            writer.WriteLiteral("0 0 600 760 re f\n");
            XMatrix mat = brush.Transform.Matrix;

            if (!mat.IsIdentity)
            {
                writer.WriteMatrix(mat);
            }

            // Just work: silly loop thru shadings
            for (int idx = shadingCount - 1; idx >= 0; idx--)
            {
                writer.WriteLiteral("q 0 0 600 760 re W n\n");
                writer.WriteLiteral("q 0 g\n");
                gs = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
                gs.SetDefault2();
                writer.WriteGraphicsState(gs);

                XMatrix transformation = new XMatrix(scaleX, 0, 0, scaleY, 0, 0);
                writer.WriteMatrix(transformation);

                string shName = writer.Resources.AddShading(shadings[idx]);
                writer.WriteLiteral("BX " + shName + " sh EX Q Q\n");
            }
            writer.WriteLiteral("Q\n");
            writer.EndContent();

            return(pattern);
        }
Beispiel #6
0
        /// <summary>
        /// Builds a PdfFormXObject from the specified brush.
        /// // If a gradient contains transparency, a soft mask is created an added to the specified graphic state.
        /// </summary>
        PdfFormXObject BuildForm(RadialGradientBrush brush, PathGeometry geometry)
        {
            PdfFormXObject pdfForm = Context.PdfDocument.Internals.CreateIndirectObject <PdfFormXObject>();

            // HACK
            pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, new PdfRectangle(0, 640, 480, 0));

            // Transparency group of the form
            //<<
            //  /I true
            //  /K false
            //  /S /Transparency
            //  /Type /Group
            //>>
            PdfTransparencyGroupAttributes tgPrimaryForm = Context.PdfDocument.Internals.CreateIndirectObject <PdfTransparencyGroupAttributes>();

            // not set by Acrobat: tgAttributes.Elements.SetName(PdfTransparencyGroupAttributes.Keys.CS, "/DeviceRGB");
            tgPrimaryForm.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.I, true);
            tgPrimaryForm.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.K, false);
            pdfForm.Elements.SetReference(PdfFormXObject.Keys.Group, tgPrimaryForm);

            // Shading
            PdfShading shading = BuildShading(brush, 1, 1);

            // ExtGState
            //<<
            //  /AIS false
            //  /BM /Normal
            //  /ca 1
            //  /CA 1
            //  /op false
            //  /OP false
            //  /OPM 1
            //  /SA true
            //  /SMask 22 0 R
            //  /Type /ExtGState
            //>>
            PdfExtGState pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();

            pdfExtGState.SetDefault1();

            // Soft mask
            PdfSoftMask softmask = BuildSoftMask(brush);

            pdfExtGState.Elements.SetReference(PdfExtGState.Keys.SMask, softmask);

            // PdfFormXObject
            //<<
            //  /BBox [200.118 369.142 582.795 -141.094]
            //  /Group 11 0 R
            //  /Length 117
            //  /Matrix [1 0 0 1 0 0]
            //  /Resources
            //  <<
            //    /ColorSpace
            //    <<
            //      /CS0 8 0 R
            //    >>
            //    /ExtGState
            //    <<
            //      /GS0 23 0 R
            //    >>
            //    /Shading
            //    <<
            //      /Sh0 14 0 R
            //    >>
            //  >>
            //  /Subtype /Form
            //>>
            //stream
            //q
            //203.868 365.392 157.5 -97.5 re
            //W* n
            //q
            //0 g
            //1 i
            ///GS0 gs
            //0.75 0 0 -0.75 200.1181183 369.1417236 cm
            //BX /Sh0 sh EX Q
            //Q
            //endstream
            PdfContentWriter writer = new PdfContentWriter(Context, pdfForm);

            writer.BeginContentRaw();
            // Acrobat 8 clips to bounding box, so we should do
            writer.WriteClip(geometry);
            //writer.WriteGraphicsState(extGState);
            //writer.WriteLiteral("0 g\n");
            writer.WriteLiteral(writer.Resources.AddExtGState(pdfExtGState) + " gs\n");

            XMatrix transform = new XMatrix(); //(brush.Viewport.Width / viewBoxForm.width, 0, 0, brush.Viewport.Height / viewBoxForm.height, 0, 0);

            writer.WriteMatrix(transform);
            writer.WriteLiteral("BX " + writer.Resources.AddShading(shading) + " sh EX\n");
            writer.EndContent();

            return(pdfForm);
        }
Beispiel #7
0
        PdfTilingPattern BuildPattern(ImageBrush brush, XMatrix transform)
        {
            // Bounding box lays always at (0,0)
            XRect bbox = new XRect(0, 0, brush.Viewport.Width, brush.Viewport.Height);

#if true
            XMatrix matrix = transform;
            matrix.Prepend(new XMatrix(1, 0, 0, 1, brush.Viewport.X, brush.Viewport.Y));
            if (brush.Transform != null)
            {
                matrix.Prepend(new XMatrix(brush.Transform.Matrix.m11, brush.Transform.Matrix.m12, brush.Transform.Matrix.m21,
                                           brush.Transform.Matrix.m22, brush.Transform.Matrix.offsetX, brush.Transform.Matrix.offsetY));
            }
#else
            double  c      = 1;
            XMatrix matrix = new XMatrix(1 * c, 0, 0, 1 * c, brush.Viewport.X * c, brush.Viewport.Y * c); // HACK: 480
            XMatrix t      = transform;
            //t.Invert();
            t.Prepend(matrix);
            //t.TranslateAppend(brush.Viewport.X , brush.Viewport.Y);
            //matrix.Append(t);
            matrix = t;
#endif
            double xStep = brush.Viewport.Width;
            double yStep = brush.Viewport.Height;

            // PdfTilingPattern
            //<<
            //  /BBox [0 0 240 120]
            //  /Length 74
            //  /Matrix [0.75 0 0 -0.75 0 480]
            //  /PaintType 1
            //  /PatternType 1
            //  /Resources
            //  <<
            //    /ExtGState
            //    <<
            //      /GS0 10 0 R
            //    >>
            //    /XObject
            //    <<
            //      /Fm0 17 0 R
            //    >>
            //  >>
            //  /TilingType 3
            //  /Type /Pattern
            //  /XStep 480
            //  /YStep 640
            //>>
            //stream
            //  q
            //  0 0 240 120 re
            //  W n
            //  q
            //    2.3999939 0 0 1.1999969 0 0 cm
            //    /GS0 gs
            //    /Fm0 Do
            //  Q
            //Q
            //endstream
            PdfTilingPattern pattern = Context.PdfDocument.Internals.CreateIndirectObject <PdfTilingPattern>();
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PatternType, 1); // Tiling
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PaintType, 1);   // Color
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.TilingType, 3);  // Constant spacing and faster tiling
            pattern.Elements.SetMatrix(PdfTilingPattern.Keys.Matrix, matrix);
            pattern.Elements.SetRectangle(PdfTilingPattern.Keys.BBox, new PdfRectangle(bbox));
            pattern.Elements.SetReal(PdfTilingPattern.Keys.XStep, xStep);
            pattern.Elements.SetReal(PdfTilingPattern.Keys.YStep, yStep);

            // Set extended graphic state like Acrobat do
            PdfExtGState pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
            pdfExtGState.SetDefault1();

            PdfFormXObject pdfForm = BuildForm(brush);
            //XRect viewBoxForm = new XRect(0, 0, 640, 480);

            PdfContentWriter writer = new PdfContentWriter(Context, pattern);
            writer.BeginContentRaw();

            // Acrobat 8 clips to bounding box, so do we
            //writer.WriteClip(bbox);

            XMatrix transformation = new XMatrix();
            double  dx             = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            double  dy             = brush.Viewport.Height / brush.Viewbox.Height * 96 / pdfForm.DpiY;
            transformation = new XMatrix(dx, 0, 0, dy, 0, 0);
            writer.WriteMatrix(transformation);
            writer.WriteGraphicsState(pdfExtGState);

            string name = writer.Resources.AddForm(pdfForm);
            writer.WriteLiteral(name + " Do\n");

            writer.EndContent();

            return(pattern);
        }
Beispiel #8
0
        /// <summary>
        /// Builds a PdfFormXObject from the specified brush.
        /// </summary>
        PdfFormXObject BuildForm(ImageBrush brush)
        {
            //<<
            //  /BBox [0 100 100 0]
            //  /Length 65
            //  /Matrix [1 0 0 1 0 0]
            //  /Resources
            //  <<
            //    /ColorSpace
            //    <<
            //      /CS0 15 0 R
            //    >>
            //    /ExtGState
            //    <<
            //      /GS0 10 0 R
            //    >>
            //    /ProcSet [/PDF /ImageC /ImageI]
            //    /XObject
            //    <<
            //      /Im0 16 0 R
            //    >>
            //  >>
            //  /Subtype /Form
            //>>
            //stream
            //  q
            //  0 0 100 100 re
            //  W n
            //  q
            //    /GS0 gs
            //    100 0 0 -100 0 100 cm
            //    /Im0 Do
            //  Q
            //Q
            //endstream
            PdfFormXObject pdfForm = Context.PdfDocument.Internals.CreateIndirectObject <PdfFormXObject>();
            XPImage        xpImage = ImageBuilder.FromImageBrush(Context, brush);
            XImage         ximage  = xpImage.XImage;

            ximage.Interpolate = false;
            double width  = ximage.PixelWidth;
            double height = ximage.PixelHeight;

            pdfForm.DpiX = ximage.HorizontalResolution;
            pdfForm.DpiY = ximage.VerticalResolution;

            // view box in point
            // XRect box = new XRect(brush.Viewbox.X * 0.75, brush.Viewbox.Y * 0.75, brush.Viewbox.Width * 0.75, brush.Viewbox.Height * 0.75);
            XRect box = new XRect(0, 0, width, height);

            pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, new PdfRectangle(0, height, width, 0));
            pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix());

            PdfContentWriter writer = new PdfContentWriter(Context, pdfForm);

            Debug.Assert(ximage != null);

            //PdfFormXObject pdfForm = xform.PdfForm;
            pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix());

            //formWriter.Size = brush.Viewport.Size;
            writer.BeginContentRaw();

            string  imageID = writer.Resources.AddImage(new PdfImage(Context.PdfDocument, ximage));
            XMatrix matrix  = new XMatrix();

            //double scaleX = brush.Viewport.Width / brush.Viewbox.Width * 4 / 3 * ximage.PointWidth;
            //double scaleY = brush.Viewport.Height / brush.Viewbox.Height * 4 / 3 * ximage.PointHeight;
            //matrix.TranslatePrepend(-brush.Viewbox.X, -brush.Viewbox.Y);
            //matrix.ScalePrepend(scaleX, scaleY);
            //matrix.TranslatePrepend(brush.Viewport.X / scaleX, brush.Viewport.Y / scaleY);

            //double scaleX = 96 / ximage.HorizontalResolution;
            //double scaleY = 96 / ximage.VerticalResolution;
            //width *= scaleX;
            //height *= scaleY;
            matrix = new XMatrix(width, 0, 0, -height, 0, height);
            writer.WriteLiteral("q\n");
            // TODO:WriteClip(path.Data);
            //formWriter.WriteLiteral("{0:0.###} 0 0 -{1:0.###} {2:0.###} {3:0.###} cm 100 Tz {4} Do Q\n",
            //  matrix.M11, matrix.M22, matrix.OffsetX, matrix.OffsetY + brush.Viewport.Height, imageID);
            writer.WriteMatrix(matrix);
            writer.WriteLiteral(imageID + " Do Q\n");

#if DEBUG
            if (DevHelper.BorderPatterns)
            {
                writer.WriteLiteral("1 1 1 rg 0 0 m {0:0.###} 0 l {0:0.###} {1:0.###} l 0 {1:0.###} l h s\n", width, height);
            }
#endif

            writer.EndContent();

            return(pdfForm);
        }
        PdfTilingPattern BuildPattern(VisualBrush brush, XMatrix transform)
        {
            // Bounding box lays always at (0,0)
            XRect bbox = new XRect(0, 0, brush.Viewport.Width, brush.Viewport.Height);

            XMatrix matrix = transform;

            matrix.Prepend(new XMatrix(1, 0, 0, 1, brush.Viewport.X, brush.Viewport.Y));
            if (brush.Transform != null)
            {
                matrix.Prepend(new XMatrix(brush.Transform.Value.M11, brush.Transform.Value.M12,
                                           brush.Transform.Value.M21, brush.Transform.Value.M22,
                                           brush.Transform.Value.OffsetX, brush.Transform.Value.OffsetY));
            }

            // Set X Step beyond the viewport if tilemode is set to none since
            // there is no other easy way to turn off tiling - NPJ
            double xStep = brush.Viewport.Width * (brush.TileMode == TileMode.None ? 2 : 1);
            double yStep = brush.Viewport.Height * (brush.TileMode == TileMode.None ? 2 : 1);

            // PdfTilingPattern
            //<<
            //  /BBox [0 0 240 120]
            //  /Length 74
            //  /Matrix [0.75 0 0 -0.75 0 480]
            //  /PaintType 1
            //  /PatternType 1
            //  /Resources
            //  <<
            //    /ExtGState
            //    <<
            //      /GS0 10 0 R
            //    >>
            //    /XObject
            //    <<
            //      /Fm0 17 0 R
            //    >>
            //  >>
            //  /TilingType 3
            //  /Type /Pattern
            //  /XStep 480
            //  /YStep 640
            //>>
            //stream
            //  q
            //  0 0 240 120 re
            //  W n
            //  q
            //    2.3999939 0 0 1.1999969 0 0 cm
            //    /GS0 gs
            //    /Fm0 Do
            //  Q
            //Q
            //endstream
            var pattern = new PdfTilingPattern(Context.PdfDocument);

            Context.PdfDocument.Internals.AddObject(pattern);
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PatternType, 1); // Tiling
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PaintType, 1);   // Color
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.TilingType, 3);  // Constant spacing and faster tiling
            pattern.Elements.SetMatrix(PdfTilingPattern.Keys.Matrix, matrix);
            pattern.Elements.SetRectangle(PdfTilingPattern.Keys.BBox, new PdfRectangle(bbox));
            pattern.Elements.SetReal(PdfTilingPattern.Keys.XStep, xStep);
            pattern.Elements.SetReal(PdfTilingPattern.Keys.YStep, yStep);

            // Set extended graphic state like Acrobat do
            var pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();

            pdfExtGState.SetDefault1();

            var pdfForm = BuildForm(brush);

            var writer = new PdfContentWriter(Context, pattern);

            writer.BeginContentRaw();

            // Acrobat 8 clips to bounding box, so do we
            //writer.WriteClip(bbox);

            XMatrix transformation = new XMatrix();
            double  dx             = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            double  dy             = brush.Viewport.Height / brush.Viewbox.Height * 96 / pdfForm.DpiY;

            transformation = new XMatrix(dx, 0, 0, dy, 0, 0);
            writer.WriteMatrix(transformation);
            writer.WriteGraphicsState(pdfExtGState);

            string name = writer.Resources.AddForm(pdfForm);

            writer.WriteLiteral(name + " Do\n");

            writer.EndContent();

            return(pattern);
        }
    /// <summary>
    /// Builds the soft mask.
    /// </summary>
    PdfSoftMask BuildSoftMask(RadialGradientBrush brush)
    {
      Debug.Assert(brush.GradientStops.HasTransparency);

      XRect viewBox = new XRect(0, 0, 360, 480); // HACK
      //XForm xform = new XForm(Context.PdfDocument, viewBox);

      PdfFormXObject form = Context.PdfDocument.Internals.CreateIndirectObject<PdfFormXObject>();
#if DEBUG
      if (DevHelper.RenderComments)
        form.Elements.SetString("/@comment", "This is the Form XObject of the soft mask");
#endif
      form.Elements.SetRectangle(PdfFormXObject.Keys.BBox, new PdfRectangle(viewBox));


      // Transparency group of mask form
      //<<
      //  /CS /DeviceGray
      //  /I false
      //  /K false
      //  /S /Transparency
      //  /Type /Group
      //>>
      PdfTransparencyGroupAttributes tgAttributes = Context.PdfDocument.Internals.CreateIndirectObject<PdfTransparencyGroupAttributes>();
      tgAttributes.Elements.SetName(PdfTransparencyGroupAttributes.Keys.CS, "/DeviceGray");
      tgAttributes.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.I, false);
      tgAttributes.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.K, false);

      // ExtGState of mask form
      //<<
      //  /AIS false
      //  /BM /Normal
      //  /ca 1
      //  /CA 1
      //  /op false
      //  /OP false
      //  /OPM 1
      //  /SA true
      //  /SMask /None
      //  /Type /ExtGState
      //>>
      PdfExtGState pdfStateMaskFrom = Context.PdfDocument.Internals.CreateIndirectObject<PdfExtGState>();
      pdfStateMaskFrom.SetDefault1();

      // Shading of mask form
      PdfShading shadingFrom = BuildShadingForSoftMask(brush);

      ////// Set reference to transparency group attributes
      ////pdfForm.Elements.SetObject(PdfFormXObject.Keys.Group, tgAttributes);
      ////pdfForm.Elements[PdfFormXObject.Keys.Matrix] = new PdfLiteral("[1.001 0 0 1.001 0.001 0.001]");

      // Soft mask
      //<<
      //  /G 21 0 R   % form
      //  /S /Luminosity
      //  /Type /Mask
      //>>
      PdfSoftMask softmask = Context.PdfDocument.Internals.CreateIndirectObject<PdfSoftMask>();  // new PdfSoftMask(this.writer.Owner);
      //extGState.Elements.SetReference(PdfExtGState.Keys.SMask, softmask);
      //this.writer.Owner.Internals.AddObject(softmask);
#if DEBUG
      if (DevHelper.RenderComments)
        softmask.Elements.SetString("/@comment", "This is the soft mask");
#endif
      softmask.Elements.SetName(PdfSoftMask.Keys.S, "/Luminosity");
      softmask.Elements.SetReference(PdfSoftMask.Keys.G, form);

      // Create content of mask form
      //<<
      //  /BBox [200.118 369.142 582.795 -141.094]
      //  /Group 16 0 R
      //  /Length 121
      //  /Matrix [1 0 0 1 0 0]
      //  /Resources
      //  <<
      //    /ExtGState
      //    <<
      //      /GS0 20 0 R
      //    >>
      //    /Shading
      //    <<
      //      /Sh0 19 0 R
      //    >>
      //  >>
      //  /Subtype /Form
      //>>
      //stream
      //  q
      //    200.118 369.142 382.677 -510.236 re
      //    W n
      //  q
      //    0 g
      //    1 i 
      //    GS0 gs
      //    0.75 0 0 -0.75 200.1181183 369.1417236 cm
      //   BX /Sh0 sh EX Q
      //  Q
      //endstream
      form.Elements.SetReference(PdfFormXObject.Keys.Group, tgAttributes);
      PdfContentWriter writer = new PdfContentWriter(Context, form);
      writer.BeginContentRaw();
      // Acrobat 8 clips to bounding box, so we should do
      // why   0 480 360 -480 re ??
      //writer.WriteClip(bbox);
      //writer.WriteGraphicsState(extGState);
      writer.WriteLiteral("1 i 0 g\n");
      writer.WriteLiteral(writer.Resources.AddExtGState(pdfStateMaskFrom) + " gs\n");

      XMatrix transform = new XMatrix(); //(brush.Viewport.Width / viewBoxForm.width, 0, 0, brush.Viewport.Height / viewBoxForm.height, 0, 0);
      writer.WriteMatrix(transform);
      writer.WriteLiteral("BX " + writer.Resources.AddShading(shadingFrom) + " sh EX\n");
      writer.EndContent();

      return softmask;
    }
    PdfShadingPattern BuildPattern(RadialGradientBrush brush, XRect boundingBox, XMatrix transform)
    {
      //<<
      //  /BBox [0 0 600 760]
      //  /Length 123
      //  /Matrix [0.75 0 0 -0.75 0 480]
      //  /PaintType 1
      //  /PatternType 1
      //  /Resources
      //  <<
      //    /ColorSpace
      //    <<
      //      /CS0 12 0 R
      //      /CS1 12 0 R
      //    >>
      //    /ExtGState
      //    <<
      //      /GS0 10 0 R
      //      /GS1 16 0 R
      //    >>
      //    /Shading
      //    <<
      //      /Sh0 15 0 R
      //    >>
      //  >>
      //  /TilingType 3
      //  /Type /Pattern
      //  /XStep 600
      //  /YStep 1520
      //>>
      //stream
      //  /CS0 cs 1 0 0  scn
      //  1 i 
      //  /GS0 gs
      //  0 0 600 759.999 re
      //  f
      //  q
      //  0 0 600 760 re
      //  W n
      //  q
      //  0 g
      //  /GS1 gs
      //  1 0 0 0.5 0 0 cm
      //  BX /Sh0 sh EX Q
      //  Q
      //endstream
      XRect bbox = new XRect(-600,-700, 1200, 1520); // HACK
      XMatrix matrix = transform;
      //matrix.Prepend(brush.Transform.Matrix);

      double xStep = 600;
      double yStep = 1520; // HACK

      PdfShadingPattern pattern = Context.PdfDocument.Internals.CreateIndirectObject<PdfShadingPattern>();
      pattern.Elements.SetInteger(PdfTilingPattern.Keys.PatternType, 1);  // Tiling
      pattern.Elements.SetInteger(PdfTilingPattern.Keys.PaintType, 1);  // Color
      pattern.Elements.SetInteger(PdfTilingPattern.Keys.TilingType, 3);  // Constant spacing and faster tiling
      pattern.Elements.SetMatrix(PdfTilingPattern.Keys.Matrix, matrix);
      pattern.Elements.SetRectangle(PdfTilingPattern.Keys.BBox, new PdfRectangle(bbox));
      pattern.Elements.SetReal(PdfTilingPattern.Keys.XStep, xStep);
      pattern.Elements.SetReal(PdfTilingPattern.Keys.YStep, yStep);

      double dx = 2 * brush.RadiusX;
      double dy = 2 * brush.RadiusY;
      XRect brushBox = new XRect(brush.Center.X - brush.RadiusX, brush.Center.Y - brush.RadiusY, dx, dy);
      Debug.Assert(dx * dy > 0, "Radius is 0.");
      double scaleX, scaleY;
      if (dx > dy)
      {
        scaleX = 1;
        scaleY = dy / dx;
      }
      else
      {
        scaleX = dx / dy;
        scaleY = 1;
      }

      PdfColorMode colorMode = PdfColorMode.Rgb;
      PdfDictionary funcReflected;
      PdfDictionary funcRegular = BuildShadingFunction(brush.GradientStops, false, colorMode, true, out funcReflected);
      if (brush.SpreadMethod != SpreadMethod.Pad)
      {
        if (CanOptimizeForTwoColors(brush.GradientStops))
        {
          PdfDictionary dummy;
          funcReflected = BuildShadingFunction(brush.GradientStops, false, colorMode, false, out dummy);
        }
        else
        {
          Context.PdfDocument.Internals.AddObject(funcRegular);
        }
      }

      //PdfShading shading = BuildShading(brush, scaleX, scaleY);

      int shadingCount = 1;
      if (brush.SpreadMethod != SpreadMethod.Pad)
      {
        // TODO: Calculate number of required shadings
        shadingCount = Convert.ToInt32(Math.Max(boundingBox.width / (2 * brush.RadiusX), boundingBox.height / (2 * brush.RadiusY)) + 1);

        // HACK: Rule of thumb, better than nothing
        shadingCount *= 2;
      }
      PdfShading[] shadings = new PdfShading[shadingCount];

      // Create the shadings
      for (int idx = 0; idx < shadingCount; idx++)
      {
        PdfShading shading = BuildShading2(brush, scaleX, scaleY, idx,
          brush.SpreadMethod == SpreadMethod.Reflect && idx % 2 == 1 ? funcReflected : funcRegular);
        shadings[idx] = shading;
      }

      PdfContentWriter writer = new PdfContentWriter(Context, pattern);
      writer.BeginContentRaw();

      // Fill background (even if spread method is not pad)
      writer.WriteLiteral("q /DeviceRGB cs\n");
      //writer.WriteLiteral(PdfEncoders.ToString(clr0, colorMode) + " rg 1 i\n");
      writer.WriteLiteral(PdfEncoders.ToString(brush.GradientStops[brush.GradientStops.Count - 1].Color, PdfColorMode.Rgb) + " rg 1 i\n");
      writer.WriteLiteral("1 i\n");
      PdfExtGState gs = Context.PdfDocument.Internals.CreateIndirectObject<PdfExtGState>();
      gs.SetDefault1();
      writer.WriteGraphicsState(gs);
      writer.WriteLiteral("0 0 600 760 re f\n");
      XMatrix mat = brush.Transform.Matrix;
      if (!mat.IsIdentity)
        writer.WriteMatrix(mat);

      // Just work: silly loop thru shadings
      for (int idx = shadingCount - 1; idx >= 0; idx--)
      {
        writer.WriteLiteral("q 0 0 600 760 re W n\n");
        writer.WriteLiteral("q 0 g\n");
        gs = Context.PdfDocument.Internals.CreateIndirectObject<PdfExtGState>();
        gs.SetDefault2();
        writer.WriteGraphicsState(gs);

        XMatrix transformation = new XMatrix(scaleX, 0, 0, scaleY, 0, 0);
        writer.WriteMatrix(transformation);

        string shName = writer.Resources.AddShading(shadings[idx]);
        writer.WriteLiteral("BX " + shName + " sh EX Q Q\n");
      }
      writer.WriteLiteral("Q\n");
      writer.EndContent();

      return pattern;
    }
    /// <summary>
    /// Builds a PdfFormXObject from the specified brush. 
    /// // If a gradient contains transparency, a soft mask is created an added to the specified graphic state.
    /// </summary>
    PdfFormXObject BuildForm(RadialGradientBrush brush, PathGeometry geometry)
    {
      PdfFormXObject pdfForm = Context.PdfDocument.Internals.CreateIndirectObject<PdfFormXObject>();

      // HACK
      pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, new PdfRectangle(0, 640, 480, 0));

      // Transparency group of the form
      //<<
      //  /I true
      //  /K false
      //  /S /Transparency
      //  /Type /Group
      //>>
      PdfTransparencyGroupAttributes tgPrimaryForm = Context.PdfDocument.Internals.CreateIndirectObject<PdfTransparencyGroupAttributes>();
      // not set by Acrobat: tgAttributes.Elements.SetName(PdfTransparencyGroupAttributes.Keys.CS, "/DeviceRGB");
      tgPrimaryForm.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.I, true);
      tgPrimaryForm.Elements.SetBoolean(PdfTransparencyGroupAttributes.Keys.K, false);
      pdfForm.Elements.SetReference(PdfFormXObject.Keys.Group, tgPrimaryForm);

      // Shading
      PdfShading shading = BuildShading(brush, 1, 1);

      // ExtGState 
      //<<
      //  /AIS false
      //  /BM /Normal
      //  /ca 1
      //  /CA 1
      //  /op false
      //  /OP false
      //  /OPM 1
      //  /SA true
      //  /SMask 22 0 R
      //  /Type /ExtGState
      //>>
      PdfExtGState pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject<PdfExtGState>();
      pdfExtGState.SetDefault1();

      // Soft mask
      PdfSoftMask softmask = BuildSoftMask(brush);
      pdfExtGState.Elements.SetReference(PdfExtGState.Keys.SMask, softmask);

      // PdfFormXObject
      //<<
      //  /BBox [200.118 369.142 582.795 -141.094]
      //  /Group 11 0 R
      //  /Length 117
      //  /Matrix [1 0 0 1 0 0]
      //  /Resources
      //  <<
      //    /ColorSpace
      //    <<
      //      /CS0 8 0 R
      //    >>
      //    /ExtGState
      //    <<
      //      /GS0 23 0 R
      //    >>
      //    /Shading
      //    <<
      //      /Sh0 14 0 R
      //    >>
      //  >>
      //  /Subtype /Form
      //>>
      //stream
      //q
      //203.868 365.392 157.5 -97.5 re
      //W* n
      //q
      //0 g
      //1 i 
      ///GS0 gs
      //0.75 0 0 -0.75 200.1181183 369.1417236 cm
      //BX /Sh0 sh EX Q
      //Q
      //endstream
      PdfContentWriter writer = new PdfContentWriter(Context, pdfForm);
      writer.BeginContentRaw();
      // Acrobat 8 clips to bounding box, so we should do
      writer.WriteClip(geometry);
      //writer.WriteGraphicsState(extGState);
      //writer.WriteLiteral("0 g\n");
      writer.WriteLiteral(writer.Resources.AddExtGState(pdfExtGState) + " gs\n");

      XMatrix transform = new XMatrix(); //(brush.Viewport.Width / viewBoxForm.width, 0, 0, brush.Viewport.Height / viewBoxForm.height, 0, 0);
      writer.WriteMatrix(transform);
      writer.WriteLiteral("BX " + writer.Resources.AddShading(shading) + " sh EX\n");
      writer.EndContent();

      return pdfForm;
    }
Beispiel #13
0
        PdfTilingPattern BuildPattern(ImageBrush brush, XMatrix transform)
        {
            // Bounding box lays always at (0,0)
            XRect bbox = new XRect(0, 0, brush.Viewport.Width, brush.Viewport.Height);
#if true
            XMatrix matrix = transform;
            matrix.Prepend(new XMatrix(1, 0, 0, 1, brush.Viewport.X, brush.Viewport.Y));
            if (brush.Transform != null)
            {
                matrix.Prepend(new XMatrix(brush.Transform.Matrix.m11, brush.Transform.Matrix.m12, brush.Transform.Matrix.m21,
                brush.Transform.Matrix.m22, brush.Transform.Matrix.offsetX, brush.Transform.Matrix.offsetY));
            }
#else
      double c = 1;
      XMatrix matrix = new XMatrix(1 * c, 0, 0, 1 * c, brush.Viewport.X * c, brush.Viewport.Y * c); // HACK: 480
      XMatrix t = transform;
      //t.Invert();
      t.Prepend(matrix);
      //t.TranslateAppend(brush.Viewport.X , brush.Viewport.Y);
      //matrix.Append(t);
      matrix = t;
#endif
            double xStep = brush.Viewport.Width;
            double yStep = brush.Viewport.Height;

            // PdfTilingPattern
            //<<
            //  /BBox [0 0 240 120]
            //  /Length 74
            //  /Matrix [0.75 0 0 -0.75 0 480]
            //  /PaintType 1
            //  /PatternType 1
            //  /Resources
            //  <<
            //    /ExtGState
            //    <<
            //      /GS0 10 0 R
            //    >>
            //    /XObject
            //    <<
            //      /Fm0 17 0 R
            //    >>
            //  >>
            //  /TilingType 3
            //  /Type /Pattern
            //  /XStep 480
            //  /YStep 640
            //>>
            //stream
            //  q
            //  0 0 240 120 re
            //  W n
            //  q
            //    2.3999939 0 0 1.1999969 0 0 cm
            //    /GS0 gs
            //    /Fm0 Do
            //  Q
            //Q
            //endstream
            PdfTilingPattern pattern = Context.PdfDocument.Internals.CreateIndirectObject<PdfTilingPattern>();
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PatternType, 1);  // Tiling
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PaintType, 1);  // Color
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.TilingType, 3);  // Constant spacing and faster tiling
            pattern.Elements.SetMatrix(PdfTilingPattern.Keys.Matrix, matrix);
            pattern.Elements.SetRectangle(PdfTilingPattern.Keys.BBox, new PdfRectangle(bbox));
            pattern.Elements.SetReal(PdfTilingPattern.Keys.XStep, xStep);
            pattern.Elements.SetReal(PdfTilingPattern.Keys.YStep, yStep);

            // Set extended graphic state like Acrobat do
            PdfExtGState pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject<PdfExtGState>();
            pdfExtGState.SetDefault1();

            PdfFormXObject pdfForm = BuildForm(brush);
            //XRect viewBoxForm = new XRect(0, 0, 640, 480);

            PdfContentWriter writer = new PdfContentWriter(Context, pattern);
            writer.BeginContentRaw();

            // Acrobat 8 clips to bounding box, so do we
            //writer.WriteClip(bbox);

            XMatrix transformation = new XMatrix();
            double dx = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            double dy = brush.Viewport.Height / brush.Viewbox.Height * 96 / pdfForm.DpiY;
            transformation = new XMatrix(dx, 0, 0, dy, 0, 0);
            writer.WriteMatrix(transformation);
            writer.WriteGraphicsState(pdfExtGState);

            string name = writer.Resources.AddForm(pdfForm);
            writer.WriteLiteral(name + " Do\n");

            writer.EndContent();

            return pattern;
        }
Beispiel #14
0
        /// <summary>
        /// Builds a PdfFormXObject from the specified brush. 
        /// </summary>
        PdfFormXObject BuildForm(ImageBrush brush)
        {
            //<<
            //  /BBox [0 100 100 0]
            //  /Length 65
            //  /Matrix [1 0 0 1 0 0]
            //  /Resources
            //  <<
            //    /ColorSpace
            //    <<
            //      /CS0 15 0 R
            //    >>
            //    /ExtGState
            //    <<
            //      /GS0 10 0 R
            //    >>
            //    /ProcSet [/PDF /ImageC /ImageI]
            //    /XObject
            //    <<
            //      /Im0 16 0 R
            //    >>
            //  >>
            //  /Subtype /Form
            //>>
            //stream
            //  q
            //  0 0 100 100 re
            //  W n
            //  q
            //    /GS0 gs
            //    100 0 0 -100 0 100 cm
            //    /Im0 Do
            //  Q
            //Q
            //endstream
            PdfFormXObject pdfForm = Context.PdfDocument.Internals.CreateIndirectObject<PdfFormXObject>();
            XPImage xpImage = ImageBuilder.FromImageBrush(Context, brush);
            XImage ximage = xpImage.XImage;
            ximage.Interpolate = false;
            double width = ximage.PixelWidth;
            double height = ximage.PixelHeight;
            pdfForm.DpiX = ximage.HorizontalResolution;
            pdfForm.DpiY = ximage.VerticalResolution;

            // view box in point
            // XRect box = new XRect(brush.Viewbox.X * 0.75, brush.Viewbox.Y * 0.75, brush.Viewbox.Width * 0.75, brush.Viewbox.Height * 0.75);
            XRect box = new XRect(0, 0, width, height);

            pdfForm.Elements.SetRectangle(PdfFormXObject.Keys.BBox, new PdfRectangle(0, height, width, 0));
            pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix());

            PdfContentWriter writer = new PdfContentWriter(Context, pdfForm);

            Debug.Assert(ximage != null);

            //PdfFormXObject pdfForm = xform.PdfForm;
            pdfForm.Elements.SetMatrix(PdfFormXObject.Keys.Matrix, new XMatrix());

            //formWriter.Size = brush.Viewport.Size;
            writer.BeginContentRaw();

            string imageID = writer.Resources.AddImage(new PdfImage(Context.PdfDocument, ximage));
            XMatrix matrix = new XMatrix();
            //double scaleX = brush.Viewport.Width / brush.Viewbox.Width * 4 / 3 * ximage.PointWidth;
            //double scaleY = brush.Viewport.Height / brush.Viewbox.Height * 4 / 3 * ximage.PointHeight;
            //matrix.TranslatePrepend(-brush.Viewbox.X, -brush.Viewbox.Y);
            //matrix.ScalePrepend(scaleX, scaleY);
            //matrix.TranslatePrepend(brush.Viewport.X / scaleX, brush.Viewport.Y / scaleY);

            //double scaleX = 96 / ximage.HorizontalResolution;
            //double scaleY = 96 / ximage.VerticalResolution;
            //width *= scaleX;
            //height *= scaleY;
            matrix = new XMatrix(width, 0, 0, -height, 0, height);
            writer.WriteLiteral("q\n");
            // TODO:WriteClip(path.Data);
            //formWriter.WriteLiteral("{0:0.###} 0 0 -{1:0.###} {2:0.###} {3:0.###} cm 100 Tz {4} Do Q\n",
            //  matrix.M11, matrix.M22, matrix.OffsetX, matrix.OffsetY + brush.Viewport.Height, imageID);
            writer.WriteMatrix(matrix);
            writer.WriteLiteral(imageID + " Do Q\n");

#if DEBUG
            if (DevHelper.BorderPatterns)
                writer.WriteLiteral("1 1 1 rg 0 0 m {0:0.###} 0 l {0:0.###} {1:0.###} l 0 {1:0.###} l h s\n", width, height);
#endif

            writer.EndContent();

            return pdfForm;
        }
Beispiel #15
0
        PdfTilingPattern BuildPattern(ImageBrush brush, XMatrix transform)
        {
            // Bounding box repects viewbox
            //XRect bbox = new XRect(brush.Viewbox.X, brush.Viewbox.Y, brush.Viewbox.Width, brush.Viewbox.Height);
            // double scalex = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            //BitmapImage src = new BitmapImage();
            //BitmapSource cropbrush = BitmapSource.Create()
            //CroppedBitmap cropbrush = new CroppedBitmap((BitmapSource)brush.ImageSource, new System.Windows.Int32Rect((int)brush.Viewbox.X, (int)brush.Viewbox.Y, (int)brush.Viewbox.Width, (int)brush.Viewbox.Height));
            //using (var fileStream = new System.IO.FileStream("c:\\fullimage.png", System.IO.FileMode.Create))
            //{
            //    BitmapEncoder encoder = new PngBitmapEncoder();
            //    encoder.Frames.Add(BitmapFrame.Create((BitmapSource)brush.ImageSource));
            //    encoder.Save(fileStream);
            //}
            double scaledpix = ((BitmapSource)brush.ImageSource).DpiX;
            double scaledpiy = ((BitmapSource)brush.ImageSource).DpiY;

            if (brush.Viewbox.X > 0 || brush.Viewbox.Y > 0)
            {
                CroppedBitmap cropbrush = new CroppedBitmap((BitmapSource)brush.ImageSource, new System.Windows.Int32Rect((int)Math.Round((brush.Viewbox.X / 96) * scaledpix), (int)Math.Round((brush.Viewbox.Y / 96) * scaledpiy), (int)Math.Round((brush.Viewbox.Width / 96) * scaledpiy), (int)Math.Round((brush.Viewbox.Height / 96) * scaledpiy)));
                //cropbrush.DpiX = scaledpix;
                //cropbrush.DpiY = scaledpiy;
                brush.ImageSource = cropbrush;
                //brush.Viewport = new System.Windows.Rect(0, 0, brush.Viewport.Width, brush.Viewport.Height);
                //brush.Viewbox = new System.Windows.Rect(0, 0, ((Math.Round((brush.Viewbox.Width / 96) * scaledpiy)) / scaledpiy * 96) , brush.Viewbox.Height);
                brush.Viewbox = new System.Windows.Rect(0, 0, brush.Viewbox.Width, brush.Viewbox.Height);
            }

            //brush = new ImageBrush(cropbrush);

            //BitmapSource
            //BitmapSource. cropbrushbitmap = new BitmapSource(cropbrush);


            //using (var fileStream = new System.IO.FileStream("c:\\cropimage.png", System.IO.FileMode.Create))
            //{
            //   BitmapEncoder encoder = new PngBitmapEncoder();
            //   encoder.Frames.Add(BitmapFrame.Create(cropbrush));
            //   encoder.Save(fileStream);
            //}

            //XRect bbox = new XRect(brush.Viewport.X - brush.Viewbox.X, brush.Viewport.Y - brush.Viewbox.Y, brush.Viewbox.Width, brush.Viewbox.Height);
            //XRect bbox = new XRect((brush.Viewbox.X / 96) * scaledpix, (brush.Viewbox.Y / 96) * scaledpiy, (brush.Viewbox.Width / 96) * scaledpix, (brush.Viewbox.Height / 96) * scaledpiy);
            //XRect bbox = new XRect(0, 0, (brush.Viewport.Width / 96) * scaledpix, (brush.Viewport.Height / 96) * scaledpiy);
            XRect bbox = new XRect(0, 0, brush.Viewport.Width, brush.Viewport.Height);

#if true
            XMatrix matrix = transform;
//this only needs to be a translate and to offset the viewbox viewport difference
            matrix.TranslatePrepend(brush.Viewport.X, brush.Viewport.Y);
            //matrix.TranslatePrepend((brush.Viewport.X - brush.Viewbox.X)+2, (brush.Viewport.Y - brush.Viewbox.Y)+2);

            if (brush.Transform != null)
            {
                matrix.Prepend(new XMatrix(brush.Transform.Value.M11, brush.Transform.Value.M12, brush.Transform.Value.M21,
                                           brush.Transform.Value.M22, brush.Transform.Value.OffsetX,
                                           brush.Transform.Value.OffsetY));
            }
#else
            double  c      = 1;
            XMatrix matrix = new XMatrix(1 * c, 0, 0, 1 * c, brush.Viewport.X * c, brush.Viewport.Y * c); // HACK: 480
            XMatrix t      = transform;
            //t.Invert();
            t.Prepend(matrix);
            //t.TranslateAppend(brush.Viewport.X , brush.Viewport.Y);
            //matrix.Append(t);
            matrix = t;
#endif
            double xStep = brush.Viewport.Width + 1;  // (brush.Viewbox.Width / 96) * scaledpix; //* (brush.TileMode == TileMode.None ? 2 : 1);
            double yStep = brush.Viewport.Height + 1; // (brush.Viewbox.Height / 96) * scaledpiy; //* (brush.TileMode == TileMode.None ? 2 : 1);


            // PdfTilingPattern
            //<<
            //  /BBox [0 0 240 120]
            //  /Length 74
            //  /Matrix [0.75 0 0 -0.75 0 480]
            //  /PaintType 1
            //  /PatternType 1
            //  /Resources
            //  <<
            //    /ExtGState
            //    <<
            //      /GS0 10 0 R
            //    >>
            //    /XObject
            //    <<
            //      /Fm0 17 0 R
            //    >>
            //  >>
            //  /TilingType 3
            //  /Type /Pattern
            //  /XStep 480
            //  /YStep 640
            //>>
            //stream
            //  q
            //  0 0 240 120 re
            //  W n
            //  q
            //    2.3999939 0 0 1.1999969 0 0 cm
            //    /GS0 gs
            //    /Fm0 Do
            //  Q
            //Q
            //endstream
            PdfTilingPattern pattern = Context.PdfDocument.Internals.CreateIndirectObject <PdfTilingPattern>();
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PatternType, 1); // Tiling
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.PaintType, 1);   // Color
            pattern.Elements.SetInteger(PdfTilingPattern.Keys.TilingType, 3);  // Constant spacing and faster tiling
            pattern.Elements.SetMatrix(PdfTilingPattern.Keys.Matrix, matrix);
            pattern.Elements.SetRectangle(PdfTilingPattern.Keys.BBox, new PdfRectangle(bbox));
            pattern.Elements.SetReal(PdfTilingPattern.Keys.XStep, xStep);
            pattern.Elements.SetReal(PdfTilingPattern.Keys.YStep, yStep);

            // Set extended graphic state like Acrobat do
            PdfExtGState pdfExtGState = Context.PdfDocument.Internals.CreateIndirectObject <PdfExtGState>();
            pdfExtGState.SetDefault1();

            PdfFormXObject pdfForm = BuildForm(brush);
            //XRect viewBoxForm = new XRect(0, 0, 640, 480);

            PdfContentWriter writer = new PdfContentWriter(Context, pattern);
            writer.BeginContentRaw();

            // Acrobat 8 clips to bounding box, so do we
            //writer.WriteClip(bbox);

            XMatrix transformation = new XMatrix();
            //double dx = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            //double dy = brush.Viewport.Height / brush.Viewbox.Height * 96 / pdfForm.DpiY;

            double dx = brush.Viewport.Width / brush.Viewbox.Width * 96 / pdfForm.DpiX;
            double dy = brush.Viewport.Height / brush.Viewbox.Height * 96 / pdfForm.DpiY;
            transformation = new XMatrix(dx, 0, 0, dy, 0, 0);
            writer.WriteMatrix(transformation);
            writer.WriteGraphicsState(pdfExtGState);

            string name = writer.Resources.AddForm(pdfForm);
            writer.WriteLiteral(name + " Do\n");

            writer.EndContent();

            return(pattern);
        }