Java iText-ColumnText设置矩形中的文本大小
我想将文本添加到一个矩形中(x,y,w,h)。文本应适合矩形的大小(表示它有最大大小,但仍包含在矩形中)。Java iText-ColumnText设置矩形中的文本大小,java,itext,Java,Itext,我想将文本添加到一个矩形中(x,y,w,h)。文本应适合矩形的大小(表示它有最大大小,但仍包含在矩形中)。 我试图根据BaseFont.getWidthPoint()测量文本大小,问题是最终文本大小不能适应矩形。看起来是这样的: 以下是我的尝试: PdfContentByte cb = writer.getDirectContent(); cb.saveState(); ColumnText ct = new ColumnText(writer.getDirectConte
我试图根据
BaseFont.getWidthPoint()
测量文本大小,问题是最终文本大小不能适应矩形。看起来是这样的:以下是我的尝试:
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;
}
PdfContentByte cb=writer.getDirectContent();
cb.saveState();
ColumnText ct=新的ColumnText(writer.getDirectContent());
Font Font=新字体(BaseFont.createFont());
宽度=80;
float maxFontSize=getMaxFontSize(BaseFont.createFont(),“text”,rectWidth);
字体设置大小(maxFontSize);
setText(新短语(“测试”,字体));
ct.setSimpleColumn(10,10,70);
ct.go();
//画矩形
cb.setColorStroke(基色蓝色);
cb.矩形(10,10,矩形宽度,70);
cb.stroke();
cb.restoreState();
//根据矩形宽度获取最大字体大小
私有静态浮点getMaxFontSize(BaseFont bf、字符串文本、整型宽度){
浮动测量宽度=1;
浮动字体大小=0.1f;
浮点数oldSize=0.1f;
while(测量宽度<宽度){
measureWidth=bf.getWidthPoint(文本,字体大小);
oldSize=fontSize;
fontSize+=0.1f;
}
返回旧尺寸;
}
你能告诉我哪里错了吗?另一个问题,我想测量宽度和高度,文本完全包含在矩形中,并且具有最大字体大小。有没有办法做到这一点 更新:以下是适用于我的完整源代码:
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;
}
private static float getMaxFontSize(BaseFont bf、字符串文本、整型宽度、整型高度){
//避免文本为空时出现无限循环
if(TextUtils.isEmpty(text)){
返回0.0f;
}
浮动字体大小=0.1f;
while(bf.getWidthPoint(文本,字体大小)高度){
fontSize-=0.1f;
maxHeight=测量高度(bf、文本、字体大小);
};
返回字体大小;
}
公共静态浮点度量值高(BaseFont BaseFont、字符串文本、浮点fontSize)
{
float ascend=baseFont.getAscentPoint(文本,fontSize);
float down=baseFont.getDescentPoint(文本,fontSize);
返回上升-下降;
}
这里有两个bug,都在
while(measureWidth < width){
measureWidth = bf.getWidthPoint(text, fontSize++);
}
while(测量宽度<宽度){
measureWidth=bf.getWidthPoint(文本,fontSize++);
}
measureWidth>=width
——换句话说,当您退出while
循环时,measureWidth
对于矩形来说已经太大了fontSize++
,这意味着在使用fontSize
计算measureWidth
后,您正在增加它。当您确实抽出时间返回它时,它比您刚才测试的值多出一个。因此,该方法的返回值将比您测试的最后一个值(由于第1点,该值已经太大)多一个ct.setSimpleColumn
中使用了错误的参数:
ct.setSimpleColumn(10, 10, rectWidth , 70);
与后面的cb.rectangle
调用不同
cb.rectangle(10, 10, rectWidth , 70);
其中有参数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);
枝节问题
除主要问题外,您的结果字体大小过大0.1;本质上,这是@David已经指出的一个错误
getMaxFontSize
方法中的主循环如下:
while(measureWidth < width){
measureWidth = bf.getWidthPoint(text, fontSize);
oldSize = fontSize;
fontSize += 0.1f;
}
更好的方法是只计算字符串宽度一次,而不使用循环,例如
private static float getMaxFontSize(BaseFont bf, String text, int width)
{
int textWidth = bf.getWidth(text);
return (1000 * width) / textWidth;
}
(此方法使用整数算法。如果您坚持精确匹配,请切换到浮点或双精度算法。)我花了很长时间使用二进制搜索方法来实现此功能,以查找适合矩形的字体大小。今天我在iText中偶然发现了一个有趣的方法 在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.
在我的iText版本中,它是静态的。
请参阅详细信息:我已更新了我的答案。对于第一个,因为我不需要获得测量宽度,所以在执行escape while循环时没有问题。第二,我尝试获取最后一个最大大小,但它不起作用,最后一个
t
字符仍会放在新行中。对。查看您的新代码-您已经修复了问题(2),但没有修复问题(1)。您正在使用oldSize
的值打破循环,对于该值,bf.getWidthPoint(text,oldSize)
已经大于width
-也就是说,它已经太大了。您不应该更改问题中的代码-应该在末尾附加任何新代码。否则,这个问题就变得毫无意义,对该网站的任何未来用户都毫无用处。我想测量宽度和高度,其中文本完全包含在矩形中,并且具有最大字体大小。-你的意思是作为一个单行线(这是你当前代码的标题),还是你也希望允许换行以最好地填充矩形?我只需要一行文字在这种情况下,应用我在回答中提到的修复,另外不允许字体大小大于矩形高。谢谢,我刚刚用一种适合我的测量高度的方法更新了我的问题。
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.