Разместить текст в TextField IText - PullRequest
4 голосов
/ 15 января 2010

Извините, если существует подобное сообщение, как у меня, но я новичок на этом форуме, и я не нашел его.

У меня проблема с динамическим изменением размера TextField. Размер зависит от размера текста. Я заполняю существующий PDF - заполняю поля в AcroForm:

form.setField ("field", "value"); (и т. Д.)

Все нормально, но я также хочу установить текст (в TextField), размер которого больше размера поля. Как я могу динамически изменить размер TextField (после / до setField или, возможно, установить какое-либо свойство поля в процессе создания AcroForm), чтобы он соответствовал тексту (текст больше, чем TextField)? Этот TextField должен иметь размер, точно такой же, как размер текста, без изменения размера шрифта на меньший размер и без прокруток в этом TextField.

Заранее спасибо за помощь.

1 Ответ

7 голосов
/ 02 ноября 2010

Ну, это легко сделать противоположное тому, что вы хотите, измените размер шрифта, чтобы весь текст был виден. Вы просто устанавливаете размер шрифта на «0», а iText (или Acrobat, или любой другой) определяет, какой размер шрифта использовать на лету (в некоторых разумных пределах).


Чтобы определить длину данного фрагмента текста, вы можете позвонить myBaseFont.getWidthPoint( fieldValToBe, fontSize ). Затем вы можете изменить размер поля до , по которому вы звоните setField. iText по умолчанию отображает поля для вас, и этот рендеринг выполняется, когда вы можете setField. Изменение размера поля после слов не изменит внешний вид поля, если вы не вызовете setField снова.

Хорошо, так как вы можете изменить размер поля? iText не поддерживает это напрямую, поэтому вы должны делать это с низкоуровневыми PDF-объектами iText. Примерно так:

AcroFields.Item fldItem = myAcroFields.getFieldItem("fieldName");

for (int i =0; i < fldItem.size(); ++i) {
  // "widget" is the visible portion of the field
  PdfDictionary widgetDict = fldItem.getwidget(0);  

  // pdf rectangles are stored as [llx, lly, urx, ury]
  PdfArray rectArr = widgetDict.getAsArray(PdfName.RECT); // should never be null
  float origX = rectArr.getAsNumber(0).floatValue();
  // overwrite the old value.  
  rectArr.set( 2, new PdfNumber( origX + newWidth + FUDGE_FACTOR ) );
}

FUDGE_FACTOR должен учитывать толщину правой и левой границ. Я бы предположил 3-5 баллов, в зависимости от скошенных и плоских границ, толщины линий и так далее. Вы, вероятно, можете просто выбрать значение и пойти с ним.

Цикл, вероятно, не нужен, так как редко, когда более одного поля имеют одно имя. OTOH, если вы против этого, вам также может потребоваться пересчитать newWidth, потому что разные экземпляры не должны использовать один и тот же размер шрифта.

И, наконец, вам может потребоваться записать этот новый rectArr в «объединенную» версию элемента, а также в версию виджета. iText почти всегда работает с объединенной версией при манипулировании полем, потому что все возможные пары ключ / значение находятся там, где вам, возможно, придется проверить значения родительского поля с версией виджета.

Ото, данные «слито» и «виджет» должен разделять один и тот же прямоугольник PdfArray, что делает точку спорной. «Rect» является значением «leaf» и никогда не будет унаследовано от родителя, поэтому массив виджета будет «скопирован» в объединенном словаре ... таким образом, он будет использоваться совместно. В любом случае вы сможете проверить это довольно легко.

assert item.getWidget(0).getAsArray(PdfName.RECT) ==
       item.getMerged(0).getAsArray(PdfName.RECT);

Обратите внимание, что это ==, а не .equals. Я не думаю, что у PdfArray есть и equals(), так что этот момент не так уж и актуален.

О, и только потому, что у меня действительно есть работа, я позволю вам выяснить, как получить BaseFont из поля самостоятельно, с толчком в правильном направлении. Вам понадобится DocumentFont через BaseFont.createFont(PRIndirectReference fontRef), и вы должны проверить Спецификации PDF , глава 12.7 (Интерактивные формы) и 9.5-9.10 (различные типы шрифтов ... которые DocumentFont будет в основном принимать заботиться о вас), чтобы узнать, где найти эту косвенную ссылку.

И чтобы понять, что это за косвенная ссылка, вам нужно прочитать главу 7.3, "Объекты", в частности 7.3.10, "Косвенные объекты".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...