001/* 002 * $Id: Font.java 4784 2011-03-15 08:33:00Z blowagie $ 003 * 004 * This file is part of the iText (R) project. 005 * Copyright (c) 1998-2011 1T3XT BVBA 006 * Authors: Bruno Lowagie, Paulo Soares, et al. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Affero General Public License version 3 010 * as published by the Free Software Foundation with the addition of the 011 * following permission added to Section 15 as permitted in Section 7(a): 012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT, 013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 014 * 015 * This program is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 017 * or FITNESS FOR A PARTICULAR PURPOSE. 018 * See the GNU Affero General Public License for more details. 019 * You should have received a copy of the GNU Affero General Public License 020 * along with this program; if not, see http://www.gnu.org/licenses or write to 021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 022 * Boston, MA, 02110-1301 USA, or download the license from the following URL: 023 * http://itextpdf.com/terms-of-use/ 024 * 025 * The interactive user interfaces in modified source and object code versions 026 * of this program must display Appropriate Legal Notices, as required under 027 * Section 5 of the GNU Affero General Public License. 028 * 029 * In accordance with Section 7(b) of the GNU Affero General Public License, 030 * a covered work must retain the producer line in every PDF that is created 031 * or manipulated using iText. 032 * 033 * You can be released from the requirements of the license by purchasing 034 * a commercial license. Buying such a license is mandatory as soon as you 035 * develop commercial activities involving the iText software without 036 * disclosing the source code of your own applications. 037 * These activities include: offering paid services to customers as an ASP, 038 * serving PDFs on the fly in a web application, shipping iText with a closed 039 * source product. 040 * 041 * For more information, please contact iText Software Corp. at this 042 * address: sales@itextpdf.com 043 */ 044package com.itextpdf.text; 045 046import com.itextpdf.text.pdf.BaseFont; 047 048/** 049 * Contains all the specifications of a font: fontfamily, size, style and color. 050 * <P> 051 * Example: <BLOCKQUOTE> 052 * 053 * <PRE> 054 * 055 * Paragraph p = new Paragraph("This is a paragraph", <STRONG>new 056 * Font(FontFamily.HELVETICA, 18, Font.BOLDITALIC, new BaseColor(0, 0, 255)) </STRONG>); 057 * 058 * </PRE> 059 * 060 * </BLOCKQUOTE> 061 */ 062 063public class Font implements Comparable<Font> { 064 065 /** 066 * Enum describing the font family 067 * 068 * @since 5.0.1 069 */ 070 public enum FontFamily { 071 COURIER, 072 HELVETICA, 073 TIMES_ROMAN, 074 SYMBOL, 075 ZAPFDINGBATS, 076 UNDEFINED 077 } 078 079 /** 080 * FontStyle. 081 * 082 * @author Balder 083 * @since 5.0.6 084 */ 085 public enum FontStyle { 086 // Created to get rid of dependency of HtmlTags 087 NORMAL("normal"), BOLD("bold"), ITALIC("italic"), OBLIQUE("oblique"), UNDERLINE( 088 "underline"), LINETHROUGH("line-through"); 089 090 private String code; 091 092 private FontStyle(final String code) { 093 this.code = code; 094 } 095 096 /** 097 * @return a string, the text value of this style. 098 * @since 5.0.6 099 */ 100 public String getValue() { 101 return code; 102 } 103 104 } 105 106 // static membervariables for the different styles 107 108 /** this is a possible style. */ 109 public static final int NORMAL = 0; 110 111 /** this is a possible style. */ 112 public static final int BOLD = 1; 113 114 /** this is a possible style. */ 115 public static final int ITALIC = 2; 116 117 /** this is a possible style. */ 118 public static final int UNDERLINE = 4; 119 120 /** this is a possible style. */ 121 public static final int STRIKETHRU = 8; 122 123 /** this is a possible style. */ 124 public static final int BOLDITALIC = BOLD | ITALIC; 125 126 // static membervariables 127 128 /** the value of an undefined attribute. */ 129 public static final int UNDEFINED = -1; 130 131 /** the value of the default size. */ 132 public static final int DEFAULTSIZE = 12; 133 134 // membervariables 135 136 /** the value of the fontfamily. */ 137 private FontFamily family = FontFamily.UNDEFINED; 138 139 /** the value of the fontsize. */ 140 private float size = UNDEFINED; 141 142 /** the value of the style. */ 143 private int style = UNDEFINED; 144 145 /** the value of the color. */ 146 private BaseColor color = null; 147 148 /** the external font */ 149 private BaseFont baseFont = null; 150 151 // constructors 152 153 /** 154 * Copy constructor of a Font 155 * 156 * @param other 157 * the font that has to be copied 158 */ 159 public Font(final Font other) { 160 this.family = other.family; 161 this.size = other.size; 162 this.style = other.style; 163 this.color = other.color; 164 this.baseFont = other.baseFont; 165 } 166 167 /** 168 * Constructs a Font. 169 * 170 * @param family 171 * the family to which this font belongs 172 * @param size 173 * the size of this font 174 * @param style 175 * the style of this font 176 * @param color 177 * the <CODE>BaseColor</CODE> of this font. 178 * @since iText 5.0.1 (first parameter has been replaced with enum) 179 */ 180 181 public Font(final FontFamily family, final float size, final int style, final BaseColor color) { 182 this.family = family; 183 this.size = size; 184 this.style = style; 185 this.color = color; 186 } 187 188 /** 189 * Constructs a Font. 190 * 191 * @param bf 192 * the external font 193 * @param size 194 * the size of this font 195 * @param style 196 * the style of this font 197 * @param color 198 * the <CODE>BaseColor</CODE> of this font. 199 */ 200 201 public Font(final BaseFont bf, final float size, final int style, final BaseColor color) { 202 this.baseFont = bf; 203 this.size = size; 204 this.style = style; 205 this.color = color; 206 } 207 208 /** 209 * Constructs a Font. 210 * 211 * @param bf 212 * the external font 213 * @param size 214 * the size of this font 215 * @param style 216 * the style of this font 217 */ 218 public Font(final BaseFont bf, final float size, final int style) { 219 this(bf, size, style, null); 220 } 221 222 /** 223 * Constructs a Font. 224 * 225 * @param bf 226 * the external font 227 * @param size 228 * the size of this font 229 */ 230 public Font(final BaseFont bf, final float size) { 231 this(bf, size, UNDEFINED, null); 232 } 233 234 /** 235 * Constructs a Font. 236 * 237 * @param bf 238 * the external font 239 */ 240 public Font(final BaseFont bf) { 241 this(bf, UNDEFINED, UNDEFINED, null); 242 } 243 244 /** 245 * Constructs a Font. 246 * 247 * @param family 248 * the family to which this font belongs 249 * @param size 250 * the size of this font 251 * @param style 252 * the style of this font 253 * @since iText 5.0.1 (first parameter has been replaced with enum) 254 */ 255 256 public Font(final FontFamily family, final float size, final int style) { 257 this(family, size, style, null); 258 } 259 260 /** 261 * Constructs a Font. 262 * 263 * @param family 264 * the family to which this font belongs 265 * @param size 266 * the size of this font 267 * @since iText 5.0.1 (first parameter has been replaced with enum) 268 */ 269 270 public Font(final FontFamily family, final float size) { 271 this(family, size, UNDEFINED, null); 272 } 273 274 /** 275 * Constructs a Font. 276 * 277 * @param family 278 * the family to which this font belongs 279 * @since iText 5.0.1 (first parameter has been replaced with enum) 280 */ 281 282 public Font(final FontFamily family) { 283 this(family, UNDEFINED, UNDEFINED, null); 284 } 285 286 /** 287 * Constructs a Font. 288 */ 289 290 public Font() { 291 this(FontFamily.UNDEFINED, UNDEFINED, UNDEFINED, null); 292 } 293 294 // implementation of the Comparable interface 295 296 /** 297 * Compares this <CODE>Font</CODE> with another 298 * 299 * @param font 300 * the other <CODE>Font</CODE> 301 * @return a value 302 */ 303 public int compareTo(final Font font) { 304 if (font == null) { 305 return -1; 306 } 307 try { 308 // FIXME using equals but equals not implemented! 309 if (baseFont != null && !baseFont.equals(font.getBaseFont())) { 310 return -2; 311 } 312 if (this.family != font.getFamily()) { 313 return 1; 314 } 315 if (this.size != font.getSize()) { 316 return 2; 317 } 318 if (this.style != font.getStyle()) { 319 return 3; 320 } 321 if (this.color == null) { 322 if (font.color == null) { 323 return 0; 324 } 325 return 4; 326 } 327 if (font.color == null) { 328 return 4; 329 } 330 if (this.color.equals(font.getColor())) { 331 return 0; 332 } 333 return 4; 334 } catch (ClassCastException cce) { 335 return -3; 336 } 337 } 338 339 // FAMILY 340 341 /** 342 * Gets the family of this font. 343 * 344 * @return the value of the family 345 */ 346 public FontFamily getFamily() { 347 return family; 348 } 349 350 /** 351 * Gets the familyname as a String. 352 * 353 * @return the familyname 354 */ 355 public String getFamilyname() { 356 String tmp = "unknown"; 357 switch (getFamily()) { 358 case COURIER: 359 return FontFactory.COURIER; 360 case HELVETICA: 361 return FontFactory.HELVETICA; 362 case TIMES_ROMAN: 363 return FontFactory.TIMES_ROMAN; 364 case SYMBOL: 365 return FontFactory.SYMBOL; 366 case ZAPFDINGBATS: 367 return FontFactory.ZAPFDINGBATS; 368 default: 369 if (baseFont != null) { 370 String[][] names = baseFont.getFamilyFontName(); 371 for (String[] name : names) { 372 if ("0".equals(name[2])) { 373 return name[3]; 374 } 375 if ("1033".equals(name[2])) { 376 tmp = name[3]; 377 } 378 if ("".equals(name[2])) { 379 tmp = name[3]; 380 } 381 } 382 } 383 } 384 return tmp; 385 } 386 387 /** 388 * Sets the family using a <CODE>String</CODE> ("Courier", "Helvetica", 389 * "Times New Roman", "Symbol" or "ZapfDingbats"). 390 * 391 * @param family 392 * A <CODE>String</CODE> representing a certain font-family. 393 */ 394 public void setFamily(final String family) { 395 this.family = getFamily(family); 396 } 397 398 /** 399 * Translates a <CODE>String</CODE> -value of a certain family into the 400 * FontFamily enum that is used for this family in this class. 401 * 402 * @param family 403 * A <CODE>String</CODE> representing a certain font-family 404 * @return the corresponding FontFamily 405 * 406 * @since 5.0.1 407 */ 408 public static FontFamily getFamily(final String family) { 409 if (family.equalsIgnoreCase(FontFactory.COURIER)) { 410 return FontFamily.COURIER; 411 } 412 if (family.equalsIgnoreCase(FontFactory.HELVETICA)) { 413 return FontFamily.HELVETICA; 414 } 415 if (family.equalsIgnoreCase(FontFactory.TIMES_ROMAN)) { 416 return FontFamily.TIMES_ROMAN; 417 } 418 if (family.equalsIgnoreCase(FontFactory.SYMBOL)) { 419 return FontFamily.SYMBOL; 420 } 421 if (family.equalsIgnoreCase(FontFactory.ZAPFDINGBATS)) { 422 return FontFamily.ZAPFDINGBATS; 423 } 424 return FontFamily.UNDEFINED; 425 } 426 427 // SIZE 428 429 /** 430 * Gets the size of this font. 431 * 432 * @return a size 433 */ 434 public float getSize() { 435 return size; 436 } 437 438 /** 439 * Gets the size that can be used with the calculated <CODE>BaseFont 440 * </CODE>. 441 * 442 * @return the size that can be used with the calculated <CODE>BaseFont 443 * </CODE> 444 */ 445 public float getCalculatedSize() { 446 float s = this.size; 447 if (s == UNDEFINED) { 448 s = DEFAULTSIZE; 449 } 450 return s; 451 } 452 453 /** 454 * Gets the leading that can be used with this font. 455 * 456 * @param linespacing 457 * a certain linespacing 458 * @return the height of a line 459 */ 460 public float getCalculatedLeading(final float linespacing) { 461 return linespacing * getCalculatedSize(); 462 } 463 464 /** 465 * Sets the size. 466 * 467 * @param size 468 * The new size of the font. 469 */ 470 public void setSize(final float size) { 471 this.size = size; 472 } 473 474 // STYLE 475 476 /** 477 * Gets the style of this font. 478 * 479 * @return a size 480 */ 481 public int getStyle() { 482 return style; 483 } 484 485 /** 486 * Gets the style that can be used with the calculated <CODE>BaseFont 487 * </CODE>. 488 * 489 * @return the style that can be used with the calculated <CODE>BaseFont 490 * </CODE> 491 */ 492 public int getCalculatedStyle() { 493 int style = this.style; 494 if (style == UNDEFINED) { 495 style = NORMAL; 496 } 497 if (baseFont != null) 498 return style; 499 if (family == FontFamily.SYMBOL || family == FontFamily.ZAPFDINGBATS) 500 return style; 501 else 502 return style & ~BOLDITALIC; 503 } 504 505 /** 506 * checks if this font is Bold. 507 * 508 * @return a <CODE>boolean</CODE> 509 */ 510 public boolean isBold() { 511 if (style == UNDEFINED) { 512 return false; 513 } 514 return (style & BOLD) == BOLD; 515 } 516 517 /** 518 * checks if this font is italic. 519 * 520 * @return a <CODE>boolean</CODE> 521 */ 522 public boolean isItalic() { 523 if (style == UNDEFINED) { 524 return false; 525 } 526 return (style & ITALIC) == ITALIC; 527 } 528 529 /** 530 * checks if this font is underlined. 531 * 532 * @return a <CODE>boolean</CODE> 533 */ 534 public boolean isUnderlined() { 535 if (style == UNDEFINED) { 536 return false; 537 } 538 return (style & UNDERLINE) == UNDERLINE; 539 } 540 541 /** 542 * checks if the style of this font is STRIKETHRU. 543 * 544 * @return a <CODE>boolean</CODE> 545 */ 546 public boolean isStrikethru() { 547 if (style == UNDEFINED) { 548 return false; 549 } 550 return (style & STRIKETHRU) == STRIKETHRU; 551 } 552 553 /** 554 * Sets the style. 555 * 556 * @param style 557 * the style. 558 */ 559 public void setStyle(final int style) { 560 this.style = style; 561 } 562 563 /** 564 * Sets the style using a <CODE>String</CODE> containing one or more of the 565 * following values: normal, bold, italic, oblique, underline, line-through 566 * 567 * @param style 568 * A <CODE>String</CODE> representing a certain style. 569 */ 570 public void setStyle(final String style) { 571 if (this.style == UNDEFINED) 572 this.style = NORMAL; 573 this.style |= getStyleValue(style); 574 } 575 576 /** 577 * Translates a <CODE>String</CODE> -value of a certain style into the index 578 * value is used for this style in this class. Supported styles are in 579 * {@link FontStyle} values are checked on {@link FontStyle#getValue()} 580 * 581 * @param style 582 * A <CODE>String</CODE> 583 * @return the corresponding value 584 */ 585 public static int getStyleValue(final String style) { 586 int s = 0; 587 if (style.indexOf(FontStyle.NORMAL.getValue()) != -1) { 588 s |= NORMAL; 589 } 590 if (style.indexOf(FontStyle.BOLD.getValue()) != -1) { 591 s |= BOLD; 592 } 593 if (style.indexOf(FontStyle.ITALIC.getValue()) != -1) { 594 s |= ITALIC; 595 } 596 if (style.indexOf(FontStyle.OBLIQUE.getValue()) != -1) { 597 s |= ITALIC; 598 } 599 if (style.indexOf(FontStyle.UNDERLINE.getValue()) != -1) { 600 s |= UNDERLINE; 601 } 602 if (style.indexOf(FontStyle.LINETHROUGH.getValue()) != -1) { 603 s |= STRIKETHRU; 604 } 605 return s; 606 } 607 608 // COLOR 609 610 /** 611 * Gets the color of this font. 612 * 613 * @return a color 614 */ 615 public BaseColor getColor() { 616 return color; 617 } 618 619 /** 620 * Sets the color. 621 * 622 * @param color 623 * the new color of the font 624 */ 625 626 public void setColor(final BaseColor color) { 627 this.color = color; 628 } 629 630 /** 631 * Sets the color. 632 * 633 * @param red 634 * the red-value of the new color 635 * @param green 636 * the green-value of the new color 637 * @param blue 638 * the blue-value of the new color 639 */ 640 public void setColor(final int red, final int green, final int blue) { 641 this.color = new BaseColor(red, green, blue); 642 } 643 644 // BASEFONT 645 646 /** 647 * Gets the <CODE>BaseFont</CODE> inside this object. 648 * 649 * @return the <CODE>BaseFont</CODE> 650 */ 651 public BaseFont getBaseFont() { 652 return baseFont; 653 } 654 655 /** 656 * Gets the <CODE>BaseFont</CODE> this class represents. For the built-in 657 * fonts a <CODE>BaseFont</CODE> is calculated. 658 * 659 * @param specialEncoding 660 * <CODE>true</CODE> to use the special encoding for Symbol and 661 * ZapfDingbats, <CODE>false</CODE> to always use <CODE>Cp1252 662 * </CODE> 663 * @return the <CODE>BaseFont</CODE> this class represents 664 */ 665 public BaseFont getCalculatedBaseFont(final boolean specialEncoding) { 666 if (baseFont != null) 667 return baseFont; 668 int style = this.style; 669 if (style == UNDEFINED) { 670 style = NORMAL; 671 } 672 String fontName = BaseFont.HELVETICA; 673 String encoding = BaseFont.WINANSI; 674 BaseFont cfont = null; 675 switch (family) { 676 case COURIER: 677 switch (style & BOLDITALIC) { 678 case BOLD: 679 fontName = BaseFont.COURIER_BOLD; 680 break; 681 case ITALIC: 682 fontName = BaseFont.COURIER_OBLIQUE; 683 break; 684 case BOLDITALIC: 685 fontName = BaseFont.COURIER_BOLDOBLIQUE; 686 break; 687 default: 688 // case NORMAL: 689 fontName = BaseFont.COURIER; 690 break; 691 } 692 break; 693 case TIMES_ROMAN: 694 switch (style & BOLDITALIC) { 695 case BOLD: 696 fontName = BaseFont.TIMES_BOLD; 697 break; 698 case ITALIC: 699 fontName = BaseFont.TIMES_ITALIC; 700 break; 701 case BOLDITALIC: 702 fontName = BaseFont.TIMES_BOLDITALIC; 703 break; 704 default: 705 case NORMAL: 706 fontName = BaseFont.TIMES_ROMAN; 707 break; 708 } 709 break; 710 case SYMBOL: 711 fontName = BaseFont.SYMBOL; 712 if (specialEncoding) 713 encoding = BaseFont.SYMBOL; 714 break; 715 case ZAPFDINGBATS: 716 fontName = BaseFont.ZAPFDINGBATS; 717 if (specialEncoding) 718 encoding = BaseFont.ZAPFDINGBATS; 719 break; 720 default: 721 case HELVETICA: 722 switch (style & BOLDITALIC) { 723 case BOLD: 724 fontName = BaseFont.HELVETICA_BOLD; 725 break; 726 case ITALIC: 727 fontName = BaseFont.HELVETICA_OBLIQUE; 728 break; 729 case BOLDITALIC: 730 fontName = BaseFont.HELVETICA_BOLDOBLIQUE; 731 break; 732 default: 733 case NORMAL: 734 fontName = BaseFont.HELVETICA; 735 break; 736 } 737 break; 738 } 739 try { 740 cfont = BaseFont.createFont(fontName, encoding, false); 741 } catch (Exception ee) { 742 throw new ExceptionConverter(ee); 743 } 744 return cfont; 745 } 746 747 // Helper methods 748 749 /** 750 * Checks if the properties of this font are undefined or null. 751 * <P> 752 * If so, the standard should be used. 753 * 754 * @return a <CODE>boolean</CODE> 755 */ 756 public boolean isStandardFont() { 757 return family == FontFamily.UNDEFINED && size == UNDEFINED 758 && style == UNDEFINED && color == null && baseFont == null; 759 } 760 761 /** 762 * Replaces the attributes that are equal to <VAR>null</VAR> with the 763 * attributes of a given font. 764 * 765 * @param font 766 * the font of a bigger element class 767 * @return a <CODE>Font</CODE> 768 */ 769 public Font difference(final Font font) { 770 if (font == null) 771 return this; 772 // size 773 float dSize = font.size; 774 if (dSize == UNDEFINED) { 775 dSize = this.size; 776 } 777 // style 778 int dStyle = UNDEFINED; 779 int style1 = this.style; 780 int style2 = font.getStyle(); 781 if (style1 != UNDEFINED || style2 != UNDEFINED) { 782 if (style1 == UNDEFINED) 783 style1 = 0; 784 if (style2 == UNDEFINED) 785 style2 = 0; 786 dStyle = style1 | style2; 787 } 788 // color 789 BaseColor dColor = font.color; 790 if (dColor == null) { 791 dColor = this.color; 792 } 793 // family 794 if (font.baseFont != null) { 795 return new Font(font.baseFont, dSize, dStyle, dColor); 796 } 797 if (font.getFamily() != FontFamily.UNDEFINED) { 798 return new Font(font.family, dSize, dStyle, dColor); 799 } 800 if (this.baseFont != null) { 801 if (dStyle == style1) { 802 return new Font(this.baseFont, dSize, dStyle, dColor); 803 } else { 804 return FontFactory.getFont(this.getFamilyname(), dSize, dStyle, 805 dColor); 806 } 807 } 808 return new Font(this.family, dSize, dStyle, dColor); 809 } 810 811}