Eh bien, il est facile de faire le contraire de ce que vous voulez, changer la taille de la police de sorte que tout le texte est visible. Vous venez de définir la taille de la police à '0', et iText (ou Acrobat, ou autre) détermine la taille de police à utiliser à la volée (dans certaines limites raisonnables).
Pour déterminer la longueur d'un morceau donné de texte, vous pouvez appeler myBaseFont.getWidthPoint(fieldValToBe, fontSize)
. Ensuite, vous pouvez dimensionner le champ avant vous appelez setField
. iText affiche par défaut les apparences de champs, et ce rendu est fait quand vous le pouvez setField
. La modification de la taille du champ afterwords ne modifie pas l'apparence du champ sauf si vous appelez de nouveau setField
.
Bon, alors comment changer la taille du champ? iText ne supporte pas cela directement, donc vous devez le faire avec les objets PDF de bas niveau d'iText. Quelque chose comme ceci:
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 doit tenir compte des bonnes & épaisseurs de frontière gauche. Je devinerais 3-5 points, en fonction des bordures biseautées et plates, de l'épaisseur de la ligne et ainsi de suite. Vous pouvez probablement juste choisir une valeur et aller avec.
La boucle est probablement inutile, car il est rare que plus d'un champ partage un nom. OTOH, si c'est ce que vous avez à faire, vous devrez peut-être également recalculer newWidth
car différentes instances n'ont pas besoin de partager la même taille de police. Enfin, vous devrez peut-être écrire ce nouveau rectArr dans la version "fusionnée" de l'élément ainsi que dans la version du widget. iText fonctionne presque universellement avec la version fusionnée lors de la manipulation d'un champ car toutes les paires clé/valeur possibles sont là, où vous devrez peut-être vérifier les valeurs du champ parent avec la version du widget.
OTOH, une donnée "fusionnée" et "widget" devrait partager le même rectangle PdfArray
, rendant le point discutable. "Rect" est une valeur "feuille" et ne sera jamais héritée d'un parent, donc le tableau du widget aura été "copié superficiellement" dans le dictionnaire fusionné ... le partageant ainsi. Dans tous les cas, vous devriez pouvoir le vérifier assez facilement.
assert item.getWidget(0).getAsArray(PdfName.RECT) ==
item.getMerged(0).getAsArray(PdfName.RECT);
Notez que c'est ==
pas .equals
. Je ne pense pas PdfArray a un equals()
, donc ce point n'est pas tout ce qui concerne non plus.Oh, et juste parce que j'ai vraiment du travail à faire, je vais vous laisser comprendre comment obtenir un BaseFont d'un champ par vous-même, avec un coup de pouce dans la bonne direction. Vous aurez besoin d'un DocumentFont
via BaseFont.createFont(PRIndirectReference fontRef)
, et vous devriez vérifier The PDF Spec, chapitre 12.7 (formulaires interactifs) et 9.5-9.10 (divers types de polices ... dont DocumentFont s'occupera en grande partie pour vous) pour savoir où trouver cette référence indirecte.
Et pour comprendre ce qu'est une référence indirecte, vous aurez besoin de lire le chapitre 7.3, «Objets», en particulier 7.3.10, «Objets indirects».
Je doute qu'il y ait d'autres questions comme celle-ci. Jamais entendu parler de quelqu'un ayant besoin de quelque chose comme ça avant, après avoir travaillé avec PDF pour> 13 ans. –