Как сделать подчеркнутый текст доступным с помощью iText 7

Я пытаюсь создать PDF-файл с нуля, и он должен быть доступен (PDF / UA). Однако у меня возникла проблема, когда я попытался добавить подчеркнутый текст. Средство проверки доступности пожаловалось, что Path не может иметь родительский диапазон. Когда я проверил фактический сгенерированный PDF-файл, я заметил, что путь не помечен как артефакт. У меня вопрос, как пометить этот путь? Или как правильно добавить подчеркнутый текст? Кодовый снайпер взорван:

        PdfDocument pdfDoc = new PdfDocument(new PdfWriter("output.pdf",
            (new WriterProperties()).AddUAXmpMetadata().SetPdfVersion(PdfVersion.PDF_1_7)));
        Document document = new Document(pdfDoc, PageSize.A4);

        //TAGGED PDF
        pdfDoc.SetTagged();
        pdfDoc.GetCatalog().SetViewerPreferences(new PdfViewerPreferences().SetDisplayDocTitle(true));
        pdfDoc.GetCatalog().SetLang(new PdfString("en-US"));
        PdfDocumentInfo info = pdfDoc.GetDocumentInfo();
        info.SetTitle("Decision No. 1234/12");

        Paragraph header = new Paragraph("HEADER");
        header.SetFont(fontDefault)
            .SetBold()
            .SetUnderline();//Set underline. A Path object was added by iText.
        header.GetAccessibilityProperties().SetRole(StandardRoles.H1);

        document.Add(header);

        document.Close();

        System.Diagnostics.Process process = new System.Diagnostics.Process();
        process.StartInfo = new System.Diagnostics.ProcessStartInfo("output.pdf") { UseShellExecute = true };
        process.Start();

РЕДАКТИРОВАТЬ: Похоже, единственный способ сделать подчеркивание доступным - использовать низкоуровневые функции. Я размещаю свой код ниже:

            PdfDocument pdfDoc = new PdfDocument(new PdfWriter("output.pdf",
                (new WriterProperties()).AddUAXmpMetadata().SetPdfVersion(PdfVersion.PDF_1_7)));
            Document document = new Document(pdfDoc, PageSize.A4);

            PdfFont font = PdfFontFactory.CreateFont("arial.ttf", true);

            //TAGGED PDF
            pdfDoc.SetTagged();
            pdfDoc.GetCatalog().SetViewerPreferences(new PdfViewerPreferences().SetDisplayDocTitle(true));
            pdfDoc.GetCatalog().SetLang(new PdfString("en-US"));
            PdfDocumentInfo info = pdfDoc.GetDocumentInfo();
            info.SetTitle("Decision No. 1234/12");

            //Method 1 - to create a underlined header
            //The Path added for the underline is not accessible (Not tagged as Artifact).
            Paragraph header = new Paragraph("HEADER");
            header.SetFont(font)
                .SetBold()
                .SetUnderline(); //Path created but not tagged as Artifact.
            header.GetAccessibilityProperties().SetRole(StandardRoles.H1);

            document.Add(header);

            //Method 2 - to create a underlined header
            //The Path added and properly tagged as Artifact
            PdfCanvas canvas = new PdfCanvas(pdfDoc.GetLastPage());

            TagTreePointer tagPointer = new TagTreePointer(pdfDoc);
            tagPointer.SetPageForTagging(pdfDoc.GetFirstPage());
            tagPointer.AddTag(StandardRoles.H1).AddTag(StandardRoles.SPAN);

            canvas
                .BeginText()
                .MoveText(50, 700)
                .SetFontAndSize(font, 12)
                .OpenTag(tagPointer.GetTagReference())
                .ShowText("HEADER")
                .CloseTag()
                .EndText();

            //Manually draw the underline (Path)
            float w = font.GetWidth("HEADER", 12);

            canvas
                .MoveTo(50, 700 - 1)
                .LineTo(50 + w, 700 - 1)
                .SetLineWidth(0.5F)
                .Stroke();

            //Close document
            document.Close();

            //Open the PDF
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            process.StartInfo = new System.Diagnostics.ProcessStartInfo("output.pdf") { UseShellExecute = true };
            process.Start();


