1 /* 2 * $Id: Font.java 3678 2009-02-07 14:46:01Z blowagie $ 3 * 4 * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. 5 * 6 * The contents of this file are subject to the Mozilla Public License Version 1.1 7 * (the "License"); you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at http://www.mozilla.org/MPL/ 9 * 10 * Software distributed under the License is distributed on an "AS IS" basis, 11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 * for the specific language governing rights and limitations under the License. 13 * 14 * The Original Code is 'iText, a free JAVA-PDF library'. 15 * 16 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by 17 * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. 18 * All Rights Reserved. 19 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer 20 * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. 21 * 22 * Contributor(s): all the names of the contributors are added in the source code 23 * where applicable. 24 * 25 * Alternatively, the contents of this file may be used under the terms of the 26 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the 27 * provisions of LGPL are applicable instead of those above. If you wish to 28 * allow use of your version of this file only under the terms of the LGPL 29 * License and not to allow others to use your version of this file under 30 * the MPL, indicate your decision by deleting the provisions above and 31 * replace them with the notice and other provisions required by the LGPL. 32 * If you do not delete the provisions above, a recipient may use your version 33 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. 34 * 35 * This library is free software; you can redistribute it and/or modify it 36 * under the terms of the MPL as stated above or under the terms of the GNU 37 * Library General Public License as published by the Free Software Foundation; 38 * either version 2 of the License, or any later version. 39 * 40 * This library is distributed in the hope that it will be useful, but WITHOUT 41 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 42 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more 43 * details. 44 * 45 * If you didn't download this code from the following link, you should check if 46 * you aren't using an obsolete version: 47 * http://www.lowagie.com/iText/ 48 */ 49 50 package com.lowagie.text; 51 52 import java.awt.Color; 53 54 import com.lowagie.text.html.Markup; 55 import com.lowagie.text.pdf.BaseFont; 56 57 /** 58 * Contains all the specifications of a font: fontfamily, size, style and color. 59 * <P> 60 * Example: <BLOCKQUOTE> 61 * 62 * <PRE> 63 * 64 * Paragraph p = new Paragraph("This is a paragraph", <STRONG>new 65 * Font(Font.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)) </STRONG>); 66 * 67 * </PRE> 68 * 69 * </BLOCKQUOTE> 70 */ 71 72 public class Font implements Comparable { 73 74 // static membervariables for the different families 75 76 /** a possible value of a font family. */ 77 public static final int COURIER = 0; 78 79 /** a possible value of a font family. */ 80 public static final int HELVETICA = 1; 81 82 /** a possible value of a font family. */ 83 public static final int TIMES_ROMAN = 2; 84 85 /** a possible value of a font family. */ 86 public static final int SYMBOL = 3; 87 88 /** a possible value of a font family. */ 89 public static final int ZAPFDINGBATS = 4; 90 91 // static membervariables for the different styles 92 93 /** this is a possible style. */ 94 public static final int NORMAL = 0; 95 96 /** this is a possible style. */ 97 public static final int BOLD = 1; 98 99 /** this is a possible style. */ 100 public static final int ITALIC = 2; 101 102 /** this is a possible style. */ 103 public static final int UNDERLINE = 4; 104 105 /** this is a possible style. */ 106 public static final int STRIKETHRU = 8; 107 108 /** this is a possible style. */ 109 public static final int BOLDITALIC = BOLD | ITALIC; 110 111 // static membervariables 112 113 /** the value of an undefined attribute. */ 114 public static final int UNDEFINED = -1; 115 116 /** the value of the default size. */ 117 public static final int DEFAULTSIZE = 12; 118 119 // membervariables 120 121 /** the value of the fontfamily. */ 122 private int family = UNDEFINED; 123 124 /** the value of the fontsize. */ 125 private float size = UNDEFINED; 126 127 /** the value of the style. */ 128 private int style = UNDEFINED; 129 130 /** the value of the color. */ 131 private Color color = null; 132 133 /** the external font */ 134 private BaseFont baseFont = null; 135 136 // constructors 137 138 /** 139 * Copy constructor of a Font 140 * 141 * @param other 142 * the font that has to be copied 143 */ 144 public Font(Font other) { 145 this.family = other.family; 146 this.size = other.size; 147 this.style = other.style; 148 this.color = other.color; 149 this.baseFont = other.baseFont; 150 } 151 152 /** 153 * Constructs a Font. 154 * 155 * @param family 156 * the family to which this font belongs 157 * @param size 158 * the size of this font 159 * @param style 160 * the style of this font 161 * @param color 162 * the <CODE>Color</CODE> of this font. 163 */ 164 165 public Font(int family, float size, int style, Color color) { 166 this.family = family; 167 this.size = size; 168 this.style = style; 169 this.color = color; 170 } 171 172 /** 173 * Constructs a Font. 174 * 175 * @param bf 176 * the external font 177 * @param size 178 * the size of this font 179 * @param style 180 * the style of this font 181 * @param color 182 * the <CODE>Color</CODE> of this font. 183 */ 184 185 public Font(BaseFont bf, float size, int style, Color color) { 186 this.baseFont = bf; 187 this.size = size; 188 this.style = style; 189 this.color = color; 190 } 191 192 /** 193 * Constructs a Font. 194 * 195 * @param bf 196 * the external font 197 * @param size 198 * the size of this font 199 * @param style 200 * the style of this font 201 */ 202 public Font(BaseFont bf, float size, int style) { 203 this(bf, size, style, null); 204 } 205 206 /** 207 * Constructs a Font. 208 * 209 * @param bf 210 * the external font 211 * @param size 212 * the size of this font 213 */ 214 public Font(BaseFont bf, float size) { 215 this(bf, size, UNDEFINED, null); 216 } 217 218 /** 219 * Constructs a Font. 220 * 221 * @param bf 222 * the external font 223 */ 224 public Font(BaseFont bf) { 225 this(bf, UNDEFINED, UNDEFINED, null); 226 } 227 228 /** 229 * Constructs a Font. 230 * 231 * @param family 232 * the family to which this font belongs 233 * @param size 234 * the size of this font 235 * @param style 236 * the style of this font 237 */ 238 239 public Font(int family, float size, int style) { 240 this(family, size, style, null); 241 } 242 243 /** 244 * Constructs a Font. 245 * 246 * @param family 247 * the family to which this font belongs 248 * @param size 249 * the size of this font 250 */ 251 252 public Font(int family, float size) { 253 this(family, size, UNDEFINED, null); 254 } 255 256 /** 257 * Constructs a Font. 258 * 259 * @param family 260 * the family to which this font belongs 261 */ 262 263 public Font(int family) { 264 this(family, UNDEFINED, UNDEFINED, null); 265 } 266 267 /** 268 * Constructs a Font. 269 */ 270 271 public Font() { 272 this(UNDEFINED, UNDEFINED, UNDEFINED, null); 273 } 274 275 // implementation of the Comparable interface 276 277 /** 278 * Compares this <CODE>Font</CODE> with another 279 * 280 * @param object 281 * the other <CODE>Font</CODE> 282 * @return a value 283 */ 284 public int compareTo(Object object) { 285 if (object == null) { 286 return -1; 287 } 288 Font font; 289 try { 290 font = (Font) object; 291 if (baseFont != null && !baseFont.equals(font.getBaseFont())) { 292 return -2; 293 } 294 if (this.family != font.getFamily()) { 295 return 1; 296 } 297 if (this.size != font.getSize()) { 298 return 2; 299 } 300 if (this.style != font.getStyle()) { 301 return 3; 302 } 303 if (this.color == null) { 304 if (font.color == null) { 305 return 0; 306 } 307 return 4; 308 } 309 if (font.color == null) { 310 return 4; 311 } 312 if (this.color.equals(font.getColor())) { 313 return 0; 314 } 315 return 4; 316 } catch (ClassCastException cce) { 317 return -3; 318 } 319 } 320 321 // FAMILY 322 323 /** 324 * Gets the family of this font. 325 * 326 * @return the value of the family 327 */ 328 public int getFamily() { 329 return family; 330 } 331 332 /** 333 * Gets the familyname as a String. 334 * 335 * @return the familyname 336 */ 337 public String getFamilyname() { 338 String tmp = "unknown"; 339 switch (getFamily()) { 340 case Font.COURIER: 341 return FontFactory.COURIER; 342 case Font.HELVETICA: 343 return FontFactory.HELVETICA; 344 case Font.TIMES_ROMAN: 345 return FontFactory.TIMES_ROMAN; 346 case Font.SYMBOL: 347 return FontFactory.SYMBOL; 348 case Font.ZAPFDINGBATS: 349 return FontFactory.ZAPFDINGBATS; 350 default: 351 if (baseFont != null) { 352 String[][] names = baseFont.getFamilyFontName(); 353 for (int i = 0; i < names.length; i++) { 354 if ("0".equals(names[i][2])) { 355 return names[i][3]; 356 } 357 if ("1033".equals(names[i][2])) { 358 tmp = names[i][3]; 359 } 360 if ("".equals(names[i][2])) { 361 tmp = names[i][3]; 362 } 363 } 364 } 365 } 366 return tmp; 367 } 368 369 /** 370 * Sets the family using a <CODE>String</CODE> ("Courier", "Helvetica", 371 * "Times New Roman", "Symbol" or "ZapfDingbats"). 372 * 373 * @param family 374 * A <CODE>String</CODE> representing a certain font-family. 375 */ 376 public void setFamily(String family) { 377 this.family = getFamilyIndex(family); 378 } 379 380 /** 381 * Translates a <CODE>String</CODE> -value of a certain family into the 382 * index that is used for this family in this class. 383 * 384 * @param family 385 * A <CODE>String</CODE> representing a certain font-family 386 * @return the corresponding index 387 */ 388 public static int getFamilyIndex(String family) { 389 if (family.equalsIgnoreCase(FontFactory.COURIER)) { 390 return COURIER; 391 } 392 if (family.equalsIgnoreCase(FontFactory.HELVETICA)) { 393 return HELVETICA; 394 } 395 if (family.equalsIgnoreCase(FontFactory.TIMES_ROMAN)) { 396 return TIMES_ROMAN; 397 } 398 if (family.equalsIgnoreCase(FontFactory.SYMBOL)) { 399 return SYMBOL; 400 } 401 if (family.equalsIgnoreCase(FontFactory.ZAPFDINGBATS)) { 402 return ZAPFDINGBATS; 403 } 404 return UNDEFINED; 405 } 406 407 // SIZE 408 409 /** 410 * Gets the size of this font. 411 * 412 * @return a size 413 */ 414 public float getSize() { 415 return size; 416 } 417 418 /** 419 * Gets the size that can be used with the calculated <CODE>BaseFont 420 * </CODE>. 421 * 422 * @return the size that can be used with the calculated <CODE>BaseFont 423 * </CODE> 424 */ 425 public float getCalculatedSize() { 426 float s = this.size; 427 if (s == UNDEFINED) { 428 s = DEFAULTSIZE; 429 } 430 return s; 431 } 432 433 /** 434 * Gets the leading that can be used with this font. 435 * 436 * @param linespacing 437 * a certain linespacing 438 * @return the height of a line 439 */ 440 public float getCalculatedLeading(float linespacing) { 441 return linespacing * getCalculatedSize(); 442 } 443 444 /** 445 * Sets the size. 446 * 447 * @param size 448 * The new size of the font. 449 */ 450 public void setSize(float size) { 451 this.size = size; 452 } 453 454 // STYLE 455 456 /** 457 * Gets the style of this font. 458 * 459 * @return a size 460 */ 461 public int getStyle() { 462 return style; 463 } 464 465 /** 466 * Gets the style that can be used with the calculated <CODE>BaseFont 467 * </CODE>. 468 * 469 * @return the style that can be used with the calculated <CODE>BaseFont 470 * </CODE> 471 */ 472 public int getCalculatedStyle() { 473 int style = this.style; 474 if (style == UNDEFINED) { 475 style = NORMAL; 476 } 477 if (baseFont != null) 478 return style; 479 if (family == SYMBOL || family == ZAPFDINGBATS) 480 return style; 481 else 482 return style & (~BOLDITALIC); 483 } 484 485 /** 486 * checks if this font is Bold. 487 * 488 * @return a <CODE>boolean</CODE> 489 */ 490 public boolean isBold() { 491 if (style == UNDEFINED) { 492 return false; 493 } 494 return (style & BOLD) == BOLD; 495 } 496 497 /** 498 * checks if this font is Bold. 499 * 500 * @return a <CODE>boolean</CODE> 501 */ 502 public boolean isItalic() { 503 if (style == UNDEFINED) { 504 return false; 505 } 506 return (style & ITALIC) == ITALIC; 507 } 508 509 /** 510 * checks if this font is underlined. 511 * 512 * @return a <CODE>boolean</CODE> 513 */ 514 public boolean isUnderlined() { 515 if (style == UNDEFINED) { 516 return false; 517 } 518 return (style & UNDERLINE) == UNDERLINE; 519 } 520 521 /** 522 * checks if the style of this font is STRIKETHRU. 523 * 524 * @return a <CODE>boolean</CODE> 525 */ 526 public boolean isStrikethru() { 527 if (style == UNDEFINED) { 528 return false; 529 } 530 return (style & STRIKETHRU) == STRIKETHRU; 531 } 532 533 /** 534 * Sets the style. 535 * 536 * @param style 537 * the style. 538 */ 539 public void setStyle(int style) { 540 this.style = style; 541 } 542 543 /** 544 * Sets the style using a <CODE>String</CODE> containing one of more of 545 * the following values: normal, bold, italic, underline, strike. 546 * 547 * @param style 548 * A <CODE>String</CODE> representing a certain style. 549 */ 550 public void setStyle(String style) { 551 if (this.style == UNDEFINED) 552 this.style = NORMAL; 553 this.style |= getStyleValue(style); 554 } 555 556 /** 557 * Translates a <CODE>String</CODE> -value of a certain style into the 558 * index value is used for this style in this class. 559 * 560 * @param style 561 * A <CODE>String</CODE> 562 * @return the corresponding value 563 */ 564 public static int getStyleValue(String style) { 565 int s = 0; 566 if (style.indexOf(Markup.CSS_VALUE_NORMAL) != -1) { 567 s |= NORMAL; 568 } 569 if (style.indexOf(Markup.CSS_VALUE_BOLD) != -1) { 570 s |= BOLD; 571 } 572 if (style.indexOf(Markup.CSS_VALUE_ITALIC) != -1) { 573 s |= ITALIC; 574 } 575 if (style.indexOf(Markup.CSS_VALUE_OBLIQUE) != -1) { 576 s |= ITALIC; 577 } 578 if (style.indexOf(Markup.CSS_VALUE_UNDERLINE) != -1) { 579 s |= UNDERLINE; 580 } 581 if (style.indexOf(Markup.CSS_VALUE_LINETHROUGH) != -1) { 582 s |= STRIKETHRU; 583 } 584 return s; 585 } 586 587 // COLOR 588 589 /** 590 * Gets the color of this font. 591 * 592 * @return a color 593 */ 594 public Color getColor() { 595 return color; 596 } 597 598 /** 599 * Sets the color. 600 * 601 * @param color 602 * the new color of the font 603 */ 604 605 public void setColor(Color color) { 606 this.color = color; 607 } 608 609 /** 610 * Sets the color. 611 * 612 * @param red 613 * the red-value of the new color 614 * @param green 615 * the green-value of the new color 616 * @param blue 617 * the blue-value of the new color 618 */ 619 public void setColor(int red, int green, int blue) { 620 this.color = new Color(red, green, blue); 621 } 622 623 // BASEFONT 624 625 /** 626 * Gets the <CODE>BaseFont</CODE> inside this object. 627 * 628 * @return the <CODE>BaseFont</CODE> 629 */ 630 public BaseFont getBaseFont() { 631 return baseFont; 632 } 633 634 /** 635 * Gets the <CODE>BaseFont</CODE> this class represents. For the built-in 636 * fonts a <CODE>BaseFont</CODE> is calculated. 637 * 638 * @param specialEncoding 639 * <CODE>true</CODE> to use the special encoding for Symbol and 640 * ZapfDingbats, <CODE>false</CODE> to always use <CODE>Cp1252 641 * </CODE> 642 * @return the <CODE>BaseFont</CODE> this class represents 643 */ 644 public BaseFont getCalculatedBaseFont(boolean specialEncoding) { 645 if (baseFont != null) 646 return baseFont; 647 int style = this.style; 648 if (style == UNDEFINED) { 649 style = NORMAL; 650 } 651 String fontName = BaseFont.HELVETICA; 652 String encoding = BaseFont.WINANSI; 653 BaseFont cfont = null; 654 switch (family) { 655 case COURIER: 656 switch (style & BOLDITALIC) { 657 case BOLD: 658 fontName = BaseFont.COURIER_BOLD; 659 break; 660 case ITALIC: 661 fontName = BaseFont.COURIER_OBLIQUE; 662 break; 663 case BOLDITALIC: 664 fontName = BaseFont.COURIER_BOLDOBLIQUE; 665 break; 666 default: 667 //case NORMAL: 668 fontName = BaseFont.COURIER; 669 break; 670 } 671 break; 672 case TIMES_ROMAN: 673 switch (style & BOLDITALIC) { 674 case BOLD: 675 fontName = BaseFont.TIMES_BOLD; 676 break; 677 case ITALIC: 678 fontName = BaseFont.TIMES_ITALIC; 679 break; 680 case BOLDITALIC: 681 fontName = BaseFont.TIMES_BOLDITALIC; 682 break; 683 default: 684 case NORMAL: 685 fontName = BaseFont.TIMES_ROMAN; 686 break; 687 } 688 break; 689 case SYMBOL: 690 fontName = BaseFont.SYMBOL; 691 if (specialEncoding) 692 encoding = BaseFont.SYMBOL; 693 break; 694 case ZAPFDINGBATS: 695 fontName = BaseFont.ZAPFDINGBATS; 696 if (specialEncoding) 697 encoding = BaseFont.ZAPFDINGBATS; 698 break; 699 default: 700 case Font.HELVETICA: 701 switch (style & BOLDITALIC) { 702 case BOLD: 703 fontName = BaseFont.HELVETICA_BOLD; 704 break; 705 case ITALIC: 706 fontName = BaseFont.HELVETICA_OBLIQUE; 707 break; 708 case BOLDITALIC: 709 fontName = BaseFont.HELVETICA_BOLDOBLIQUE; 710 break; 711 default: 712 case NORMAL: 713 fontName = BaseFont.HELVETICA; 714 break; 715 } 716 break; 717 } 718 try { 719 cfont = BaseFont.createFont(fontName, encoding, false); 720 } catch (Exception ee) { 721 throw new ExceptionConverter(ee); 722 } 723 return cfont; 724 } 725 726 727 // Helper methods 728 729 /** 730 * Checks if the properties of this font are undefined or null. 731 * <P> 732 * If so, the standard should be used. 733 * 734 * @return a <CODE>boolean</CODE> 735 */ 736 public boolean isStandardFont() { 737 return (family == UNDEFINED && size == UNDEFINED && style == UNDEFINED 738 && color == null && baseFont == null); 739 } 740 741 /** 742 * Replaces the attributes that are equal to <VAR>null</VAR> with the 743 * attributes of a given font. 744 * 745 * @param font 746 * the font of a bigger element class 747 * @return a <CODE>Font</CODE> 748 */ 749 public Font difference(Font font) { 750 if (font == null) return this; 751 // size 752 float dSize = font.size; 753 if (dSize == UNDEFINED) { 754 dSize = this.size; 755 } 756 // style 757 int dStyle = UNDEFINED; 758 int style1 = this.style; 759 int style2 = font.getStyle(); 760 if (style1 != UNDEFINED || style2 != UNDEFINED) { 761 if (style1 == UNDEFINED) 762 style1 = 0; 763 if (style2 == UNDEFINED) 764 style2 = 0; 765 dStyle = style1 | style2; 766 } 767 // color 768 Color dColor = font.color; 769 if (dColor == null) { 770 dColor = this.color; 771 } 772 // family 773 if (font.baseFont != null) { 774 return new Font(font.baseFont, dSize, dStyle, dColor); 775 } 776 if (font.getFamily() != UNDEFINED) { 777 return new Font(font.family, dSize, dStyle, dColor); 778 } 779 if (this.baseFont != null) { 780 if (dStyle == style1) { 781 return new Font(this.baseFont, dSize, dStyle, dColor); 782 } else { 783 return FontFactory.getFont(this.getFamilyname(), dSize, dStyle, 784 dColor); 785 } 786 } 787 return new Font(this.family, dSize, dStyle, dColor); 788 } 789 790 }