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 }
791