Я думаю, что в целом настройка этого уровня в любом случае потребует вполне подходящего кода. Полностью переопределение draw
действительно может не сработать, поскольку некоторые подробности частной реализации не предоставляются публике c. Одним из вариантов, конечно, является дублирование этих деталей реализации в ваш пользовательский рендер.
Другая идея - подключить к PdfCanvas
, который выполняет низкоуровневое рисование. Вы можете создать свою собственную оболочку, подобную следующей, и делегировать все операции экземпляру PdfCanvas
, который вы оберните, за исключением пары «интересных» операций, в которых вы будете настраивать logi c и применять некоторые стили:
private static class PdfCanvasWrapper extends PdfCanvas {
private PdfCanvas delegate;
public PdfCanvasWrapper(PdfCanvas wrapped) {
super(wrapped.getContentStream(), wrapped.getResources(), wrapped.getDocument());
this.delegate = wrapped;
}
// "Interesting" methods
@Override
public PdfCanvas endText() {
delegate.endText();
delegate.setFillColor(ColorConstants.BLACK);
delegate.rectangle(10, 10, 300, 300);
delegate.fill();
return this;
}
// "Boring" methods - just delegate the implementation to the wrapped instance
@Override
public PdfCanvas beginVariableText() {
delegate.beginVariableText();
return this;
}
@Override
public PdfCanvas endVariableText() {
delegate.endVariableText();
return this;
}
// Override all other members like above
}
В этом случае ваш пользовательский текстовый рендерер подключит только правильный DrawContext
, но будет использовать операцию draw
по умолчанию:
private static class CustomTextRenderer extends TextRenderer {
public CustomTextRenderer(Text textElement) {
super(textElement);
}
@Override
public void draw(DrawContext drawContext) {
DrawContext newContext = new DrawContext(drawContext.getDocument(), new PdfCanvasWrapper(drawContext.getCanvas()));
super.draw(newContext);
}
@Override
public CustomTextRenderer getNextRenderer() {
return new CustomTextRenderer((Text) modelElement);
}
}
Main может выглядеть так:
Paragraph p = new Paragraph();
Text text = new Text("Hello");
text.setTextRenderingMode(TextRenderingMode.CLIP);
text.setNextRenderer(new CustomTextRenderer(text));
p.add(text);
В целом этот подход также является хакерским и, конечно, зависит от деталей реализации в той же степени, что и первоначальный подход, который вы предложили. Предложенный вами подход является более стабильным, но требует больше кода и, возможно, большей настройки при обновлении до новой версии библиотеки. Подход, который я описал выше, более хакерский, но приводит к меньшему количеству бизнес-логики c копирования и, возможно, проще в обслуживании.