1 47 package com.lowagie.text.pdf; 48 49 import java.io.IOException ; 50 51 import com.lowagie.text.DocumentException; 52 import com.lowagie.text.Image; 53 import com.lowagie.text.Rectangle; 54 83 public class PushbuttonField extends BaseField { 84 85 86 public static final int LAYOUT_LABEL_ONLY = 1; 87 88 public static final int LAYOUT_ICON_ONLY = 2; 89 90 public static final int LAYOUT_ICON_TOP_LABEL_BOTTOM = 3; 91 92 public static final int LAYOUT_LABEL_TOP_ICON_BOTTOM = 4; 93 94 public static final int LAYOUT_ICON_LEFT_LABEL_RIGHT = 5; 95 96 public static final int LAYOUT_LABEL_LEFT_ICON_RIGHT = 6; 97 98 public static final int LAYOUT_LABEL_OVER_ICON = 7; 99 100 public static final int SCALE_ICON_ALWAYS = 1; 101 102 public static final int SCALE_ICON_NEVER = 2; 103 104 public static final int SCALE_ICON_IS_TOO_BIG = 3; 105 106 public static final int SCALE_ICON_IS_TOO_SMALL = 4; 107 108 111 private int layout = LAYOUT_LABEL_ONLY; 112 113 116 private Image image; 117 118 121 private PdfTemplate template; 122 123 126 private int scaleIcon = SCALE_ICON_ALWAYS; 127 128 131 private boolean proportionalIcon = true; 132 133 136 private float iconVerticalAdjustment = 0.5f; 137 138 141 private float iconHorizontalAdjustment = 0.5f; 142 143 146 private boolean iconFitToBounds; 147 148 private PdfTemplate tp; 149 150 157 public PushbuttonField(PdfWriter writer, Rectangle box, String fieldName) { 158 super(writer, box, fieldName); 159 } 160 161 165 public int getLayout() { 166 return this.layout; 167 } 168 169 177 public void setLayout(int layout) { 178 if (layout < LAYOUT_LABEL_ONLY || layout > LAYOUT_LABEL_OVER_ICON) 179 throw new IllegalArgumentException ("Layout out of bounds."); 180 this.layout = layout; 181 } 182 183 187 public Image getImage() { 188 return this.image; 189 } 190 191 195 public void setImage(Image image) { 196 this.image = image; 197 template = null; 198 } 199 200 204 public PdfTemplate getTemplate() { 205 return this.template; 206 } 207 208 212 public void setTemplate(PdfTemplate template) { 213 this.template = template; 214 image = null; 215 } 216 217 221 public int getScaleIcon() { 222 return this.scaleIcon; 223 } 224 225 232 public void setScaleIcon(int scaleIcon) { 233 if (scaleIcon < SCALE_ICON_ALWAYS || scaleIcon > SCALE_ICON_IS_TOO_SMALL) 234 scaleIcon = SCALE_ICON_ALWAYS; 235 this.scaleIcon = scaleIcon; 236 } 237 238 242 public boolean isProportionalIcon() { 243 return this.proportionalIcon; 244 } 245 246 251 public void setProportionalIcon(boolean proportionalIcon) { 252 this.proportionalIcon = proportionalIcon; 253 } 254 255 259 public float getIconVerticalAdjustment() { 260 return this.iconVerticalAdjustment; 261 } 262 263 269 public void setIconVerticalAdjustment(float iconVerticalAdjustment) { 270 if (iconVerticalAdjustment < 0) 271 iconVerticalAdjustment = 0; 272 else if (iconVerticalAdjustment > 1) 273 iconVerticalAdjustment = 1; 274 this.iconVerticalAdjustment = iconVerticalAdjustment; 275 } 276 277 281 public float getIconHorizontalAdjustment() { 282 return this.iconHorizontalAdjustment; 283 } 284 285 291 public void setIconHorizontalAdjustment(float iconHorizontalAdjustment) { 292 if (iconHorizontalAdjustment < 0) 293 iconHorizontalAdjustment = 0; 294 else if (iconHorizontalAdjustment > 1) 295 iconHorizontalAdjustment = 1; 296 this.iconHorizontalAdjustment = iconHorizontalAdjustment; 297 } 298 299 private float calculateFontSize(float w, float h) throws IOException , DocumentException { 300 BaseFont ufont = getRealFont(); 301 float fsize = fontSize; 302 if (fsize == 0) { 303 float bw = ufont.getWidthPoint(text, 1); 304 if (bw == 0) 305 fsize = 12; 306 else 307 fsize = w / bw; 308 float nfsize = h / (1 - ufont.getFontDescriptor(BaseFont.DESCENT, 1)); 309 fsize = Math.min(fsize, nfsize); 310 if (fsize < 4) 311 fsize = 4; 312 } 313 return fsize; 314 } 315 316 322 public PdfAppearance getAppearance() throws IOException , DocumentException { 323 PdfAppearance app = getBorderAppearance(); 324 Rectangle box = new Rectangle(app.getBoundingBox()); 325 if ((text == null || text.length() == 0) && (layout == LAYOUT_LABEL_ONLY || (image == null && template == null && iconReference == null))) { 326 return app; 327 } 328 if (layout == LAYOUT_ICON_ONLY && image == null && template == null && iconReference == null) 329 return app; 330 BaseFont ufont = getRealFont(); 331 boolean borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET; 332 float h = box.getHeight() - borderWidth * 2; 333 float bw2 = borderWidth; 334 if (borderExtra) { 335 h -= borderWidth * 2; 336 bw2 *= 2; 337 } 338 float offsetX = (borderExtra ? 2 * borderWidth : borderWidth); 339 offsetX = Math.max(offsetX, 1); 340 float offX = Math.min(bw2, offsetX); 341 tp = null; 342 float textX = Float.NaN; 343 float textY = 0; 344 float fsize = fontSize; 345 float wt = box.getWidth() - 2 * offX - 2; 346 float ht = box.getHeight() - 2 * offX; 347 float adj = (iconFitToBounds ? 0 : offX + 1); 348 int nlayout = layout; 349 if (image == null && template == null && iconReference == null) 350 nlayout = LAYOUT_LABEL_ONLY; 351 Rectangle iconBox = null; 352 while (true) { 353 switch (nlayout) { 354 case LAYOUT_LABEL_ONLY: 355 case LAYOUT_LABEL_OVER_ICON: 356 if (text != null && text.length() > 0 && wt > 0 && ht > 0) { 357 fsize = calculateFontSize(wt, ht); 358 textX = (box.getWidth() - ufont.getWidthPoint(text, fsize)) / 2; 359 textY = (box.getHeight() - ufont.getFontDescriptor(BaseFont.ASCENT, fsize)) / 2; 360 } 361 case LAYOUT_ICON_ONLY: 362 if (nlayout == LAYOUT_LABEL_OVER_ICON || nlayout == LAYOUT_ICON_ONLY) 363 iconBox = new Rectangle(box.getLeft() + adj, box.getBottom() + adj, box.getRight() - adj, box.getTop() - adj); 364 break; 365 case LAYOUT_ICON_TOP_LABEL_BOTTOM: 366 if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { 367 nlayout = LAYOUT_ICON_ONLY; 368 continue; 369 } 370 float nht = box.getHeight() * 0.35f - offX; 371 if (nht > 0) 372 fsize = calculateFontSize(wt, nht); 373 else 374 fsize = 4; 375 textX = (box.getWidth() - ufont.getWidthPoint(text, fsize)) / 2; 376 textY = offX - ufont.getFontDescriptor(BaseFont.DESCENT, fsize); 377 iconBox = new Rectangle(box.getLeft() + adj, textY + fsize, box.getRight() - adj, box.getTop() - adj); 378 break; 379 case LAYOUT_LABEL_TOP_ICON_BOTTOM: 380 if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { 381 nlayout = LAYOUT_ICON_ONLY; 382 continue; 383 } 384 nht = box.getHeight() * 0.35f - offX; 385 if (nht > 0) 386 fsize = calculateFontSize(wt, nht); 387 else 388 fsize = 4; 389 textX = (box.getWidth() - ufont.getWidthPoint(text, fsize)) / 2; 390 textY = box.getHeight() - offX - fsize; 391 if (textY < offX) 392 textY = offX; 393 iconBox = new Rectangle(box.getLeft() + adj, box.getBottom() + adj, box.getRight() - adj, textY + ufont.getFontDescriptor(BaseFont.DESCENT, fsize)); 394 break; 395 case LAYOUT_LABEL_LEFT_ICON_RIGHT: 396 if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { 397 nlayout = LAYOUT_ICON_ONLY; 398 continue; 399 } 400 float nw = box.getWidth() * 0.35f - offX; 401 if (nw > 0) 402 fsize = calculateFontSize(wt, nw); 403 else 404 fsize = 4; 405 if (ufont.getWidthPoint(text, fsize) >= wt) { 406 nlayout = LAYOUT_LABEL_ONLY; 407 fsize = fontSize; 408 continue; 409 } 410 textX = offX + 1; 411 textY = (box.getHeight() - ufont.getFontDescriptor(BaseFont.ASCENT, fsize)) / 2; 412 iconBox = new Rectangle(textX + ufont.getWidthPoint(text, fsize), box.getBottom() + adj, box.getRight() - adj, box.getTop() - adj); 413 break; 414 case LAYOUT_ICON_LEFT_LABEL_RIGHT: 415 if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { 416 nlayout = LAYOUT_ICON_ONLY; 417 continue; 418 } 419 nw = box.getWidth() * 0.35f - offX; 420 if (nw > 0) 421 fsize = calculateFontSize(wt, nw); 422 else 423 fsize = 4; 424 if (ufont.getWidthPoint(text, fsize) >= wt) { 425 nlayout = LAYOUT_LABEL_ONLY; 426 fsize = fontSize; 427 continue; 428 } 429 textX = box.getWidth() - ufont.getWidthPoint(text, fsize) - offX - 1; 430 textY = (box.getHeight() - ufont.getFontDescriptor(BaseFont.ASCENT, fsize)) / 2; 431 iconBox = new Rectangle(box.getLeft() + adj, box.getBottom() + adj, textX - 1, box.getTop() - adj); 432 break; 433 } 434 break; 435 } 436 if (textY < box.getBottom() + offX) 437 textY = box.getBottom() + offX; 438 if (iconBox != null && (iconBox.getWidth() <= 0 || iconBox.getHeight() <= 0)) 439 iconBox = null; 440 boolean haveIcon = false; 441 float boundingBoxWidth = 0; 442 float boundingBoxHeight = 0; 443 PdfArray matrix = null; 444 if (iconBox != null) { 445 if (image != null) { 446 tp = new PdfTemplate(writer); 447 tp.setBoundingBox(new Rectangle(image)); 448 writer.addDirectTemplateSimple(tp, PdfName.FRM); 449 tp.addImage(image, image.getWidth(), 0, 0, image.getHeight(), 0, 0); 450 haveIcon = true; 451 boundingBoxWidth = tp.getBoundingBox().getWidth(); 452 boundingBoxHeight = tp.getBoundingBox().getHeight(); 453 } 454 else if (template != null) { 455 tp = new PdfTemplate(writer); 456 tp.setBoundingBox(new Rectangle(template.getWidth(), template.getHeight())); 457 writer.addDirectTemplateSimple(tp, PdfName.FRM); 458 tp.addTemplate(template, template.getBoundingBox().getLeft(), template.getBoundingBox().getBottom()); 459 haveIcon = true; 460 boundingBoxWidth = tp.getBoundingBox().getWidth(); 461 boundingBoxHeight = tp.getBoundingBox().getHeight(); 462 } 463 else if (iconReference != null) { 464 PdfDictionary dic = (PdfDictionary)PdfReader.getPdfObject(iconReference); 465 if (dic != null) { 466 Rectangle r2 = PdfReader.getNormalizedRectangle((PdfArray)PdfReader.getPdfObject(dic.get(PdfName.BBOX))); 467 matrix = (PdfArray)PdfReader.getPdfObject(dic.get(PdfName.MATRIX)); 468 haveIcon = true; 469 boundingBoxWidth = r2.getWidth(); 470 boundingBoxHeight = r2.getHeight(); 471 } 472 } 473 } 474 if (haveIcon) { 475 float icx = iconBox.getWidth() / boundingBoxWidth; 476 float icy = iconBox.getHeight() / boundingBoxHeight; 477 if (proportionalIcon) { 478 switch (scaleIcon) { 479 case SCALE_ICON_IS_TOO_BIG: 480 icx = Math.min(icx, icy); 481 icx = Math.min(icx, 1); 482 break; 483 case SCALE_ICON_IS_TOO_SMALL: 484 icx = Math.min(icx, icy); 485 icx = Math.max(icx, 1); 486 break; 487 case SCALE_ICON_NEVER: 488 icx = 1; 489 break; 490 default: 491 icx = Math.min(icx, icy); 492 break; 493 } 494 icy = icx; 495 } 496 else { 497 switch (scaleIcon) { 498 case SCALE_ICON_IS_TOO_BIG: 499 icx = Math.min(icx, 1); 500 icy = Math.min(icy, 1); 501 break; 502 case SCALE_ICON_IS_TOO_SMALL: 503 icx = Math.max(icx, 1); 504 icy = Math.max(icy, 1); 505 break; 506 case SCALE_ICON_NEVER: 507 icx = icy = 1; 508 break; 509 default: 510 break; 511 } 512 } 513 float xpos = iconBox.getLeft() + (iconBox.getWidth() - (boundingBoxWidth * icx)) * iconHorizontalAdjustment; 514 float ypos = iconBox.getBottom() + (iconBox.getHeight() - (boundingBoxHeight * icy)) * iconVerticalAdjustment; 515 app.saveState(); 516 app.rectangle(iconBox.getLeft(), iconBox.getBottom(), iconBox.getWidth(), iconBox.getHeight()); 517 app.clip(); 518 app.newPath(); 519 if (tp != null) 520 app.addTemplate(tp, icx, 0, 0, icy, xpos, ypos); 521 else { 522 float cox = 0; 523 float coy = 0; 524 if (matrix != null && matrix.size() == 6) { 525 PdfNumber nm = (PdfNumber)PdfReader.getPdfObject((PdfObject)matrix.getArrayList().get(4)); 526 if (nm != null) 527 cox = nm.floatValue(); 528 nm = (PdfNumber)PdfReader.getPdfObject((PdfObject)matrix.getArrayList().get(5)); 529 if (nm != null) 530 coy = nm.floatValue(); 531 } 532 app.addTemplateReference(iconReference, PdfName.FRM, icx, 0, 0, icy, xpos - cox * icx, ypos - coy * icy); 533 } 534 app.restoreState(); 535 } 536 if (!Float.isNaN(textX)) { 537 app.saveState(); 538 app.rectangle(offX, offX, box.getWidth() - 2 * offX, box.getHeight() - 2 * offX); 539 app.clip(); 540 app.newPath(); 541 if (textColor == null) 542 app.resetGrayFill(); 543 else 544 app.setColorFill(textColor); 545 app.beginText(); 546 app.setFontAndSize(ufont, fsize); 547 app.setTextMatrix(textX, textY); 548 app.showText(text); 549 app.endText(); 550 app.restoreState(); 551 } 552 return app; 553 } 554 555 561 public PdfFormField getField() throws IOException , DocumentException { 562 PdfFormField field = PdfFormField.createPushButton(writer); 563 field.setWidget(box, PdfAnnotation.HIGHLIGHT_INVERT); 564 if (fieldName != null) { 565 field.setFieldName(fieldName); 566 if ((options & READ_ONLY) != 0) 567 field.setFieldFlags(PdfFormField.FF_READ_ONLY); 568 if ((options & REQUIRED) != 0) 569 field.setFieldFlags(PdfFormField.FF_REQUIRED); 570 } 571 if (text != null) 572 field.setMKNormalCaption(text); 573 if (rotation != 0) 574 field.setMKRotation(rotation); 575 field.setBorderStyle(new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3))); 576 PdfAppearance tpa = getAppearance(); 577 field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tpa); 578 PdfAppearance da = (PdfAppearance)tpa.getDuplicate(); 579 da.setFontAndSize(getRealFont(), fontSize); 580 if (textColor == null) 581 da.setGrayFill(0); 582 else 583 da.setColorFill(textColor); 584 field.setDefaultAppearanceString(da); 585 if (borderColor != null) 586 field.setMKBorderColor(borderColor); 587 if (backgroundColor != null) 588 field.setMKBackgroundColor(backgroundColor); 589 switch (visibility) { 590 case HIDDEN: 591 field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_HIDDEN); 592 break; 593 case VISIBLE_BUT_DOES_NOT_PRINT: 594 break; 595 case HIDDEN_BUT_PRINTABLE: 596 field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_NOVIEW); 597 break; 598 default: 599 field.setFlags(PdfAnnotation.FLAGS_PRINT); 600 break; 601 } 602 if (tp != null) 603 field.setMKNormalIcon(tp); 604 field.setMKTextPosition(layout - 1); 605 PdfName scale = PdfName.A; 606 if (scaleIcon == SCALE_ICON_IS_TOO_BIG) 607 scale = PdfName.B; 608 else if (scaleIcon == SCALE_ICON_IS_TOO_SMALL) 609 scale = PdfName.S; 610 else if (scaleIcon == SCALE_ICON_NEVER) 611 scale = PdfName.N; 612 field.setMKIconFit(scale, proportionalIcon ? PdfName.P : PdfName.A, iconHorizontalAdjustment, 613 iconVerticalAdjustment, iconFitToBounds); 614 return field; 615 } 616 617 621 public boolean isIconFitToBounds() { 622 return this.iconFitToBounds; 623 } 624 625 632 public void setIconFitToBounds(boolean iconFitToBounds) { 633 this.iconFitToBounds = iconFitToBounds; 634 } 635 636 639 private PRIndirectReference iconReference; 640 641 645 public PRIndirectReference getIconReference() { 646 return this.iconReference; 647 } 648 649 653 public void setIconReference(PRIndirectReference iconReference) { 654 this.iconReference = iconReference; 655 } 656 657 } | Popular Tags |