person LeoX    schedule 01.04.2021    source источник


Ответы (2)


Следующий код подчеркивает текст и создает выходные данные PDF / UA, которые проходят проверку PAC3 и программу проверки Acrobat Preflight PDF / UA.

public void testUnderline() throws IOException {
    // Create PDF/UA with underline text
    String filename = "./results/Underline.pdf";
    WriterProperties properties = new WriterProperties();
    properties.addUAXmpMetadata().setPdfVersion(PdfVersion.PDF_1_7);
    PdfWriter writer = new PdfWriter(filename, properties);
    pdfDoc = new PdfDocument(writer);
    //Make document tagged
    pdfDoc.setTagged();
    pdfDoc.getCatalog().setLang(new PdfString("en-US"));
    pdfDoc.getCatalog().setViewerPreferences(new PdfViewerPreferences().setDisplayDocTitle(true));
    PdfDocumentInfo info = pdfDoc.getDocumentInfo();
    info.setTitle("Hello Underline!");
    document = new Document(pdfDoc);

    // Must embed font for PDF/UA
    byte[] inputBytes = Files.readAllBytes(Paths.get("./resources/fonts/opensans-regular.ttf"));
    boolean embedded = true;
    boolean cached = false;
    PdfFont font = PdfFontFactory.createFont(inputBytes, PdfEncodings.CP1252, embedded, cached);
  
    Text text = new Text("This is an underlined Text object");
    text.setFont(font);
    text.setFontSize(16F);
    text.setUnderline();
    Paragraph para = new Paragraph();
    para.add(text);
    document.add(para);
    document.close();
    System.out.println(CREATED + filename);
}
person tjackson    schedule 07.04.2021
comment
Кстати, у меня проблема с созданием вывода PDF / UA, содержащего гиперссылки. См. stackoverflow.com/questions/66873854/ Если вы догадались, я буду признателен за ответ. Спасибо - person tjackson; 07.04.2021
comment
К сожалению, он не проходит валидатор Commonlook. Вы используете ту же функцию SetUnderline, которая не работает должным образом. Однако низкоуровневые функции работают безупречно. Я отправлю код в качестве ответа позже. @tjackson - person LeoX; 08.04.2021
comment
Кстати, я опубликовал ответ на возникшую у вас проблему с гиперссылкой. Надеюсь, это поможет. @tjackson - person LeoX; 08.04.2021

Я подозреваю, что проблема в том, что для вывода PDF / UA требуется, чтобы все шрифты были встроены, и вы можете использовать встроенный шрифт. Чтобы использовать что-то вроде следующего для загрузки шрифта для встраивания.

byte[] inputBytes = Files.readAllBytes(Paths.get("./resources/fonts/opensans-regular.ttf"));
boolean embedded = true;
boolean cached = false;
PdfFont font = setFont(inputBytes, PdfEncodings.CP1252, embedded, cached);

Вам также может потребоваться создать объект Text, затем установить шрифт, размер точки, атрибуты подчеркивания для объекта Text и, наконец, добавить объект Text в абзац. Например,

Text text = new Text("HEADER");
text.setFont(font);
int pointSize = 10;
text.setFontSize(pointSize);
text.setUnderline();
person tjackson    schedule 06.04.2021
comment
Спасибо за ответ, но проблема не в этом. Я не включил код, в котором был создан fontDefault. Вот. PdfFont fontDefault = PdfFontFactory.CreateFont (arial.ttf, true); Это встроенный шрифт TrueType. Настоящая проблема в том, что этот объект Path не был помечен как Artifact. Я не знаю, как пометить этот объект Path (подчеркнутый). - person LeoX; 06.04.2021
comment
Должна быть проблема с установкой подчеркивания в объекте Paragraph. - person tjackson; 07.04.2021