10
10
import com .itextpdf .basics .io .PdfTokenizer ;
11
11
import com .itextpdf .basics .io .RandomAccessFileOrArray ;
12
12
import com .itextpdf .basics .io .RandomAccessSourceFactory ;
13
- import com .itextpdf .core .font .PdfFontFactory ;
14
- import com .itextpdf .core .pdf .canvas .PdfCanvas ;
15
- import com .itextpdf .core .pdf .canvas .PdfCanvasConstants ;
16
13
import com .itextpdf .core .color .Color ;
17
14
import com .itextpdf .core .color .DeviceCmyk ;
18
15
import com .itextpdf .core .color .DeviceGray ;
19
16
import com .itextpdf .core .color .DeviceRgb ;
20
17
import com .itextpdf .core .font .PdfFont ;
18
+ import com .itextpdf .core .font .PdfFontFactory ;
21
19
import com .itextpdf .core .pdf .PdfArray ;
22
20
import com .itextpdf .core .pdf .PdfDictionary ;
23
21
import com .itextpdf .core .pdf .PdfDocument ;
32
30
import com .itextpdf .core .pdf .action .PdfAction ;
33
31
import com .itextpdf .core .pdf .annot .PdfAnnotation ;
34
32
import com .itextpdf .core .pdf .annot .PdfWidgetAnnotation ;
33
+ import com .itextpdf .core .pdf .canvas .PdfCanvas ;
34
+ import com .itextpdf .core .pdf .canvas .PdfCanvasConstants ;
35
35
import com .itextpdf .core .pdf .xobject .PdfFormXObject ;
36
36
import com .itextpdf .core .pdf .xobject .PdfImageXObject ;
37
+ import com .itextpdf .model .Canvas ;
38
+ import com .itextpdf .model .Property ;
39
+ import com .itextpdf .model .element .Paragraph ;
37
40
38
41
import java .io .IOException ;
39
42
import java .util .ArrayList ;
40
43
import java .util .HashSet ;
41
44
import java .util .List ;
42
45
import java .util .Set ;
43
- import java .util .StringTokenizer ;
44
46
45
47
/**
46
48
* This class represents a single field or field group in an {@link com.itextpdf.forms.PdfAcroForm
@@ -255,8 +257,26 @@ public static PdfTextFormField createText(PdfDocument doc, Rectangle rect, Strin
255
257
* @return a new {@link PdfTextFormField}
256
258
*/
257
259
public static PdfTextFormField createText (PdfDocument doc , Rectangle rect , String name , String value , PdfFont font , int fontSize ) {
260
+ return createText (doc , rect , name , value , font , fontSize , false );
261
+ }
262
+
263
+ /**
264
+ * Creates a named {@link PdfTextFormField text form field} with an initial
265
+ * value, with a specified font and font size.
266
+ *
267
+ * @param doc the {@link PdfDocument} to create the text field in
268
+ * @param rect the location on the page for the text field
269
+ * @param name the name of the form field
270
+ * @param value the initial value
271
+ * @param font a {@link PdfFont}
272
+ * @param fontSize a positive integer
273
+ * @param multiline true for multiline text field
274
+ * @return a new {@link PdfTextFormField}
275
+ */
276
+ public static PdfTextFormField createText (PdfDocument doc , Rectangle rect , String name , String value , PdfFont font , int fontSize , boolean multiline ) {
258
277
PdfWidgetAnnotation annot = new PdfWidgetAnnotation (rect );
259
278
PdfTextFormField field = new PdfTextFormField (annot , doc );
279
+ field .setMultiline (multiline );
260
280
field .font = font ;
261
281
field .fontSize = fontSize ;
262
282
field .setValue (value );
@@ -265,6 +285,41 @@ public static PdfTextFormField createText(PdfDocument doc, Rectangle rect, Strin
265
285
return field ;
266
286
}
267
287
288
+ /**
289
+ * Creates a named {@link PdfTextFormField multilined text form field} with an initial
290
+ * value, with a specified font and font size.
291
+ *
292
+ * @param doc the {@link PdfDocument} to create the text field in
293
+ * @param rect the location on the page for the text field
294
+ * @param name the name of the form field
295
+ * @param value the initial value
296
+ * @param font a {@link PdfFont}
297
+ * @param fontSize a positive integer
298
+ * @return a new {@link PdfTextFormField}
299
+ */
300
+ public static PdfTextFormField createMultilineText (PdfDocument doc , Rectangle rect , String name , String value , PdfFont font , int fontSize ) {
301
+ return createText (doc , rect , name , value , font , fontSize , true );
302
+ }
303
+
304
+ /**
305
+ * Creates a named {@link PdfTextFormField multiline text form field} with an initial
306
+ * value, and the form's default font specified in
307
+ * {@link com.itextpdf.forms.PdfAcroForm#getDefaultResources}.
308
+ *
309
+ * @param doc the {@link PdfDocument} to create the text field in
310
+ * @param rect the location on the page for the text field
311
+ * @param name the name of the form field
312
+ * @param value the initial value
313
+ * @return a new {@link PdfTextFormField}
314
+ */
315
+ public static PdfTextFormField createMultilineText (PdfDocument doc , Rectangle rect , String name , String value ) {
316
+ try {
317
+ return createText (doc , rect , name , value , PdfFontFactory .createFont (), DEFAULT_FONT_SIZE , true );
318
+ } catch (IOException e ) {
319
+ throw new PdfException (e .getLocalizedMessage ());
320
+ }
321
+ }
322
+
268
323
/**
269
324
* Creates an empty {@link PdfChoiceFormField choice form field}.
270
325
*
@@ -451,6 +506,7 @@ public static PdfButtonFormField createPushButton(PdfDocument doc, Rectangle rec
451
506
PdfButtonFormField field = new PdfButtonFormField (annot , doc );
452
507
field .setPushButton (true );
453
508
field .setFieldName (name );
509
+ field .text = caption ;
454
510
field .font = font ;
455
511
field .fontSize = fontSize ;
456
512
@@ -625,6 +681,8 @@ public <T extends PdfFormField> T setValue(String value) {
625
681
kid = ((PdfIndirectReference ) kid ).getRefersTo ();
626
682
}
627
683
PdfFormField field = new PdfFormField ((PdfDictionary ) kid );
684
+ field .font = font ;
685
+ field .fontSize = fontSize ;
628
686
field .setValue (value );
629
687
}
630
688
}
@@ -1794,32 +1852,38 @@ protected PdfFormXObject drawTextAppearance(Rectangle rect, PdfFont font, int fo
1794
1852
canvas .
1795
1853
beginVariableText ().
1796
1854
saveState ().
1797
- newPath ().
1798
- beginText ().
1799
- setFontAndSize (font , fontSize );
1855
+ newPath ();
1856
+
1857
+ Paragraph paragraph = new Paragraph (value ).setFont (font ).setFontSize (fontSize ).setMultipliedLeading (1 ).setPaddings (0 , 2 , 0 , 2 );
1858
+ setParagraphProperties (paragraph , value );
1800
1859
if (color != null ) {
1801
- canvas .setFillColor (color );
1802
- } else {
1803
- canvas .resetFillColorRgb ();
1860
+ paragraph .setFontColor (color );
1804
1861
}
1805
1862
Integer justification = getJustification ();
1806
1863
if (justification == null ) {
1807
1864
justification = 0 ;
1808
1865
}
1809
- drawTextAligned (canvas , justification , value , 2 , height / 2 - fontSize * 0.3f , font , fontSize );
1866
+ float x = 0 ;
1867
+ Property .TextAlignment textAlignment = Property .TextAlignment .LEFT ;
1868
+ if (justification == ALIGN_RIGHT ) {
1869
+ textAlignment = Property .TextAlignment .RIGHT ;
1870
+ x = rect .getWidth ();
1871
+ } else if (justification == ALIGN_CENTER ) {
1872
+ textAlignment = Property .TextAlignment .CENTER ;
1873
+ x = rect .getWidth () / 2 ;
1874
+ }
1875
+ new Canvas (canvas , getDocument (), new Rectangle (0 , -height , 0 , 2 * height )).showTextAligned (paragraph , x , rect .getHeight () / 2 , textAlignment , Property .VerticalAlignment .MIDDLE );
1876
+
1810
1877
canvas .
1811
- endText ().
1812
1878
restoreState ().
1813
1879
endVariableText ();
1814
1880
1815
-
1816
1881
PdfFormXObject xObject = new PdfFormXObject (new Rectangle (0 , 0 , width , height ));
1817
1882
xObject .getPdfObject ().getOutputStream ().writeBytes (stream .getBytes ());
1818
1883
1819
1884
return xObject ;
1820
1885
}
1821
1886
1822
-
1823
1887
/**
1824
1888
* Draws the visual appearance of multiline text in a form field.
1825
1889
*
@@ -1838,39 +1902,26 @@ protected PdfFormXObject drawMultiLineTextAppearance(Rectangle rect, PdfFont fon
1838
1902
float width = rect .getWidth ();
1839
1903
float height = rect .getHeight ();
1840
1904
1841
- List <String > strings = font .splitString (value , fontSize , width - 6 );
1842
-
1843
- value = "" ;
1844
- for (String str : strings ) {
1845
- value += str + '\n' ;
1846
- }
1847
- value = value .substring (0 , value .length () - 1 );
1848
-
1849
1905
drawBorder (canvas , width , height );
1850
1906
canvas .
1851
1907
beginVariableText ().
1852
1908
saveState ().
1853
1909
rectangle (3 , 3 , width - 6 , height - 6 ).
1854
1910
clip ().
1855
- newPath ().
1856
- beginText ().
1857
- setFontAndSize (font , fontSize );
1911
+ newPath ();
1912
+
1913
+ Canvas modelCanvas = new Canvas (canvas , getDocument (), new Rectangle (3 , 0 , width - 6 , height - 2 ));
1914
+ Paragraph paragraph = new Paragraph (value ).setFont (font ).setFontSize (fontSize ).setMargins (0 , 0 , 0 , 0 ).setMultipliedLeading (1 );
1915
+ setParagraphProperties (paragraph , value );
1916
+ if (value != null && value .length () > 0 ) {
1917
+ paragraph .setFontScript (Character .UnicodeScript .of (value .charAt (0 )));
1918
+ }
1858
1919
if (color != null ) {
1859
- canvas .setFillColor (color );
1860
- } else {
1861
- canvas .resetFillColorRgb ();
1920
+ paragraph .setFontColor (color );
1862
1921
}
1922
+ modelCanvas .add (paragraph );
1863
1923
1864
- canvas .setTextMatrix (4 , 5 );
1865
- StringTokenizer tokenizer = new StringTokenizer (value , "\n " );
1866
- while (tokenizer .hasMoreTokens ()) {
1867
- height -= fontSize * 1.2 ;
1868
- canvas .
1869
- setTextMatrix (3 , height ).
1870
- showText (tokenizer .nextToken ());
1871
- }
1872
1924
canvas .
1873
- endText ().
1874
1925
restoreState ().
1875
1926
endVariableText ();
1876
1927
@@ -2067,13 +2118,14 @@ protected void drawButton(PdfCanvas canvas, float x, float y, float width, float
2067
2118
lineTo (x + width - 1 , y + 1 ).
2068
2119
lineTo (x + width - 1 , y + height - 1 ).
2069
2120
stroke ().
2070
- resetFillColorRgb ().
2071
- beginText ().
2072
- setFontAndSize (font , fontSize ).
2073
- setTextMatrix (0 , y + (height - fontSize ) / 2 ).
2074
- showText (text ).
2075
- endText ().
2076
- restoreState ();
2121
+ resetFillColorRgb ();
2122
+
2123
+ Paragraph paragraph = new Paragraph (text ).setFont (font ).setFontSize (fontSize ).setMargin (0 ).setMultipliedLeading (1 ).
2124
+ setVerticalAlignment (Property .VerticalAlignment .MIDDLE );
2125
+ setParagraphProperties (paragraph , text );
2126
+ new Canvas (canvas , getDocument (), new Rectangle (0 , -height , width , 2 * height )).showTextAligned (paragraph , width / 2 , height / 2 , Property .TextAlignment .CENTER , Property .VerticalAlignment .MIDDLE );
2127
+
2128
+ canvas .restoreState ();
2077
2129
}
2078
2130
2079
2131
/**
@@ -2119,17 +2171,15 @@ private String obfuscatePassword(String text) {
2119
2171
return new String (pchar );
2120
2172
}
2121
2173
2122
- private void drawTextAligned ( PdfCanvas canvas , int alignment , String text , float x , float y , PdfFont font , int fontSize ) {
2123
- switch ( alignment ) {
2124
- case ALIGN_CENTER :
2125
- x = ( getRect ( getPdfObject ()). getWidth () - font . getWidth ( text , fontSize )) / 2 ;
2126
- break ;
2127
- case ALIGN_RIGHT :
2128
- x = ( getRect ( getPdfObject ()). getWidth () - font . getWidth ( text , fontSize ) );
2129
- break ;
2174
+ private void setParagraphProperties ( Paragraph paragraph , String value ) {
2175
+ // TODO this is temporary and will be replaced by script autodetection logic on model level
2176
+ if ( value != null && value . length () > 0 ) {
2177
+ Character . UnicodeScript script = Character . UnicodeScript . of ( value . charAt ( 0 )) ;
2178
+ paragraph . setFontScript ( script ) ;
2179
+ if ( script == Character . UnicodeScript . ARABIC || script == Character . UnicodeScript . HEBREW ) {
2180
+ paragraph . setBaseDirection ( Property . BaseDirection . RIGHT_TO_LEFT );
2181
+ }
2130
2182
}
2131
- canvas .setTextMatrix (x , y );
2132
- canvas .showText (text );
2133
2183
}
2134
2184
2135
2185
}
0 commit comments