Skip to content

Commit 4ca8a9f

Browse files
committed
Implement unicode-range processing.
DEVSIX-1998
1 parent c05cebf commit 4ca8a9f

File tree

2 files changed

+106
-34
lines changed

2 files changed

+106
-34
lines changed

src/main/java/com/itextpdf/html2pdf/attach/ProcessorContext.java

Lines changed: 83 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ This file is part of the iText (R) project.
4444

4545
import com.itextpdf.html2pdf.ConverterProperties;
4646
import com.itextpdf.html2pdf.attach.impl.DefaultTagWorkerFactory;
47-
import com.itextpdf.html2pdf.attach.impl.OutlineHandler;
4847
import com.itextpdf.html2pdf.attach.impl.LinkContext;
48+
import com.itextpdf.html2pdf.attach.impl.OutlineHandler;
4949
import com.itextpdf.html2pdf.css.apply.ICssApplierFactory;
5050
import com.itextpdf.html2pdf.css.apply.impl.DefaultCssApplierFactory;
5151
import com.itextpdf.html2pdf.css.resolve.CssContext;
@@ -58,6 +58,7 @@ This file is part of the iText (R) project.
5858
import com.itextpdf.layout.font.FontInfo;
5959
import com.itextpdf.layout.font.FontProvider;
6060
import com.itextpdf.layout.font.FontSet;
61+
import com.itextpdf.layout.font.Range;
6162
import com.itextpdf.styledxmlparser.css.media.MediaDeviceDescription;
6263
import com.itextpdf.styledxmlparser.resolver.resource.ResourceResolver;
6364

