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 == nullreturn 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