pdfbox - 在 PDFBOX 中围绕字符绘制边界框
问题描述
我想为我绘制到 pdf 的每个字符计算边界框,用于一堆不同的字体和大小。对于不同的字体,它似乎有不同的工作方式,例如 arial mt 与常规的大象。
例如,我一直在使用 - 符号来感受这一点,在 Arial 中,左下角是 65,440,大象是 7,165,但大象被画得更高,我找不到这个动作的来源。
大多数字体的工作方式更像 Arial,字体的顶部为 height/2,但这不适用于大象字体。
准确计算边界框需要包括哪些因素?
package com.nexiaem.nemocr.generatepdf;
import java.awt.Color;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont;
import org.apache.pdfbox.util.Vector;
/**
*
* @author bjames
*/
public class DrawBoundngBox {
public static void main(String[] args){
try{
PDPage thisPage = new PDPage(new PDRectangle(100, 40));
PDDocument document = new PDDocument();
document.addPage(thisPage);
//PDTrueTypeFont font = PDTrueTypeFont.loadTTF(document, new File("C:\\windows\\fonts\\elephnt.ttf"));
PDTrueTypeFont font = PDTrueTypeFont.loadTTF(document, new File("C:\\windows\\fonts\\arial.ttf"));
PDPageContentStream contentStream = new PDPageContentStream(document, thisPage);
int thisSize = 10;
float currentX = 0;
float width = 0;
String charactersToWrite = "aj";
char[] characters = charactersToWrite.toCharArray();
for(char thisChar: characters){
String thisCharString = Character.toString(thisChar);
width = (font.getWidthFromFont((int)thisChar) / 1000.0f) * thisSize;
GeneralPath charPath = font.getPath((int)thisChar);
Rectangle2D charRect = charPath.getBounds2D();
float charMinX = thisSize * (float)charRect.getMinX() / 1000.0f;
float charMaxX = thisSize * (float)charRect.getMaxX() / 1000.0f;
float charMinY = thisSize * (float)charRect.getMinY() / 1000.0f;
float charX = thisSize * (float)charRect.getX() / 1000.0f;
float charY = thisSize * (float)charRect.getY() / 1000.0f;
Vector displacement = font.getDisplacement((int)thisChar);
float charWidth = thisSize * (float)charRect.getWidth()/ 1000.0f;
width = charMaxX - charMinX;
float height = ((float)charRect.getHeight()/ 1000.0f) * thisSize;
contentStream.setStrokingColor(Color.red);
contentStream.moveTo(currentX + charMinX/2, 10 + charMinY/2);
contentStream.lineTo(currentX + charMinX/2, 10 + charMinY/2 + height/2);
contentStream.lineTo(currentX + charMinX/2 + width/2, 10 + charMinY/2 + height/2);
contentStream.lineTo(currentX + charMinX/2 + width/2, 10 + charMinY/2);
contentStream.lineTo(currentX + charMinX/2, 10 + charMinY/2);
contentStream.stroke();
contentStream.setStrokingColor(Color.green);
contentStream.moveTo(currentX + charX, 10 + charY);
contentStream.lineTo(currentX + charX, 10 + charY + height);
contentStream.lineTo(currentX + charX + width, 10 + charY + height);
contentStream.lineTo(currentX + charX + width, 10 + charY);
contentStream.lineTo(currentX + charX, 10 + charY);
contentStream.stroke();
contentStream.setStrokingColor(Color.yellow);
contentStream.moveTo(currentX, 10);
contentStream.lineTo(currentX, 10 + height);
contentStream.lineTo(currentX + width, 10 + height);
contentStream.lineTo(currentX + width, 10);
contentStream.lineTo(currentX, 10);
contentStream.stroke();
contentStream.beginText();
contentStream.setFont(font, thisSize);
contentStream.newLineAtOffset(currentX, 10);
currentX = currentX + 30;
contentStream.showText(thisCharString);
contentStream.endText();
}
contentStream.close();
document.save("C:\\temp\\DrawBB.pdf");
document.close();
}catch(IOException ex) {
Logger.getLogger(DrawBoundngBox.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
解决方案
推荐阅读
- django - 如何将一个表列复制到 Django 中的另一个表列?
- firebase - 通过 REST API 更新 Firebase Auth 用户声明
- ruby-on-rails - devise-jwt 使用的“拒绝列表”表是否无限保留所有过期的令牌?
- c++ - 在 C++ 数组中添加新项目
- reactjs - 元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“调色板”
- bash - 使用 grep 删除字符串中的重复项
- reactjs - 带有处理程序的自定义 useState 未按预期工作
- r - 使用 R 中的 data.table 进行分组条件过滤
- postgresql - 在 PostgreSQL 中使用数组或 json 格式化字符串列
- reactjs - jss-snapshot-serializer:jss 嵌套选择器或@media 查询不会添加到 json 快照 (JEST)