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