public override void SetTransformation(double translateX, double translateY, double rotate, double scaleX, double scaleY) { translateX *= MmToPt; translateY *= MmToPt; _canvas.RestoreState(); _lastStrokingColor = 0; _lastNonStrokingColor = 0; _lastLineWidth = 1; _lastFont = null; _lastFontSize = 0; _canvas.SaveState(); AffineTransform matrix = new AffineTransform(); matrix.Translate(translateX, translateY); if (rotate != 0) { matrix.Rotate(rotate); } if (scaleX != 1 || scaleY != 1) { matrix.Scale(scaleX, scaleY); } _canvas.ConcatMatrix(matrix); }
private AffineTransform GetGradientTransformToUserSpaceOnUse(Rectangle objectBoundingBox, bool isObjectBoundingBox ) { AffineTransform gradientTransform = new AffineTransform(); if (isObjectBoundingBox) { gradientTransform.Translate(objectBoundingBox.GetX(), objectBoundingBox.GetY()); // We need to scale with dividing the lengths by 0.75 as further we should // concatenate gradient transformation matrix which has no absolute parsing. // For example, if gradientTransform is set to translate(1, 1) and gradientUnits // is set to "objectBoundingBox" then the gradient should be shifted horizontally // and vertically exactly by the size of the element bounding box. So, again, // as we parse translate(1, 1) to translation(0.75, 0.75) the bounding box in // the gradient vector space should be 0.75x0.75 in order for such translation // to shift by the complete size of bounding box. gradientTransform.Scale(objectBoundingBox.GetWidth() / 0.75, objectBoundingBox.GetHeight() / 0.75); } AffineTransform svgGradientTransformation = GetGradientTransform(); if (svgGradientTransformation != null) { gradientTransform.Concatenate(svgGradientTransformation); } return(gradientTransform); }
private static AffineTransform CreateGradientTransform(Rectangle2D r) { double cx = r.CenterX; double cy = r.CenterY; AffineTransform xform = AffineTransform.GetTranslateInstance(cx, cy); xform.Scale(r.Width / 2, r.Height / 2); xform.Translate(-cx, -cy); return(xform); }
// --------------------------------------------------------------------------- /** * Creates a PDF document. */ public byte[] CreatePdf() { // step 1 Rectangle rect = new Rectangle(-595, -842, 595, 842); using (MemoryStream ms = new MemoryStream()) { using (Document document = new Document(rect)) { // step 2 PdfWriter writer = PdfWriter.GetInstance(document, ms); // step 3 document.Open(); // step 4 PdfContentByte canvas = writer.DirectContent; // draw coordinate system canvas.MoveTo(-595, 0); canvas.LineTo(595, 0); canvas.MoveTo(0, -842); canvas.LineTo(0, 842); canvas.Stroke(); // read the PDF with the logo PdfReader reader = new PdfReader(RESOURCE); PdfTemplate template = writer.GetImportedPage(reader, 1); // add it canvas.SaveState(); canvas.AddTemplate(template, 0, 0); AffineTransform af = new AffineTransform(); af.Translate(-595, 0); af.Scale(0.5f, 0.5f); canvas.Transform(af); canvas.AddTemplate(template, 0, 0); canvas.ConcatCTM(AffineTransform.GetTranslateInstance(595, 595)); canvas.AddTemplate(template, 0, 0); canvas.RestoreState(); canvas.SaveState(); af = new AffineTransform(1f, 0f, 0.4f, 1f, -750f, -650f); canvas.AddTemplate(template, af); canvas.RestoreState(); canvas.SaveState(); af = new AffineTransform(0, -1, -1, 0, 650, 0); canvas.AddTemplate(template, af); af = new AffineTransform(0, -0.2f, -0.5f, 0, 350, 0); canvas.AddTemplate(template, af); canvas.RestoreState(); } return(ms.ToArray()); } }
public virtual void BuilderWithNoneSpreadingAndCanvasTransformTest() { AbstractLinearGradientBuilder gradientBuilder = new StrategyBasedLinearGradientBuilder().SetGradientDirectionAsStrategy (StrategyBasedLinearGradientBuilder.GradientStrategy.TO_RIGHT).SetSpreadMethod(GradientSpreadMethod.NONE ).AddColorStop(new GradientColorStop(ColorConstants.RED.GetColorValue(), 0d, GradientColorStop.OffsetType .RELATIVE)).AddColorStop(new GradientColorStop(ColorConstants.GREEN.GetColorValue(), 0.5, GradientColorStop.OffsetType .RELATIVE)).AddColorStop(new GradientColorStop(ColorConstants.BLUE.GetColorValue(), 1d, GradientColorStop.OffsetType .RELATIVE)); AffineTransform canvasTransform = AffineTransform.GetTranslateInstance(50, -50); canvasTransform.Scale(0.8, 1.1); canvasTransform.Rotate(Math.PI / 3, 400f, 550f); GenerateAndComparePdfs("builderWithNoneSpreadingAndCanvasTransformTest.pdf", canvasTransform, gradientBuilder ); }
private void AddLinearGradientITextAPIApproach(PdfDocument pdfDoc) { AbstractLinearGradientBuilder gradientBuilder = new StrategyBasedLinearGradientBuilder() .SetGradientDirectionAsStrategy(StrategyBasedLinearGradientBuilder.GradientStrategy.TO_TOP_RIGHT) .SetSpreadMethod(GradientSpreadMethod.PAD) .AddColorStop(new GradientColorStop(ColorConstants.CYAN.GetColorValue())) .AddColorStop(new GradientColorStop(ColorConstants.GREEN.GetColorValue())) .AddColorStop(new GradientColorStop(new float[] { 1f, 0f, 0f }, 0.5f, GradientColorStop.OffsetType.RELATIVE)); AffineTransform canvasTransform = AffineTransform.GetTranslateInstance(50, -50); canvasTransform.Scale(0.8, 1.1); canvasTransform.Rotate(Math.PI / 3, 400f, 550f); Rectangle rectangleToDraw = new Rectangle(50f, 450f, 500f, 300f); GeneratePdf(pdfDoc, canvasTransform, gradientBuilder, rectangleToDraw); }
/// <summary>Evaluates the minimal domain that covers the box with vector normals.</summary> /// <remarks> /// Evaluates the minimal domain that covers the box with vector normals. /// The domain corresponding to the initial vector is [0, 1]. /// </remarks> /// <param name="coords"> /// the array of exactly two elements that describe /// the base vector (corresponding to [0,1] domain, that need to be adjusted /// to cover the box /// </param> /// <param name="toCover">the box that needs to be covered</param> /// <returns> /// the array of two elements in ascending order specifying the calculated covering /// domain /// </returns> protected internal static double[] EvaluateCoveringDomain(Point[] coords, Rectangle toCover) { if (toCover == null) { return(new double[] { 0d, 1d }); } AffineTransform transform = new AffineTransform(); double scale = 1d / (coords[0].Distance(coords[1])); double sin = -(coords[1].GetY() - coords[0].GetY()) * scale; double cos = (coords[1].GetX() - coords[0].GetX()) * scale; if (Math.Abs(cos) < ZERO_EPSILON) { cos = 0d; sin = sin > 0d ? 1d : -1d; } else { if (Math.Abs(sin) < ZERO_EPSILON) { sin = 0d; cos = cos > 0d ? 1d : -1d; } } transform.Concatenate(new AffineTransform(cos, sin, -sin, cos, 0, 0)); transform.Scale(scale, scale); transform.Translate(-coords[0].GetX(), -coords[0].GetY()); Point[] rectanglePoints = toCover.ToPointsArray(); double minX = transform.Transform(rectanglePoints[0], null).GetX(); double maxX = minX; for (int i = 1; i < rectanglePoints.Length; ++i) { double currentX = transform.Transform(rectanglePoints[i], null).GetX(); minX = Math.Min(minX, currentX); maxX = Math.Max(maxX, currentX); } return(new double[] { minX, maxX }); }
public override LayoutResult Layout(LayoutContext layoutContext) { LayoutArea area = layoutContext.GetArea().Clone(); Rectangle layoutBox = area.GetBBox(); ApplyMargins(layoutBox, false); occupiedArea = new LayoutArea(area.GetPageNumber(), new Rectangle(layoutBox.GetX(), layoutBox.GetY() + layoutBox .GetHeight(), 0, 0)); width = RetrieveWidth(layoutBox.GetWidth()); float? angle = this.GetPropertyAsFloat(Property.ROTATION_ANGLE); PdfXObject xObject = ((Image)(GetModelElement())).GetXObject(); imageWidth = xObject.GetWidth(); imageHeight = xObject.GetHeight(); width = width == null ? imageWidth : width; height = (float)width / imageWidth * imageHeight; fixedXPosition = this.GetPropertyAsFloat(Property.X); fixedYPosition = this.GetPropertyAsFloat(Property.Y); float? horizontalScaling = this.GetPropertyAsFloat(Property.HORIZONTAL_SCALING, 1f); float? verticalScaling = this.GetPropertyAsFloat(Property.VERTICAL_SCALING, 1f); AffineTransform t = new AffineTransform(); if (xObject is PdfFormXObject && width != imageWidth) { horizontalScaling *= width / imageWidth; verticalScaling *= height / imageHeight; } if (horizontalScaling != 1) { if (xObject is PdfFormXObject) { t.Scale((float)horizontalScaling, 1); } width *= (float)horizontalScaling; } if (verticalScaling != 1) { if (xObject is PdfFormXObject) { t.Scale(1, (float)verticalScaling); } height *= (float)verticalScaling; } float imageItselfScaledWidth = (float)width; float imageItselfScaledHeight = (float)height; // See in adjustPositionAfterRotation why angle = 0 is necessary if (null == angle) { angle = 0f; } t.Rotate((float)angle); float scaleCoef = AdjustPositionAfterRotation((float)angle, layoutBox.GetWidth(), layoutBox.GetHeight()); imageItselfScaledHeight *= scaleCoef; imageItselfScaledWidth *= scaleCoef; if (xObject is PdfFormXObject) { t.Scale(scaleCoef, scaleCoef); } GetMatrix(t, imageItselfScaledWidth, imageItselfScaledHeight); // indicates whether the placement is forced bool isPlacingForced = false; if (width > layoutBox.GetWidth() || height > layoutBox.GetHeight()) { if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT))) { isPlacingForced = true; } else { return(new LayoutResult(LayoutResult.NOTHING, occupiedArea, null, this, this)); } } occupiedArea.GetBBox().MoveDown(height); occupiedArea.GetBBox().SetHeight(height); occupiedArea.GetBBox().SetWidth((float)width); float leftMargin = (float)this.GetPropertyAsFloat(Property.MARGIN_LEFT); float topMargin = (float)this.GetPropertyAsFloat(Property.MARGIN_TOP); if (leftMargin != 0 || topMargin != 0) { TranslateImage(leftMargin, topMargin, t); GetMatrix(t, imageItselfScaledWidth, imageItselfScaledHeight); } ApplyMargins(occupiedArea.GetBBox(), true); return(new LayoutResult(LayoutResult.FULL, occupiedArea, null, null, isPlacingForced ? this : null)); }
public override LayoutResult Layout(LayoutContext layoutContext) { LayoutArea area = layoutContext.GetArea().Clone(); Rectangle layoutBox = area.GetBBox().Clone(); AffineTransform t = new AffineTransform(); Image modelElement = (Image)(GetModelElement()); PdfXObject xObject = modelElement.GetXObject(); imageWidth = modelElement.GetImageWidth(); imageHeight = modelElement.GetImageHeight(); CalculateImageDimensions(layoutBox, t, xObject); OverflowPropertyValue?overflowX = null != parent?parent.GetProperty <OverflowPropertyValue?>(Property.OVERFLOW_X ) : OverflowPropertyValue.FIT; bool nowrap = false; if (parent is LineRenderer) { nowrap = true.Equals(this.parent.GetOwnProperty <bool?>(Property.NO_SOFT_WRAP_INLINE)); } IList <Rectangle> floatRendererAreas = layoutContext.GetFloatRendererAreas(); float clearHeightCorrection = FloatingHelper.CalculateClearHeightCorrection(this, floatRendererAreas, layoutBox ); FloatPropertyValue?floatPropertyValue = this.GetProperty <FloatPropertyValue?>(Property.FLOAT); if (FloatingHelper.IsRendererFloating(this, floatPropertyValue)) { layoutBox.DecreaseHeight(clearHeightCorrection); FloatingHelper.AdjustFloatedBlockLayoutBox(this, layoutBox, width, floatRendererAreas, floatPropertyValue, overflowX); } else { clearHeightCorrection = FloatingHelper.AdjustLayoutBoxAccordingToFloats(floatRendererAreas, layoutBox, width , clearHeightCorrection, null); } ApplyMargins(layoutBox, false); Border[] borders = GetBorders(); ApplyBorderBox(layoutBox, borders, false); float?declaredMaxHeight = RetrieveMaxHeight(); OverflowPropertyValue?overflowY = null == parent || ((null == declaredMaxHeight || declaredMaxHeight > layoutBox .GetHeight()) && !layoutContext.IsClippedHeight()) ? OverflowPropertyValue.FIT : parent.GetProperty <OverflowPropertyValue? >(Property.OVERFLOW_Y); bool processOverflowX = !IsOverflowFit(overflowX) || nowrap; bool processOverflowY = !IsOverflowFit(overflowY); if (IsAbsolutePosition()) { ApplyAbsolutePosition(layoutBox); } occupiedArea = new LayoutArea(area.GetPageNumber(), new Rectangle(layoutBox.GetX(), layoutBox.GetY() + layoutBox .GetHeight(), 0, 0)); float imageItselfScaledWidth = (float)width; float imageItselfScaledHeight = (float)height; if (IsFixedLayout()) { fixedXPosition = this.GetPropertyAsFloat(Property.LEFT); fixedYPosition = this.GetPropertyAsFloat(Property.BOTTOM); } float?angle = this.GetPropertyAsFloat(Property.ROTATION_ANGLE); // See in adjustPositionAfterRotation why angle = 0 is necessary if (null == angle) { angle = 0f; } t.Rotate((float)angle); initialOccupiedAreaBBox = GetOccupiedAreaBBox().Clone(); float scaleCoef = AdjustPositionAfterRotation((float)angle, layoutBox.GetWidth(), layoutBox.GetHeight()); imageItselfScaledHeight *= scaleCoef; imageItselfScaledWidth *= scaleCoef; initialOccupiedAreaBBox.MoveDown(imageItselfScaledHeight); initialOccupiedAreaBBox.SetHeight(imageItselfScaledHeight); initialOccupiedAreaBBox.SetWidth(imageItselfScaledWidth); if (xObject is PdfFormXObject) { t.Scale(scaleCoef, scaleCoef); } GetMatrix(t, imageItselfScaledWidth, imageItselfScaledHeight); // indicates whether the placement is forced bool isPlacingForced = false; if (width > layoutBox.GetWidth() || height > layoutBox.GetHeight()) { if (true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT)) || (width > layoutBox.GetWidth() && processOverflowX ) || (height > layoutBox.GetHeight() && processOverflowY)) { isPlacingForced = true; } else { ApplyMargins(initialOccupiedAreaBBox, true); ApplyBorderBox(initialOccupiedAreaBBox, true); occupiedArea.GetBBox().SetHeight(initialOccupiedAreaBBox.GetHeight()); return(new MinMaxWidthLayoutResult(LayoutResult.NOTHING, occupiedArea, null, this, this)); } } occupiedArea.GetBBox().MoveDown((float)height); if (borders[3] != null) { height += (float)Math.Sin((float)angle) * borders[3].GetWidth(); } occupiedArea.GetBBox().SetHeight((float)height); occupiedArea.GetBBox().SetWidth((float)width); UnitValue leftMargin = this.GetPropertyAsUnitValue(Property.MARGIN_LEFT); if (!leftMargin.IsPointValue()) { ILog logger = LogManager.GetLogger(typeof(iText.Layout.Renderer.ImageRenderer)); logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.PROPERTY_IN_PERCENTS_NOT_SUPPORTED, Property .MARGIN_LEFT)); } UnitValue topMargin = this.GetPropertyAsUnitValue(Property.MARGIN_TOP); if (!topMargin.IsPointValue()) { ILog logger = LogManager.GetLogger(typeof(iText.Layout.Renderer.ImageRenderer)); logger.Error(MessageFormatUtil.Format(iText.IO.LogMessageConstant.PROPERTY_IN_PERCENTS_NOT_SUPPORTED, Property .MARGIN_TOP)); } if (0 != leftMargin.GetValue() || 0 != topMargin.GetValue()) { TranslateImage(leftMargin.GetValue(), topMargin.GetValue(), t); GetMatrix(t, imageItselfScaledWidth, imageItselfScaledHeight); } ApplyBorderBox(occupiedArea.GetBBox(), borders, true); ApplyMargins(occupiedArea.GetBBox(), true); if (angle != 0) { ApplyRotationLayout((float)angle); } float unscaledWidth = occupiedArea.GetBBox().GetWidth() / scaleCoef; MinMaxWidth minMaxWidth = new MinMaxWidth(unscaledWidth, unscaledWidth, 0); UnitValue rendererWidth = this.GetProperty <UnitValue>(Property.WIDTH); if (rendererWidth != null && rendererWidth.IsPercentValue()) { minMaxWidth.SetChildrenMinWidth(0); float coeff = imageWidth / (float)RetrieveWidth(area.GetBBox().GetWidth()); minMaxWidth.SetChildrenMaxWidth(unscaledWidth * coeff); } else { bool autoScale = HasProperty(Property.AUTO_SCALE) && (bool)this.GetProperty <bool?>(Property.AUTO_SCALE); bool autoScaleWidth = HasProperty(Property.AUTO_SCALE_WIDTH) && (bool)this.GetProperty <bool?>(Property.AUTO_SCALE_WIDTH ); if (autoScale || autoScaleWidth) { minMaxWidth.SetChildrenMinWidth(0); } } FloatingHelper.RemoveFloatsAboveRendererBottom(floatRendererAreas, this); LayoutArea editedArea = FloatingHelper.AdjustResultOccupiedAreaForFloatAndClear(this, floatRendererAreas, layoutContext.GetArea().GetBBox(), clearHeightCorrection, false); ApplyAbsolutePositionIfNeeded(layoutContext); return(new MinMaxWidthLayoutResult(LayoutResult.FULL, editedArea, null, null, isPlacingForced ? this : null ).SetMinMaxWidth(minMaxWidth)); }
private void CalculateImageDimensions(Rectangle layoutBox, AffineTransform t, PdfXObject xObject) { width = this.GetProperty <UnitValue>(Property.WIDTH) != null?RetrieveWidth(layoutBox.GetWidth()) : null; float?declaredHeight = RetrieveHeight(); height = declaredHeight; if (width == null && height == null) { width = imageWidth; height = (float)width / imageWidth * imageHeight; } else { if (width == null) { width = (float)height / imageHeight * imageWidth; } else { if (height == null) { height = (float)width / imageWidth * imageHeight; } } } float?horizontalScaling = this.GetPropertyAsFloat(Property.HORIZONTAL_SCALING, 1f); float?verticalScaling = this.GetPropertyAsFloat(Property.VERTICAL_SCALING, 1f); if (xObject is PdfFormXObject && width != imageWidth) { horizontalScaling *= width / imageWidth; verticalScaling *= height / imageHeight; } if (horizontalScaling != 1) { if (xObject is PdfFormXObject) { t.Scale((float)horizontalScaling, 1); width = imageWidth * (float)horizontalScaling; } else { width *= (float)horizontalScaling; } } if (verticalScaling != 1) { if (xObject is PdfFormXObject) { t.Scale(1, (float)verticalScaling); height = imageHeight * (float)verticalScaling; } else { height *= (float)verticalScaling; } } // Constrain width and height according to min/max width float?minWidth = RetrieveMinWidth(layoutBox.GetWidth()); float?maxWidth = RetrieveMaxWidth(layoutBox.GetWidth()); if (null != minWidth && width < minWidth) { height *= minWidth / width; width = minWidth; } else { if (null != maxWidth && width > maxWidth) { height *= maxWidth / width; width = maxWidth; } } // Constrain width and height according to min/max height, which has precedence over width settings float?minHeight = RetrieveMinHeight(); float?maxHeight = RetrieveMaxHeight(); if (null != minHeight && height < minHeight) { width *= minHeight / height; height = minHeight; } else { if (null != maxHeight && height > maxHeight) { width *= maxHeight / height; this.height = maxHeight; } else { if (null != declaredHeight && !height.Equals(declaredHeight)) { width *= declaredHeight / height; height = declaredHeight; } } } }
/// <summary> /// 每页两张发票 /// </summary> /// <param name="files"></param> /// <param name="outputFile"></param> public static void Merge4(IEnumerable <string> files, string outputFile) { var queue = new ConcurrentQueue <string>(files); var document = new Document(); var margin = 20; try { var writer = PdfWriter.GetInstance(document, new FileStream(outputFile, FileMode.Create)); var size = PageSize.A4.Rotate(); document.Open(); document.SetPageSize(size); PdfContentByte cb = writer.DirectContent; do { document.NewPage(); for (int i = 0; i < 4; i++) { if (TryAppendPage(i) == false) { break; } } } while (queue.Count > 0); bool TryAppendPage(int type) { if (queue.TryDequeue(out var p) == false) { return(false); } var reader = new PdfReader(p); var page = writer.GetImportedPage(reader, 1); AffineTransform af = new AffineTransform(); var scaleHeight = (size.Height - margin * 4) / 2 / page.Height; var scaleWidth = (size.Width - margin * 4) / 2 / page.Width; var scale = Math.Min(scaleHeight, scaleWidth); var height = ((size.Height - margin * 4) / 2 - scale * page.Height) / 2; var width = ((size.Width - margin * 4) / 2 - scale * page.Width) / 2; switch (type) { case 2: default: af.Translate(margin + width, margin + height); break; case 3: af.Translate(margin + width + size.Width / 2, margin + height); break; case 0: af.Translate(margin + width, margin + height + size.Height / 2); break; case 1: af.Translate(margin + width + size.Width / 2, margin + height + size.Height / 2); break; } af.Scale(scale, scale); cb.AddTemplate(page, af); return(true); } } catch (Exception e) { throw e; } finally { document.Close(); } }