diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/OpacityTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/OpacityTest.cs index 6f3b5a043..a3c9f6c51 100644 --- a/itext.tests/itext.svg.tests/itext/svg/renderers/OpacityTest.cs +++ b/itext.tests/itext.svg.tests/itext/svg/renderers/OpacityTest.cs @@ -60,16 +60,14 @@ public virtual void TestRGBA() { [NUnit.Framework.Test] public virtual void TestFillOpacityWithComma() { - //TODO DEVSIX-2678 + //TODO DEVSIX-2678 SVG: Displaying invalid value of fill-opacity incorrectly NUnit.Framework.Assert.Catch(typeof(FormatException), () => ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER , "testFillOpacityWithComma")); } [NUnit.Framework.Test] public virtual void TestFillOpacityWithPercents() { - //TODO DEVSIX-2678 - NUnit.Framework.Assert.Catch(typeof(FormatException), () => ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER - , "testFillOpacityWithPercents")); + ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testFillOpacityWithPercents"); } [NUnit.Framework.Test] @@ -87,9 +85,7 @@ public virtual void TestStrokeOpacityWithComma() { [NUnit.Framework.Test] public virtual void TestStrokeOpacityWithPercents() { - //TODO DEVSIX-2679 - NUnit.Framework.Assert.Catch(typeof(FormatException), () => ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER - , "testStrokeOpacityWithPercents")); + ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "testStrokeOpacityWithPercents"); } [NUnit.Framework.Test] diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/StrokeTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/StrokeTest.cs index dfa19d2b9..402ae7c66 100644 --- a/itext.tests/itext.svg.tests/itext/svg/renderers/StrokeTest.cs +++ b/itext.tests/itext.svg.tests/itext/svg/renderers/StrokeTest.cs @@ -131,19 +131,19 @@ public virtual void StrokeObjectsOverlap1Test() { [NUnit.Framework.Test] public virtual void StrokeObjectsOverlap2Test() { - //TODO DEVSIX-7338: Update cmp file + //TODO DEVSIX-7338: SVG stroke on group applied incorrectly ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "strokeOnGroup2"); } [NUnit.Framework.Test] public virtual void StrokeObjectsOverlap3Test() { - //TODO DEVSIX-7338: Update cmp file + //TODO DEVSIX-7338: SVG stroke on group applied incorrectly ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "strokeOnGroupNoInsideStroke"); } [NUnit.Framework.Test] public virtual void StrokeObjectsOverlap4Test() { - //TODO DEVSIX-7338: Update cmp file + //TODO DEVSIX-7338: SVG stroke on group applied incorrectly ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "strokeOnGroupNoInsideStroke2"); } diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/SvgImageRendererTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/SvgImageRendererTest.cs index f7708bca1..d76111228 100644 --- a/itext.tests/itext.svg.tests/itext/svg/renderers/SvgImageRendererTest.cs +++ b/itext.tests/itext.svg.tests/itext/svg/renderers/SvgImageRendererTest.cs @@ -201,7 +201,7 @@ public virtual void RelativeSizedSvg4Test() { } [NUnit.Framework.Test] - public virtual void RelativeSizedSvg5Test() { + public virtual void RelativeSizedSvgInImgTest() { String svgName = "viewbox_percent_height_percent_width_prRatio_none"; String svgFileName = SOURCE_FOLDER + svgName + ".svg"; String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + ".pdf"; @@ -226,5 +226,288 @@ public virtual void RelativeSizedSvg5Test() { NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER , "diff")); } + + [NUnit.Framework.Test] + public virtual void RelativeSizedSvgInImg2Test() { + String svgName = "viewbox_percent_height_percent_width_prRatio_none"; + String svgFileName = SOURCE_FOLDER + svgName + ".svg"; + String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + "_img" + ".pdf"; + String outFileName = DESTINATION_FOLDER + svgName + "_img" + ".pdf"; + using (Document document = new Document(new PdfDocument(new PdfWriter(outFileName, new WriterProperties(). + SetCompressionLevel(0))))) { + INode parsedSvg = SvgConverter.Parse(FileUtil.GetInputStreamForFile(svgFileName)); + ISvgProcessorResult result = new DefaultSvgProcessor().Process(parsedSvg, new SvgConverterProperties().SetBaseUri + (svgFileName)); + SvgDrawContext svgDrawContext = new SvgDrawContext(new ResourceResolver(SOURCE_FOLDER), null); + SvgImageXObject svgImageXObject = new SvgImageXObject(result, svgDrawContext, 12, document.GetPdfDocument( + )); + svgImageXObject.SetIsCreatedByImg(true); + Div div = new Div().SetWidth(400).SetHeight(300); + SvgImage svgImage = new SvgImage(svgImageXObject); + svgImage.SetWidth(UnitValue.CreatePointValue(300)); + svgImage.SetHeight(UnitValue.CreatePointValue(200)); + div.Add(svgImage); + document.Add(div); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER + , "diff")); + } + + [NUnit.Framework.Test] + public virtual void RelativeSizedSvgInImg3Test() { + String svgName = "viewbox_percent_height_percent_width_prRatio_max_max"; + String svgFileName = SOURCE_FOLDER + svgName + ".svg"; + String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + "_img" + ".pdf"; + String outFileName = DESTINATION_FOLDER + svgName + "_img" + ".pdf"; + using (Document document = new Document(new PdfDocument(new PdfWriter(outFileName, new WriterProperties(). + SetCompressionLevel(0))))) { + INode parsedSvg = SvgConverter.Parse(FileUtil.GetInputStreamForFile(svgFileName)); + ISvgProcessorResult result = new DefaultSvgProcessor().Process(parsedSvg, new SvgConverterProperties().SetBaseUri + (svgFileName)); + SvgDrawContext svgDrawContext = new SvgDrawContext(new ResourceResolver(SOURCE_FOLDER), null); + SvgImageXObject svgImageXObject = new SvgImageXObject(result, svgDrawContext, 12, document.GetPdfDocument( + )); + svgImageXObject.SetIsCreatedByImg(true); + Div div = new Div().SetWidth(300).SetHeight(300); + SvgImage svgImage = new SvgImage(svgImageXObject); + svgImage.SetWidth(UnitValue.CreatePointValue(200)); + svgImage.SetHeight(UnitValue.CreatePointValue(100)); + div.Add(svgImage); + document.Add(div); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER + , "diff")); + } + + [NUnit.Framework.Test] + public virtual void RelativeSizedSvgInImg4Test() { + String svgName = "viewbox_fixed_height_percent_width_no_viewbox"; + String svgFileName = SOURCE_FOLDER + svgName + ".svg"; + String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + "_img" + ".pdf"; + String outFileName = DESTINATION_FOLDER + svgName + "_img" + ".pdf"; + using (Document document = new Document(new PdfDocument(new PdfWriter(outFileName, new WriterProperties(). + SetCompressionLevel(0))))) { + INode parsedSvg = SvgConverter.Parse(FileUtil.GetInputStreamForFile(svgFileName)); + ISvgProcessorResult result = new DefaultSvgProcessor().Process(parsedSvg, new SvgConverterProperties().SetBaseUri + (svgFileName)); + SvgDrawContext svgDrawContext = new SvgDrawContext(new ResourceResolver(SOURCE_FOLDER), null); + SvgImageXObject svgImageXObject = new SvgImageXObject(result, svgDrawContext, 12, document.GetPdfDocument( + )); + svgImageXObject.SetIsCreatedByImg(true); + SvgImage svgImage = new SvgImage(svgImageXObject); + svgImage.SetWidth(100); + svgImage.SetHeight(300); + document.Add(svgImage); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER + , "diff")); + } + + [NUnit.Framework.Test] + public virtual void RelativeSizedSvgInImg5Test() { + String svgName = "fixed_height_and_width"; + String svgFileName = SOURCE_FOLDER + svgName + ".svg"; + String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + "_img" + ".pdf"; + String outFileName = DESTINATION_FOLDER + svgName + "_img" + ".pdf"; + using (Document document = new Document(new PdfDocument(new PdfWriter(outFileName, new WriterProperties(). + SetCompressionLevel(0))))) { + INode parsedSvg = SvgConverter.Parse(FileUtil.GetInputStreamForFile(svgFileName)); + ISvgProcessorResult result = new DefaultSvgProcessor().Process(parsedSvg, new SvgConverterProperties().SetBaseUri + (svgFileName)); + SvgDrawContext svgDrawContext = new SvgDrawContext(new ResourceResolver(SOURCE_FOLDER), null); + SvgImageXObject svgImageXObject = new SvgImageXObject(result, svgDrawContext, 12, document.GetPdfDocument( + )); + svgImageXObject.SetIsCreatedByImg(true); + SvgImage svgImage = new SvgImage(svgImageXObject); + document.Add(svgImage); + NUnit.Framework.Assert.IsTrue(svgImageXObject.IsRelativeSized()); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER + , "diff")); + } + + [NUnit.Framework.Test] + public virtual void RelativeSizedSvgInImg6Test() { + String svgName = "relativeSizedSvg"; + String svgFileName = SOURCE_FOLDER + svgName + ".svg"; + String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + "_img" + ".pdf"; + String outFileName = DESTINATION_FOLDER + svgName + "_img" + ".pdf"; + using (Document document = new Document(new PdfDocument(new PdfWriter(outFileName, new WriterProperties(). + SetCompressionLevel(0))))) { + INode parsedSvg = SvgConverter.Parse(FileUtil.GetInputStreamForFile(svgFileName)); + ISvgProcessorResult result = new DefaultSvgProcessor().Process(parsedSvg, new SvgConverterProperties().SetBaseUri + (svgFileName)); + SvgDrawContext svgDrawContext = new SvgDrawContext(new ResourceResolver(SOURCE_FOLDER), null); + SvgImageXObject svgImageXObject = new SvgImageXObject(result, svgDrawContext, 12, document.GetPdfDocument( + )); + svgImageXObject.SetIsCreatedByImg(true); + SvgImage svgImage = new SvgImage(svgImageXObject); + svgImage.SetWidth(100.0F); + document.Add(svgImage); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER + , "diff")); + } + + [NUnit.Framework.Test] + public virtual void RelativeSizedSvgInImg7Test() { + String svgName = "relativeSizedSvg"; + String svgFileName = SOURCE_FOLDER + svgName + ".svg"; + String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + "2_img" + ".pdf"; + String outFileName = DESTINATION_FOLDER + svgName + "2_img" + ".pdf"; + using (Document document = new Document(new PdfDocument(new PdfWriter(outFileName, new WriterProperties(). + SetCompressionLevel(0))))) { + INode parsedSvg = SvgConverter.Parse(FileUtil.GetInputStreamForFile(svgFileName)); + ISvgProcessorResult result = new DefaultSvgProcessor().Process(parsedSvg, new SvgConverterProperties().SetBaseUri + (svgFileName)); + SvgDrawContext svgDrawContext = new SvgDrawContext(new ResourceResolver(SOURCE_FOLDER), null); + SvgImageXObject svgImageXObject = new SvgImageXObject(result, svgDrawContext, 12, document.GetPdfDocument( + )); + svgImageXObject.SetIsCreatedByImg(true); + SvgImage svgImage = new SvgImage(svgImageXObject); + svgImage.SetHeight(100.0F); + document.Add(svgImage); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER + , "diff")); + } + + [NUnit.Framework.Test] + public virtual void RelativeSizedSvgInImg8Test() { + String svgName = "fixed_height_and_width_2"; + String svgFileName = SOURCE_FOLDER + svgName + ".svg"; + String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + "_img" + ".pdf"; + String outFileName = DESTINATION_FOLDER + svgName + "_img" + ".pdf"; + using (Document document = new Document(new PdfDocument(new PdfWriter(outFileName, new WriterProperties(). + SetCompressionLevel(0))))) { + INode parsedSvg = SvgConverter.Parse(FileUtil.GetInputStreamForFile(svgFileName)); + ISvgProcessorResult result = new DefaultSvgProcessor().Process(parsedSvg, new SvgConverterProperties().SetBaseUri + (svgFileName)); + SvgDrawContext svgDrawContext = new SvgDrawContext(new ResourceResolver(SOURCE_FOLDER), null); + SvgImageXObject svgImageXObject = new SvgImageXObject(result, svgDrawContext, 12, document.GetPdfDocument( + )); + svgImageXObject.SetIsCreatedByImg(true); + SvgImage svgImage = new SvgImage(svgImageXObject); + document.Add(svgImage); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER + , "diff")); + } + + [NUnit.Framework.Test] + public virtual void RelativeSizedSvgInImg9Test() { + String svgName = "fixed_height_and_width_3"; + String svgFileName = SOURCE_FOLDER + svgName + ".svg"; + String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + "_img" + ".pdf"; + String outFileName = DESTINATION_FOLDER + svgName + "_img" + ".pdf"; + using (Document document = new Document(new PdfDocument(new PdfWriter(outFileName, new WriterProperties(). + SetCompressionLevel(0))))) { + INode parsedSvg = SvgConverter.Parse(FileUtil.GetInputStreamForFile(svgFileName)); + ISvgProcessorResult result = new DefaultSvgProcessor().Process(parsedSvg, new SvgConverterProperties().SetBaseUri + (svgFileName)); + SvgDrawContext svgDrawContext = new SvgDrawContext(new ResourceResolver(SOURCE_FOLDER), null); + SvgImageXObject svgImageXObject = new SvgImageXObject(result, svgDrawContext, 12, document.GetPdfDocument( + )); + svgImageXObject.SetIsCreatedByImg(true); + SvgImage svgImage = new SvgImage(svgImageXObject); + document.Add(svgImage); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER + , "diff")); + } + + [NUnit.Framework.Test] + public virtual void RelativeSizedSvgInObjTest() { + String svgName = "fixed_height_and_width"; + String svgFileName = SOURCE_FOLDER + svgName + ".svg"; + String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + "_obj" + ".pdf"; + String outFileName = DESTINATION_FOLDER + svgName + "_obj" + ".pdf"; + using (Document document = new Document(new PdfDocument(new PdfWriter(outFileName, new WriterProperties(). + SetCompressionLevel(0))))) { + INode parsedSvg = SvgConverter.Parse(FileUtil.GetInputStreamForFile(svgFileName)); + ISvgProcessorResult result = new DefaultSvgProcessor().Process(parsedSvg, new SvgConverterProperties().SetBaseUri + (svgFileName)); + ISvgNodeRenderer topSvgRenderer = result.GetRootRenderer(); + Rectangle wh = SvgCssUtils.ExtractWidthAndHeight(topSvgRenderer, 0.0F, new SvgDrawContext(null, null)); + SvgImageXObject xObject = new SvgImageXObject(wh, result, new ResourceResolver(SOURCE_FOLDER)); + xObject.SetIsCreatedByObject(true); + SvgImage image = new SvgImage(xObject); + image.SetWidth(200.0F); + document.Add(image); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER + , "diff")); + } + + [NUnit.Framework.Test] + public virtual void RelativeSizedSvgInObj2Test() { + String svgName = "fixed_height_and_width"; + String svgFileName = SOURCE_FOLDER + svgName + ".svg"; + String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + "_obj2" + ".pdf"; + String outFileName = DESTINATION_FOLDER + svgName + "_obj2" + ".pdf"; + using (Document document = new Document(new PdfDocument(new PdfWriter(outFileName, new WriterProperties(). + SetCompressionLevel(0))))) { + INode parsedSvg = SvgConverter.Parse(FileUtil.GetInputStreamForFile(svgFileName)); + ISvgProcessorResult result = new DefaultSvgProcessor().Process(parsedSvg, new SvgConverterProperties().SetBaseUri + (svgFileName)); + ISvgNodeRenderer topSvgRenderer = result.GetRootRenderer(); + Rectangle wh = SvgCssUtils.ExtractWidthAndHeight(topSvgRenderer, 0.0F, new SvgDrawContext(null, null)); + SvgImageXObject xObject = new SvgImageXObject(wh, result, new ResourceResolver(SOURCE_FOLDER)); + xObject.SetIsCreatedByObject(true); + SvgImage image = new SvgImage(xObject); + image.SetWidth(200.0F); + image.SetHeight(200.0F); + document.Add(image); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER + , "diff")); + } + + [NUnit.Framework.Test] + public virtual void RelativeSizedSvgInObj3Test() { + String svgName = "fixed_height_and_width_2"; + String svgFileName = SOURCE_FOLDER + svgName + ".svg"; + String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + "_obj" + ".pdf"; + String outFileName = DESTINATION_FOLDER + svgName + "_obj" + ".pdf"; + using (Document document = new Document(new PdfDocument(new PdfWriter(outFileName, new WriterProperties(). + SetCompressionLevel(0))))) { + INode parsedSvg = SvgConverter.Parse(FileUtil.GetInputStreamForFile(svgFileName)); + ISvgProcessorResult result = new DefaultSvgProcessor().Process(parsedSvg, new SvgConverterProperties().SetBaseUri + (svgFileName)); + ISvgNodeRenderer topSvgRenderer = result.GetRootRenderer(); + Rectangle wh = SvgCssUtils.ExtractWidthAndHeight(topSvgRenderer, 0.0F, new SvgDrawContext(null, null)); + SvgImageXObject xObject = new SvgImageXObject(wh, result, new ResourceResolver(SOURCE_FOLDER)); + xObject.SetIsCreatedByObject(true); + SvgImage image = new SvgImage(xObject); + image.SetHeight(200.0F); + document.Add(image); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER + , "diff")); + } + + [NUnit.Framework.Test] + public virtual void RelativeSizedSvgInObj4Test() { + String svgName = "fixed_height_and_width_2"; + String svgFileName = SOURCE_FOLDER + svgName + ".svg"; + String cmpFileName = SOURCE_FOLDER + "cmp_" + svgName + "_obj2" + ".pdf"; + String outFileName = DESTINATION_FOLDER + svgName + "_obj2" + ".pdf"; + using (Document document = new Document(new PdfDocument(new PdfWriter(outFileName, new WriterProperties(). + SetCompressionLevel(0))))) { + INode parsedSvg = SvgConverter.Parse(FileUtil.GetInputStreamForFile(svgFileName)); + ISvgProcessorResult result = new DefaultSvgProcessor().Process(parsedSvg, new SvgConverterProperties().SetBaseUri + (svgFileName)); + ISvgNodeRenderer topSvgRenderer = result.GetRootRenderer(); + Rectangle wh = SvgCssUtils.ExtractWidthAndHeight(topSvgRenderer, 0.0F, new SvgDrawContext(null, null)); + SvgImageXObject xObject = new SvgImageXObject(wh, result, new ResourceResolver(SOURCE_FOLDER)); + xObject.SetIsCreatedByObject(true); + SvgImage image = new SvgImage(xObject); + image.SetHeight(200.0F); + image.SetWidth(200.0F); + document.Add(image); + } + NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(outFileName, cmpFileName, DESTINATION_FOLDER + , "diff")); + } } } diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest.cs index 66d10621e..c03b2623c 100644 --- a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest.cs +++ b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest.cs @@ -312,5 +312,25 @@ public virtual void MarkerParentElementTest() { // Compare with Chrome browser ConvertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER, "markerParentElement"); } + + [NUnit.Framework.Test] + public virtual void MarkerDefinedInStyleTest() { + ConvertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER, "markerDefinedInStyle"); + } + + [NUnit.Framework.Test] + public virtual void MarkerOnGroupTest() { + ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "markerOnGroup"); + } + + [NUnit.Framework.Test] + public virtual void MarkerOnSvgTest() { + ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "markerOnSvg"); + } + + [NUnit.Framework.Test] + public virtual void MarkerOnSymbolTest() { + ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "markerOnSymbol"); + } } } diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/SymbolTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/SymbolTest.cs index d0604b1af..8c94493a0 100644 --- a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/SymbolTest.cs +++ b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/SymbolTest.cs @@ -125,7 +125,6 @@ public virtual void BothStyleAttributeTest() { [NUnit.Framework.Test] public virtual void OpacityAttributeTest() { - // TODO DEVSIX-2258 Processing of stroke attribute is not currently correct supported ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "opacityAttrTest"); } diff --git a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/TextSvgBranchRendererIntegrationTest.cs b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/TextSvgBranchRendererIntegrationTest.cs index 5d6968514..609d716a1 100644 --- a/itext.tests/itext.svg.tests/itext/svg/renderers/impl/TextSvgBranchRendererIntegrationTest.cs +++ b/itext.tests/itext.svg.tests/itext/svg/renderers/impl/TextSvgBranchRendererIntegrationTest.cs @@ -318,5 +318,10 @@ public virtual void TextWhiteSpacePreWrapTest() { public virtual void TextWhiteSpacePreLineTest() { ConvertAndCompareSinglePage(SOURCE_FOLDER, DESTINATION_FOLDER, "textWhiteSpacePreLine"); } + + [NUnit.Framework.Test] + public virtual void TextRelativeXYTest() { + ConvertAndCompare(SOURCE_FOLDER, DESTINATION_FOLDER, "textRelativeXY"); + } } } diff --git a/itext.tests/itext.svg.tests/itext/svg/utils/SvgTextUtilTest.cs b/itext.tests/itext.svg.tests/itext/svg/utils/SvgTextUtilTest.cs index 920f0bdd3..8f040d750 100644 --- a/itext.tests/itext.svg.tests/itext/svg/utils/SvgTextUtilTest.cs +++ b/itext.tests/itext.svg.tests/itext/svg/utils/SvgTextUtilTest.cs @@ -22,6 +22,7 @@ You should have received a copy of the GNU Affero General Public License */ using System; using iText.Svg; +using iText.Svg.Renderers; using iText.Svg.Renderers.Impl; using iText.Test; @@ -185,7 +186,7 @@ public virtual void ProcessWhiteSpaceBreakLine() { ); root.AddChild(textAfter); //Run - SvgTextUtil.ProcessWhiteSpace(root, true); + SvgTextUtil.ProcessWhiteSpace(root, true, new SvgDrawContext(null, null)); root.GetChildren()[0].GetAttribute(SvgConstants.Attributes.TEXT_CONTENT); //Create result array String[] actual = new String[] { root.GetChildren()[0].GetAttribute(SvgConstants.Attributes.TEXT_CONTENT), @@ -217,7 +218,7 @@ public virtual void ProcessWhiteSpaceAbsPositionChange() { ); root.AddChild(textAfter); //Run - SvgTextUtil.ProcessWhiteSpace(root, true); + SvgTextUtil.ProcessWhiteSpace(root, true, new SvgDrawContext(null, null)); root.GetChildren()[0].GetAttribute(SvgConstants.Attributes.TEXT_CONTENT); //Create result array String[] actual = new String[] { root.GetChildren()[0].GetAttribute(SvgConstants.Attributes.TEXT_CONTENT), diff --git a/itext.tests/itext.svg.tests/itext/svg/utils/TransformUtilsTest.cs b/itext.tests/itext.svg.tests/itext/svg/utils/TransformUtilsTest.cs index 6f14531b1..0acd05cd1 100644 --- a/itext.tests/itext.svg.tests/itext/svg/utils/TransformUtilsTest.cs +++ b/itext.tests/itext.svg.tests/itext/svg/utils/TransformUtilsTest.cs @@ -21,6 +21,7 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ using System; +using iText.Commons.Utils; using iText.Kernel.Geom; using iText.Svg.Exceptions; using iText.Test; @@ -173,5 +174,29 @@ public virtual void MixedWhiteSpace() { AffineTransform expected = AffineTransform.GetTranslateInstance(2.25, 0); NUnit.Framework.Assert.AreEqual(expected, actual); } + + [NUnit.Framework.Test] + public virtual void ParseInvalidRotateTest() { + Exception e = NUnit.Framework.Assert.Catch(typeof(SvgProcessingException), () => TransformUtils.ParseTransform + ("rotate(text)")); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(SvgExceptionMessageConstant.INVALID_TRANSFORM_VALUE + , "text"), e.Message); + } + + [NUnit.Framework.Test] + public virtual void ParseInvalidSkewXTest() { + Exception e = NUnit.Framework.Assert.Catch(typeof(SvgProcessingException), () => TransformUtils.ParseTransform + ("skewX(text)")); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(SvgExceptionMessageConstant.INVALID_TRANSFORM_VALUE + , "text"), e.Message); + } + + [NUnit.Framework.Test] + public virtual void ParseInvalidSkewYTest() { + Exception e = NUnit.Framework.Assert.Catch(typeof(SvgProcessingException), () => TransformUtils.ParseTransform + ("skewY(text)")); + NUnit.Framework.Assert.AreEqual(MessageFormatUtil.Format(SvgExceptionMessageConstant.INVALID_TRANSFORM_VALUE + , "text"), e.Message); + } } } diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_fillOpacityInheritance.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_fillOpacityInheritance.pdf index 5c1faff7a..2795ea5fd 100644 Binary files a/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_fillOpacityInheritance.pdf and b/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_fillOpacityInheritance.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_strokeDasharrayInheritance.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_strokeDasharrayInheritance.pdf index 7848e724a..3c2bf951a 100644 Binary files a/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_strokeDasharrayInheritance.pdf and b/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_strokeDasharrayInheritance.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_strokeDashoffsetInheritance.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_strokeDashoffsetInheritance.pdf index 711622d76..f51cf1eff 100644 Binary files a/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_strokeDashoffsetInheritance.pdf and b/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_strokeDashoffsetInheritance.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_strokeOpacityInheritance.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_strokeOpacityInheritance.pdf index f35994f4b..c4960a9a8 100644 Binary files a/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_strokeOpacityInheritance.pdf and b/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_strokeOpacityInheritance.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_usePropertiesInheritance.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_usePropertiesInheritance.pdf index a2185f306..dcddc24fd 100644 Binary files a/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_usePropertiesInheritance.pdf and b/itext.tests/itext.svg.tests/resources/itext/svg/css/DefaultInheritance/cmp_usePropertiesInheritance.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_2_img.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_2_img.pdf new file mode 100644 index 000000000..0f3903f0b Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_2_img.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_2_obj.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_2_obj.pdf new file mode 100644 index 000000000..6bd3c2109 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_2_obj.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_2_obj2.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_2_obj2.pdf new file mode 100644 index 000000000..b8e94a978 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_2_obj2.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_3_img.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_3_img.pdf new file mode 100644 index 000000000..b06c37734 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_3_img.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_img.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_img.pdf new file mode 100644 index 000000000..0277e9604 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_img.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_obj.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_obj.pdf new file mode 100644 index 000000000..b108e934f Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_obj.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_obj2.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_obj2.pdf new file mode 100644 index 000000000..db613b61c Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_fixed_height_and_width_obj2.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_relativeSizedSvg2_img.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_relativeSizedSvg2_img.pdf new file mode 100644 index 000000000..9b90765b7 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_relativeSizedSvg2_img.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_relativeSizedSvg_img.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_relativeSizedSvg_img.pdf new file mode 100644 index 000000000..98a050a30 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_relativeSizedSvg_img.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_viewbox_fixed_height_percent_width_no_viewbox_img.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_viewbox_fixed_height_percent_width_no_viewbox_img.pdf new file mode 100644 index 000000000..d67c6b0c9 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_viewbox_fixed_height_percent_width_no_viewbox_img.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_viewbox_percent_height_percent_width_prRatio_max_max_img.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_viewbox_percent_height_percent_width_prRatio_max_max_img.pdf new file mode 100644 index 000000000..0254513bb Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_viewbox_percent_height_percent_width_prRatio_max_max_img.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_viewbox_percent_height_percent_width_prRatio_none_img.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_viewbox_percent_height_percent_width_prRatio_none_img.pdf new file mode 100644 index 000000000..9a765a5e9 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/cmp_viewbox_percent_height_percent_width_prRatio_none_img.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/fixed_height_and_width.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/fixed_height_and_width.svg new file mode 100644 index 000000000..f7329d2e0 --- /dev/null +++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/fixed_height_and_width.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/fixed_height_and_width_2.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/fixed_height_and_width_2.svg new file mode 100644 index 000000000..328f4e8db --- /dev/null +++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/fixed_height_and_width_2.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/fixed_height_and_width_3.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/fixed_height_and_width_3.svg new file mode 100644 index 000000000..c7f6c4e55 --- /dev/null +++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/fixed_height_and_width_3.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/relativeSizedSvg.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/relativeSizedSvg.svg new file mode 100644 index 000000000..aee3647af --- /dev/null +++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/relativeSizedSvg.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/viewbox_fixed_height_percent_width_no_viewbox.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/viewbox_fixed_height_percent_width_no_viewbox.svg new file mode 100644 index 000000000..48f622bef --- /dev/null +++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/viewbox_fixed_height_percent_width_no_viewbox.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/viewbox_percent_height_percent_width_prRatio_max_max.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/viewbox_percent_height_percent_width_prRatio_max_max.svg new file mode 100644 index 000000000..03b2ccb69 --- /dev/null +++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/SvgImageRendererTest/viewbox_percent_height_percent_width_prRatio_max_max.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_markerDefinedInStyle.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_markerDefinedInStyle.pdf new file mode 100644 index 000000000..620ab0888 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_markerDefinedInStyle.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_markerOnGroup.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_markerOnGroup.pdf new file mode 100644 index 000000000..0685077b3 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_markerOnGroup.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_markerOnSvg.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_markerOnSvg.pdf new file mode 100644 index 000000000..e13c3b1ce Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_markerOnSvg.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_markerOnSymbol.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_markerOnSymbol.pdf new file mode 100644 index 000000000..7b021def6 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/cmp_markerOnSymbol.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/markerDefinedInStyle.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/markerDefinedInStyle.svg new file mode 100644 index 000000000..0c11a35bd --- /dev/null +++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/markerDefinedInStyle.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/markerOnGroup.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/markerOnGroup.svg new file mode 100644 index 000000000..6252f9aac --- /dev/null +++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/markerOnGroup.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + marker attribute + + + + + + + + + marker-start, marker-mid and marker-end attributes + + + + + + + + + \ No newline at end of file diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/markerOnSvg.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/markerOnSvg.svg new file mode 100644 index 000000000..604c199fe --- /dev/null +++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/markerOnSvg.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/markerOnSymbol.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/markerOnSymbol.svg new file mode 100644 index 000000000..20a3bc078 --- /dev/null +++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/MarkerSvgNodeRendererIntegrationTest/markerOnSymbol.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/OpacityTest/cmp_testFillOpacityWithPercents.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/OpacityTest/cmp_testFillOpacityWithPercents.pdf new file mode 100644 index 000000000..5b00213b2 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/OpacityTest/cmp_testFillOpacityWithPercents.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/OpacityTest/cmp_testStrokeOpacityWithPercents.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/OpacityTest/cmp_testStrokeOpacityWithPercents.pdf new file mode 100644 index 000000000..0b5a9851e Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/OpacityTest/cmp_testStrokeOpacityWithPercents.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/OpacityTest/testFillOpacityWithComma.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/OpacityTest/testFillOpacityWithComma.svg index 0f3993c9a..fdba21f2e 100644 --- a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/OpacityTest/testFillOpacityWithComma.svg +++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/OpacityTest/testFillOpacityWithComma.svg @@ -2,10 +2,10 @@ - + - + - + \ No newline at end of file diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_strokeOnGroup2.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_strokeOnGroup2.pdf index bb284ef5f..c0a84f28b 100644 Binary files a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_strokeOnGroup2.pdf and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_strokeOnGroup2.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_strokeOnGroupNoInsideStroke2.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_strokeOnGroupNoInsideStroke2.pdf index 20b2e6c1f..3be7279d9 100644 Binary files a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_strokeOnGroupNoInsideStroke2.pdf and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_strokeOnGroupNoInsideStroke2.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_strokeOnGroupNoInsideStroke3.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_strokeOnGroupNoInsideStroke3.pdf index 0c001f407..8f3ba829f 100644 Binary files a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_strokeOnGroupNoInsideStroke3.pdf and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/StrokeTest/cmp_strokeOnGroupNoInsideStroke3.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/SymbolTest/cmp_opacityAttrTest.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/SymbolTest/cmp_opacityAttrTest.pdf index 20418970e..6fdd9cb4a 100644 Binary files a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/SymbolTest/cmp_opacityAttrTest.pdf and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/SymbolTest/cmp_opacityAttrTest.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/TSpanNodeRendererIntegrationTest/cmp_textDecorationDashedStroke.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/TSpanNodeRendererIntegrationTest/cmp_textDecorationDashedStroke.pdf index 747acce63..db5339de0 100644 Binary files a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/TSpanNodeRendererIntegrationTest/cmp_textDecorationDashedStroke.pdf and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/TSpanNodeRendererIntegrationTest/cmp_textDecorationDashedStroke.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/TextSvgBranchRendererIntegrationTest/cmp_textRelativeXY.pdf b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/TextSvgBranchRendererIntegrationTest/cmp_textRelativeXY.pdf new file mode 100644 index 000000000..d9b255cd4 Binary files /dev/null and b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/TextSvgBranchRendererIntegrationTest/cmp_textRelativeXY.pdf differ diff --git a/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/TextSvgBranchRendererIntegrationTest/textRelativeXY.svg b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/TextSvgBranchRendererIntegrationTest/textRelativeXY.svg new file mode 100644 index 000000000..0809beef5 --- /dev/null +++ b/itext.tests/itext.svg.tests/resources/itext/svg/renderers/impl/TextSvgBranchRendererIntegrationTest/textRelativeXY.svg @@ -0,0 +1,36 @@ + + x="1em" y="2em" + x="1em" y="2rem" + x="1em" y="30%" + + x="35%" y="2em" + x="35%" y="2rem" + x="35%" y="30%" + + x="12rem" y="2em" + x="12rem" y="2rem" + x="12rem" y="30%" + + + + + + x="1rem" y="1em" + x="50%" y="1rem" + x="5em" y="50%" + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/itext/itext.kernel/itext/kernel/pdf/xobject/PdfFormXObject.cs b/itext/itext.kernel/itext/kernel/pdf/xobject/PdfFormXObject.cs index 9f09d8d7e..455972510 100644 --- a/itext/itext.kernel/itext/kernel/pdf/xobject/PdfFormXObject.cs +++ b/itext/itext.kernel/itext/kernel/pdf/xobject/PdfFormXObject.cs @@ -435,5 +435,21 @@ public virtual iText.Kernel.Pdf.Xobject.PdfFormXObject Put(PdfName key, PdfObjec SetModified(); return this; } + + /// If the form xobject is relative sized. + /// + /// If the form xobject is relative sized. This information + /// is used during xobject layout to resolve it's relative size. + /// + /// + /// + /// + /// if the xobject is relative sized, + /// + /// otherwise + /// + public virtual bool IsRelativeSized() { + return false; + } } } diff --git a/itext/itext.layout/itext/layout/renderer/ImageRenderer.cs b/itext/itext.layout/itext/layout/renderer/ImageRenderer.cs index f211278f9..675cff7f8 100644 --- a/itext/itext.layout/itext/layout/renderer/ImageRenderer.cs +++ b/itext/itext.layout/itext/layout/renderer/ImageRenderer.cs @@ -455,7 +455,8 @@ private void CalculateImageDimensions(Rectangle layoutBox, AffineTransform t, Pd } float? horizontalScaling = this.GetPropertyAsFloat(Property.HORIZONTAL_SCALING, 1f); float? verticalScaling = this.GetPropertyAsFloat(Property.VERTICAL_SCALING, 1f); - if (xObject is PdfFormXObject && width != imageWidth) { + if (xObject is PdfFormXObject && (JavaUtil.FloatCompare((float)width, imageWidth) != 0 || JavaUtil.FloatCompare + ((float)height, imageHeight) != 0)) { horizontalScaling *= width / imageWidth; verticalScaling *= height / imageHeight; } diff --git a/itext/itext.styledxmlparser/itext/styledxmlparser/resolver/resource/ResourceResolver.cs b/itext/itext.styledxmlparser/itext/styledxmlparser/resolver/resource/ResourceResolver.cs index d1ef55673..717af29a8 100644 --- a/itext/itext.styledxmlparser/itext/styledxmlparser/resolver/resource/ResourceResolver.cs +++ b/itext/itext.styledxmlparser/itext/styledxmlparser/resolver/resource/ResourceResolver.cs @@ -265,7 +265,10 @@ protected internal virtual PdfXObject TryResolveUrlImageSource(String uri) { PdfXObject imageXObject = imageCache.GetImage(imageResolvedSrc); if (imageXObject == null) { imageXObject = CreateImageByUrl(url); - if (imageXObject != null) { + //relative sized xObject can't be cached because it's internal state depends on the context + bool isAbsoluteSized = imageXObject != null && !(imageXObject is PdfFormXObject && ((PdfFormXObject)imageXObject + ).IsRelativeSized()); + if (isAbsoluteSized) { imageCache.PutImage(imageResolvedSrc, imageXObject); } } diff --git a/itext/itext.svg/itext/svg/SvgConstants.cs b/itext/itext.svg/itext/svg/SvgConstants.cs index 334a86fc7..5fae5e4a4 100644 --- a/itext/itext.svg/itext/svg/SvgConstants.cs +++ b/itext/itext.svg/itext/svg/SvgConstants.cs @@ -549,6 +549,9 @@ public sealed class Attributes : CommonAttributeConstants { /// Attribute defining the stroke linecap. public const String STROKE_LINECAP = "stroke-linecap"; + /// Attribute defining the stroke linejoin. + public const String STROKE_LINEJOIN = "stroke-linejoin"; + /// Attribute defining the stroke miterlimit. public const String STROKE_MITERLIMIT = "stroke-miterlimit"; diff --git a/itext/itext.svg/itext/svg/css/impl/SvgAttributeInheritance.cs b/itext/itext.svg/itext/svg/css/impl/SvgAttributeInheritance.cs index e07b9bf38..0bad0b480 100644 --- a/itext/itext.svg/itext/svg/css/impl/SvgAttributeInheritance.cs +++ b/itext/itext.svg/itext/svg/css/impl/SvgAttributeInheritance.cs @@ -29,22 +29,23 @@ You should have received a copy of the GNU Affero General Public License namespace iText.Svg.Css.Impl { /// Helper class that allows you to check if a property is inheritable. public class SvgAttributeInheritance : IStyleInheritance { - /// - /// Set of inheritable SVG style attributes - /// in accordance with "http://www.w3schools.com/cssref/" - /// and "https://developer.mozilla.org/en-US/docs/Web/CSS/Reference" - /// + /// Set of inheritable SVG style attributes in accordance with "https://www.w3.org/TR/SVG2/propidx.html". + /// private static readonly ICollection inheritableProperties = JavaCollectionsUtil.UnmodifiableSet(new - HashSet(JavaUtil.ArraysAsList(SvgConstants.Attributes.CLIP_RULE, SvgConstants.Attributes.FILL, - SvgConstants.Attributes.FILL_RULE, SvgConstants.Attributes.STROKE, SvgConstants.Attributes.STROKE_WIDTH - , SvgConstants.Attributes.TEXT_ANCHOR))); + HashSet(JavaUtil.ArraysAsList(SvgConstants.Attributes.DIRECTION, SvgConstants.Attributes.FILL, + SvgConstants.Attributes.FILL_OPACITY, SvgConstants.Attributes.FILL_RULE, SvgConstants.Attributes.MARKER + , SvgConstants.Attributes.MARKER_MID, SvgConstants.Attributes.MARKER_END, SvgConstants.Attributes.MARKER_START + , SvgConstants.Attributes.STROKE, SvgConstants.Attributes.STROKE_DASHARRAY, SvgConstants.Attributes.STROKE_DASHOFFSET + , SvgConstants.Attributes.STROKE_LINECAP, SvgConstants.Attributes.STROKE_LINEJOIN, SvgConstants.Attributes + .STROKE_MITERLIMIT, SvgConstants.Attributes.STROKE_OPACITY, SvgConstants.Attributes.STROKE_WIDTH, SvgConstants.Attributes + .TEXT_ANCHOR, SvgConstants.Attributes.CLIP_RULE))); - // clip-rule - // fill - // fill-rule - // stroke - // stroke-width - // text-anchor + // The following attributes haven't been supported in iText yet: + // color-interpolation, color-rendering, glyph-orientation-vertical, image-rendering, + // paint-order, pointer-events, shape-rendering, text-rendering. + // All the rest are either here or in com.itextpdf.styledxmlparser.css.resolve.CssInheritance + // TODO DEVSIX-5890 Add Support to SVG dominant-baseline attribute + // CLIP_RULE isn't from the spec above, but seems it's required according to some tests public virtual bool IsInheritable(String cssProperty) { return inheritableProperties.Contains(cssProperty); } diff --git a/itext/itext.svg/itext/svg/exceptions/SvgExceptionMessageConstant.cs b/itext/itext.svg/itext/svg/exceptions/SvgExceptionMessageConstant.cs index e577af0ef..5d7e1c199 100644 --- a/itext/itext.svg/itext/svg/exceptions/SvgExceptionMessageConstant.cs +++ b/itext/itext.svg/itext/svg/exceptions/SvgExceptionMessageConstant.cs @@ -56,6 +56,8 @@ public sealed class SvgExceptionMessageConstant { public const String INVALID_TRANSFORM_DECLARATION = "Transformation declaration is not formed correctly."; + public const String INVALID_TRANSFORM_VALUE = "Invalid transformation value: {0}"; + public const String LINE_TO_EXPECTS_FOLLOWING_PARAMETERS_GOT_0 = "(x y)+ parameters are expected for lineTo operator. Got: {0}"; public const String MOVE_TO_EXPECTS_FOLLOWING_PARAMETERS_GOT_0 = "(x y)+ parameters are expected for moveTo operator. Got: {0}"; diff --git a/itext/itext.svg/itext/svg/renderers/SvgImageRenderer.cs b/itext/itext.svg/itext/svg/renderers/SvgImageRenderer.cs index 4be35a9f6..ba9338e3a 100644 --- a/itext/itext.svg/itext/svg/renderers/SvgImageRenderer.cs +++ b/itext/itext.svg/itext/svg/renderers/SvgImageRenderer.cs @@ -21,7 +21,9 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ using iText.Kernel.Geom; +using iText.Kernel.Pdf; using iText.Layout.Layout; +using iText.Layout.Properties; using iText.Layout.Renderer; using iText.Svg; using iText.Svg.Element; @@ -47,8 +49,45 @@ public SvgImageRenderer(SvgImage image) public override LayoutResult Layout(LayoutContext layoutContext) { SvgImage svgImage = (SvgImage)modelElement; + Rectangle layoutBox = layoutContext.GetArea().GetBBox(); if (svgImage.GetSvgImageXObject().IsRelativeSized()) { - CalculateRelativeSizedSvgSize(svgImage, layoutContext.GetArea().GetBBox()); + CalculateRelativeSizedSvgSize(svgImage, layoutBox); + } + else { + if (svgImage.GetSvgImageXObject().IsCreatedByObject() && !true.Equals(GetPropertyAsBoolean(Property.FORCED_PLACEMENT + ))) { + SvgImageRenderer.NullableArea retrievedArea = new SvgImageRenderer.NullableArea(RetrieveWidth(layoutBox.GetWidth + ()), RetrieveHeight()); + PdfArray bbox = svgImage.GetSvgImageXObject().GetBBox(); + if (retrievedArea.width != null && retrievedArea.height != null) { + bbox.Set(2, new PdfNumber((double)retrievedArea.width)); + bbox.Set(3, new PdfNumber((double)retrievedArea.height)); + imageWidth = (float)retrievedArea.width; + imageHeight = (float)retrievedArea.height; + } + else { + if (retrievedArea.width != null) { + SvgImageRenderer.Area bboxArea = new SvgImageRenderer.Area(((PdfNumber)bbox.Get(2)).FloatValue(), ((PdfNumber + )bbox.Get(3)).FloatValue()); + double verticalScaling = (double)retrievedArea.width / bboxArea.width; + bbox.Set(2, new PdfNumber((double)retrievedArea.width)); + bbox.Set(3, new PdfNumber(bboxArea.height * verticalScaling)); + imageWidth = (float)retrievedArea.width; + imageHeight = imageHeight * (float)verticalScaling; + } + else { + if (retrievedArea.height != null) { + SvgImageRenderer.Area bboxArea = new SvgImageRenderer.Area(((PdfNumber)bbox.Get(2)).FloatValue(), ((PdfNumber + )bbox.Get(3)).FloatValue()); + double horizontalScaling = (double)retrievedArea.height / bboxArea.height; + bbox.Set(2, new PdfNumber(bboxArea.width * horizontalScaling)); + bbox.Set(3, new PdfNumber((double)retrievedArea.height)); + imageWidth = imageWidth * (float)horizontalScaling; + imageHeight = (float)retrievedArea.height; + } + } + } + } } return base.Layout(layoutContext); } @@ -69,32 +108,118 @@ private void CalculateRelativeSizedSvgSize(SvgImage svgImage, Rectangle layoutBo // but in that case SVG isn't relative and processed as usual image aspectRatio = viewBoxValues[2] / viewBoxValues[3]; } - float? retrievedAreaWidth = RetrieveWidth(layoutBox.GetWidth()); - float? retrievedAreaHeight = RetrieveHeight(); - float areaWidth = retrievedAreaWidth == null ? (aspectRatio == null ? SvgConstants.Values.DEFAULT_VIEWPORT_WIDTH - : layoutBox.GetWidth()) : (float)retrievedAreaWidth; - float areaHeight = retrievedAreaHeight == null ? SvgConstants.Values.DEFAULT_VIEWPORT_HEIGHT : (float)retrievedAreaHeight; - float finalWidth; - float finalHeight; - if (aspectRatio != null && (retrievedAreaHeight == null || retrievedAreaWidth == null)) { - if (retrievedAreaWidth == null && retrievedAreaHeight != null) { - finalHeight = areaHeight; - finalWidth = (float)(finalHeight * aspectRatio); + SvgImageRenderer.NullableArea retrievedArea = new SvgImageRenderer.NullableArea(RetrieveWidth(layoutBox.GetWidth + ()), RetrieveHeight()); + bool preserveAspectRatioNone = SvgConstants.Values.NONE.Equals(svgRootRenderer.GetAttribute(SvgConstants.Attributes + .PRESERVE_ASPECT_RATIO)); + SvgImageRenderer.Area area = new SvgImageRenderer.Area(); + area.width = retrievedArea.width == null ? (aspectRatio == null ? SvgConstants.Values.DEFAULT_VIEWPORT_WIDTH + : layoutBox.GetWidth()) : (float)retrievedArea.width; + area.height = retrievedArea.height == null ? (aspectRatio == null ? SvgConstants.Values.DEFAULT_VIEWPORT_HEIGHT + : layoutBox.GetHeight()) : (float)retrievedArea.height; + UnitValue elementWidth = svgImageXObject.GetElementWidth(); + UnitValue elementHeight = svgImageXObject.GetElementHeight(); + //For aspect ratio none we're using the default viewport instead of layoutBox to behave like a browser + //But this only for , for all other cases using layoutBox as a fallback + SvgImageRenderer.Area finalArea = new SvgImageRenderer.Area(); + if (preserveAspectRatioNone && svgImageXObject.IsCreatedByImg()) { + finalArea.width = retrievedArea.width == null ? SvgConstants.Values.DEFAULT_VIEWPORT_WIDTH : (float)retrievedArea + .width; + finalArea.height = retrievedArea.height == null ? SvgConstants.Values.DEFAULT_VIEWPORT_HEIGHT : (float)retrievedArea + .height; + } + else { + finalArea = InitMissingMetricsAndApplyAspectRatio(aspectRatio, retrievedArea, area, elementWidth, elementHeight + ); + } + if (svgImageXObject.IsCreatedByImg() && viewBoxValues == null) { + if (this.GetProperty(Property.WIDTH) == null) { + this.SetProperty(Property.WIDTH, UnitValue.CreatePointValue(finalArea.width)); } - else { - finalWidth = areaWidth; - finalHeight = (float)(finalWidth / aspectRatio); + if (RetrieveHeight() == null) { + this.SetProperty(Property.HEIGHT, UnitValue.CreatePointValue(finalArea.height)); } + svgImageXObject.UpdateBBox(finalArea.width, finalArea.height); } else { - finalWidth = areaWidth; - finalHeight = areaHeight; + svgRootRenderer.SetAttribute(SvgConstants.Attributes.WIDTH, null); + svgRootRenderer.SetAttribute(SvgConstants.Attributes.HEIGHT, null); + svgImageXObject.UpdateBBox(finalArea.width, finalArea.height); } - svgRootRenderer.SetAttribute(SvgConstants.Attributes.WIDTH, null); - svgRootRenderer.SetAttribute(SvgConstants.Attributes.HEIGHT, null); - svgImageXObject.UpdateBBox(finalWidth, finalHeight); imageWidth = svgImage.GetImageWidth(); imageHeight = svgImage.GetImageHeight(); } + + private SvgImageRenderer.Area InitMissingMetricsAndApplyAspectRatio(float? aspectRatio, SvgImageRenderer.NullableArea + retrievedArea, SvgImageRenderer.Area area, UnitValue xObjectWidth, UnitValue xObjectHeight) { + SvgImageRenderer.Area finalArea = new SvgImageRenderer.Area(); + if (!TryToApplyAspectRatio(retrievedArea, area, finalArea, aspectRatio)) { + if (xObjectWidth != null && xObjectWidth.IsPointValue() && retrievedArea.width == null) { + area.width = xObjectWidth.GetValue(); + retrievedArea.width = area.width; + this.SetProperty(Property.WIDTH, UnitValue.CreatePointValue(area.width)); + } + if (xObjectHeight != null && xObjectHeight.IsPointValue() && retrievedArea.height == null) { + area.height = xObjectHeight.GetValue(); + retrievedArea.height = area.height; + this.SetProperty(Property.HEIGHT, UnitValue.CreatePointValue(area.height)); + } + bool isAspectRatioApplied = TryToApplyAspectRatio(retrievedArea, area, area, aspectRatio); + if (!isAspectRatioApplied && aspectRatio != null && retrievedArea.height == null) { + // retrievedArea.width is also null here + area.height = (float)(area.width / aspectRatio); + } + finalArea.width = area.width; + finalArea.height = area.height; + } + return finalArea; + } + + private static bool TryToApplyAspectRatio(SvgImageRenderer.NullableArea retrievedArea, SvgImageRenderer.Area + inputArea, SvgImageRenderer.Area resultArea, float? aspectRatio) { + if (aspectRatio == null) { + return false; + } + if (retrievedArea.width == null && retrievedArea.height != null) { + resultArea.height = inputArea.height; + resultArea.width = (float)(inputArea.height * (float)aspectRatio); + return true; + } + else { + if (retrievedArea.width != null && retrievedArea.height == null) { + resultArea.width = inputArea.width; + resultArea.height = (float)(inputArea.width / (float)aspectRatio); + return true; + } + } + return false; + } + + private class NullableArea { + public float? width; + + public float? height; + + public NullableArea(float? width, float? height) { + this.width = width; + this.height = height; + } + } + + private class Area { + public float width; + + public float height; + + public Area() { + width = 0.0f; + height = 0.0f; + } + + public Area(float width, float height) { + this.width = width; + this.height = height; + } + } } } diff --git a/itext/itext.svg/itext/svg/renderers/impl/AbstractSvgNodeRenderer.cs b/itext/itext.svg/itext/svg/renderers/impl/AbstractSvgNodeRenderer.cs index e4e8c3c9a..4379741c6 100644 --- a/itext/itext.svg/itext/svg/renderers/impl/AbstractSvgNodeRenderer.cs +++ b/itext/itext.svg/itext/svg/renderers/impl/AbstractSvgNodeRenderer.cs @@ -580,9 +580,16 @@ private TransparentColor GetColorFromAttributeValue(SvgDrawContext context, Stri private float GetOpacityByAttributeName(String attributeName, float generalOpacity) { float opacity = generalOpacity; - String opacityValue = GetAttribute(attributeName); - if (opacityValue != null && !SvgConstants.Values.NONE.EqualsIgnoreCase(opacityValue)) { - opacity *= float.Parse(opacityValue, System.Globalization.CultureInfo.InvariantCulture); + String opacityStr = GetAttribute(attributeName); + if (opacityStr != null && !SvgConstants.Values.NONE.EqualsIgnoreCase(opacityStr)) { + float opacityValue; + if (CssTypesValidationUtils.IsPercentageValue(opacityStr)) { + opacityValue = CssDimensionParsingUtils.ParseRelativeValue(opacityStr, 1f); + } + else { + opacityValue = float.Parse(opacityStr, System.Globalization.CultureInfo.InvariantCulture); + } + opacity *= opacityValue; } return opacity; } diff --git a/itext/itext.svg/itext/svg/renderers/impl/ISvgTextNodeRenderer.cs b/itext/itext.svg/itext/svg/renderers/impl/ISvgTextNodeRenderer.cs index 5853f6075..2b30341f8 100644 --- a/itext/itext.svg/itext/svg/renderers/impl/ISvgTextNodeRenderer.cs +++ b/itext/itext.svg/itext/svg/renderers/impl/ISvgTextNodeRenderer.cs @@ -63,8 +63,36 @@ public interface ISvgTextNodeRenderer : ISvgNodeRenderer { [Obsolete] bool ContainsRelativeMove(); + /// + /// This method is deprecated and will be replaced with new signature + /// containsAbsolutePositionChange(SvgDrawContext). + /// + /// + /// This method is deprecated and will be replaced with new signature + /// containsAbsolutePositionChange(SvgDrawContext). + /// This is needed because x/y can contain relative values, so SvgDrawContext is needed to resolve them. + /// + /// + /// + /// + /// if an absolute position is specified via x/y attributes, + /// + /// otherwise + /// + [Obsolete] bool ContainsAbsolutePositionChange(); + /// + /// This method is deprecated and will be replaced with new signature + /// getAbsolutePositionChanges(SvgDrawContext). + /// + /// + /// This method is deprecated and will be replaced with new signature + /// getAbsolutePositionChanges(SvgDrawContext). + /// This is needed because x/y can contain relative values, so SvgDrawContext is needed to resolve them. + /// + /// text absolute position + [Obsolete] float[][] GetAbsolutePositionChanges(); /// Return the bounding rectangle of the text element. diff --git a/itext/itext.svg/itext/svg/renderers/impl/TextLeafSvgNodeRenderer.cs b/itext/itext.svg/itext/svg/renderers/impl/TextLeafSvgNodeRenderer.cs index 8d78cb8e8..600274abe 100644 --- a/itext/itext.svg/itext/svg/renderers/impl/TextLeafSvgNodeRenderer.cs +++ b/itext/itext.svg/itext/svg/renderers/impl/TextLeafSvgNodeRenderer.cs @@ -71,11 +71,13 @@ public virtual bool ContainsRelativeMove() { } //Leaf text elements do not contain any kind of transformation + [Obsolete] public virtual bool ContainsAbsolutePositionChange() { return false; } //Leaf text elements do not contain any kind of transformation + [Obsolete] public virtual float[][] GetAbsolutePositionChanges() { float[] part = new float[] { 0f }; return new float[][] { part, part }; diff --git a/itext/itext.svg/itext/svg/renderers/impl/TextSvgBranchRenderer.cs b/itext/itext.svg/itext/svg/renderers/impl/TextSvgBranchRenderer.cs index f3651ae36..8f8ac231a 100644 --- a/itext/itext.svg/itext/svg/renderers/impl/TextSvgBranchRenderer.cs +++ b/itext/itext.svg/itext/svg/renderers/impl/TextSvgBranchRenderer.cs @@ -32,6 +32,7 @@ You should have received a copy of the GNU Affero General Public License using iText.Layout.Properties; using iText.Layout.Renderer; using iText.StyledXmlParser.Css.Util; +using iText.StyledXmlParser.Exceptions; using iText.Svg; using iText.Svg.Css; using iText.Svg.Renderers; @@ -114,7 +115,7 @@ public virtual float[] GetRelativeTranslation() { public virtual float[] GetRelativeTranslation(SvgDrawContext context) { if (!moveResolved) { - ResolveTextMove(context); + ResolveRelativeTextMove(context); } return new float[] { xMove, yMove }; } @@ -126,7 +127,7 @@ public virtual bool ContainsRelativeMove() { public virtual bool ContainsRelativeMove(SvgDrawContext context) { if (!moveResolved) { - ResolveTextMove(context); + ResolveRelativeTextMove(context); } bool isNullMove = CssUtils.CompareFloats(0f, xMove) && CssUtils.CompareFloats(0f, yMove); // comparison to 0 @@ -134,15 +135,23 @@ public virtual bool ContainsRelativeMove(SvgDrawContext context) { } public virtual bool ContainsAbsolutePositionChange() { + return ContainsAbsolutePositionChange(new SvgDrawContext(null, null)); + } + + public virtual bool ContainsAbsolutePositionChange(SvgDrawContext context) { if (!posResolved) { - ResolveTextPosition(); + ResolveAbsoluteTextPosition(context); } return (xPos != null && xPos.Length > 0) || (yPos != null && yPos.Length > 0); } public virtual float[][] GetAbsolutePositionChanges() { + return GetAbsolutePositionChanges(new SvgDrawContext(null, null)); + } + + public virtual float[][] GetAbsolutePositionChanges(SvgDrawContext context) { if (!posResolved) { - ResolveTextPosition(); + ResolveAbsoluteTextPosition(context); } return new float[][] { xPos, yPos }; } @@ -166,12 +175,14 @@ public virtual TextRectangle GetTextRectangle(SvgDrawContext context, Point star // building of properly positioned rectangles without any drawing or visual properties applying. foreach (ISvgTextNodeRenderer child in children) { if (child is iText.Svg.Renderers.Impl.TextSvgBranchRenderer) { - startPoint = ((iText.Svg.Renderers.Impl.TextSvgBranchRenderer)child).GetStartPoint(context, startPoint); - if (child.ContainsAbsolutePositionChange() && textChunkRect != null) { + iText.Svg.Renderers.Impl.TextSvgBranchRenderer childText = (iText.Svg.Renderers.Impl.TextSvgBranchRenderer + )child; + startPoint = childText.GetStartPoint(context, startPoint); + if (childText.ContainsAbsolutePositionChange(context) && textChunkRect != null) { commonRect = GetCommonRectangleWithAnchor(commonRect, textChunkRect, rootX, textAnchorValue); // Start new text chunk. textChunkRect = null; - textAnchorValue = child.GetAttribute(SvgConstants.Attributes.TEXT_ANCHOR); + textAnchorValue = childText.GetAttribute(SvgConstants.Attributes.TEXT_ANCHOR); rootX = (float)startPoint.GetX(); } } @@ -196,7 +207,7 @@ public override Rectangle GetObjectBoundingBox(SvgDrawContext context) { if (objectBoundingBox == null) { // Handle white-spaces if (!whiteSpaceProcessed) { - SvgTextUtil.ProcessWhiteSpace(this, true); + SvgTextUtil.ProcessWhiteSpace(this, true, context); } objectBoundingBox = GetTextRectangle(context, null); } @@ -224,7 +235,7 @@ protected internal override void DoDraw(SvgDrawContext context) { } // Handle white-spaces if (!whiteSpaceProcessed) { - SvgTextUtil.ProcessWhiteSpace(this, true); + SvgTextUtil.ProcessWhiteSpace(this, true, context); } this.paragraph = new Paragraph(); this.paragraph.SetProperty(Property.FORCED_PLACEMENT, true); @@ -307,10 +318,10 @@ internal virtual void AddTextChild(Text text, SvgDrawContext drawContext) { //\cond DO_NOT_DOCUMENT internal virtual void PerformDrawing(SvgDrawContext context) { - if (this.ContainsAbsolutePositionChange()) { + if (this.ContainsAbsolutePositionChange(context)) { DrawLastTextChunk(context); // TODO: DEVSIX-2507 support rotate and other attributes - float[][] absolutePositions = this.GetAbsolutePositionChanges(); + float[][] absolutePositions = this.GetAbsolutePositionChanges(context); AffineTransform newTransform = GetTextTransform(absolutePositions, context); StartNewTextChunk(context, newTransform); } @@ -382,7 +393,7 @@ internal override void ApplyFillAndStrokeProperties(AbstractSvgNodeRenderer.Fill } //\endcond - private void ResolveTextMove(SvgDrawContext context) { + private void ResolveRelativeTextMove(SvgDrawContext context) { if (this.attributesAndStyles != null) { String xRawValue = this.attributesAndStyles.Get(SvgConstants.Attributes.DX); String yRawValue = this.attributesAndStyles.Get(SvgConstants.Attributes.DY); @@ -400,16 +411,37 @@ private void ResolveTextMove(SvgDrawContext context) { } } - private void ResolveTextPosition() { + private void ResolveAbsoluteTextPosition(SvgDrawContext context) { if (this.attributesAndStyles != null) { String xRawValue = this.attributesAndStyles.Get(SvgConstants.Attributes.X); String yRawValue = this.attributesAndStyles.Get(SvgConstants.Attributes.Y); - xPos = GetPositionsFromString(xRawValue); - yPos = GetPositionsFromString(yRawValue); + xPos = GetPositionsFromString(xRawValue, context, true); + yPos = GetPositionsFromString(yRawValue, context, false); posResolved = true; } } + private float[] GetPositionsFromString(String rawValuesString, SvgDrawContext context, bool isHorizontal) { + float[] result = null; + IList valuesList = SvgCssUtils.SplitValueList(rawValuesString); + if (!valuesList.IsEmpty()) { + result = new float[valuesList.Count]; + for (int i = 0; i < valuesList.Count; i++) { + String value = valuesList[i]; + if (CssDimensionParsingUtils.DeterminePositionBetweenValueAndUnit(value) == 0) { + throw new StyledXMLParserException(MessageFormatUtil.Format(StyledXMLParserException.NAN, value)); + } + if (isHorizontal) { + result[i] = ParseHorizontalLength(value, context); + } + else { + result[i] = ParseVerticalLength(value, context); + } + } + } + return result; + } + private static AffineTransform GetTextTransform(float[][] absolutePositions, SvgDrawContext context) { AffineTransform tf = new AffineTransform(); // If x is not specified, but y is, we need to correct for preceding text. @@ -427,18 +459,6 @@ private static AffineTransform GetTextTransform(float[][] absolutePositions, Svg return tf; } - private static float[] GetPositionsFromString(String rawValuesString) { - float[] result = null; - IList valuesList = SvgCssUtils.SplitValueList(rawValuesString); - if (!valuesList.IsEmpty()) { - result = new float[valuesList.Count]; - for (int i = 0; i < valuesList.Count; i++) { - result[i] = CssDimensionParsingUtils.ParseAbsoluteLength(valuesList[i]); - } - } - return result; - } - /// /// Adjust absolutely positioned text chunk (shift it to the start of view port, apply text anchor) and /// merge it with the common text rectangle. @@ -499,16 +519,17 @@ private void ApplyTextAnchor(String textAnchorValue, bool isRtl) { private Point GetStartPoint(SvgDrawContext context, Point basePoint) { double x = 0; double y = 0; - if (GetAbsolutePositionChanges()[0] != null) { - x = GetAbsolutePositionChanges()[0][0]; + float[][] absolutePosition = GetAbsolutePositionChanges(context); + if (absolutePosition[0] != null) { + x = absolutePosition[0][0]; } else { if (basePoint != null) { x = basePoint.GetX(); } } - if (GetAbsolutePositionChanges()[1] != null) { - y = GetAbsolutePositionChanges()[1][0]; + if (absolutePosition[1] != null) { + y = absolutePosition[1][0]; } else { if (basePoint != null) { diff --git a/itext/itext.svg/itext/svg/utils/SvgTextUtil.cs b/itext/itext.svg/itext/svg/utils/SvgTextUtil.cs index 623f14cd5..80437d5b9 100644 --- a/itext/itext.svg/itext/svg/utils/SvgTextUtil.cs +++ b/itext/itext.svg/itext/svg/utils/SvgTextUtil.cs @@ -110,7 +110,24 @@ public static String TrimTrailingWhitespace(String toTrim) { /// root of the text-renderer subtree /// true if this element is a leading element(either the first child or the first element after an absolute position change) /// + [System.ObsoleteAttribute(@"use ProcessWhiteSpace(iText.Svg.Renderers.Impl.TextSvgBranchRenderer, bool, iText.Svg.Renderers.SvgDrawContext) instead" + )] public static void ProcessWhiteSpace(TextSvgBranchRenderer root, bool isLeadingElement) { + ProcessWhiteSpace(root, isLeadingElement, new SvgDrawContext(null, null)); + } + + /// Process the whitespace inside the Text Tree. + /// + /// Process the whitespace inside the Text Tree. + /// Whitespace is collapsed and new lines are handled + /// A leading element in each subtree is handled different: the preceding whitespace is trimmed instead of kept + /// + /// root of the text-renderer subtree + /// true if this element is a leading element(either the first child or the first element after an absolute position change) + /// + /// the svg draw context + public static void ProcessWhiteSpace(TextSvgBranchRenderer root, bool isLeadingElement, SvgDrawContext context + ) { // When svg is parsed by jsoup it leaves all whitespace in text element as is. Meaning that // tab/space indented xml files will retain their tabs and spaces. // The following regex replaces all whitespace with a single space. @@ -135,9 +152,10 @@ public static void ProcessWhiteSpace(TextSvgBranchRenderer root, bool isLeadingE // If child is leaf, process contents, if it is branch, call function again. if (child is TextSvgBranchRenderer) { // Branch processing. - ProcessWhiteSpace((TextSvgBranchRenderer)child, child.ContainsAbsolutePositionChange() || isLeadingElement + TextSvgBranchRenderer childText = (TextSvgBranchRenderer)child; + ProcessWhiteSpace(childText, childText.ContainsAbsolutePositionChange(context) || isLeadingElement, context ); - ((TextSvgBranchRenderer)child).MarkWhiteSpaceProcessed(); + childText.MarkWhiteSpaceProcessed(); isLeadingElement = false; } if (child is TextLeafSvgNodeRenderer) { diff --git a/itext/itext.svg/itext/svg/utils/TransformUtils.cs b/itext/itext.svg/itext/svg/utils/TransformUtils.cs index 47fd03a38..1c32992bc 100644 --- a/itext/itext.svg/itext/svg/utils/TransformUtils.cs +++ b/itext/itext.svg/itext/svg/utils/TransformUtils.cs @@ -203,7 +203,7 @@ private static AffineTransform CreateSkewYTransformation(IList values) { if (values.Count != 1) { throw new SvgProcessingException(SvgExceptionMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); } - double tan = Math.Tan(MathUtil.ToRadians((float)CssDimensionParsingUtils.ParseFloat(values[0]))); + double tan = Math.Tan(MathUtil.ToRadians(ParseTransformationValue(values[0]))); //Differs from the notation in the PDF-spec for skews return new AffineTransform(1, tan, 0, 1, 0, 0); } @@ -215,7 +215,7 @@ private static AffineTransform CreateSkewXTransformation(IList values) { if (values.Count != 1) { throw new SvgProcessingException(SvgExceptionMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); } - double tan = Math.Tan(MathUtil.ToRadians((float)CssDimensionParsingUtils.ParseFloat(values[0]))); + double tan = Math.Tan(MathUtil.ToRadians(ParseTransformationValue(values[0]))); //Differs from the notation in the PDF-spec for skews return new AffineTransform(1, 0, tan, 1, 0, 0); } @@ -227,7 +227,7 @@ private static AffineTransform CreateRotationTransformation(IList values if (values.Count != 1 && values.Count != 3) { throw new SvgProcessingException(SvgExceptionMessageConstant.TRANSFORM_INCORRECT_NUMBER_OF_VALUES); } - double angle = MathUtil.ToRadians((float)CssDimensionParsingUtils.ParseFloat(values[0])); + double angle = MathUtil.ToRadians(ParseTransformationValue(values[0])); if (values.Count == 3) { float centerX = CssDimensionParsingUtils.ParseAbsoluteLength(values[1]); float centerY = CssDimensionParsingUtils.ParseAbsoluteLength(values[2]); @@ -294,5 +294,16 @@ private static IList GetValuesFromTransformationString(String transforma String numbers = transformation.JSubstring(transformation.IndexOf('(') + 1, transformation.IndexOf(')')); return SvgCssUtils.SplitValueList(numbers); } + + private static float ParseTransformationValue(String valueStr) { + float? valueParsed = CssDimensionParsingUtils.ParseFloat(valueStr); + if (valueParsed == null) { + throw new SvgProcessingException(MessageFormatUtil.Format(SvgExceptionMessageConstant.INVALID_TRANSFORM_VALUE + , valueStr)); + } + else { + return (float)valueParsed; + } + } } } diff --git a/itext/itext.svg/itext/svg/xobject/SvgImageXObject.cs b/itext/itext.svg/itext/svg/xobject/SvgImageXObject.cs index 8b1b1b134..adf724918 100644 --- a/itext/itext.svg/itext/svg/xobject/SvgImageXObject.cs +++ b/itext/itext.svg/itext/svg/xobject/SvgImageXObject.cs @@ -44,6 +44,10 @@ public class SvgImageXObject : PdfFormXObject { private bool isGenerated = false; + private bool isCreatedByImg = false; + + private bool isCreatedByObject = false; + private float em; private SvgDrawContext svgDrawContext; @@ -81,6 +85,30 @@ public SvgImageXObject(ISvgProcessorResult result, SvgDrawContext svgContext, fl this.svgDrawContext = svgContext; } + /// Set if SVG image is created from HTML img tag context + /// true if object is created from HTML img tag, false otherwise + public virtual void SetIsCreatedByImg(bool isCreatedByImg) { + this.isCreatedByImg = isCreatedByImg; + } + + /// Check if SVG image is created from HTML img tag context + /// true if object is created from HTML img tag, false otherwise + public virtual bool IsCreatedByImg() { + return isCreatedByImg; + } + + /// Set if SVG image is created from HTML object tag context + /// true if object is created from HTML object tag, false otherwise + public virtual void SetIsCreatedByObject(bool isCreatedByObject) { + this.isCreatedByObject = isCreatedByObject; + } + + /// Check if SVG image is created from HTML object tag context + /// true if object is created from HTML object tag, false otherwise + public virtual bool IsCreatedByObject() { + return isCreatedByObject; + } + /// If the SVG image is relative sized. /// /// If the SVG image is relative sized. This information @@ -93,33 +121,13 @@ public SvgImageXObject(ISvgProcessorResult result, SvgDrawContext svgContext, fl /// /// otherwise /// - /// + /// /// - public virtual bool IsRelativeSized() { + public override bool IsRelativeSized() { return isRelativeSized; } - /// Sets if the SVG image is relative sized. - /// - /// Sets if the SVG image is relative sized. This information - /// is used during image layouting to resolve it's relative size. - /// - /// - /// - /// - /// if the SVG image is relative sized, - /// - /// otherwise - /// - /// - /// - public virtual void SetRelativeSized(bool relativeSized) { - // TODO DEVSIX-8829 remove/deprecate this method after ticket will be done - isRelativeSized = relativeSized; - } - /// Returns processor result containing the SVG information. /// {ISvgProcessorResult} processor result. public virtual ISvgProcessorResult GetResult() { @@ -167,11 +175,8 @@ public virtual void Generate(PdfDocument document) { /// Updated XObject BBox for relative sized SVG image. /// the area width where SVG image will be drawn /// the area height where SVG image will be drawn - public virtual void UpdateBBox(float? areaWidth, float? areaHeight) { - // TODO DEVSIX-8829 change parameters to float, not Float - if (areaWidth != null && areaHeight != null) { - svgDrawContext.SetCustomViewport(new Rectangle((float)areaWidth, (float)areaHeight)); - } + public virtual void UpdateBBox(float areaWidth, float areaHeight) { + svgDrawContext.SetCustomViewport(new Rectangle(areaWidth, areaHeight)); Rectangle bbox = SvgCssUtils.ExtractWidthAndHeight(result.GetRootRenderer(), em, svgDrawContext); SetBBox(new PdfArray(bbox)); } diff --git a/port-hash b/port-hash index 9ec7545e8..31eca6a60 100644 --- a/port-hash +++ b/port-hash @@ -1 +1 @@ -f30448605fa9dd1829b16011c3962f1aba3233cf +8d4fbb6308e2126af33891bf5ad981ec9f2fd81b