Java iText- ColumnText 在矩形中设置文本适合大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20769881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iText- ColumnText set text fit size in Rectangle
提问by R4j
I want to add text into a rectangle(x,y,w,h). Text should be fitted size of rectangle (mean it has a maximum size but it still contains in rectangle).
I tried to measure the text size base on BaseFont.getWidthPoint()
The problem is the final text size can't fit the rect. It looks like this:
我想将文本添加到矩形(x,y,w,h)中。文本应该适合矩形的大小(意味着它有一个最大大小,但它仍然包含在矩形中)。
我试图BaseFont.getWidthPoint()
根据问题来测量文本大小问题是最终的文本大小不能适合矩形。它看起来像这样:
Here is my try:
这是我的尝试:
PdfContentByte cb = writer.getDirectContent();
cb.saveState();
ColumnText ct = new ColumnText(writer.getDirectContent());
Font font = new Font(BaseFont.createFont());
int rectWidth = 80;
float maxFontSize = getMaxFontSize(BaseFont.createFont(), "text", rectWidth );
font.setSize(maxFontSize);
ct.setText(new Phrase("test", font));
ct.setSimpleColumn(10, 10, rectWidth , 70);
ct.go();
// draw the rect
cb.setColorStroke(BaseColor.BLUE);
cb.rectangle(10, 10, rectWidth , 70);
cb.stroke();
cb.restoreState();
// get max font size base on rect width
private static float getMaxFontSize(BaseFont bf, String text, int width){
float measureWidth = 1;
float fontSize = 0.1f;
float oldSize = 0.1f;
while(measureWidth < width){
measureWidth = bf.getWidthPoint(text, fontSize);
oldSize = fontSize;
fontSize += 0.1f;
}
return oldSize;
}
Could you please tell me where I am wrong?
你能告诉我我错在哪里吗?
Another problem, I want to measure for both width and height, which text completely contains in rectangle and has the maximum font size. Is there any way to do this?
另一个问题,我想测量宽度和高度,哪个文本完全包含在矩形中并且具有最大字体大小。有没有办法做到这一点?
Update: here is the complete source code that worked for me:
更新:这是对我有用的完整源代码:
private static float getMaxFontSize(BaseFont bf, String text, int width, int height){
// avoid infinite loop when text is empty
if(TextUtils.isEmpty(text)){
return 0.0f;
}
float fontSize = 0.1f;
while(bf.getWidthPoint(text, fontSize) < width){
fontSize += 0.1f;
}
float maxHeight = measureHeight(bf, text, fontSize);
while(maxHeight > height){
fontSize -= 0.1f;
maxHeight = measureHeight(bf, text, fontSize);
};
return fontSize;
}
public static float measureHeight(BaseFont baseFont, String text, float fontSize)
{
float ascend = baseFont.getAscentPoint(text, fontSize);
float descend = baseFont.getDescentPoint(text, fontSize);
return ascend - descend;
}
采纳答案by mkl
The main issue
主要问题
The main issue is that you use the wrong arguments in ct.setSimpleColumn
:
主要问题是您在ct.setSimpleColumn
以下内容中使用了错误的参数:
ct.setSimpleColumn(10, 10, rectWidth , 70);
In contrast to the later cb.rectangle
call
与后来的cb.rectangle
电话相反
cb.rectangle(10, 10, rectWidth , 70);
which has arguments float x, float y, float w, float h
(w
and h
being width and height) the method ct.setSimpleColumn
has arguments float llx, float lly, float urx, float ury
(llbeing lower leftand urbeing upper right). Thus your ct.setSimpleColumn
should look like this:
它有参数float x, float y, float w, float h
(w
并且h
是宽度和高度)该方法ct.setSimpleColumn
有参数float llx, float lly, float urx, float ury
(ll是左下角,ur是右上角)。因此你ct.setSimpleColumn
应该看起来像这样:
ct.setSimpleColumn(10, 10, 10 + rectWidth, 10 + 70);
A side issue
一个侧面问题
In addition to the main issue your result font size is 0.1 too large; essentially this is an error already pointed out by @David.
除了主要问题之外,您的结果字体大小为 0.1 太大;本质上,这是@David 已经指出的错误。
Your main loop in your getMaxFontSize
method is this:
您getMaxFontSize
方法中的主循环是这样的:
while(measureWidth < width){
measureWidth = bf.getWidthPoint(text, fontSize);
oldSize = fontSize;
fontSize += 0.1f;
}
This essentially results in oldSize
(which eventually is returned) being the first font size which does notfit. You could fix this by instead using
这基本上导致oldSize
(最终返回)是第一个不适合的字体大小。你可以通过使用来解决这个问题
while(bf.getWidthPoint(text, fontSize) < width){
oldSize = fontSize;
fontSize += 0.1f;
}
Even better would be an approach only calculating the string width once, not using a loop at all, e.g.
更好的是只计算一次字符串宽度的方法,根本不使用循环,例如
private static float getMaxFontSize(BaseFont bf, String text, int width)
{
int textWidth = bf.getWidth(text);
return (1000 * width) / textWidth;
}
(This method uses integer arithmetic. If you insist on an exact fit, switch to float or double arithmetic.)
(此方法使用整数算术。如果您坚持精确拟合,请切换到浮点或双精度算术。)
回答by Dawood ibn Kareem
There are two bugs here, both in
这里有两个错误,都在
while(measureWidth < width){
measureWidth = bf.getWidthPoint(text, fontSize++);
}
- You're staying in the loop until
measureWidth >= width
- in other words, by the time you escape from thewhile
loop,measureWidth
is already too big for the rectangle. - You're doing
fontSize++
, which means that after you've usedfontSize
to calculatemeasureWidth
, you're increasing it. When you do get round to returning it, it's one more than the value you just tested. So the return value from the method will be one more than the last value that you tested (which, due to point 1., was already too big).
- 您一直停留在循环中,直到
measureWidth >= width
- 换句话说,当您从while
循环中逃脱时,measureWidth
对于矩形来说已经太大了。 - 你在做
fontSize++
,这意味着在你使用fontSize
了计算之后measureWidth
,你正在增加它。当您确实要返回它时,它比您刚刚测试的值多 1。因此,该方法的返回值将比您测试的最后一个值多一个(由于第 1 点,该值已经太大了)。
回答by Дмитрий Игоревич
I've spent quite a while to implement such functionality using binary search method to find rectangle fitting font size. And today i stumbled upon an interesting method in iText...
我花了很长时间来使用二进制搜索方法来实现这样的功能,以找到适合字体大小的矩形。今天我在 iText 中偶然发现了一个有趣的方法......
It is quite a new method in iText ColumnText
;
这是 iText 中相当新的方法ColumnText
;
public float fitText(Font font, String text, Rectangle rect, float maxFontSize, int runDirection)
//Fits the text to some rectangle adjusting the font size as needed.
In my version of iText it is static. See details: http://developers.itextpdf.com/reference/com.itextpdf.text.pdf.ColumnText
在我的 iText 版本中,它是静态的。查看详情:http: //developers.itextpdf.com/reference/com.itextpdf.text.pdf.ColumnText