Skip to content

Commit 61fdbaa

Browse files
committed
Add processing of calligraphic indic and arabic fonts
DEVSIX-1881 Autoported commit. Original commit hash: [fe2dd856]
1 parent f40bcfe commit 61fdbaa

File tree

10 files changed

+228
-6
lines changed

10 files changed

+228
-6
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.IO;
3+
using iText.Kernel.Utils;
4+
using iText.Test;
5+
using iText.Test.Attributes;
6+
7+
namespace iText.Html2pdf {
8+
public class FontProviderTest : ExtendedITextTest {
9+
public static readonly String sourceFolder = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
10+
.CurrentContext.TestDirectory) + "/resources/itext/html2pdf/FontProviderTest/";
11+
12+
public static readonly String destinationFolder = NUnit.Framework.TestContext.CurrentContext.TestDirectory
13+
+ "/test/itext/html2pdf/FontProviderTest/";
14+
15+
private const String TYPOGRAPHY_WARNING = "Cannot find pdfCalligraph module, which was implicitly required by one of the layout properties";
16+
17+
// Actually the results are invalid because there is no pdfCalligraph.
18+
// But we'd like to test how Free Sans works for a specific scripts.
19+
[NUnit.Framework.OneTimeSetUp]
20+
public static void BeforeClass() {
21+
CreateDestinationFolder(destinationFolder);
22+
}
23+
24+
/// <exception cref="System.IO.IOException"/>
25+
/// <exception cref="System.Exception"/>
26+
[NUnit.Framework.Test]
27+
[LogMessage(TYPOGRAPHY_WARNING, Count = 14)]
28+
public virtual void HebrewTest() {
29+
HtmlConverter.ConvertToPdf(new FileInfo(sourceFolder + "hebrew.html"), new FileInfo(destinationFolder + "hebrew.pdf"
30+
));
31+
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(destinationFolder + "hebrew.pdf", sourceFolder
32+
+ "cmp_hebrew.pdf", destinationFolder, "diffHebrew_"));
33+
}
34+
35+
/// <exception cref="System.IO.IOException"/>
36+
/// <exception cref="System.Exception"/>
37+
[NUnit.Framework.Test]
38+
public virtual void DevanagariTest() {
39+
HtmlConverter.ConvertToPdf(new FileInfo(sourceFolder + "devanagari.html"), new FileInfo(destinationFolder
40+
+ "devanagari.pdf"));
41+
NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(destinationFolder + "devanagari.pdf", sourceFolder
42+
+ "cmp_devanagari.pdf", destinationFolder, "diffDevanagari_"));
43+
}
44+
}
45+
}
Binary file not shown.
Binary file not shown.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2+
<html>
3+
<head></head>
4+
<body style="font-family: Times New Roman,Times,serif;">
5+
<h1>Result is invalid because there is no pdfCalligraph!</h1>
6+
<div>
7+
<b>अनुच्छेद १. सभी मनुष्यों को गौरव और अधिकारों के मामले में जन्मजात स्वतन्त्रता और समानता प्राप्त है । उन्हें बुद्धि और अन्तरात्मा की देन प्राप्त है और परस्पर उन्हें भाईचारे के भाव से बर्ताव करना चाहिए ।</b>
8+
9+
अनुच्छेद २. सभी को इस घोषणा में सन्निहित सभी अधिकारों और आज़ादियों को प्राप्त करने का हक़ है और इस मामले में जाति, वर्ण, लिंग, भाषा, धर्म, राजनीति या अन्य विचार-प्रणाली, किसी देश या समाज विशेष में जन्म, सम्पत्ति या किसी प्रकार की अन्य मर्यादा आदि के कारण भेदभाव का विचार न किया जाएगा । इसके अतिरिक्त, चाहे कोई देश या प्रदेश स्वतन्त्र हो, संरक्षित हो, या स्त्रशासन रहित हो या परिमित प्रभुसत्ता वाला हो, उस देश या प्रदेश की राजनैतिक, क्षेत्रीय या अन्तर्राष्ट्रीय स्थिति के आधार पर वहां के निवासियों के प्रति कोई फ़रक़ न रखा जाएगा ।
10+
</div>
11+
</body>
12+
</html>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2+
<html>
3+
<head></head>
4+
<body style="font-family: Times New Roman,Times,serif; direction: rtl;">
5+
<h1>Result is invalid because there is no pdfCalligraph!</h1>
6+
<div>
7+
<b>סעיף א. כל בני אדם נולדו בני חורין ושווים בערכם ובזכויותיהם. כולם חוננו בתבונה ובמצפון, לפיכך חובה עליהם לנהוג איש ברעהו ברוח של אחוה.</b>
8+
9+
סעיף ב. כל אדם זכאי לזכויות ולחרויות שנקבעו בהכרזש זו ללא הפליה כלשהיא מטעמי גזע, צבע, מין, לשון, דח, דעה פוליטית או דעה בבעיות אחרות, בגלל מוצא לאומי או חברתי, קנין, לידה או מעמד אחר. גדולה מזו, לא יופלה אדם על פי מעמדה המדיני, על פי סמכותה או על פי מעמדה הבינלאומי של המדינה או הארץ שאליה הוא שייך, דין שהארץ היא עצמאית, ובין שהיא נתונה לנאמנות, בין שהיא נטולת שלטון עצמי ובין שריבונותה מוגבלת כל הגבלה אחרת.
10+
</div>
11+
</body>
12+
</html>

