/** * <summary>Shows the specified external object.</summary> * <remarks>Default line alignment is applied.</remarks> * <param name="xObject">External object.</param> * <param name="size">Size of the external object.</param> * <returns>Whether the external object was successfully shown.</returns> */ public bool ShowXObject( xObjects::XObject xObject, SizeF?size ) { return(ShowXObject(xObject, size, lineAlignment)); }
/** * <summary>Shows the specified external object.</summary> * <param name="xObject">External object.</param> * <param name="size">Size of the external object.</param> * <param name="lineAlignment">Line alignment. It can be: * <list type="bullet"> * <item><see cref="LineAlignmentEnum"/></item> * <item><see cref="Length">: arbitrary super-/sub-script, depending on whether the value is * positive or not.</item> * </list> * </param> * <returns>Whether the external object was successfully shown.</returns> */ public bool ShowXObject( xObjects::XObject xObject, SizeF?size, object lineAlignment ) { if (xObject == null || !EnsureRow(true)) { return(false); } if (!size.HasValue) { size = xObject.Size; } lineAlignment = ResolveLineAlignment(lineAlignment); while (true) { if (OperationUtils.Compare(currentRow.Y + size.Value.Height, frame.Height) == 1) // Object's height exceeds block's remaining vertical space. { // Terminate current row and exit! EndRow(false); return(false); } else if (OperationUtils.Compare(currentRow.Width + size.Value.Width, frame.Width) < 1) // There's room for the object in the current row. { PointF location = new PointF( (float)currentRow.Width, (float)currentRow.Y ); RowObject obj; { obj = new RowObject( RowObject.TypeEnum.XObject, baseComposer.BeginLocalState(), // Opens the row object's local state. size.Value.Height, size.Value.Width, 0, lineAlignment, size.Value.Height, 0, 0 ); baseComposer.ShowXObject(xObject, location, size); baseComposer.End(); // Closes the row object's local state. } AddRowObject(obj, lineAlignment); return(true); } else // There's NOT enough room for the object in the current row. { // Go to next row! EndRow(false); BeginRow(); } } }
internal XObjectWrapper(ContentScanner scanner) : base((XObject)scanner.Current) { SKMatrix ctm = scanner.State.Ctm; this.box = SKRect.Create( ctm.TransX, scanner.ContextSize.Height - ctm.TransY, ctm.ScaleX, Math.Abs(ctm.ScaleY) ); this.name = BaseDataObject.Name; this.xObject = BaseDataObject.GetResource(scanner.ContentContext); }
internal XObjectWrapper( ContentScanner scanner ) : base((XObject)scanner.Current) { Matrix ctm = scanner.State.Ctm; this.box = new RectangleF( ctm.Elements[4], scanner.ContextSize.Height - ctm.Elements[5], ctm.Elements[0], Math.Abs(ctm.Elements[3]) ); this.name = BaseDataObject.Name; this.xObject = BaseDataObject.GetResource(scanner.ContentContext); }
private void BuildTextBlockPage2( Document document ) { // 1. Add the page to the document! Page page = new Page(document); // Instantiates the page inside the document context. document.Pages.Add(page); // Puts the page in the pages collection. SizeF pageSize = page.Size; // 2. Create a content composer for the page! PrimitiveComposer composer = new PrimitiveComposer(page); // 3. Drawing the page contents... fonts::Font mainFont = new fonts::StandardType1Font(document, fonts::StandardType1Font.FamilyEnum.Courier, true, false); int stepCount = 5; int step = (int)(pageSize.Height) / (stepCount + 1); BlockComposer blockComposer = new BlockComposer(composer); { blockComposer.Begin( new RectangleF( 30, 0, pageSize.Width - 60, step * .8f ), XAlignmentEnum.Center, YAlignmentEnum.Middle ); composer.SetFont(mainFont, 32); blockComposer.ShowText("Block line alignment"); blockComposer.End(); } // Drawing the text block... { fonts::Font sampleFont = new fonts::StandardType1Font(document, fonts::StandardType1Font.FamilyEnum.Times, false, false); entities::Image sampleImage = entities::Image.Get(GetResourcePath("images" + System.IO.Path.DirectorySeparatorChar + "gnu.jpg")); xObjects::XObject sampleImageXObject = sampleImage.ToXObject(document); IList <LineAlignmentEnum> lineAlignments = new List <LineAlignmentEnum>((LineAlignmentEnum[])Enum.GetValues(typeof(LineAlignmentEnum))); float frameHeight = (pageSize.Height - 130 - 5 * lineAlignments.Count * 2) / (lineAlignments.Count * 2); float frameWidth = (pageSize.Width - 60 - 5 * lineAlignments.Count) / lineAlignments.Count; int imageSize = 7; for (int index = 0, length = lineAlignments.Count; index < length; index++) { LineAlignmentEnum lineAlignment = lineAlignments[index]; for (int imageIndex = 0, imageLength = lineAlignments.Count; imageIndex < imageLength; imageIndex++) { LineAlignmentEnum imageAlignment = lineAlignments[imageIndex]; for (int index2 = 0, length2 = 2; index2 < length2; index2++) { RectangleF frame = new RectangleF( 30 + (frameWidth + 5) * imageIndex, 100 + (frameHeight + 5) * (index * 2 + index2), frameWidth, frameHeight ); blockComposer.Begin(frame, XAlignmentEnum.Left, YAlignmentEnum.Top); { composer.SetFont(mainFont, 3); blockComposer.ShowText("Text: " + lineAlignment); blockComposer.ShowBreak(); blockComposer.ShowText("Image: " + imageAlignment); } blockComposer.End(); blockComposer.Begin(frame, XAlignmentEnum.Left, YAlignmentEnum.Middle); { composer.SetFont(sampleFont, 3); blockComposer.ShowText("Previous row boundary."); blockComposer.ShowBreak(); composer.SetFont(sampleFont, index2 == 0 ? 3 : 6); blockComposer.ShowText("Alignment:"); composer.SetFont(sampleFont, index2 == 0 ? 6 : 3); blockComposer.ShowText(" aligned to " + lineAlignment + " ", lineAlignment); blockComposer.ShowXObject(sampleImageXObject, new SizeF(imageSize, imageSize), imageAlignment); blockComposer.ShowBreak(); composer.SetFont(sampleFont, 3); blockComposer.ShowText("Next row boundary."); } blockComposer.End(); composer.BeginLocalState(); { composer.SetLineWidth(0.1f); composer.SetLineDash(new LineDash(new double[] { 1, 4 }, 4)); composer.DrawRectangle(blockComposer.Frame); composer.Stroke(); } composer.End(); composer.BeginLocalState(); { composer.SetLineWidth(0.1f); composer.SetLineDash(new LineDash(new double[] { 1, 1 }, 1)); composer.DrawRectangle(blockComposer.BoundBox); composer.Stroke(); } composer.End(); } } } } // 4. Flush the contents into the page! composer.Flush(); }
private void BuildMiscellaneousPage( Document document ) { // 1. Add the page to the document! Page page = new Page(document); // Instantiates the page inside the document context. document.Pages.Add(page); // Puts the page in the pages collection. SizeF pageSize = page.Size; // 2. Create a content composer for the page! PrimitiveComposer composer = new PrimitiveComposer(page); // 3. Drawing the page contents... composer.SetFont( new fonts::StandardType1Font( document, fonts::StandardType1Font.FamilyEnum.Courier, true, false ), 32 ); { BlockComposer blockComposer = new BlockComposer(composer); blockComposer.Begin(new RectangleF(30, 0, pageSize.Width - 60, 50), XAlignmentEnum.Center, YAlignmentEnum.Middle); blockComposer.ShowText("Miscellaneous"); blockComposer.End(); } composer.BeginLocalState(); composer.SetLineJoin(LineJoinEnum.Round); composer.SetLineCap(LineCapEnum.Round); // 3.1. Polygon. composer.DrawPolygon( new PointF[] { new PointF(100, 200), new PointF(150, 150), new PointF(200, 150), new PointF(250, 200) } ); // 3.2. Polyline. composer.DrawPolyline( new PointF[] { new PointF(300, 200), new PointF(350, 150), new PointF(400, 150), new PointF(450, 200) } ); composer.Stroke(); // 3.3. Rectangle (both squared and rounded). int x = 50; int radius = 0; while (x < 500) { if (x > 300) { composer.SetLineDash(new LineDash(new double[] { 5, 5 }, 3)); } composer.SetFillColor(new DeviceRGBColor(1, x / 500d, x / 500d)); composer.DrawRectangle( new RectangleF(x, 250, 150, 100), radius // NOTE: radius parameter determines the rounded angle size. ); composer.FillStroke(); x += 175; radius += 10; } composer.End(); // End local state. composer.BeginLocalState(); composer.SetFont( composer.State.Font, 12 ); // 3.4. Line cap parameter. int y = 400; foreach (LineCapEnum lineCap in (LineCapEnum[])Enum.GetValues(typeof(LineCapEnum))) { composer.ShowText( lineCap + ":", new PointF(50, y), XAlignmentEnum.Left, YAlignmentEnum.Middle, 0 ); composer.SetLineWidth(12); composer.SetLineCap(lineCap); composer.DrawLine( new PointF(120, y), new PointF(220, y) ); composer.Stroke(); composer.BeginLocalState(); composer.SetLineWidth(1); composer.SetStrokeColor(DeviceRGBColor.White); composer.SetLineCap(LineCapEnum.Butt); composer.DrawLine( new PointF(120, y), new PointF(220, y) ); composer.Stroke(); composer.End(); // End local state. y += 30; } // 3.5. Line join parameter. y += 50; foreach (LineJoinEnum lineJoin in (LineJoinEnum[])Enum.GetValues(typeof(LineJoinEnum))) { composer.ShowText( lineJoin + ":", new PointF(50, y), XAlignmentEnum.Left, YAlignmentEnum.Middle, 0 ); composer.SetLineWidth(12); composer.SetLineJoin(lineJoin); PointF[] points = new PointF[] { new PointF(120, y + 25), new PointF(150, y - 25), new PointF(180, y + 25) }; composer.DrawPolyline(points); composer.Stroke(); composer.BeginLocalState(); composer.SetLineWidth(1); composer.SetStrokeColor(DeviceRGBColor.White); composer.SetLineCap(LineCapEnum.Butt); composer.DrawPolyline(points); composer.Stroke(); composer.End(); // End local state. y += 50; } composer.End(); // End local state. // 3.6. Clipping. /* * NOTE: Clipping should be conveniently enclosed within a local state * in order to easily resume the unaltered drawing area after the operation completes. */ composer.BeginLocalState(); composer.DrawPolygon( new PointF[] { new PointF(220, 410), new PointF(300, 490), new PointF(450, 360), new PointF(430, 520), new PointF(590, 565), new PointF(420, 595), new PointF(460, 730), new PointF(380, 650), new PointF(330, 765), new PointF(310, 640), new PointF(220, 710), new PointF(275, 570), new PointF(170, 500), new PointF(275, 510) } ); composer.Clip(); // Showing a clown image... // Instantiate a jpeg image object! entities::Image image = entities::Image.Get(GetResourcePath("images" + System.IO.Path.DirectorySeparatorChar + "Clown.jpg")); // Abstract image (entity). xObjects::XObject imageXObject = image.ToXObject(document); // Show the image! composer.ShowXObject( imageXObject, new PointF(170, 320), GeomUtils.Scale(imageXObject.Size, new SizeF(450, 0)) ); composer.End(); // End local state. // 4. Flush the contents into the page! composer.Flush(); }
/** * <summary>Scans a content level looking for images.</summary> */ /* * NOTE: Page contents are represented by a sequence of content objects, * possibly nested into multiple levels. */ private void Scan( ContentScanner level, Page page ) { if (level == null) { return; } while (level.MoveNext()) { ContentObject current = level.Current; if (current is ContainerObject) { // Scan the inner level! Scan( level.ChildLevel, page ); } else { ContentScanner.GraphicsObjectWrapper objectWrapper = level.CurrentWrapper; if (objectWrapper == null) { continue; } /* * NOTE: Images can be represented on a page either as * external objects (XObject) or inline objects. */ SizeF?imageSize = null; // Image native size. if (objectWrapper is ContentScanner.XObjectWrapper) { ContentScanner.XObjectWrapper xObjectWrapper = (ContentScanner.XObjectWrapper)objectWrapper; xObjects::XObject xObject = xObjectWrapper.XObject; // Is the external object an image? if (xObject is xObjects::ImageXObject) { Console.Write( "External Image '" + xObjectWrapper.Name + "' (" + xObject.BaseObject + ")" // Image key and indirect reference. ); imageSize = xObject.Size; // Image native size. } } else if (objectWrapper is ContentScanner.InlineImageWrapper) { Console.Write("Inline Image"); InlineImage inlineImage = ((ContentScanner.InlineImageWrapper)objectWrapper).InlineImage; imageSize = inlineImage.Size; // Image native size. } if (imageSize.HasValue) { RectangleF box = objectWrapper.Box.Value; // Image position (location and size) on the page. Console.WriteLine( " on page " + page.Number + " (" + page.BaseObject + ")" // Page index and indirect reference. ); Console.WriteLine(" Coordinates:"); Console.WriteLine(" x: " + Math.Round(box.X)); Console.WriteLine(" y: " + Math.Round(box.Y)); Console.WriteLine(" width: " + Math.Round(box.Width) + " (native: " + Math.Round(imageSize.Value.Width) + ")"); Console.WriteLine(" height: " + Math.Round(box.Height) + " (native: " + Math.Round(imageSize.Value.Height) + ")"); } } } }