1 package org.columba.core.print; 17 18 import java.awt.Color ; 19 import java.awt.Font ; 20 import java.awt.Graphics2D ; 21 import java.awt.font.FontRenderContext ; 22 import java.awt.font.LineBreakMeasurer ; 23 import java.awt.font.TextAttribute ; 24 import java.awt.font.TextLayout ; 25 import java.awt.geom.Point2D ; 26 import java.text.AttributedCharacterIterator ; 27 import java.text.AttributedString ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Vector ; 31 32 33 public class cParagraph extends cPrintObject { 34 public static final int LEFT = 0; 35 public static final int CENTER = 1; 36 public static final int RIGHT = 2; 37 public static final int BLOCK = 3; 38 private String original; 39 private List paragraphs; 40 private int alignment; 41 private Font font; 42 43 public cParagraph() { 44 super(); 45 paragraphs = new Vector (); 46 47 alignment = 0; 48 49 font = new Font ("Default", Font.PLAIN, 10); 50 } 51 52 public void setFontStyle(int style) { 53 font = font.deriveFont(style); 54 55 updateFont(); 56 } 57 58 public void setFontSize(float size) { 59 font = font.deriveFont(size); 60 updateFont(); 61 } 62 63 private void updateFont() { 64 for (Iterator it = paragraphs.iterator(); it.hasNext();) { 65 ((AttributedString ) it.next()).addAttribute(TextAttribute.FONT, font); 66 67 } 70 } 71 72 79 private String validate(String t) { 80 if ((t.indexOf("\n\n") == -1) && (!t.startsWith("\n"))) { 81 return t; 82 } 83 84 StringBuffer result = new StringBuffer (); 85 86 if (t.startsWith("\n")) { 88 result.append(' '); 89 } 90 91 char last = ' '; 93 94 for (int i = 0; i < t.length(); i++) { 95 if ((t.charAt(i) == '\n') && (last == '\n')) { 96 result.append(" \n"); 97 } else { 98 result.append(t.charAt(i)); 99 } 100 101 last = t.charAt(i); 102 } 103 104 return result.toString(); 105 } 106 107 public void setText(String t) { 108 original = validate(t); 109 110 paragraphs.clear(); 111 112 StringBuffer buffer = new StringBuffer (); 113 114 AttributedString act; 115 116 for (int i = 0; i < original.length(); i++) { 117 if (original.charAt(i) == '\n') { 118 act = new AttributedString (buffer.toString()); 119 act.addAttribute(TextAttribute.FONT, font); 120 paragraphs.add(act); 121 buffer = new StringBuffer (); 122 } else { 123 buffer.append(original.charAt(i)); 124 } 125 } 126 127 if (buffer.length() != 0) { 128 act = new AttributedString (buffer.toString()); 129 act.addAttribute(TextAttribute.FONT, font); 130 paragraphs.add(act); 131 } 132 } 133 134 public void setTextAlignment(int v) { 135 alignment = v; 136 } 137 138 public void print(Graphics2D g) { 139 computePositionAndSize(); 140 141 Color saveForeground = g.getColor(); 142 143 g.setColor(color); 144 145 switch (alignment) { 146 case LEFT: 147 renderLeftAligned(g); 148 149 break; 150 151 case RIGHT: 152 renderRightAligned(g); 153 154 break; 155 156 case CENTER: 157 renderCenterAligned(g); 158 159 break; 160 } 161 162 g.setColor(saveForeground); 163 } 164 165 private void renderLeftAligned(Graphics2D g) { 166 Point2D.Double pen = getDrawingOrigin().getPoint2D(); 167 168 double width = getDrawingSize().getWidth().getPoints(); 169 170 for (Iterator it = paragraphs.iterator(); it.hasNext();) { 171 LineBreakMeasurer lineBreaker = new LineBreakMeasurer (((AttributedString ) it.next()).getIterator(), 172 new FontRenderContext (null, true, true)); 173 174 TextLayout layout; 180 181 while ((layout = lineBreaker.nextLayout((float) width)) != null) { 182 pen.y += layout.getAscent(); 183 184 layout.draw(g, (float) pen.x, (float) pen.y); 185 186 pen.y += (layout.getDescent() + layout.getLeading()); 187 } 188 } 189 } 190 191 private void renderRightAligned(Graphics2D g) { 192 Point2D.Double pen = getDrawingOrigin().getPoint2D(); 193 194 double width = getDrawingSize().getWidth().getPoints(); 195 196 for (Iterator it = paragraphs.iterator(); it.hasNext();) { 197 LineBreakMeasurer lineBreaker = new LineBreakMeasurer (((AttributedString ) it.next()).getIterator(), 198 new FontRenderContext (null, true, true)); 199 200 TextLayout layout; 206 float layoutX; 207 208 while ((layout = lineBreaker.nextLayout((float) width)) != null) { 209 pen.y += layout.getAscent(); 210 211 layoutX = ((float) (pen.x + width)) - layout.getAdvance(); 212 213 layout.draw(g, layoutX, (float) pen.y); 214 215 pen.y += (layout.getDescent() + layout.getLeading()); 216 } 217 } 218 } 219 220 private void renderCenterAligned(Graphics2D g) { 221 Point2D.Double pen = getDrawingOrigin().getPoint2D(); 222 223 double width = getDrawingSize().getWidth().getPoints(); 224 225 for (Iterator it = paragraphs.iterator(); it.hasNext();) { 226 LineBreakMeasurer lineBreaker = new LineBreakMeasurer (((AttributedString ) it.next()).getIterator(), 227 new FontRenderContext (null, true, true)); 228 229 TextLayout layout; 235 236 float layoutX; 237 238 while ((layout = lineBreaker.nextLayout((float) width)) != null) { 239 pen.y += layout.getAscent(); 240 241 layoutX = ((float) (pen.x + (width / 2))) - 242 (layout.getAdvance() / 2); 243 244 layout.draw(g, layoutX, (float) pen.y); 245 246 pen.y += (layout.getDescent() + layout.getLeading()); 247 } 248 } 249 } 250 251 public cSize getSize(cUnit w) { 252 cCmUnit textHeight = new cCmUnit(); 253 float maxAdvance = -1; 254 255 Point2D.Double pen = new Point2D.Double (0.0, 0.0); 256 257 double width = w.sub(leftMargin).sub(rightMargin).getPoints(); 258 259 for (Iterator it = paragraphs.iterator(); it.hasNext();) { 260 LineBreakMeasurer lineBreaker = new LineBreakMeasurer (((AttributedString ) it.next()).getIterator(), 261 new FontRenderContext (null, true, true)); 262 263 TextLayout layout; 269 270 while ((layout = lineBreaker.nextLayout((float) width)) != null) { 271 pen.y += (layout.getAscent() + layout.getDescent() + 272 layout.getLeading()); 273 274 if (layout.getAdvance() > maxAdvance) { 275 maxAdvance = layout.getAdvance(); 276 } 277 } 278 } 279 280 textHeight.setPoints(pen.y); 281 textHeight.addI(topMargin); 282 textHeight.addI(bottomMargin); 283 284 cCmUnit bwidth = new cCmUnit(); 285 bwidth.setPoints(maxAdvance); 286 bwidth.addI(leftMargin); 287 bwidth.addI(rightMargin); 288 289 return new cSize(bwidth, textHeight); 290 } 291 292 public cPrintObject breakBlock(cUnit w, cUnit maxHeight) { 293 AttributedCharacterIterator it; 294 int lastPos; 295 int pos = 0; 296 297 cParagraph remainParagraph = null; 298 299 Point2D.Double pen = new Point2D.Double (0.0, topMargin.getPoints()); 300 301 double width = w.sub(leftMargin).sub(rightMargin).getPoints(); 302 303 for (Iterator iter = paragraphs.iterator(); iter.hasNext();) { 304 it = ((AttributedString ) iter.next()).getIterator(); 305 306 LineBreakMeasurer lineBreaker = new LineBreakMeasurer (it, 309 new FontRenderContext (null, true, true)); 310 311 TextLayout layout; 312 lastPos = 0; 313 314 while ((layout = lineBreaker.nextLayout((float) width)) != null) { 315 pen.y += (layout.getAscent() + layout.getDescent() + 316 layout.getLeading()); 317 318 if (pen.y > maxHeight.getPoints()) { 319 remainParagraph = new cParagraph(); 320 remainParagraph.setTextAlignment(alignment); 321 remainParagraph.setTopMargin(topMargin); 322 remainParagraph.setLeftMargin(leftMargin); 323 remainParagraph.setRightMargin(rightMargin); 324 325 topMargin = new cCmUnit(); 326 327 remainParagraph.setText(original.substring(0, pos + 328 lastPos)); 329 this.setText(original.substring(pos + lastPos)); 330 331 return remainParagraph; 332 } 333 334 lastPos += layout.getCharacterCount(); 335 } 336 337 pos += (it.getEndIndex() + 1); 338 } 339 340 return remainParagraph; 341 } 342 343 public Font getFont() { 344 return font; 345 } 346 347 public void setFont(Font font) { 348 this.font = font; 349 updateFont(); 350 } 351 } 352 | Popular Tags |