1 package org.columba.core.print; 18 19 import java.awt.Graphics2D ; 20 import java.awt.Rectangle ; 21 import java.awt.Shape ; 22 import java.awt.geom.Point2D ; 23 import java.io.IOException ; 24 import java.net.URL ; 25 import java.util.logging.Logger ; 26 27 import javax.swing.JTextPane ; 28 import javax.swing.text.Document ; 29 import javax.swing.text.View ; 30 import javax.swing.text.html.HTMLDocument ; 31 import javax.swing.text.html.HTMLEditorKit ; 32 33 34 42 public class cHTMLPart extends cPrintObject { 43 44 private static final Logger LOG = Logger.getLogger("org.columba.core.print"); 45 46 47 private JTextPane mPane = null; 48 49 50 private cUnit mStartY = new cCmUnit(0.0); 51 52 53 private boolean mScaleAllowed; 54 55 59 public cHTMLPart() { 60 this(false); 61 } 62 63 67 public cHTMLPart(boolean scaleAllowed) { 68 super(); 69 mScaleAllowed = scaleAllowed; 70 } 71 72 76 public void setHTML(HTMLDocument html) { 77 mPane = new JTextPane (); 78 mPane.setDoubleBuffered(false); 79 mPane.setContentType("text/html"); 80 mPane.setDocument(html); mStartY = new cCmUnit(0.0); } 83 84 90 public void setHTML(URL url) throws IOException { 91 95 mPane = new JTextPane (); 96 mPane.setDoubleBuffered(false); 97 mPane.setEditorKit(new SyncHTMLEditorKit()); 98 mPane.setContentType("text/html"); 99 mPane.setPage(url); 100 mStartY = new cCmUnit(0.0); } 102 103 110 protected void setStartY(cUnit y) { 111 mStartY = new cCmUnit(y); 112 } 113 114 120 public void print(Graphics2D g) { 121 124 computePositionAndSize(); 125 126 cPoint origin = getDrawingOrigin(); 128 double width = getDrawingSize().getWidth().getPoints(); 129 double height = getPage().getPrintableAreaSize().getHeight() 130 .sub(getLocation().getY()).getPoints(); 131 132 138 mPane.setSize((int) width, Integer.MAX_VALUE); 141 mPane.validate(); 142 143 View rootView = mPane.getUI().getRootView(mPane); 144 145 double scale = scaleFactor(new cPointUnit(width)); 147 g.scale(scale, scale); 148 149 Shape oldClip = g.getClip(); 151 g.setClip((int) (origin.getX().getPoints() / scale), 152 (int) (origin.getY().getPoints() / scale), (int) (width / scale), 153 (int) (height / scale)); 154 155 Point2D.Double trans = new Point2D.Double (g.getClipBounds().getX(), 157 g.getClipBounds().getY()); 158 g.translate(trans.getX(), trans.getY()); 159 160 Rectangle allocation = new Rectangle (0, (int) -mStartY.getPoints(), 163 (int) mPane.getMinimumSize().getWidth(), 164 (int) mPane.getPreferredSize().getHeight()); 165 printView(g, rootView, allocation, height / scale); 166 167 g.translate(-trans.getX(), -trans.getY()); 169 g.scale(1 / scale, 1 / scale); 170 g.setClip(oldClip); 171 } 172 173 183 private void printView(Graphics2D g, View view, Shape allocation, 184 double maxHeight) { 185 if (view.getViewCount() > 0) { 186 Shape childAllocation; 188 View childView; 189 190 for (int i = 0; i < view.getViewCount(); i++) { 191 childAllocation = view.getChildAllocation(i, allocation); 192 193 if (childAllocation != null) { 194 childView = view.getView(i); 195 196 printView(g, childView, childAllocation, maxHeight); 198 } 199 } 200 } else { 201 double viewStartY = allocation.getBounds().getY(); 203 204 if ((viewStartY >= 0) && (viewStartY < maxHeight)) { 205 view.paint(g, allocation); 207 } 208 } 209 } 210 211 226 public cSize getSize(cUnit maxWidth) { 227 230 231 double width = maxWidth.sub(leftMargin).sub(rightMargin).getPoints(); 233 mPane.setSize((int) width, Integer.MAX_VALUE); 234 mPane.validate(); 235 236 double height = mPane.getPreferredSize().getHeight(); 237 238 height = height - mStartY.getPoints(); 240 241 double scale = scaleFactor(new cPointUnit(width)); 243 cUnit w = new cCmUnit(maxWidth); cUnit h = new cCmUnit(); 245 h.setPoints(height); h.addI(topMargin); h.addI(bottomMargin); h.setPoints(h.getPoints() * scale); 250 return new cSize(w, h); 251 } 252 253 263 private double scaleFactor(cUnit maxWidth) { 264 mPane.validate(); 266 if (!mScaleAllowed) { 267 LOG.info("Scaling not active - returning scale=1.0"); 268 269 return 1.0; 270 } else { 271 double width = maxWidth.sub(leftMargin).sub(rightMargin).getPoints(); 273 double scale; 274 275 if (mPane.getMinimumSize().getWidth() > width) { 276 scale = width / mPane.getMinimumSize().getWidth(); 277 } else { 278 scale = 1.0; } 280 281 LOG.info("Returning scale=" + scale); 282 283 return scale; 284 } 285 } 286 287 298 public cPrintObject breakBlock(cUnit w, cUnit maxHeight) { 299 302 303 cSize contentSize = this.getSize(w); double scale = scaleFactor(w); 306 int width = (int) (contentSize.getWidth().getPoints() / scale); 307 int height = (int) (contentSize.getHeight().getPoints() / scale); 308 int startY = (int) mStartY.getPoints(); 309 310 Rectangle allocation = new Rectangle (0, -startY, width, height 313 + startY); 314 315 double breakHeight = maxHeight.getPoints() / scale; 318 323 View rootView = mPane.getUI().getRootView(mPane); 324 breakHeight = calcBreakHeightFromView(rootView, allocation, breakHeight); 325 326 cHTMLPart remainder = new cHTMLPart(mScaleAllowed); 328 remainder.setHTML((HTMLDocument ) mPane.getDocument()); 329 remainder.setStartY(mStartY); 330 331 cUnit newStartY = new cCmUnit(); 333 334 if (breakHeight < height) { 335 newStartY.setPoints(mStartY.getPoints() + breakHeight); 336 } else { newStartY = mStartY.add(contentSize.getHeight()); 338 } 339 340 this.setStartY(newStartY); 341 342 return remainder; 343 } 344 345 353 private double calcBreakHeightFromView(View view, Shape allocation, 354 double actBreakHeight) { 355 if (view.getViewCount() > 0) { 356 double breakHeight = actBreakHeight; 358 Shape childAllocation; 359 View childView; 360 361 for (int i = 0; i < view.getViewCount(); i++) { 362 childAllocation = view.getChildAllocation(i, allocation); 363 364 if (childAllocation != null) { 365 childView = view.getView(i); 366 367 breakHeight = calcBreakHeightFromView(childView, 370 childAllocation, breakHeight); 371 } 372 } 373 374 return breakHeight; } else { 376 double allocY = allocation.getBounds().getY(); 378 double allocMaxY = allocation.getBounds().getMaxY(); 379 if ((allocY >= 0) && (allocY < actBreakHeight) 380 && (allocMaxY > actBreakHeight)) { 381 383 394 if (allocY < (actBreakHeight * 0.01)) { 395 return actBreakHeight; } else { 397 if (allocY < actBreakHeight) { 399 return allocY; } else { 401 return actBreakHeight; } 403 } 404 } else { 405 return actBreakHeight; } 407 } 408 } 409 } 410 411 412 416 class SyncHTMLEditorKit extends HTMLEditorKit { 417 424 public Document createDefaultDocument() { 425 Document doc = super.createDefaultDocument(); 426 ((HTMLDocument ) doc).setAsynchronousLoadPriority(-1); 427 428 return doc; 429 } 430 } 431 | Popular Tags |