itext/itext.html2pdf/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Reflection;
22
using System.Runtime.CompilerServices;
33
using System.Runtime.InteropServices;
4+
using Versions.Attributes;
45

56
[assembly: AssemblyTitle("iText.Html2Pdf")]
67
[assembly: AssemblyDescription("")]
@@ -27,6 +28,8 @@
2728

2829
[assembly: Guid("ff6ba09d-3655-466a-8c17-a7bfd3479ca1")]
2930

31+
[assembly: TypographyVersion("2.0.2.0")]
32+
3033
[assembly: AssemblyVersion("2.1.1.0")]
3134
[assembly: AssemblyFileVersion("2.1.1.0")]
3235
[assembly: AssemblyInformationalVersion("2.1.1-SNAPSHOT")]
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2018 iText Group NV
4+
Authors: iText Software.
5+
6+
This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU Affero General Public License version 3
8+
as published by the Free Software Foundation with the addition of the
9+
following permission added to Section 15 as permitted in Section 7(a):
10+
FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
11+
ITEXT GROUP. ITEXT GROUP DISCLAIMS THE WARRANTY OF NON INFRINGEMENT
12+
OF THIRD PARTY RIGHTS
13+
14+
This program is distributed in the hope that it will be useful, but
15+
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16+
or FITNESS FOR A PARTICULAR PURPOSE.
17+
See the GNU Affero General Public License for more details.
18+
You should have received a copy of the GNU Affero General Public License
19+
along with this program; if not, see http://www.gnu.org/licenses or write to
20+
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21+
Boston, MA, 02110-1301 USA, or download the license from the following URL:
22+
http://itextpdf.com/terms-of-use/
23+
24+
The interactive user interfaces in modified source and object code versions
25+
of this program must display Appropriate Legal Notices, as required under
26+
Section 5 of the GNU Affero General Public License.
27+
28+
In accordance with Section 7(b) of the GNU Affero General Public License,
29+
a covered work must retain the producer line in every PDF that is created
30+
or manipulated using iText.
31+
32+
You can be released from the requirements of the license by purchasing
33+
a commercial license. Buying such a license is mandatory as soon as you
34+
develop commercial activities involving the iText software without
35+
disclosing the source code of your own applications.
36+
These activities include: offering paid services to customers as an ASP,
37+
serving PDFs on the fly in a web application, shipping iText with a closed
38+
source product.
39+
40+
For more information, please contact iText Software Corp. at this
41+
42+
*/
43+
using System;
44+
45+
namespace Versions.Attributes {
46+
[AttributeUsage(AttributeTargets.Assembly)]
47+
internal class TypographyVersionAttribute : Attribute {
48+
internal string TypographyVersion { get; private set; }
49+
50+
internal TypographyVersionAttribute(string typographyVersion) {
51+
this.TypographyVersion = typographyVersion;
52+
}
53+
}
54+
}

