То, что вы хотите, это DocumentFont
.Вы не можете создавать их напрямую, конструктор является частным пакетом, но BaseFont.createFont(PRIndirectReference)
сделает свое дело.
Так что вам просто нужно получить PRIndirectReference
для шрифта, который вы хотите."PR" приходят из PdfReader.Есть два способа найти шрифт, который вы ищете, и получить ссылку на него:
1) Перечислять каждый объект в PdfReader, отфильтровывая все, что не является PRStream
, оттуда отбрасывая все, чтоне /Type /Font
, а ищет шрифт с правильным именем.
public PRIndirectReference findNamedFont( PdfReader myReader, String desiredFontName) {
int objNum = 0;
PdfObject curObj;
do {
//The "Release" version doesn't keep a reference
//to the object so it can be GC'd later. Quite Handy
//when dealing with Really Big PDFs.
curObj = myReader.getPdfObjectRelease( objNum++ );
if (curObj instanceof PRStream) {
PRStream stream = (PRStream)curObj;
PdfName type = stream.getAsName(PdfName.TYPE);
if (PdfName.FONT.equals(type)) {
PdfString fontName = stream.getAsString(PdfName.BASEFONT);
if (desiredFontName.equals(fontName.toString())) {
return curObj.getIndRef();
}
}
}
} while (curObj != null);
return null;
}
2) Изучайте словари ресурсов ваших страниц /Font <<>>
, ищите шрифт с правильным именем.Имейте в виду, что у ресурсов формы XObject есть свои собственные ресурсы, которые вы должны проверить по следующему адресу:
public PRIndirectReference findFontInPage(PdfReader reader, String desiredName, int i) {
PdfDictionary page = reader.getPageN(i);
return findFontInResources(page.getAsDict(PdfName.RESOURCES), desiredName);
}
public PRIndirectReference findFontInResources(PdfDictionary resources, String desiredName) {
if (resources != null) {
PdfDictionary fonts = resources.getAsDict(PdfName.FONTS);
if (fonts != null) {
for (PdfName curFontName : fonts.keySet()) {
PRStream curFont (PRStream)= fonts.getAsStream(curFontName);
if (desiredName.equals(curFont.getAsString(PdfName.BASEFONT).toString()) {
return (PRIndirectReference) curFont.getIndirectReference();
}
}
}
PdfDictionary xobjs = resources.getAsDict(PdfName.XOBJECTS);
if (xobjs != null) {
for (PdfName curXObjName : xobjs.keySet()) {
PRStream curXObj = (PRStream)xobjs.getAsStream(curXObjName);
if (curXObj != null && PdfName.FORM.equals(curXObj.getAsName(PdfName.SUBTYPE)) {
PdfDictionary resources = curXObj.getAsDict(PdfName.RESOURCES);
PRIndirectReference ref = findFontInResources(resources, desiredName);
if (ref != null) {
return ref;
}
}
}
}
}
return null;
}
Любой из них даст вам PRIndirectReference
, который вы ищете.Затем вы звоните BaseFont.createFont(myPRRef)
, и у вас будет DocumentFont
, что вам нужно.Первый метод найдет любой шрифт в PDF, тогда как второй найдет только те шрифты, которые фактически используются.
Кроме того, для заданных шрифтов должен быть тег «6-random-letters-plus-sign»добавляется к имени шрифта.НЕ используйте подмножество шрифтов.Используемые символы могут не входить в подмножество, что приводит к тому, что я называю проблемой «arry ole».Звучит красиво и грязно, но на самом деле это было просто имя нашего продавца: «Гарри Воле» пропустил буквы в верхнем регистре, потому что я подменил какой-то шрифт, которого у меня не должно быть Many Moons Ago.
PS: никогдавставлять подмножества шрифтов, которые вы собираетесь использовать в поле формы.Нет, Буэно.
Обычный отказ от "я написал весь этот код в поле для ответов здесь" применяется, но я написал много такого рода кода, так что он может просто работать "из коробки".Скрестить пальцы.;)