|
16 | 16 | import com.itextpdf.layout.Canvas; |
17 | 17 | import com.itextpdf.layout.Document; |
18 | 18 | import com.itextpdf.layout.borders.Border; |
| 19 | +import com.itextpdf.layout.element.AbstractElement; |
19 | 20 | import com.itextpdf.layout.element.Cell; |
20 | 21 | import com.itextpdf.layout.element.Div; |
21 | 22 | import com.itextpdf.layout.element.IBlockElement; |
|
26 | 27 | import com.itextpdf.layout.element.Paragraph; |
27 | 28 | import com.itextpdf.layout.element.Table; |
28 | 29 | import com.itextpdf.layout.element.Text; |
| 30 | +import com.itextpdf.layout.font.FontProvider; |
| 31 | +import com.itextpdf.layout.font.FontSet; |
29 | 32 | import com.itextpdf.layout.properties.HorizontalAlignment; |
| 33 | +import com.itextpdf.layout.properties.Property; |
30 | 34 | import com.itextpdf.layout.properties.TextAlignment; |
31 | 35 | import com.itextpdf.layout.properties.UnitValue; |
32 | 36 | import de.tum.cit.aet.core.exception.PDFGenerationException; |
@@ -58,6 +62,9 @@ public class PDFBuilder { |
58 | 62 | private static final DeviceRgb PRIMARY_COLOR = new DeviceRgb(0x18, 0x72, 0xDD); |
59 | 63 | private static final DeviceRgb METADATA_COLOR = new DeviceRgb(0x8d, 0x8d, 0x8f); |
60 | 64 |
|
| 65 | + // Reused across exports so converted HTML uses the same Helvetica font as the rest of the document. |
| 66 | + private static final FontProvider HTML_FONT_PROVIDER = createHelveticaFontProvider(); |
| 67 | + |
61 | 68 | // ----------------- Font Sizes ----------------- |
62 | 69 | private static final float FONT_SIZE_MAIN_HEADING = 18f; |
63 | 70 |
|
@@ -517,18 +524,52 @@ private void addMetadata(PdfDocument pdfDoc, PdfFont normalFont) { |
517 | 524 | } |
518 | 525 | } |
519 | 526 |
|
| 527 | + /** |
| 528 | + * Creates a font provider exposing only the Helvetica family (regular, bold, italic and |
| 529 | + * bold-italic) with Helvetica as the default family, so HTML conversion stays on a single font. |
| 530 | + * |
| 531 | + * @return a font provider limited to the Helvetica family |
| 532 | + */ |
| 533 | + private static FontProvider createHelveticaFontProvider() { |
| 534 | + FontSet fontSet = new FontSet(); |
| 535 | + fontSet.addFont(StandardFonts.HELVETICA); |
| 536 | + fontSet.addFont(StandardFonts.HELVETICA_BOLD); |
| 537 | + fontSet.addFont(StandardFonts.HELVETICA_OBLIQUE); |
| 538 | + fontSet.addFont(StandardFonts.HELVETICA_BOLDOBLIQUE); |
| 539 | + return new FontProvider(fontSet, StandardFonts.HELVETICA); |
| 540 | + } |
| 541 | + |
| 542 | + /** |
| 543 | + * Drops the font sizes the HTML converter resolved onto nested elements so that they inherit the |
| 544 | + * size set on the surrounding block instead. Converted bold and italic runs carry their own font |
| 545 | + * size, which would otherwise take precedence and render them larger than the text around them. |
| 546 | + * Their font is deliberately kept, since that is what selects the bold or italic Helvetica variant. |
| 547 | + * |
| 548 | + * @param element the converted element whose descendants should inherit the block font size |
| 549 | + */ |
| 550 | + private static void clearNestedFontSizes(IElement element) { |
| 551 | + if (element instanceof AbstractElement<?> abstractElement) { |
| 552 | + for (IElement child : abstractElement.getChildren()) { |
| 553 | + child.deleteOwnProperty(Property.FONT_SIZE); |
| 554 | + clearNestedFontSizes(child); |
| 555 | + } |
| 556 | + } |
| 557 | + } |
| 558 | + |
520 | 559 | private List<IBlockElement> parseHtmlContent(String html, PdfFont normalFont) { |
521 | 560 | List<IBlockElement> elements = new ArrayList<>(); |
522 | 561 |
|
523 | 562 | try { |
524 | 563 | String processedHtml = html.replaceAll("<ol>", "<ul>").replaceAll("</ol>", "</ul>"); |
525 | 564 |
|
526 | 565 | ConverterProperties props = new ConverterProperties(); |
| 566 | + props.setFontProvider(HTML_FONT_PROVIDER); |
527 | 567 |
|
528 | 568 | List<IElement> pdfElements = HtmlConverter.convertToElements(processedHtml, props); |
529 | 569 |
|
530 | 570 | for (IElement element : pdfElements) { |
531 | 571 | if (element instanceof IBlockElement blockElement) { |
| 572 | + clearNestedFontSizes(blockElement); |
532 | 573 | if (blockElement instanceof Paragraph) { |
533 | 574 | ((Paragraph) blockElement).setFont(normalFont) |
534 | 575 | .setFontSize(FONT_SIZE_TEXT) |
|
0 commit comments