1 /* 2 * TextStyle.java 27 nov. 2008 3 * 4 * Sweet Home 3D, Copyright (c) 2008 Emmanuel PUYBARET / eTeks <info@eteks.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 package com.eteks.sweethome3d.model; 21 22 import java.io.IOException; 23 import java.io.ObjectInputStream; 24 import java.io.Serializable; 25 import java.lang.ref.WeakReference; 26 import java.util.ArrayList; 27 import java.util.List; 28 29 /** 30 * The different attributes that define a text style. 31 * @author Emmanuel Puybaret 32 */ 33 public class TextStyle implements Serializable { 34 private static final long serialVersionUID = 1L; 35 36 public enum Alignment {LEFT, CENTER, RIGHT} 37 38 private final String fontName; 39 private final float fontSize; 40 private final boolean bold; 41 private final boolean italic; 42 private Alignment alignment; 43 44 private static final List<WeakReference<TextStyle>> textStylesCache = new ArrayList<WeakReference<TextStyle>>(); 45 TextStyle(float fontSize)46 public TextStyle(float fontSize) { 47 this(fontSize, false, false); 48 } 49 TextStyle(float fontSize, boolean bold, boolean italic)50 public TextStyle(float fontSize, boolean bold, boolean italic) { 51 this(null, fontSize, bold, italic); 52 } 53 54 /** 55 * Creates a text style from its font's name, its size and style. 56 * @since 5.0 57 */ TextStyle(String fontName, float fontSize, boolean bold, boolean italic)58 public TextStyle(String fontName, float fontSize, boolean bold, boolean italic) { 59 this(fontName, fontSize, bold, italic, Alignment.CENTER); 60 } 61 62 /** 63 * Creates a text style from its font's name, its size, style and alignment. 64 * @since 6.0 65 */ TextStyle(String fontName, float fontSize, boolean bold, boolean italic, Alignment alignment)66 public TextStyle(String fontName, float fontSize, boolean bold, boolean italic, Alignment alignment) { 67 this(fontName, fontSize, bold, italic, alignment, true); 68 } 69 TextStyle(String fontName, float fontSize, boolean bold, boolean italic, Alignment alignment, boolean cached)70 private TextStyle(String fontName, float fontSize, boolean bold, boolean italic, 71 Alignment alignment, boolean cached) { 72 this.fontName = fontName; 73 this.fontSize = fontSize; 74 this.bold = bold; 75 this.italic = italic; 76 this.alignment = alignment; 77 78 if (cached) { 79 textStylesCache.add(new WeakReference<TextStyle>(this)); 80 } 81 } 82 83 /** 84 * Reads style and updates cache. 85 */ readObject(ObjectInputStream in)86 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 87 in.defaultReadObject(); 88 if (this.alignment == null) { 89 this.alignment = Alignment.CENTER; 90 } 91 textStylesCache.add(new WeakReference<TextStyle>(this)); 92 } 93 94 /** 95 * Returns the text style instance matching the given parameters. 96 */ getInstance(String fontName, float fontSize, boolean bold, boolean italic, Alignment alignment)97 private TextStyle getInstance(String fontName, float fontSize, boolean bold, boolean italic, Alignment alignment) { 98 TextStyle textStyle = new TextStyle(fontName, fontSize, bold, italic, alignment, false); 99 for (int i = textStylesCache.size() - 1; i >= 0; i--) { 100 TextStyle cachedTextStyle = textStylesCache.get(i).get(); 101 if (cachedTextStyle == null) { 102 textStylesCache.remove(i); 103 } else if (cachedTextStyle.equals(textStyle)) { 104 return textStyle; 105 } 106 } 107 textStylesCache.add(new WeakReference<TextStyle>(textStyle)); 108 return textStyle; 109 } 110 111 /** 112 * Returns the font name of this text style. 113 */ getFontName()114 public String getFontName() { 115 return this.fontName; 116 } 117 118 /** 119 * Returns the font size of this text style. 120 */ getFontSize()121 public float getFontSize() { 122 return this.fontSize; 123 } 124 125 /** 126 * Returns whether this text style is bold or not. 127 */ isBold()128 public boolean isBold() { 129 return this.bold; 130 } 131 132 /** 133 * Returns whether this text style is italic or not. 134 */ isItalic()135 public boolean isItalic() { 136 return this.italic; 137 } 138 139 /** 140 * Returns the alignment applied on text using this style. 141 * @since 6.0 142 */ getAlignment()143 public Alignment getAlignment() { 144 return this.alignment; 145 } 146 147 /** 148 * Returns a derived style of this text style with a given font name. 149 * @since 5.0 150 */ deriveStyle(String fontName)151 public TextStyle deriveStyle(String fontName) { 152 if (getFontName() == fontName 153 || (fontName != null && fontName.equals(getFontName()))) { 154 return this; 155 } else { 156 return getInstance(fontName, getFontSize(), isBold(), isItalic(), getAlignment()); 157 } 158 } 159 160 /** 161 * Returns a derived style of this text style with a given font size. 162 */ deriveStyle(float fontSize)163 public TextStyle deriveStyle(float fontSize) { 164 if (getFontSize() == fontSize) { 165 return this; 166 } else { 167 return getInstance(getFontName(), fontSize, isBold(), isItalic(), getAlignment()); 168 } 169 } 170 171 /** 172 * Returns a derived style of this text style with a given alignment. 173 */ deriveStyle(Alignment alignment)174 public TextStyle deriveStyle(Alignment alignment) { 175 if (getAlignment() == alignment) { 176 return this; 177 } else { 178 return getInstance(getFontName(), getFontSize(), isBold(), isItalic(), alignment); 179 } 180 } 181 182 /** 183 * Returns a derived style of this text style with a given bold style. 184 */ deriveBoldStyle(boolean bold)185 public TextStyle deriveBoldStyle(boolean bold) { 186 if (isBold() == bold) { 187 return this; 188 } else { 189 return getInstance(getFontName(), getFontSize(), bold, isItalic(), getAlignment()); 190 } 191 } 192 193 /** 194 * Returns a derived style of this text style with a given italic style. 195 */ deriveItalicStyle(boolean italic)196 public TextStyle deriveItalicStyle(boolean italic) { 197 if (isItalic() == italic) { 198 return this; 199 } else { 200 return getInstance(getFontName(), getFontSize(), isBold(), italic, getAlignment()); 201 } 202 } 203 204 /** 205 * Returns <code>true</code> if this text style is equal to <code>object</code>. 206 */ 207 @Override equals(Object object)208 public boolean equals(Object object) { 209 if (object instanceof TextStyle) { 210 TextStyle textStyle = (TextStyle)object; 211 return (textStyle.fontName == this.fontName 212 || (textStyle.fontName != null && textStyle.fontName.equals(this.fontName))) 213 && textStyle.fontSize == this.fontSize 214 && textStyle.bold == this.bold 215 && textStyle.italic == this.italic 216 && textStyle.alignment == this.alignment; 217 } 218 return false; 219 } 220 221 /** 222 * Returns a hash code for this text style. 223 */ 224 @Override hashCode()225 public int hashCode() { 226 int hashCode = Float.floatToIntBits(this.fontSize); 227 if (this.fontName != null) { 228 hashCode += this.fontName.hashCode(); 229 } 230 if (this.bold) { 231 hashCode++; 232 } 233 if (this.italic) { 234 hashCode++; 235 } 236 hashCode += this.alignment.hashCode(); 237 return hashCode; 238 } 239 } 240