首页 > 解决方案 > 如何使用 itext7 在固定矩形内缩放文本?

问题描述

我正在尝试在 c# 中使用 itext7 制作一个 pdf 文档,该文档应该具有包含不同文本的固定矩形,这些文本应该在(不可见)矩形的边界内缩放。

我试图找到是否有自动缩放,但到目前为止只发现表单域的自动缩放。由于 pdf 将用于绘制文本,因此表单域没有用。

下面的代码是放置一个具有固定尺寸的“框”的片段,其中所有文本都应按比例显示(在一行上)

float fontSize = 22f;

Text lineTxt = new Text("A VERY LONG TEXT SHOULD BE SCALED").SetFont(lineFont).SetFontSize(fontSize);

iText.Kernel.Geom.Rectangle lineTxtRect = new iText.Kernel.Geom.Rectangle(100, posHeight - 200, (float)plotline.producttype_plotmaxwidthpts, (float)plotline.producttype_plotmaxheightpts);

Div lineDiv = new Div();
lineDiv.SetMaxHeight((float)plotline.producttype_plotmaxheightpts);
lineDiv.SetWidth((float)plotline.producttype_plotmaxwidthpts);
lineDiv.SetHeight((float)plotline.producttype_plotmaxheightpts);
lineDiv.SetVerticalAlignment(VerticalAlignment.MIDDLE);
lineDiv.SetBorder(new DashedBorder(1));

Paragraph linePara = new Paragraph().Add(lineTxt).
        SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).
        SetBorder(new DottedBorder(1)).
        SetMultipliedLeading(0.7f).
        SetMaxHeight((float)plotline.producttype_plotmaxheightpts).
        SetHeight((float)plotline.producttype_plotmaxheightpts);

lineDiv.Add(linePara);

new Canvas(PageCanvas, pdf, lineTxtRect).Add(lineDiv).SetBorder(new SolidBorder(1f));

标签: c#pdfasp.net-coreitext7

解决方案


iText 7 的布局模块允许您模拟元素的渲染(通过从元素创建渲染器树然后使用Layout方法)并检查它是否适合给定区域(通过检查LayoutResult对象)。因此,您可以做的是检查文本是否适合具有给定字体大小的固定矩形。然后你可以对字体大小进行二进制搜索。

这是一个示例代码:

PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));

Text lineTxt = new Text("A VERY LONG TEXT SHOULD BE SCALED");

iText.Kernel.Geom.Rectangle lineTxtRect = new iText.Kernel.Geom.Rectangle(100, 200, 100, 100);

Div lineDiv = new Div();
lineDiv.SetVerticalAlignment(VerticalAlignment.MIDDLE);
lineDiv.SetBorder(new DashedBorder(1));

Paragraph linePara = new Paragraph().Add(lineTxt)
    .SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).SetBorder(new DottedBorder(1))
    .SetMultipliedLeading(0.7f);
lineDiv.Add(linePara);

float fontSizeL = 1; // 1 is the font size that is definitely small enough to draw all the text 
float fontSizeR = 20; // 20 is the maximum value of the font size you want to use

Canvas canvas = new Canvas(new PdfCanvas(pdfDocument.AddNewPage()), pdfDocument, lineTxtRect);

// Binary search on the font size
while (Math.Abs(fontSizeL - fontSizeR) > 1e-1) {
    float curFontSize = (fontSizeL + fontSizeR) / 2;
    lineDiv.SetFontSize(curFontSize);
    // It is important to set parent for the current element renderer to a root renderer
    IRenderer renderer = lineDiv.CreateRendererSubTree().SetParent(canvas.GetRenderer());
    LayoutContext context = new LayoutContext(new LayoutArea(1, lineTxtRect));
    if (renderer.Layout(context).GetStatus() == LayoutResult.FULL) {
        // we can fit all the text with curFontSize
        fontSizeL = curFontSize;
    } else {
        fontSizeR = curFontSize;
    }
}

// Use the biggest font size that is still small enough to fit all the text
lineDiv.SetFontSize(fontSizeL);
canvas.Add(lineDiv);

pdfDocument.Close();

推荐阅读