Это ошибка в PDFBox.
(Ну, в вашем коде также есть проблема, но причина этой проблемы - в PDFBox.)
Ошибка
Проблема в том, что вызов PDColor.toRGB()
в
fillColorRgb = filledPath.getValue().toRGB();
повреждает само значение цвета для конкретного рассматриваемого цвета!
Рассматриваемое цветовое пространство является разделительным цветомпространство.Таким образом, PDColor.toRGB()
вызывает PDSeparation.toRGB(float[])
, используя в качестве параметра его член components
.
Если значение RGB для данного параметра еще не находится в кэше в цветовом пространстве, PDSeparation.toRGB(float[])
оценивает tintTransform
для заданных параметров.Для рассматриваемого цветового пространства преобразование оттенка является экземпляром PDFunctionType0
.Таким образом, вызывается PDFunctionType0.eval(float[])
.
К сожалению PDFunctionType0.eval(float[])
предполагает, что он может использовать параметр массива input
для своих собственных целей:
input[i] = clipToRange(input[i], domain.getMin(), domain.getMax());
input[i] = interpolate(input[i], domain.getMin(), domain.getMax(),
encodeValues.getMin(), encodeValues.getMax());
input[i] = clipToRange(input[i], 0, sizeValues[i] - 1);
Но этот массив является исходным PDColor
участник components
.Таким образом, эта оценка изменяет один компонент вашего цветового объекта с 0,172 до 43,688.
Позже toRGB
требует, чтобы этот цвет нашел 43,688 (или другое значение из-за дальнейших нежелательных изменений), что намного превышает максимальное значение1.0, поэтому они обрезают его до 1.0 и преобразуют оттуда.Но цвет в этом цветовом пространстве с компонентом 1.0 - это именно тот цвет, который используется для текста переднего плана.Таким образом, ваш код думает, что фон и передний план - это одно и то же.
Обходное решение
Чтобы исправить эту проблему, необходимо переписать метод PDFunctionType0.eval(float[])
, чтобы он не записывался в массив параметров.Быстрый способ сделать это - добавить
input = input.clone();
в начало этого метода PDFunctionType0.eval(float[])
.
Проблема в вашем коде
Ваш метод getTextPositionCenterPoint
использует поворот страницы для определения центра базовой линии заданного TextPosition
.Это верно только для текста, который после поворота страницы рисуется вертикально.В случае вашего документа, однако, это не так.Таким образом, вместо поворота страницы вам нужно проанализировать текстовую матрицу для определения фактического направления текста.
Это не будет иметь большого значения в вашем случае, потому что значение TextPosition.getWidth()
, которое вы используетеширина символов также рассчитывается на основе поворота страницы.Поскольку рассматриваемая страница не поворачивается, а направление текста поворачивается на 90 °, TextPosition.getWidth()
всегда возвращает 0 ... Возможно, вы захотите работать с getWidthDirAdj()
вместо ...