public override ContentObject ToInlineObject(PrimitiveComposer composer) { ContentObject barcodeObject = composer.BeginLocalState(); { fonts::Font font = fonts::PdfType1Font.Load(composer.Scanner.Contents.Document, fonts::PdfType1Font.FamilyEnum.Helvetica, false, false); double fontSize = (DigitGlyphWidth / font.GetWidth(code.Substring(0, 1), 1)); // 1. Bars. { double elementX = DigitWidth; int[] elementWidths = GetElementWidths(); double guardBarIndentY = DigitHeight / 2; bool isBar = true; for (int elementIndex = 0; elementIndex < elementWidths.Length; elementIndex++) { double elementWidth = elementWidths[elementIndex]; // Dark element? /* * NOTE: EAN symbol elements alternate bars to spaces. */ if (isBar) { composer.DrawRectangle( SKRect.Create( (float)elementX, 0, (float)elementWidth, (float)(BarHeight + ( // Guard bar? Array.BinarySearch <int>(GuardBarIndexes, elementIndex) >= 0 ? guardBarIndentY // Guard bar. : 0 // Symbol character. )) ) ); } elementX += elementWidth; isBar = !isBar; } composer.Fill(); } // 2. Digits. { composer.SetFont(font, fontSize); double digitY = BarHeight + (DigitHeight - (font.GetAscent(fontSize))) / 2; // Showing the digits... for (int digitIndex = 0; digitIndex < 13; digitIndex++) { string digit = code.Substring(digitIndex, 1); double pX = DigitGlyphXs[digitIndex] // Digit position. - font.GetWidth(digit, fontSize) / 2; // Centering. // Show the current digit! composer.ShowText( digit, new SKPoint((float)pX, (float)digitY) ); } } composer.End(); } return(barcodeObject); }
private FormXObject BuildTemplate(Document document, DateTime creationDate) { // Create a template (form)! FormXObject template = new FormXObject(document, document.PageSize.Value); SKSize templateSize = template.Size; // Get form content stream! PrimitiveComposer composer = new PrimitiveComposer(template); // Showing the header image inside the common content stream... // Instantiate a jpeg image object! entities::Image image = entities::Image.Get(GetResourcePath("images" + Path.DirectorySeparatorChar + "mountains.jpg")); // Abstract image (entity). // Show the image inside the common content stream! composer.ShowXObject( image.ToXObject(document), new SKPoint(0, 0), new SKSize(templateSize.Width - 50, 125) ); // Showing the 'PdfClown' label inside the common content stream... composer.BeginLocalState(); composer.SetFillColor(new colorSpaces::DeviceRGBColor(115f / 255, 164f / 255, 232f / 255)); // Set the font to use! composer.SetFont(fonts::PdfType1Font.Load(document, fonts::PdfType1Font.FamilyEnum.Times, true, false), 120); // Show the text! composer.ShowText( "PdfClown", new SKPoint( 0, templateSize.Height - (float)composer.State.Font.GetAscent(composer.State.FontSize) ) ); // Drawing the side rectangle... composer.DrawRectangle( SKRect.Create( (float)templateSize.Width - 50, 0, 50, (float)templateSize.Height ) ); composer.Fill(); composer.End(); // Showing the side text inside the common content stream... composer.BeginLocalState(); { composer.SetFont(fonts::PdfType1Font.Load(document, fonts::PdfType1Font.FamilyEnum.Helvetica, false, false), 8); composer.SetFillColor(colorSpaces::DeviceRGBColor.White); composer.BeginLocalState(); { composer.Rotate( 90, new SKPoint( templateSize.Width - 50, templateSize.Height - 25 ) ); BlockComposer blockComposer = new BlockComposer(composer); blockComposer.Begin( SKRect.Create(0, 0, 300, 50), XAlignmentEnum.Left, YAlignmentEnum.Middle ); { blockComposer.ShowText("Generated by PDF Clown on " + creationDate); blockComposer.ShowBreak(); blockComposer.ShowText("For more info, visit http://www.pdfclown.org"); } blockComposer.End(); } composer.End(); } composer.End(); composer.Flush(); return(template); }
private void BuildSimpleTextPage( 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. Inserting contents... // Set the font to use! composer.SetFont( new fonts::StandardType1Font( document, fonts::StandardType1Font.FamilyEnum.Courier, true, false ), 32 ); XAlignmentEnum[] xAlignments = (XAlignmentEnum[])Enum.GetValues(typeof(XAlignmentEnum)); YAlignmentEnum[] yAlignments = (YAlignmentEnum[])Enum.GetValues(typeof(YAlignmentEnum)); int step = (int)(pageSize.Height) / ((xAlignments.Length - 1) * yAlignments.Length + 1); BlockComposer blockComposer = new BlockComposer(composer); RectangleF frame = new RectangleF( 30, 0, pageSize.Width - 60, step / 2 ); blockComposer.Begin(frame, XAlignmentEnum.Center, YAlignmentEnum.Middle); blockComposer.ShowText("Simple alignment"); blockComposer.End(); frame = new RectangleF( 30, pageSize.Height - step / 2, pageSize.Width - 60, step / 2 - 10 ); blockComposer.Begin(frame, XAlignmentEnum.Left, YAlignmentEnum.Bottom); composer.SetFont(composer.State.Font, 10); blockComposer.ShowText( "NOTE: showText(...) methods return the actual bounding box of the text shown.\n" + "NOTE: The rotation parameter can be freely defined as a floating point value." ); blockComposer.End(); composer.SetFont(composer.State.Font, 12); int x = 30; int y = step; int alignmentIndex = 0; foreach (XAlignmentEnum xAlignment in (XAlignmentEnum[])Enum.GetValues(typeof(XAlignmentEnum))) { /* * NOTE: As text shown through PrimitiveComposer has no bounding box constraining its extension, * applying the justified alignment has no effect (it degrades to center alignment); * in order to get such an effect, use BlockComposer instead. */ if (xAlignment.Equals(XAlignmentEnum.Justify)) { continue; } foreach (YAlignmentEnum yAlignment in (YAlignmentEnum[])Enum.GetValues(typeof(YAlignmentEnum))) { if (alignmentIndex % 2 == 0) { composer.BeginLocalState(); composer.SetFillColor(BackColor); composer.DrawRectangle( new RectangleF( 0, y - step / 2, pageSize.Width, step ) ); composer.Fill(); composer.End(); } composer.ShowText( xAlignment + " " + yAlignment + ":", new PointF(x, y), XAlignmentEnum.Left, YAlignmentEnum.Middle, 0 ); y += step; alignmentIndex++; } } float rotationStep = 0; float rotation = 0; for ( int columnIndex = 0; columnIndex < 2; columnIndex++ ) { switch (columnIndex) { case 0: x = 200; rotationStep = 0; break; case 1: x = (int)pageSize.Width / 2 + 100; rotationStep = 360 / ((xAlignments.Length - 1) * yAlignments.Length - 1); break; } y = step; rotation = 0; foreach (XAlignmentEnum xAlignment in (XAlignmentEnum[])Enum.GetValues(typeof(XAlignmentEnum))) { /* * NOTE: As text shown through PrimitiveComposer has no bounding box constraining its extension, * applying the justified alignment has no effect (it degrades to center alignment); * in order to get such an effect, use BlockComposer instead. */ if (xAlignment.Equals(XAlignmentEnum.Justify)) { continue; } foreach (YAlignmentEnum yAlignment in (YAlignmentEnum[])Enum.GetValues(typeof(YAlignmentEnum))) { float startArcAngle = 0; switch (xAlignment) { case XAlignmentEnum.Left: // OK -- NOOP. break; case XAlignmentEnum.Right: case XAlignmentEnum.Center: startArcAngle = 180; break; } composer.DrawArc( new RectangleF( x - 10, y - 10, 20, 20 ), startArcAngle, startArcAngle + rotation ); DrawText( composer, "PDF Clown", new PointF(x, y), xAlignment, yAlignment, rotation ); y += step; rotation += rotationStep; } } } // 4. Flush the contents into the page! composer.Flush(); }
/* * TODO: refresh should happen just before serialization, on document event (e.g. OnWrite()) */ private void RefreshAppearance( ) { FormXObject normalAppearance; RectangleF box = org.pdfclown.objects.Rectangle.Wrap(BaseDataObject[PdfName.Rect]).ToRectangleF(); { AppearanceStates normalAppearances = Appearance.Normal; normalAppearance = normalAppearances[null]; if (normalAppearance != null) { normalAppearance.Box = box; normalAppearance.BaseDataObject.Body.SetLength(0); } else { normalAppearances[null] = normalAppearance = new FormXObject(Document, box); } } PrimitiveComposer composer = new PrimitiveComposer(normalAppearance); { float yOffset = box.Height - Page.Box.Height; MarkupTypeEnum markupType = MarkupType; switch (markupType) { case MarkupTypeEnum.Highlight: { ExtGState defaultExtGState; { ExtGStateResources extGStates = normalAppearance.Resources.ExtGStates; defaultExtGState = extGStates[HighlightExtGStateName]; if (defaultExtGState == null) { if (extGStates.Count > 0) { extGStates.Clear(); } extGStates[HighlightExtGStateName] = defaultExtGState = new ExtGState(Document); defaultExtGState.AlphaShape = false; defaultExtGState.BlendMode = new List <BlendModeEnum>(new BlendModeEnum[] { BlendModeEnum.Multiply }); } } composer.ApplyState(defaultExtGState); composer.SetFillColor(Color); { foreach (Quad markupBox in MarkupBoxes) { PointF[] points = markupBox.Points; float markupBoxHeight = points[3].Y - points[0].Y; float markupBoxMargin = GetMarkupBoxMargin(markupBoxHeight); composer.DrawCurve( new PointF(points[3].X, points[3].Y + yOffset), new PointF(points[0].X, points[0].Y + yOffset), new PointF(points[3].X - markupBoxMargin, points[3].Y - markupBoxMargin + yOffset), new PointF(points[0].X - markupBoxMargin, points[0].Y + markupBoxMargin + yOffset) ); composer.DrawLine( new PointF(points[1].X, points[1].Y + yOffset) ); composer.DrawCurve( new PointF(points[2].X, points[2].Y + yOffset), new PointF(points[1].X + markupBoxMargin, points[1].Y + markupBoxMargin + yOffset), new PointF(points[2].X + markupBoxMargin, points[2].Y - markupBoxMargin + yOffset) ); composer.Fill(); } } } break; case MarkupTypeEnum.Squiggly: { composer.SetStrokeColor(Color); composer.SetLineCap(LineCapEnum.Round); composer.SetLineJoin(LineJoinEnum.Round); { foreach (Quad markupBox in MarkupBoxes) { PointF[] points = markupBox.Points; float markupBoxHeight = points[3].Y - points[0].Y; float lineWidth = markupBoxHeight * .05f; float step = markupBoxHeight * .125f; float boxXOffset = points[3].X; float boxYOffset = points[3].Y + yOffset - lineWidth; bool phase = false; composer.SetLineWidth(lineWidth); for (float x = 0, xEnd = points[2].X - boxXOffset; x < xEnd || !phase; x += step) { PointF point = new PointF(x + boxXOffset, (phase ? -step : 0) + boxYOffset); if (x == 0) { composer.StartPath(point); } else { composer.DrawLine(point); } phase = !phase; } } composer.Stroke(); } } break; case MarkupTypeEnum.StrikeOut: case MarkupTypeEnum.Underline: { composer.SetStrokeColor(Color); { float lineYRatio = 0; switch (markupType) { case MarkupTypeEnum.StrikeOut: lineYRatio = .5f; break; case MarkupTypeEnum.Underline: lineYRatio = .9f; break; default: throw new NotImplementedException(); } foreach (Quad markupBox in MarkupBoxes) { PointF[] points = markupBox.Points; float markupBoxHeight = points[3].Y - points[0].Y; float boxYOffset = markupBoxHeight * lineYRatio + yOffset; composer.SetLineWidth(markupBoxHeight * .065); composer.DrawLine( new PointF(points[3].X, points[0].Y + boxYOffset), new PointF(points[2].X, points[1].Y + boxYOffset) ); } composer.Stroke(); } } break; default: throw new NotImplementedException(); } } composer.Flush(); }
/* TODO: refresh should happen just before serialization, on document event (e.g. OnWrite()) */ private void RefreshAppearance( ) { FormXObject normalAppearance; RectangleF box = org.pdfclown.objects.Rectangle.Wrap(BaseDataObject[PdfName.Rect]).ToRectangleF(); { AppearanceStates normalAppearances = Appearance.Normal; normalAppearance = normalAppearances[null]; if(normalAppearance != null) { normalAppearance.Box = box; normalAppearance.BaseDataObject.Body.SetLength(0); } else {normalAppearances[null] = normalAppearance = new FormXObject(Document, box);} } PrimitiveComposer composer = new PrimitiveComposer(normalAppearance); { float yOffset = box.Height - Page.Box.Height; MarkupTypeEnum markupType = MarkupType; switch(markupType) { case MarkupTypeEnum.Highlight: { ExtGState defaultExtGState; { ExtGStateResources extGStates = normalAppearance.Resources.ExtGStates; defaultExtGState = extGStates[HighlightExtGStateName]; if(defaultExtGState == null) { if(extGStates.Count > 0) {extGStates.Clear();} extGStates[HighlightExtGStateName] = defaultExtGState = new ExtGState(Document); defaultExtGState.AlphaShape = false; defaultExtGState.BlendMode = new List<BlendModeEnum>(new BlendModeEnum[]{BlendModeEnum.Multiply}); } } composer.ApplyState(defaultExtGState); composer.SetFillColor(Color); { foreach(Quad markupBox in MarkupBoxes) { PointF[] points = markupBox.Points; float markupBoxHeight = points[3].Y - points[0].Y; float markupBoxMargin = GetMarkupBoxMargin(markupBoxHeight); composer.DrawCurve( new PointF(points[3].X, points[3].Y + yOffset), new PointF(points[0].X, points[0].Y + yOffset), new PointF(points[3].X - markupBoxMargin, points[3].Y - markupBoxMargin + yOffset), new PointF(points[0].X - markupBoxMargin, points[0].Y + markupBoxMargin + yOffset) ); composer.DrawLine( new PointF(points[1].X, points[1].Y + yOffset) ); composer.DrawCurve( new PointF(points[2].X, points[2].Y + yOffset), new PointF(points[1].X + markupBoxMargin, points[1].Y + markupBoxMargin + yOffset), new PointF(points[2].X + markupBoxMargin, points[2].Y - markupBoxMargin + yOffset) ); composer.Fill(); } } } break; case MarkupTypeEnum.Squiggly: { composer.SetStrokeColor(Color); composer.SetLineCap(LineCapEnum.Round); composer.SetLineJoin(LineJoinEnum.Round); { foreach(Quad markupBox in MarkupBoxes) { PointF[] points = markupBox.Points; float markupBoxHeight = points[3].Y - points[0].Y; float lineWidth = markupBoxHeight * .02f; float step = markupBoxHeight * .125f; float boxXOffset = points[3].X; float boxYOffset = points[3].Y + yOffset - lineWidth; bool phase = false; composer.SetLineWidth(lineWidth); for(float x = 0, xEnd = points[2].X - boxXOffset; x < xEnd || !phase; x += step) { PointF point = new PointF(x + boxXOffset, (phase ? -step : 0) + boxYOffset); if(x == 0) {composer.StartPath(point);} else {composer.DrawLine(point);} phase = !phase; } } composer.Stroke(); } } break; case MarkupTypeEnum.StrikeOut: case MarkupTypeEnum.Underline: { composer.SetStrokeColor(Color); { float lineYRatio = 0; switch(markupType) { case MarkupTypeEnum.StrikeOut: lineYRatio = .575f; break; case MarkupTypeEnum.Underline: lineYRatio = .85f; break; default: throw new NotImplementedException(); } foreach(Quad markupBox in MarkupBoxes) { PointF[] points = markupBox.Points; float markupBoxHeight = points[3].Y - points[0].Y; float boxYOffset = markupBoxHeight * lineYRatio + yOffset; composer.SetLineWidth(markupBoxHeight * .065); composer.DrawLine( new PointF(points[3].X, points[0].Y + boxYOffset), new PointF(points[2].X, points[1].Y + boxYOffset) ); } composer.Stroke(); } } break; default: throw new NotImplementedException(); } } composer.Flush(); }
public override ContentObject ToInlineObject( PrimitiveComposer composer ) { ContentObject barcodeObject = composer.BeginLocalState(); { fonts::Font font = new fonts::StandardType1Font( composer.Scanner.Contents.Document, fonts::StandardType1Font.FamilyEnum.Helvetica, false, false ); double fontSize = (DigitGlyphWidth / font.GetWidth(code.Substring(0,1), 1)); // 1. Bars. { double elementX = DigitWidth; int[] elementWidths = GetElementWidths(); double guardBarIndentY = DigitHeight / 2; bool isBar = true; for( int elementIndex = 0; elementIndex < elementWidths.Length; elementIndex++ ) { double elementWidth = elementWidths[elementIndex]; // Dark element? /* NOTE: EAN symbol elements alternate bars to spaces. */ if(isBar) { composer.DrawRectangle( new RectangleF( (float)elementX, 0, (float)elementWidth, (float)(BarHeight + ( // Guard bar? Array.BinarySearch<int>(GuardBarIndexes, elementIndex) >= 0 ? guardBarIndentY // Guard bar. : 0 // Symbol character. )) ) ); } elementX += elementWidth; isBar = !isBar; } composer.Fill(); } // 2. Digits. { composer.SetFont(font,fontSize); double digitY = BarHeight + (DigitHeight - (font.GetAscent(fontSize))) / 2; // Showing the digits... for( int digitIndex = 0; digitIndex < 13; digitIndex++ ) { string digit = code.Substring(digitIndex, 1); double pX = DigitGlyphXs[digitIndex] // Digit position. - font.GetWidth(digit,fontSize) / 2; // Centering. // Show the current digit! composer.ShowText( digit, new PointF((float)pX,(float)digitY) ); } } composer.End(); } return barcodeObject; }
private void BuildSimpleTextPage( 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. Inserting contents... // Set the font to use! composer.SetFont( new fonts::StandardType1Font( document, fonts::StandardType1Font.FamilyEnum.Courier, true, false ), 32 ); XAlignmentEnum[] xAlignments = (XAlignmentEnum[])Enum.GetValues(typeof(XAlignmentEnum)); YAlignmentEnum[] yAlignments = (YAlignmentEnum[])Enum.GetValues(typeof(YAlignmentEnum)); int step = (int)(pageSize.Height) / ((xAlignments.Length-1) * yAlignments.Length+1); BlockComposer blockComposer = new BlockComposer(composer); RectangleF frame = new RectangleF( 30, 0, pageSize.Width-60, step/2 ); blockComposer.Begin(frame,XAlignmentEnum.Center,YAlignmentEnum.Middle); blockComposer.ShowText("Simple alignment"); blockComposer.End(); frame = new RectangleF( 30, pageSize.Height-step/2, pageSize.Width-60, step/2 -10 ); blockComposer.Begin(frame,XAlignmentEnum.Left,YAlignmentEnum.Bottom); composer.SetFont(composer.State.Font,10); blockComposer.ShowText( "NOTE: showText(...) methods return the actual bounding box of the text shown.\n" + "NOTE: The rotation parameter can be freely defined as a floating point value." ); blockComposer.End(); composer.SetFont(composer.State.Font,12); int x = 30; int y = step; int alignmentIndex = 0; foreach(XAlignmentEnum xAlignment in (XAlignmentEnum[])Enum.GetValues(typeof(XAlignmentEnum))) { /* NOTE: As text shown through PrimitiveComposer has no bounding box constraining its extension, applying the justified alignment has no effect (it degrades to center alignment); in order to get such an effect, use BlockComposer instead. */ if(xAlignment.Equals(XAlignmentEnum.Justify)) continue; foreach(YAlignmentEnum yAlignment in (YAlignmentEnum[])Enum.GetValues(typeof(YAlignmentEnum))) { if(alignmentIndex % 2 == 0) { composer.BeginLocalState(); composer.SetFillColor(BackColor); composer.DrawRectangle( new RectangleF( 0, y-step/2, pageSize.Width, step ) ); composer.Fill(); composer.End(); } composer.ShowText( xAlignment + " " + yAlignment + ":", new PointF(x,y), XAlignmentEnum.Left, YAlignmentEnum.Middle, 0 ); y+=step; alignmentIndex++; } } float rotationStep = 0; float rotation = 0; for( int columnIndex = 0; columnIndex < 2; columnIndex++ ) { switch(columnIndex) { case 0: x = 200; rotationStep = 0; break; case 1: x = (int)pageSize.Width / 2 + 100; rotationStep = 360 / ((xAlignments.Length-1) * yAlignments.Length-1); break; } y = step; rotation = 0; foreach(XAlignmentEnum xAlignment in (XAlignmentEnum[])Enum.GetValues(typeof(XAlignmentEnum))) { /* NOTE: As text shown through PrimitiveComposer has no bounding box constraining its extension, applying the justified alignment has no effect (it degrades to center alignment); in order to get such an effect, use BlockComposer instead. */ if(xAlignment.Equals(XAlignmentEnum.Justify)) continue; foreach(YAlignmentEnum yAlignment in (YAlignmentEnum[])Enum.GetValues(typeof(YAlignmentEnum))) { float startArcAngle = 0; switch(xAlignment) { case XAlignmentEnum.Left: // OK -- NOOP. break; case XAlignmentEnum.Right: case XAlignmentEnum.Center: startArcAngle = 180; break; } composer.DrawArc( new RectangleF( x-10, y-10, 20, 20 ), startArcAngle, startArcAngle+rotation ); DrawText( composer, "PDF Clown", new PointF(x,y), xAlignment, yAlignment, rotation ); y+=step; rotation+=rotationStep; } } } // 4. Flush the contents into the page! composer.Flush(); }
private FormXObject BuildTemplate( Document document, DateTime creationDate ) { // Create a template (form)! FormXObject template = new FormXObject(document, document.PageSize.Value); SizeF templateSize = template.Size; // Get form content stream! PrimitiveComposer composer = new PrimitiveComposer(template); // Showing the header image inside the common content stream... // Instantiate a jpeg image object! entities::Image image = entities::Image.Get(GetResourcePath("images" + Path.DirectorySeparatorChar + "mountains.jpg")); // Abstract image (entity). // Show the image inside the common content stream! composer.ShowXObject( image.ToXObject(document), new PointF(0,0), new SizeF(templateSize.Width - 50, 125) ); // Showing the 'PDFClown' label inside the common content stream... composer.BeginLocalState(); composer.SetFillColor(new colorSpaces::DeviceRGBColor(115f / 255, 164f / 255, 232f / 255)); // Set the font to use! composer.SetFont( new fonts::StandardType1Font( document, fonts::StandardType1Font.FamilyEnum.Times, true, false ), 120 ); // Show the text! composer.ShowText( "PDFClown", new PointF( 0, templateSize.Height - (float)composer.State.Font.GetAscent(composer.State.FontSize) ) ); // Drawing the side rectangle... composer.DrawRectangle( new RectangleF( (float)templateSize.Width - 50, 0, 50, (float)templateSize.Height ) ); composer.Fill(); composer.End(); // Showing the side text inside the common content stream... composer.BeginLocalState(); { composer.SetFont( new fonts::StandardType1Font( document, fonts::StandardType1Font.FamilyEnum.Helvetica, false, false ), 8 ); composer.SetFillColor(colorSpaces::DeviceRGBColor.White); composer.BeginLocalState(); { composer.Rotate( 90, new PointF( templateSize.Width - 50, templateSize.Height - 25 ) ); BlockComposer blockComposer = new BlockComposer(composer); blockComposer.Begin( new RectangleF(0,0,300,50), XAlignmentEnum.Left, YAlignmentEnum.Middle ); { blockComposer.ShowText("Generated by PDF Clown on " + creationDate); blockComposer.ShowBreak(); blockComposer.ShowText("For more info, visit http://www.pdfclown.org"); } blockComposer.End(); } composer.End(); } composer.End(); composer.Flush(); return template; }