Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java iText-ColumnText设置矩形中的文本大小_Java_Itext - Fatal编程技术网

Java iText-ColumnText设置矩形中的文本大小

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

我想将文本添加到一个矩形中(x,y,w,h)。文本应适合矩形的大小(表示它有最大大小,但仍包含在矩形中)。
我试图根据
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.