iText 背景不透明度
iText Background Opacity
我想使用 iText 7 将具有半透明背景的文本覆盖在现有文本上。为 text
元素设置背景不透明度似乎不起作用(第 1 行),我只能为整个 paragraph
(第 2 行)设置它:
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Text;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.VerticalAlignment;
import java.io.IOException;
public class TextBackgroundOpacityTest {
public static void main(String[] args) throws IOException {
try (Document doc = new Document( new PdfDocument(new PdfWriter("TextBackgroundOpacityTest.pdf")))) {
doc.add(new Paragraph(new String(new char[130]).replace("[=10=]", "A")));
// opacity doesn't work for text element
doc.showTextAligned(new Paragraph(new Text("missing background transparency").setBackgroundColor(ColorConstants.WHITE, .8f)), 500, 805, 0, TextAlignment.RIGHT, VerticalAlignment.TOP, 0);
// opacity for the whole paragraph works, but this is not what I want
doc.showTextAligned(new Paragraph("whole pharagraph background transparancy").setBackgroundColor(ColorConstants.WHITE, .8f), 500, 785, 0, TextAlignment.RIGHT, VerticalAlignment.TOP, 0);
}
}
}
如何将文本叠加到第 2 行所示的半透明背景上,但只是叠加文本,而不是整个段落?期望的输出:
要解决该解决方案,您可以使用自定义渲染器。如果您查看在为段落设置透明背景时调用的 BlockRenderer#drawBackground
,您可以在那里看到以下几行:
TransparentColor backgroundColor = new TransparentColor(background.getColor(), background.getOpacity());
drawContext.getCanvas().saveState().setFillColor(backgroundColor.getColor());
backgroundColor.applyFillTransparency(drawContext.getCanvas());
TextRenderer
,但是,有自己的实现,不尊重透明背景。但是我们可以自定义渲染器实现。我们需要从当前 TextRenderer
实现中复制粘贴相当多的代码,但好消息是我们不需要更改很多代码。只需在正确的位置插入两行:
TransparentColor backgroundColor = new TransparentColor(background.getColor(), background.getOpacity());
backgroundColor.applyFillTransparency(drawContext.getCanvas());
总的来说,我们得到以下实现:
private static class TextRendererWithBackgroundOpacity extends TextRenderer {
public TextRendererWithBackgroundOpacity(Text textElement) {
super(textElement);
}
@Override
public void drawBackground(DrawContext drawContext) {
Background background = this.<Background>getProperty(Property.BACKGROUND);
Float textRise = this.getPropertyAsFloat(Property.TEXT_RISE);
Rectangle bBox = getOccupiedAreaBBox();
Rectangle backgroundArea = applyMargins(bBox, false);
float bottomBBoxY = backgroundArea.getY();
float leftBBoxX = backgroundArea.getX();
if (background != null) {
boolean isTagged = drawContext.isTaggingEnabled();
PdfCanvas canvas = drawContext.getCanvas();
if (isTagged) {
canvas.openTag(new CanvasArtifact());
}
boolean backgroundAreaIsClipped = clipBackgroundArea(drawContext, backgroundArea);
canvas.saveState().setFillColor(background.getColor());
TransparentColor backgroundColor = new TransparentColor(background.getColor(), background.getOpacity());
backgroundColor.applyFillTransparency(drawContext.getCanvas());
canvas.rectangle(leftBBoxX - background.getExtraLeft(), bottomBBoxY + (float) textRise - background.getExtraBottom(),
backgroundArea.getWidth() + background.getExtraLeft() + background.getExtraRight(),
backgroundArea.getHeight() - (float) textRise + background.getExtraTop() + background.getExtraBottom());
canvas.fill().restoreState();
if (backgroundAreaIsClipped) {
drawContext.getCanvas().restoreState();
}
if (isTagged) {
canvas.closeTag();
}
}
}
@Override
public IRenderer getNextRenderer() {
return new TextRendererWithBackgroundOpacity((Text)modelElement);
}
}
要使 Text
元素使用自定义渲染器实现,只需调用 setNextRenderer
方法:
Text customTextElement = new Text("missing background transparency");
customTextElement.setNextRenderer(new TextRendererWithBackgroundOpacity(customTextElement));
顺便说一句,非常欢迎您将修复程序作为拉取请求提交给 iText(请遵循 contribution guidelines though). The repository is located at https://github.com/itext/itext7
我想使用 iText 7 将具有半透明背景的文本覆盖在现有文本上。为 text
元素设置背景不透明度似乎不起作用(第 1 行),我只能为整个 paragraph
(第 2 行)设置它:
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Text;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.VerticalAlignment;
import java.io.IOException;
public class TextBackgroundOpacityTest {
public static void main(String[] args) throws IOException {
try (Document doc = new Document( new PdfDocument(new PdfWriter("TextBackgroundOpacityTest.pdf")))) {
doc.add(new Paragraph(new String(new char[130]).replace("[=10=]", "A")));
// opacity doesn't work for text element
doc.showTextAligned(new Paragraph(new Text("missing background transparency").setBackgroundColor(ColorConstants.WHITE, .8f)), 500, 805, 0, TextAlignment.RIGHT, VerticalAlignment.TOP, 0);
// opacity for the whole paragraph works, but this is not what I want
doc.showTextAligned(new Paragraph("whole pharagraph background transparancy").setBackgroundColor(ColorConstants.WHITE, .8f), 500, 785, 0, TextAlignment.RIGHT, VerticalAlignment.TOP, 0);
}
}
}
如何将文本叠加到第 2 行所示的半透明背景上,但只是叠加文本,而不是整个段落?期望的输出:
要解决该解决方案,您可以使用自定义渲染器。如果您查看在为段落设置透明背景时调用的 BlockRenderer#drawBackground
,您可以在那里看到以下几行:
TransparentColor backgroundColor = new TransparentColor(background.getColor(), background.getOpacity());
drawContext.getCanvas().saveState().setFillColor(backgroundColor.getColor());
backgroundColor.applyFillTransparency(drawContext.getCanvas());
TextRenderer
,但是,有自己的实现,不尊重透明背景。但是我们可以自定义渲染器实现。我们需要从当前 TextRenderer
实现中复制粘贴相当多的代码,但好消息是我们不需要更改很多代码。只需在正确的位置插入两行:
TransparentColor backgroundColor = new TransparentColor(background.getColor(), background.getOpacity());
backgroundColor.applyFillTransparency(drawContext.getCanvas());
总的来说,我们得到以下实现:
private static class TextRendererWithBackgroundOpacity extends TextRenderer {
public TextRendererWithBackgroundOpacity(Text textElement) {
super(textElement);
}
@Override
public void drawBackground(DrawContext drawContext) {
Background background = this.<Background>getProperty(Property.BACKGROUND);
Float textRise = this.getPropertyAsFloat(Property.TEXT_RISE);
Rectangle bBox = getOccupiedAreaBBox();
Rectangle backgroundArea = applyMargins(bBox, false);
float bottomBBoxY = backgroundArea.getY();
float leftBBoxX = backgroundArea.getX();
if (background != null) {
boolean isTagged = drawContext.isTaggingEnabled();
PdfCanvas canvas = drawContext.getCanvas();
if (isTagged) {
canvas.openTag(new CanvasArtifact());
}
boolean backgroundAreaIsClipped = clipBackgroundArea(drawContext, backgroundArea);
canvas.saveState().setFillColor(background.getColor());
TransparentColor backgroundColor = new TransparentColor(background.getColor(), background.getOpacity());
backgroundColor.applyFillTransparency(drawContext.getCanvas());
canvas.rectangle(leftBBoxX - background.getExtraLeft(), bottomBBoxY + (float) textRise - background.getExtraBottom(),
backgroundArea.getWidth() + background.getExtraLeft() + background.getExtraRight(),
backgroundArea.getHeight() - (float) textRise + background.getExtraTop() + background.getExtraBottom());
canvas.fill().restoreState();
if (backgroundAreaIsClipped) {
drawContext.getCanvas().restoreState();
}
if (isTagged) {
canvas.closeTag();
}
}
}
@Override
public IRenderer getNextRenderer() {
return new TextRendererWithBackgroundOpacity((Text)modelElement);
}
}
要使 Text
元素使用自定义渲染器实现,只需调用 setNextRenderer
方法:
Text customTextElement = new Text("missing background transparency");
customTextElement.setNextRenderer(new TextRendererWithBackgroundOpacity(customTextElement));
顺便说一句,非常欢迎您将修复程序作为拉取请求提交给 iText(请遵循 contribution guidelines though). The repository is located at https://github.com/itext/itext7