IText7.1.3 добавление SVG в PdfDocument

Использование iText 7.1.3 и попытка добавить файл SVG в PdfDocument дает результат, где тексты длиной 1 не отображаются. Я нашел, где это может быть проблема. Прошу членов команды iText проверить это.

try {
      SvgConverter.drawOnCanvas(svgUrl.openStream(), pdfCanvas_, imageLlx, imageLly);
} catch (IOException e) {
      e.printStackTrace();
}

Вызов отладчика:

processText:255, DefaultSvgProcessor (com.itextpdf.svg.processors.impl)
visit:212, DefaultSvgProcessor (com.itextpdf.svg.processors.impl)
visit:204, DefaultSvgProcessor (com.itextpdf.svg.processors.impl)
visit:204, DefaultSvgProcessor (com.itextpdf.svg.processors.impl)
executeDepthFirstTraversal:153, DefaultSvgProcessor (com.itextpdf.svg.processors.impl)
process:106, DefaultSvgProcessor (com.itextpdf.svg.processors.impl)
process:768, SvgConverter (com.itextpdf.svg.converter)
convertToXObject:555, SvgConverter (com.itextpdf.svg.converter)
convertToXObject:590, SvgConverter (com.itextpdf.svg.converter)
drawOnCanvas:380, SvgConverter (com.itextpdf.svg.converter)

В функции processText, в строке для Обрезать конечные пробелы

trimmedText = SvgTextUtil.trimTrailingWhitespace("A");

для trimmedText = A (length = 1) возвращает пустую строку

/**
* Process the text contained in the text-node
*
* @param textNode node containing text to process
*/
private void processText(ITextNode textNode) {
    ISvgNodeRenderer parentRenderer = this.processorState.top();

    if (parentRenderer instanceof TextSvgNodeRenderer) {
        // 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.
        //TODO(RND-906) evaluate regex and trim methods
        String trimmedText = textNode.wholeText().replaceAll("\\s+", " ");
        //Trim leading whitespace
        trimmedText = SvgTextUtil.trimLeadingWhitespace(trimmedText);
        //Trim trailing whitespace
        trimmedText = SvgTextUtil.trimTrailingWhitespace(trimmedText);
        parentRenderer.setAttribute(SvgConstants.Attributes.TEXT_CONTENT, trimmedText);
    }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
285
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В trimTrailingWhitespace действительно есть ошибка, на которую вы указали

public static String trimTrailingWhitespace(String toTrim) {
    if (toTrim == null){
        return "";
    }
    int end = toTrim.length();
    if (end > 0) {
        int current = end - 1;
        while (current > 0) {
            char currentChar = toTrim.charAt(current);
            if (Character.isWhitespace(currentChar) && !(currentChar == '\n' || currentChar == '\r')) {
                //if the character is whitespace and not a newline, increase current
                current--;
            } else {
                break;
            }
        }
        if (current == 0){
            return "";
        }else {
            return toTrim.substring(0, current + 1);
        }
    }else{
        return toTrim;
    }
}

Как уже указывает комментарий //if the character is whitespace and not a newline, increase current, за которым следует current--;, этот метод является копией trimLeadingWhitespace (где строка после идентичного комментария действительно увеличиваетсяcurrent), измененной для работы на другом конце параметра String. К сожалению, модификация была неправильной: если строка содержит непробельный символ в позиции 0, а после этого только пробелы, она ошибочно считается пустой.

Исправление заключалось бы в замене

while (current > 0)

к

while (current >= 0)

а также

if (current == 0)

к

if (current < 0)

С этим исправлением

if (end > 0) {
    [...]
}else{
    return toTrim;
}

рамка вокруг [...] становится ненужной. И петлю while можно было бы более компактно сформулировать как петлю for, например нравится:

public static String trimTrailingWhitespace(String toTrim) {
    if (toTrim == null) {
        return "";
    }
    int current = toTrim.length() - 1;
    for ( ; current >= 0; current--) {
        char currentChar = toTrim.charAt(current);
        if (!(Character.isWhitespace(currentChar) && !(currentChar == '\n' || currentChar == '\r'))) {
            break;
        }
    }
    return current < 0 ? "" : toTrim.substring(0, current + 1);
}

Другие вопросы по теме