itext/itext.html2pdf/itext.html2pdf.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<Compile Include="Properties\AssemblyInfo.cs" />
4949
<Compile Include="Properties\KeyVersionAttribute.cs" />
5050
<Compile Include="Html2PdfExtensions.cs" />
51+
<Compile Include="Properties\TypographyVersionAttribute.cs" />
5152
</ItemGroup>
5253
<ItemGroup>
5354
<ProjectReference Include="..\..\..\itextcore\itext\itext.forms\itext.forms.csproj" Condition="Exists('..\..\..\itextcore\itext\itext.forms\itext.forms.csproj')">

itext/itext.html2pdf/itext/html2pdf/resolver/font/DefaultFontProvider.cs

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,13 @@ source product.
4141
4242
*/
4343
using System;
44+
using System.Collections.Generic;
4445
using System.IO;
46+
using System.Reflection;
47+
using Common.Logging;
48+
using Versions.Attributes;
4549
using iText.IO.Util;
50+
using iText.Layout.Font;
4651
using iText.StyledXmlParser.Resolver.Font;
4752

4853
namespace iText.Html2pdf.Resolver.Font {
@@ -54,6 +59,10 @@ namespace iText.Html2pdf.Resolver.Font {
5459
/// series of fonts that are shipped with the add-on.
5560
/// </summary>
5661
public class DefaultFontProvider : BasicFontProvider {
62+
/// <summary>The logger.</summary>
63+
private static readonly ILog LOGGER = LogManager.GetLogger(typeof(iText.Html2pdf.Resolver.Font.DefaultFontProvider
64+
));
65+
5766
/// <summary>The path to the shipped fonts.</summary>
5867
private const String SHIPPED_FONT_RESOURCE_PATH = "iText.Html2Pdf.font.";
5968

@@ -62,6 +71,9 @@ public class DefaultFontProvider : BasicFontProvider {
6271
, "FreeMonoOblique.ttf", "FreeSans.ttf", "FreeSansBold.ttf", "FreeSansBoldOblique.ttf", "FreeSansOblique.ttf"
6372
, "FreeSerif.ttf", "FreeSerifBold.ttf", "FreeSerifBoldItalic.ttf", "FreeSerifItalic.ttf" };
6473

74+
private static readonly Range FREE_FONT_RANGE = new RangeBuilder().AddRange(0, 0x058F).AddRange(0x0E80, int.MaxValue
75+
).Create();
76+
6577
/// <summary>
6678
/// Creates a new
6779
/// <see cref="DefaultFontProvider"/>
@@ -85,22 +97,105 @@ public DefaultFontProvider()
8597
public DefaultFontProvider(bool registerStandardPdfFonts, bool registerShippedFreeFonts, bool registerSystemFonts
8698
)
8799
: base(registerStandardPdfFonts, registerSystemFonts) {
100+
// This range exclude Hebrew, Arabic, Syriac, Arabic Supplement, Thaana, NKo, Samaritan,
101+
// Mandaic, Syriac Supplement, Arabic Extended-A, Devanagari, Bengali, Gurmukhi, Gujarati,
102+
// Oriya, Tamil, Telugu, Kannada, Malayalam, Sinhala, Thai unicode blocks.
103+
// Those blocks either require pdfCalligraph or do not supported by GNU Free Fonts.
88104
if (registerShippedFreeFonts) {
89-
AddShippedFreeFonts();
105+
AddShippedFreeFonts(AddCalligraphFonts());
90106
}
91107
}
92108

93109
/// <summary>Adds the shipped free fonts.</summary>
94-
private void AddShippedFreeFonts() {
110+
private void AddShippedFreeFonts(Range rangeToLoad) {
95111
foreach (String fontName in SHIPPED_FONT_NAMES) {
96-
Stream stream = ResourceUtil.GetResourceStream(SHIPPED_FONT_RESOURCE_PATH + fontName);
97112
try {
98-
byte[] fontProgramBytes = StreamUtil.InputStreamToArray(stream);
99-
AddFont(fontProgramBytes);
113+
using (Stream stream = ResourceUtil.GetResourceStream(SHIPPED_FONT_RESOURCE_PATH + fontName)) {
114+
byte[] fontProgramBytes = StreamUtil.InputStreamToArray(stream);
115+
AddFont(fontProgramBytes, null, rangeToLoad);
116+
}
117+
}
118+
catch (Exception) {
119+
LOGGER.Error(iText.Html2pdf.LogMessageConstant.ERROR_LOADING_FONT);
120+
}
121+
}
122+
}
123+
124+
private Range AddCalligraphFonts() {
125+
String methodName = "LoadShippedFonts";
126+
Type klass = null;
127+
try {
128+
klass = GetTypographyUtilsClass();
129+
}
130+
catch (TypeLoadException) {
131+
}
132+
if (klass != null) {
133+
try {
134+
Type[] cArg = new Type[] { typeof(FontProvider) };
135+
MethodInfo m = klass.GetMethod(methodName);
136+
// an empty array of arguments is needed for autoport
137+
Object[] args = new Object[] { };
138+
List<byte[]> fontStreams = (List<byte[]>)m.Invoke(cArg, args);
139+
foreach (byte[] font in fontStreams) {
140+
AddFont(font);
141+
}
142+
// here we return a unicode range that excludes the loaded from the calligraph module fonts
143+
// i.e. the unicode range that is to be rendered with standard or shipped free fonts
144+
return FREE_FONT_RANGE;
100145
}
101146
catch (Exception) {
147+
LOGGER.Error(iText.Html2pdf.LogMessageConstant.ERROR_LOADING_FONT);
102148
}
103149
}
150+
return null;
151+
}
152+
153+
private static Type GetTypographyUtilsClass() {
154+
String partialName = "iText.Typography.Util.TypographyShippedFontsUtil, iText.Typography";
155+
String classFullName = null;
156+
157+
Assembly html2pdfAssembly = typeof(DefaultFontProvider).GetAssembly();
158+
try {
159+
Attribute customAttribute = html2pdfAssembly.GetCustomAttribute(typeof(TypographyVersionAttribute));
160+
if (customAttribute is TypographyVersionAttribute) {
161+
string typographyVersion = ((TypographyVersionAttribute) customAttribute).TypographyVersion;
162+
string format = "{0}, Version={1}, Culture=neutral, PublicKeyToken=8354ae6d2174ddca";
163+
classFullName = String.Format(format, partialName, typographyVersion);
164+
}
165+
} catch (Exception ignored) {
166+
}
167+
168+
Type type = null;
169+
if (classFullName != null) {
170+
String fileLoadExceptionMessage = null;
171+
try {
172+
type = System.Type.GetType(classFullName);
173+
} catch (FileLoadException fileLoadException) {
174+
fileLoadExceptionMessage = fileLoadException.Message;
175+
}
176+
if (type == null) {
177+
// try to find typography assembly by it's partial name and check if it refers to current version of itext core
178+
try {
179+
type = System.Type.GetType(partialName);
180+
} catch {
181+
// ignore
182+
}
183+
if (type != null) {
184+
bool doesReferToCurrentVersionOfCore = false;
185+
foreach (AssemblyName assemblyName in type.GetAssembly().GetReferencedAssemblies()) {
186+
if ("itext.io".Equals(assemblyName.Name)) {
187+
doesReferToCurrentVersionOfCore = assemblyName.Version.Equals(html2pdfAssembly.GetName().Version);
188+
break;
189+
}
190+
}
191+
if (!doesReferToCurrentVersionOfCore) {
192+
type = null;
193+
}
194+
}
195+
}
196+
}
197+
198+
return type;
104199
}
105200
}
106201
}

port-hash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
53b816e01ae0a2696e4b24f74b16b1d5b3490919
1+
fe2dd856e0f77647614a62a231148acdf0d9499e

0 commit comments

Comments
 (0)