1 /* 2 * Copyright 2005 by Paulo Soares. 3 * 4 * The contents of this file are subject to the Mozilla Public License Version 1.1 5 * (the "License"); you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at http://www.mozilla.org/MPL/ 7 * 8 * Software distributed under the License is distributed on an "AS IS" basis, 9 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 10 * for the specific language governing rights and limitations under the License. 11 * 12 * The Original Code is 'iText, a free JAVA-PDF library'. 13 * 14 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by 15 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. 16 * All Rights Reserved. 17 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer 18 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. 19 * 20 * Contributor(s): all the names of the contributors are added in the source code 21 * where applicable. 22 * 23 * Alternatively, the contents of this file may be used under the terms of the 24 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the 25 * provisions of LGPL are applicable instead of those above. If you wish to 26 * allow use of your version of this file only under the terms of the LGPL 27 * License and not to allow others to use your version of this file under 28 * the MPL, indicate your decision by deleting the provisions above and 29 * replace them with the notice and other provisions required by the LGPL. 30 * If you do not delete the provisions above, a recipient may use your version 31 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. 32 * 33 * This library is free software; you can redistribute it and/or modify it 34 * under the terms of the MPL as stated above or under the terms of the GNU 35 * Library General Public License as published by the Free Software Foundation; 36 * either version 2 of the License, or any later version. 37 * 38 * This library is distributed in the hope that it will be useful, but WITHOUT 39 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 40 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more 41 * details. 42 * 43 * If you didn't download this code from the following link, you should check if 44 * you aren't using an obsolete version: 45 * http://www.lowagie.com/iText/ 46 */ 47 package com.lowagie.text.pdf; 48 49 import java.io.IOException; 50 import com.lowagie.text.error_messages.MessageLocalization; 51 52 import com.lowagie.text.DocumentException; 53 import com.lowagie.text.Image; 54 import com.lowagie.text.Rectangle; 55 /** 56 * Creates a pushbutton field. It supports all the text and icon alignments. 57 * The icon may be an image or a template. 58 * <p> 59 * Example usage: 60 * <p> 61 * <PRE> 62 * Document document = new Document(PageSize.A4, 50, 50, 50, 50); 63 * PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf")); 64 * document.open(); 65 * PdfContentByte cb = writer.getDirectContent(); 66 * Image img = Image.getInstance("image.png"); 67 * PushbuttonField bt = new PushbuttonField(writer, new Rectangle(100, 100, 200, 200), "Button1"); 68 * bt.setText("My Caption"); 69 * bt.setFontSize(0); 70 * bt.setImage(img); 71 * bt.setLayout(PushbuttonField.LAYOUT_ICON_TOP_LABEL_BOTTOM); 72 * bt.setBackgroundColor(Color.cyan); 73 * bt.setBorderStyle(PdfBorderDictionary.STYLE_SOLID); 74 * bt.setBorderColor(Color.red); 75 * bt.setBorderWidth(3); 76 * PdfFormField ff = bt.getField(); 77 * PdfAction ac = PdfAction.createSubmitForm("http://www.submit-site.com", null, 0); 78 * ff.setAction(ac); 79 * writer.addAnnotation(ff); 80 * document.close(); 81 * </PRE> 82 * @author Paulo Soares (psoares@consiste.pt) 83 */ 84 public class PushbuttonField extends BaseField { 85 86 /** A layout option */ 87 public static final int LAYOUT_LABEL_ONLY = 1; 88 /** A layout option */ 89 public static final int LAYOUT_ICON_ONLY = 2; 90 /** A layout option */ 91 public static final int LAYOUT_ICON_TOP_LABEL_BOTTOM = 3; 92 /** A layout option */ 93 public static final int LAYOUT_LABEL_TOP_ICON_BOTTOM = 4; 94 /** A layout option */ 95 public static final int LAYOUT_ICON_LEFT_LABEL_RIGHT = 5; 96 /** A layout option */ 97 public static final int LAYOUT_LABEL_LEFT_ICON_RIGHT = 6; 98 /** A layout option */ 99 public static final int LAYOUT_LABEL_OVER_ICON = 7; 100 /** An icon scaling option */ 101 public static final int SCALE_ICON_ALWAYS = 1; 102 /** An icon scaling option */ 103 public static final int SCALE_ICON_NEVER = 2; 104 /** An icon scaling option */ 105 public static final int SCALE_ICON_IS_TOO_BIG = 3; 106 /** An icon scaling option */ 107 public static final int SCALE_ICON_IS_TOO_SMALL = 4; 108 109 /** 110 * Holds value of property layout. 111 */ 112 private int layout = LAYOUT_LABEL_ONLY; 113 114 /** 115 * Holds value of property image. 116 */ 117 private Image image; 118 119 /** 120 * Holds value of property template. 121 */ 122 private PdfTemplate template; 123 124 /** 125 * Holds value of property scaleIcon. 126 */ 127 private int scaleIcon = SCALE_ICON_ALWAYS; 128 129 /** 130 * Holds value of property proportionalIcon. 131 */ 132 private boolean proportionalIcon = true; 133 134 /** 135 * Holds value of property iconVerticalAdjustment. 136 */ 137 private float iconVerticalAdjustment = 0.5f; 138 139 /** 140 * Holds value of property iconHorizontalAdjustment. 141 */ 142 private float iconHorizontalAdjustment = 0.5f; 143 144 /** 145 * Holds value of property iconFitToBounds. 146 */ 147 private boolean iconFitToBounds; 148 149 private PdfTemplate tp; 150 151 /** 152 * Creates a new instance of PushbuttonField 153 * @param writer the document <CODE>PdfWriter</CODE> 154 * @param box the field location and dimensions 155 * @param fieldName the field name. If <CODE>null</CODE> only the widget keys 156 * will be included in the field allowing it to be used as a kid field. 157 */ PushbuttonField(PdfWriter writer, Rectangle box, String fieldName)158 public PushbuttonField(PdfWriter writer, Rectangle box, String fieldName) { 159 super(writer, box, fieldName); 160 } 161 162 /** 163 * Getter for property layout. 164 * @return Value of property layout. 165 */ getLayout()166 public int getLayout() { 167 return this.layout; 168 } 169 170 /** 171 * Sets the icon and label layout. Possible values are <CODE>LAYOUT_LABEL_ONLY</CODE>, 172 * <CODE>LAYOUT_ICON_ONLY</CODE>, <CODE>LAYOUT_ICON_TOP_LABEL_BOTTOM</CODE>, 173 * <CODE>LAYOUT_LABEL_TOP_ICON_BOTTOM</CODE>, <CODE>LAYOUT_ICON_LEFT_LABEL_RIGHT</CODE>, 174 * <CODE>LAYOUT_LABEL_LEFT_ICON_RIGHT</CODE> and <CODE>LAYOUT_LABEL_OVER_ICON</CODE>. 175 * The default is <CODE>LAYOUT_LABEL_ONLY</CODE>. 176 * @param layout New value of property layout. 177 */ setLayout(int layout)178 public void setLayout(int layout) { 179 if (layout < LAYOUT_LABEL_ONLY || layout > LAYOUT_LABEL_OVER_ICON) 180 throw new IllegalArgumentException(MessageLocalization.getComposedMessage("layout.out.of.bounds")); 181 this.layout = layout; 182 } 183 184 /** 185 * Getter for property image. 186 * @return Value of property image. 187 */ getImage()188 public Image getImage() { 189 return this.image; 190 } 191 192 /** 193 * Sets the icon as an image. 194 * @param image the image 195 */ setImage(Image image)196 public void setImage(Image image) { 197 this.image = image; 198 template = null; 199 } 200 201 /** 202 * Getter for property template. 203 * @return Value of property template. 204 */ getTemplate()205 public PdfTemplate getTemplate() { 206 return this.template; 207 } 208 209 /** 210 * Sets the icon as a template. 211 * @param template the template 212 */ setTemplate(PdfTemplate template)213 public void setTemplate(PdfTemplate template) { 214 this.template = template; 215 image = null; 216 } 217 218 /** 219 * Getter for property scaleIcon. 220 * @return Value of property scaleIcon. 221 */ getScaleIcon()222 public int getScaleIcon() { 223 return this.scaleIcon; 224 } 225 226 /** 227 * Sets the way the icon will be scaled. Possible values are 228 * <CODE>SCALE_ICON_ALWAYS</CODE>, <CODE>SCALE_ICON_NEVER</CODE>, 229 * <CODE>SCALE_ICON_IS_TOO_BIG</CODE> and <CODE>SCALE_ICON_IS_TOO_SMALL</CODE>. 230 * The default is <CODE>SCALE_ICON_ALWAYS</CODE>. 231 * @param scaleIcon the way the icon will be scaled 232 */ setScaleIcon(int scaleIcon)233 public void setScaleIcon(int scaleIcon) { 234 if (scaleIcon < SCALE_ICON_ALWAYS || scaleIcon > SCALE_ICON_IS_TOO_SMALL) 235 scaleIcon = SCALE_ICON_ALWAYS; 236 this.scaleIcon = scaleIcon; 237 } 238 239 /** 240 * Getter for property proportionalIcon. 241 * @return Value of property proportionalIcon. 242 */ isProportionalIcon()243 public boolean isProportionalIcon() { 244 return this.proportionalIcon; 245 } 246 247 /** 248 * Sets the way the icon is scaled. If <CODE>true</CODE> the icon is scaled proportionally, 249 * if <CODE>false</CODE> the scaling is done anamorphicaly. 250 * @param proportionalIcon the way the icon is scaled 251 */ setProportionalIcon(boolean proportionalIcon)252 public void setProportionalIcon(boolean proportionalIcon) { 253 this.proportionalIcon = proportionalIcon; 254 } 255 256 /** 257 * Getter for property iconVerticalAdjustment. 258 * @return Value of property iconVerticalAdjustment. 259 */ getIconVerticalAdjustment()260 public float getIconVerticalAdjustment() { 261 return this.iconVerticalAdjustment; 262 } 263 264 /** 265 * A number between 0 and 1 indicating the fraction of leftover space to allocate at the bottom of the icon. 266 * A value of 0 positions the icon at the bottom of the annotation rectangle. 267 * A value of 0.5 centers it within the rectangle. The default is 0.5. 268 * @param iconVerticalAdjustment a number between 0 and 1 indicating the fraction of leftover space to allocate at the bottom of the icon 269 */ setIconVerticalAdjustment(float iconVerticalAdjustment)270 public void setIconVerticalAdjustment(float iconVerticalAdjustment) { 271 if (iconVerticalAdjustment < 0) 272 iconVerticalAdjustment = 0; 273 else if (iconVerticalAdjustment > 1) 274 iconVerticalAdjustment = 1; 275 this.iconVerticalAdjustment = iconVerticalAdjustment; 276 } 277 278 /** 279 * Getter for property iconHorizontalAdjustment. 280 * @return Value of property iconHorizontalAdjustment. 281 */ getIconHorizontalAdjustment()282 public float getIconHorizontalAdjustment() { 283 return this.iconHorizontalAdjustment; 284 } 285 286 /** 287 * A number between 0 and 1 indicating the fraction of leftover space to allocate at the left of the icon. 288 * A value of 0 positions the icon at the left of the annotation rectangle. 289 * A value of 0.5 centers it within the rectangle. The default is 0.5. 290 * @param iconHorizontalAdjustment a number between 0 and 1 indicating the fraction of leftover space to allocate at the left of the icon 291 */ setIconHorizontalAdjustment(float iconHorizontalAdjustment)292 public void setIconHorizontalAdjustment(float iconHorizontalAdjustment) { 293 if (iconHorizontalAdjustment < 0) 294 iconHorizontalAdjustment = 0; 295 else if (iconHorizontalAdjustment > 1) 296 iconHorizontalAdjustment = 1; 297 this.iconHorizontalAdjustment = iconHorizontalAdjustment; 298 } 299 calculateFontSize(float w, float h)300 private float calculateFontSize(float w, float h) throws IOException, DocumentException { 301 BaseFont ufont = getRealFont(); 302 float fsize = fontSize; 303 if (fsize == 0) { 304 float bw = ufont.getWidthPoint(text, 1); 305 if (bw == 0) 306 fsize = 12; 307 else 308 fsize = w / bw; 309 float nfsize = h / (1 - ufont.getFontDescriptor(BaseFont.DESCENT, 1)); 310 fsize = Math.min(fsize, nfsize); 311 if (fsize < 4) 312 fsize = 4; 313 } 314 return fsize; 315 } 316 317 /** 318 * Gets the button appearance. 319 * @throws IOException on error 320 * @throws DocumentException on error 321 * @return the button appearance 322 */ getAppearance()323 public PdfAppearance getAppearance() throws IOException, DocumentException { 324 PdfAppearance app = getBorderAppearance(); 325 Rectangle box = new Rectangle(app.getBoundingBox()); 326 if ((text == null || text.length() == 0) && (layout == LAYOUT_LABEL_ONLY || (image == null && template == null && iconReference == null))) { 327 return app; 328 } 329 if (layout == LAYOUT_ICON_ONLY && image == null && template == null && iconReference == null) 330 return app; 331 BaseFont ufont = getRealFont(); 332 boolean borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET; 333 float h = box.getHeight() - borderWidth * 2; 334 float bw2 = borderWidth; 335 if (borderExtra) { 336 h -= borderWidth * 2; 337 bw2 *= 2; 338 } 339 float offsetX = (borderExtra ? 2 * borderWidth : borderWidth); 340 offsetX = Math.max(offsetX, 1); 341 float offX = Math.min(bw2, offsetX); 342 tp = null; 343 float textX = Float.NaN; 344 float textY = 0; 345 float fsize = fontSize; 346 float wt = box.getWidth() - 2 * offX - 2; 347 float ht = box.getHeight() - 2 * offX; 348 float adj = (iconFitToBounds ? 0 : offX + 1); 349 int nlayout = layout; 350 if (image == null && template == null && iconReference == null) 351 nlayout = LAYOUT_LABEL_ONLY; 352 Rectangle iconBox = null; 353 while (true) { 354 switch (nlayout) { 355 case LAYOUT_LABEL_ONLY: 356 case LAYOUT_LABEL_OVER_ICON: 357 if (text != null && text.length() > 0 && wt > 0 && ht > 0) { 358 fsize = calculateFontSize(wt, ht); 359 textX = (box.getWidth() - ufont.getWidthPoint(text, fsize)) / 2; 360 textY = (box.getHeight() - ufont.getFontDescriptor(BaseFont.ASCENT, fsize)) / 2; 361 } 362 case LAYOUT_ICON_ONLY: 363 if (nlayout == LAYOUT_LABEL_OVER_ICON || nlayout == LAYOUT_ICON_ONLY) 364 iconBox = new Rectangle(box.getLeft() + adj, box.getBottom() + adj, box.getRight() - adj, box.getTop() - adj); 365 break; 366 case LAYOUT_ICON_TOP_LABEL_BOTTOM: 367 if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { 368 nlayout = LAYOUT_ICON_ONLY; 369 continue; 370 } 371 float nht = box.getHeight() * 0.35f - offX; 372 if (nht > 0) 373 fsize = calculateFontSize(wt, nht); 374 else 375 fsize = 4; 376 textX = (box.getWidth() - ufont.getWidthPoint(text, fsize)) / 2; 377 textY = offX - ufont.getFontDescriptor(BaseFont.DESCENT, fsize); 378 iconBox = new Rectangle(box.getLeft() + adj, textY + fsize, box.getRight() - adj, box.getTop() - adj); 379 break; 380 case LAYOUT_LABEL_TOP_ICON_BOTTOM: 381 if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { 382 nlayout = LAYOUT_ICON_ONLY; 383 continue; 384 } 385 nht = box.getHeight() * 0.35f - offX; 386 if (nht > 0) 387 fsize = calculateFontSize(wt, nht); 388 else 389 fsize = 4; 390 textX = (box.getWidth() - ufont.getWidthPoint(text, fsize)) / 2; 391 textY = box.getHeight() - offX - fsize; 392 if (textY < offX) 393 textY = offX; 394 iconBox = new Rectangle(box.getLeft() + adj, box.getBottom() + adj, box.getRight() - adj, textY + ufont.getFontDescriptor(BaseFont.DESCENT, fsize)); 395 break; 396 case LAYOUT_LABEL_LEFT_ICON_RIGHT: 397 if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { 398 nlayout = LAYOUT_ICON_ONLY; 399 continue; 400 } 401 float nw = box.getWidth() * 0.35f - offX; 402 if (nw > 0) 403 fsize = calculateFontSize(wt, nw); 404 else 405 fsize = 4; 406 if (ufont.getWidthPoint(text, fsize) >= wt) { 407 nlayout = LAYOUT_LABEL_ONLY; 408 fsize = fontSize; 409 continue; 410 } 411 textX = offX + 1; 412 textY = (box.getHeight() - ufont.getFontDescriptor(BaseFont.ASCENT, fsize)) / 2; 413 iconBox = new Rectangle(textX + ufont.getWidthPoint(text, fsize), box.getBottom() + adj, box.getRight() - adj, box.getTop() - adj); 414 break; 415 case LAYOUT_ICON_LEFT_LABEL_RIGHT: 416 if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { 417 nlayout = LAYOUT_ICON_ONLY; 418 continue; 419 } 420 nw = box.getWidth() * 0.35f - offX; 421 if (nw > 0) 422 fsize = calculateFontSize(wt, nw); 423 else 424 fsize = 4; 425 if (ufont.getWidthPoint(text, fsize) >= wt) { 426 nlayout = LAYOUT_LABEL_ONLY; 427 fsize = fontSize; 428 continue; 429 } 430 textX = box.getWidth() - ufont.getWidthPoint(text, fsize) - offX - 1; 431 textY = (box.getHeight() - ufont.getFontDescriptor(BaseFont.ASCENT, fsize)) / 2; 432 iconBox = new Rectangle(box.getLeft() + adj, box.getBottom() + adj, textX - 1, box.getTop() - adj); 433 break; 434 } 435 break; 436 } 437 if (textY < box.getBottom() + offX) 438 textY = box.getBottom() + offX; 439 if (iconBox != null && (iconBox.getWidth() <= 0 || iconBox.getHeight() <= 0)) 440 iconBox = null; 441 boolean haveIcon = false; 442 float boundingBoxWidth = 0; 443 float boundingBoxHeight = 0; 444 PdfArray matrix = null; 445 if (iconBox != null) { 446 if (image != null) { 447 tp = new PdfTemplate(writer); 448 tp.setBoundingBox(new Rectangle(image)); 449 writer.addDirectTemplateSimple(tp, PdfName.FRM); 450 tp.addImage(image, image.getWidth(), 0, 0, image.getHeight(), 0, 0); 451 haveIcon = true; 452 boundingBoxWidth = tp.getBoundingBox().getWidth(); 453 boundingBoxHeight = tp.getBoundingBox().getHeight(); 454 } 455 else if (template != null) { 456 tp = new PdfTemplate(writer); 457 tp.setBoundingBox(new Rectangle(template.getWidth(), template.getHeight())); 458 writer.addDirectTemplateSimple(tp, PdfName.FRM); 459 tp.addTemplate(template, template.getBoundingBox().getLeft(), template.getBoundingBox().getBottom()); 460 haveIcon = true; 461 boundingBoxWidth = tp.getBoundingBox().getWidth(); 462 boundingBoxHeight = tp.getBoundingBox().getHeight(); 463 } 464 else if (iconReference != null) { 465 PdfDictionary dic = (PdfDictionary)PdfReader.getPdfObject(iconReference); 466 if (dic != null) { 467 Rectangle r2 = PdfReader.getNormalizedRectangle(dic.getAsArray(PdfName.BBOX)); 468 matrix = dic.getAsArray(PdfName.MATRIX); 469 haveIcon = true; 470 boundingBoxWidth = r2.getWidth(); 471 boundingBoxHeight = r2.getHeight(); 472 } 473 } 474 } 475 if (haveIcon) { 476 float icx = iconBox.getWidth() / boundingBoxWidth; 477 float icy = iconBox.getHeight() / boundingBoxHeight; 478 if (proportionalIcon) { 479 switch (scaleIcon) { 480 case SCALE_ICON_IS_TOO_BIG: 481 icx = Math.min(icx, icy); 482 icx = Math.min(icx, 1); 483 break; 484 case SCALE_ICON_IS_TOO_SMALL: 485 icx = Math.min(icx, icy); 486 icx = Math.max(icx, 1); 487 break; 488 case SCALE_ICON_NEVER: 489 icx = 1; 490 break; 491 default: 492 icx = Math.min(icx, icy); 493 break; 494 } 495 icy = icx; 496 } 497 else { 498 switch (scaleIcon) { 499 case SCALE_ICON_IS_TOO_BIG: 500 icx = Math.min(icx, 1); 501 icy = Math.min(icy, 1); 502 break; 503 case SCALE_ICON_IS_TOO_SMALL: 504 icx = Math.max(icx, 1); 505 icy = Math.max(icy, 1); 506 break; 507 case SCALE_ICON_NEVER: 508 icx = icy = 1; 509 break; 510 default: 511 break; 512 } 513 } 514 float xpos = iconBox.getLeft() + (iconBox.getWidth() - (boundingBoxWidth * icx)) * iconHorizontalAdjustment; 515 float ypos = iconBox.getBottom() + (iconBox.getHeight() - (boundingBoxHeight * icy)) * iconVerticalAdjustment; 516 app.saveState(); 517 app.rectangle(iconBox.getLeft(), iconBox.getBottom(), iconBox.getWidth(), iconBox.getHeight()); 518 app.clip(); 519 app.newPath(); 520 if (tp != null) 521 app.addTemplate(tp, icx, 0, 0, icy, xpos, ypos); 522 else { 523 float cox = 0; 524 float coy = 0; 525 if (matrix != null && matrix.size() == 6) { 526 PdfNumber nm = matrix.getAsNumber(4); 527 if (nm != null) 528 cox = nm.floatValue(); 529 nm = matrix.getAsNumber(5); 530 if (nm != null) 531 coy = nm.floatValue(); 532 } 533 app.addTemplateReference(iconReference, PdfName.FRM, icx, 0, 0, icy, xpos - cox * icx, ypos - coy * icy); 534 } 535 app.restoreState(); 536 } 537 if (!Float.isNaN(textX)) { 538 app.saveState(); 539 app.rectangle(offX, offX, box.getWidth() - 2 * offX, box.getHeight() - 2 * offX); 540 app.clip(); 541 app.newPath(); 542 if (textColor == null) 543 app.resetGrayFill(); 544 else 545 app.setColorFill(textColor); 546 app.beginText(); 547 app.setFontAndSize(ufont, fsize); 548 app.setTextMatrix(textX, textY); 549 app.showText(text); 550 app.endText(); 551 app.restoreState(); 552 } 553 return app; 554 } 555 556 /** 557 * Gets the pushbutton field. 558 * @throws IOException on error 559 * @throws DocumentException on error 560 * @return the pushbutton field 561 */ getField()562 public PdfFormField getField() throws IOException, DocumentException { 563 PdfFormField field = PdfFormField.createPushButton(writer); 564 field.setWidget(box, PdfAnnotation.HIGHLIGHT_INVERT); 565 if (fieldName != null) { 566 field.setFieldName(fieldName); 567 if ((options & READ_ONLY) != 0) 568 field.setFieldFlags(PdfFormField.FF_READ_ONLY); 569 if ((options & REQUIRED) != 0) 570 field.setFieldFlags(PdfFormField.FF_REQUIRED); 571 } 572 if (text != null) 573 field.setMKNormalCaption(text); 574 if (rotation != 0) 575 field.setMKRotation(rotation); 576 field.setBorderStyle(new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3))); 577 PdfAppearance tpa = getAppearance(); 578 field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tpa); 579 PdfAppearance da = (PdfAppearance)tpa.getDuplicate(); 580 da.setFontAndSize(getRealFont(), fontSize); 581 if (textColor == null) 582 da.setGrayFill(0); 583 else 584 da.setColorFill(textColor); 585 field.setDefaultAppearanceString(da); 586 if (borderColor != null) 587 field.setMKBorderColor(borderColor); 588 if (backgroundColor != null) 589 field.setMKBackgroundColor(backgroundColor); 590 switch (visibility) { 591 case HIDDEN: 592 field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_HIDDEN); 593 break; 594 case VISIBLE_BUT_DOES_NOT_PRINT: 595 break; 596 case HIDDEN_BUT_PRINTABLE: 597 field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_NOVIEW); 598 break; 599 default: 600 field.setFlags(PdfAnnotation.FLAGS_PRINT); 601 break; 602 } 603 if (tp != null) 604 field.setMKNormalIcon(tp); 605 field.setMKTextPosition(layout - 1); 606 PdfName scale = PdfName.A; 607 if (scaleIcon == SCALE_ICON_IS_TOO_BIG) 608 scale = PdfName.B; 609 else if (scaleIcon == SCALE_ICON_IS_TOO_SMALL) 610 scale = PdfName.S; 611 else if (scaleIcon == SCALE_ICON_NEVER) 612 scale = PdfName.N; 613 field.setMKIconFit(scale, proportionalIcon ? PdfName.P : PdfName.A, iconHorizontalAdjustment, 614 iconVerticalAdjustment, iconFitToBounds); 615 return field; 616 } 617 618 /** 619 * Getter for property iconFitToBounds. 620 * @return Value of property iconFitToBounds. 621 */ isIconFitToBounds()622 public boolean isIconFitToBounds() { 623 return this.iconFitToBounds; 624 } 625 626 /** 627 * If <CODE>true</CODE> the icon will be scaled to fit fully within the bounds of the annotation, 628 * if <CODE>false</CODE> the border width will be taken into account. The default 629 * is <CODE>false</CODE>. 630 * @param iconFitToBounds if <CODE>true</CODE> the icon will be scaled to fit fully within the bounds of the annotation, 631 * if <CODE>false</CODE> the border width will be taken into account 632 */ setIconFitToBounds(boolean iconFitToBounds)633 public void setIconFitToBounds(boolean iconFitToBounds) { 634 this.iconFitToBounds = iconFitToBounds; 635 } 636 637 /** 638 * Holds value of property iconReference. 639 */ 640 private PRIndirectReference iconReference; 641 642 /** 643 * Gets the reference to an existing icon. 644 * @return the reference to an existing icon. 645 */ getIconReference()646 public PRIndirectReference getIconReference() { 647 return this.iconReference; 648 } 649 650 /** 651 * Sets the reference to an existing icon. 652 * @param iconReference the reference to an existing icon 653 */ setIconReference(PRIndirectReference iconReference)654 public void setIconReference(PRIndirectReference iconReference) { 655 this.iconReference = iconReference; 656 } 657 658 } 659