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