@@ -66,60 +67,96 @@ This file is part of the iText (R) project.
6667
*/
6768
public class ProcessorContext {
6869

69-
/** The font provider. */
70+
/**
71+
* The font provider.
72+
*/
7073
private FontProvider fontProvider;
7174

72-
/** Temporary set of fonts used in the PDF. */
75+
/**
76+
* Temporary set of fonts used in the PDF.
77+
*/
7378
private FontSet tempFonts;
7479

75-
/** The resource resolver. */
80+
/**
81+
* The resource resolver.
82+
*/
7683
private ResourceResolver resourceResolver;
7784

78-
/** The device description. */
85+
/**
86+
* The device description.
87+
*/
7988
private MediaDeviceDescription deviceDescription;
8089

81-
/** The tag worker factory. */
90+
/**
91+
* The tag worker factory.
92+
*/
8293
private ITagWorkerFactory tagWorkerFactory;
8394

84-
/** The CSS applier factory. */
95+
/**
96+
* The CSS applier factory.
97+
*/
8598
private ICssApplierFactory cssApplierFactory;
8699

87-
/** The base URI. */
100+
/**
101+
* The base URI.
102+
*/
88103
private String baseUri;
89104

90-
/** Indicates whether an AcroForm needs to be created. */
105+
/**
106+
* Indicates whether an AcroForm needs to be created.
107+
*/
91108
private boolean createAcroForm;
92109

93-
/** The form field name resolver. */
110+
/**
111+
* The form field name resolver.
112+
*/
94113
private FormFieldNameResolver formFieldNameResolver;
95114

96-
/** The radio check resolver. */
115+
/**
116+
* The radio check resolver.
117+
*/
97118
private RadioCheckResolver radioCheckResolver;
98119

99-
/** The outline handler. */
120+
/**
121+
* The outline handler.
122+
*/
100123
private OutlineHandler outlineHandler;
101124

102-
/** Indicates whether the document should be opened in immediate flush or not **/
125+
/**
126+
* Indicates whether the document should be opened in immediate flush or not
127+
**/
103128
private boolean immediateFlush;
104129

105130
// Variable fields
106131

107-
/** The state. */
132+
/**
133+
* The state.
134+
*/
108135
private State state;
109136

110-
/** The CSS context. */
137+
/**
138+
* The CSS context.
139+
*/
111140
private CssContext cssContext;
112141

113-
/** The link context */
142+
/**
143+
* The link context
144+
*/
114145
private LinkContext linkContext;
115146

116-
/** The PDF document. */
147+
/**
148+
* The PDF document.
149+
*/
117150
private PdfDocument pdfDocument;
118151

119-
/** The Processor meta info */
152+
/**
153+
* The Processor meta info
154+
*/
120155
private IMetaInfo metaInfo;
121156

122-
/** Internal state variable to keep track of whether the processor is currently inside an inlineSvg*/
157+
/**
158+
* Internal state variable to keep track of whether the processor is currently inside an inlineSvg
159+
*/
123160
private boolean processingInlineSvg;
124161

125162
/**
@@ -316,25 +353,44 @@ public OutlineHandler getOutlineHandler() {
316353
* Add temporary font from @font-face.
317354
*
318355
* @param fontInfo the font info
319-
* @param alias the alias
356+
* @param alias the alias
320357
*/
321358
public void addTemporaryFont(FontInfo fontInfo, String alias) {
322-
if (tempFonts == null) tempFonts = new FontSet();
359+
if (tempFonts == null) {
360+
tempFonts = new FontSet();
361+
}
323362
tempFonts.addFont(fontInfo, alias);
324363
}
325364

326365
/**
327366
* Add temporary font from @font-face.
328367
*
329368
* @param fontProgram the font program
330-
* @param encoding the encoding
331-
* @param alias the alias
369+
* @param encoding the encoding
370+
* @param alias the alias
332371
*/
333372
public void addTemporaryFont(FontProgram fontProgram, String encoding, String alias) {
334-
if (tempFonts == null) tempFonts = new FontSet();
373+
if (tempFonts == null) {
374+
tempFonts = new FontSet();
375+
}
335376
tempFonts.addFont(fontProgram, encoding, alias);
336377
}
337378

379+
/**
380+
* Add temporary font from @font-face.
381+
*
382+
* @param fontProgram the font program
383+
* @param encoding the encoding
384+
* @param alias the alias
385+
* @param unicodeRange the unicode range
386+
*/
387+
public void addTemporaryFont(FontProgram fontProgram, String encoding, String alias, Range unicodeRange) {
388+
if (tempFonts == null) {
389+
tempFonts = new FontSet();
390+
}
391+
tempFonts.addFont(fontProgram, encoding, alias, unicodeRange);
392+
}
393+
338394
/**
339395
* Check fonts in font provider and temporary font set.
340396
*
@@ -379,16 +435,17 @@ public void reset(PdfDocument pdfDocument) {
379435
*
380436
* @return the baseUri
381437
*/
382-
public String getBaseUri(){
438+
public String getBaseUri() {
383439
return baseUri;
384440
}
385441

386442

387443
/**
388444
* Checks if immediateFlush is set
445+
*
389446
* @return true if immediateFlush is set, false if not.
390447
*/
391-
public boolean isImmediateFlush(){
448+
public boolean isImmediateFlush() {
392449
return immediateFlush;
393450
}
394451

src/main/java/com/itextpdf/html2pdf/attach/impl/DefaultHtmlProcessor.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,14 @@ This file is part of the iText (R) project.
7272
import com.itextpdf.layout.IPropertyContainer;
7373
import com.itextpdf.layout.element.Div;
7474
import com.itextpdf.layout.font.FontInfo;
75+
import com.itextpdf.layout.font.Range;
7576
import com.itextpdf.layout.property.Property;
77+
import com.itextpdf.styledxmlparser.css.CssDeclaration;
7678
import com.itextpdf.styledxmlparser.css.CssFontFaceRule;
7779
import com.itextpdf.styledxmlparser.css.ICssResolver;
7880
import com.itextpdf.styledxmlparser.css.pseudo.CssPseudoElementNode;
7981
import com.itextpdf.styledxmlparser.css.pseudo.CssPseudoElementUtil;
82+
import com.itextpdf.styledxmlparser.css.util.CssUtils;
8083
import com.itextpdf.styledxmlparser.node.IElementNode;
8184
import com.itextpdf.styledxmlparser.node.INode;
8285
import com.itextpdf.styledxmlparser.node.ITextNode;
@@ -330,7 +333,7 @@ private void visit(INode node) {
330333
if (element.name().equals(TagConstants.BODY) || element.name().equals(TagConstants.HTML))
331334
runApplier(element, tagWorker);
332335
for (INode childNode : element.childNodes()) {
333-
if(!context.isProcessingInlineSvg()) {
336+
if (!context.isProcessingInlineSvg()) {
334337
visit(childNode);
335338
}
336339
}
@@ -433,10 +436,11 @@ private void addFontFaceFonts() {
433436
if (cssResolver instanceof DefaultCssResolver) {
434437
for (CssFontFaceRule fontFace : ((DefaultCssResolver) cssResolver).getFonts()) {
435438
boolean findSupportedSrc = false;
436-
FontFace ff = FontFace.create(fontFace.getProperties());
439+
List<CssDeclaration> declarations = fontFace.getProperties();
440+
FontFace ff = FontFace.create(declarations);
437441
if (ff != null) {
438442
for (FontFace.FontFaceSrc src : ff.getSources()) {
439-
if (createFont(ff.getFontFamily(), src)) {
443+
if (createFont(ff.getFontFamily(), src, resolveUnicodeRange(declarations))) {
440444
findSupportedSrc = true;
441445
break;
442446
}
@@ -449,14 +453,25 @@ private void addFontFaceFonts() {
449453
}
450454
}
451455

456+
private Range resolveUnicodeRange(List<CssDeclaration> declarations) {
457+
Range range = null;
458+
for (CssDeclaration descriptor : declarations) {
459+
if ("unicode-range".equals(descriptor.getProperty())) {
460+
range = CssUtils.parseUnicodeRange(descriptor.getExpression());
461+
}
462+
}
463+
return range;
464+
}
465+
452466
/**
453467
* Creates a font and adds it to the context.
454468
*
455-
* @param fontFamily the font family
456-
* @param src the source of the font
469+
* @param fontFamily the font family
470+
* @param src the source of the font
471+
* @param unicodeRange the unicode range
457472
* @return true, if successful
458473
*/
459-
private boolean createFont(String fontFamily, FontFace.FontFaceSrc src) {
474+
private boolean createFont(String fontFamily, FontFace.FontFaceSrc src, Range unicodeRange) {
460475
if (!supportedFontFormat(src.format)) {
461476
return false;
462477
} else if (src.isLocal) { // to method with lazy initialization
@@ -476,7 +491,7 @@ private boolean createFont(String fontFamily, FontFace.FontFaceSrc src) {
476491
byte[] bytes = context.getResourceResolver().retrieveBytesFromResource(src.src);
477492
if (bytes != null) {
478493
FontProgram fp = FontProgramFactory.createFont(bytes, false);
479-
context.addTemporaryFont(fp, PdfEncodings.IDENTITY_H, fontFamily);
494+
context.addTemporaryFont(fp, PdfEncodings.IDENTITY_H, fontFamily, unicodeRange);
480495
return true;
481496
}
482497
} catch (Exception ignored) {
@@ -522,7 +537,7 @@ private void visitPseudoElement(IElementNode node, ITagWorker tagWorker, String
522537
if (!(TagConstants.INPUT.equals(node.name()) || TagConstants.TEXTAREA.equals(node.name())) || // TODO DEVSIX-1944: Resolve the issue and remove the line
523538
null == tagWorker
524539
|| !(tagWorker.getElementResult() instanceof IPlaceholderable)
525-
|| null == ((IPlaceholderable)tagWorker.getElementResult()).getPlaceholder()) {
540+
|| null == ((IPlaceholderable) tagWorker.getElementResult()).getPlaceholder()) {
526541
return;
527542
}
528543
break;

0 commit comments

Comments
 (0)