/****************************************************************************** * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program is distributed in the hope * * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * * or via info@compiere.org or http://www.compiere.org/license.html * *****************************************************************************/ package org.compiere.print.layout; import java.awt.Container; import java.awt.Graphics; import java.awt.IllegalComponentStateException; import java.awt.Rectangle; import java.awt.Shape; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.Reader; import java.io.StringReader; import java.util.logging.Level; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.Element; import javax.swing.text.Position; import javax.swing.text.View; import javax.swing.text.ViewFactory; import javax.swing.text.html.HTMLDocument; import javax.swing.text.html.HTMLEditorKit; import org.compiere.util.CLogger; /** * HTML Renderer View * * @author Jorg Janke * @version $Id: HTMLRenderer.java,v 1.3 2006/07/30 00:53:02 jjanke Exp $ */ public class HTMLRenderer extends View implements Externalizable { /** * generated serial id */ private static final long serialVersionUID = 7180048200607805705L; /** * Get View from HTML String * @param html html string * @return renderer view */ public static HTMLRenderer get (String html) { HTMLEditorKit kit = new HTMLEditorKit(); HTMLDocument doc = (HTMLDocument)kit.createDefaultDocument(); try { doc.remove(0, doc.getLength()); Reader r = new StringReader(html); kit.read(r, doc, 0); } catch (Exception e) { log.log(Level.SEVERE, "", e); } // Create Renderer Element element = doc.getDefaultRootElement(); ViewFactory factory = kit.getViewFactory(); View view = factory.create(element); // Y_AXIS is main HTMLRenderer renderer = new HTMLRenderer (factory, view); renderer.preferenceChanged (null, true, true); return renderer; } // get /** Logger */ private static CLogger log = CLogger.getCLogger(HTMLRenderer.class); /** * @deprecated */ @Deprecated public HTMLRenderer() { super(null); } /** * Internal Constructor.
* Call {@link #get(String)} instead. * @param f factory * @param v root view */ public HTMLRenderer (ViewFactory f, View v) { super(null); m_factory = f; m_view = v; m_view.setParent(this); m_container = new Container(); m_element = m_view.getElement(); // initially layout to the preferred size try { setSize(m_view.getPreferredSpan(X_AXIS), m_view.getPreferredSpan(Y_AXIS)); } catch (IllegalComponentStateException e) { if (log.isLoggable(Level.INFO)) log.info("Exception ignored: " + e.toString() + " " + e.getLocalizedMessage()); } } // HTMLRenderer private int m_width; private View m_view; private ViewFactory m_factory; private Container m_container; private Element m_element; private Rectangle m_allocation; private float m_viewWidth; private float m_viewHeight; /** * Get Width * @return width */ public float getWidth() { return getPreferredSpan(javax.swing.text.View.X_AXIS); } // getWidth /** * Get Height * @return height */ public float getHeight() { return getPreferredSpan(javax.swing.text.View.Y_AXIS); } // getHeight /** * Get Height for one line * @return height (hard coded to 30) */ public float getHeightOneLine() { return 30f; // HARDCODED } // getHeightOneLine /** * Set Allocation (actual print size) * @param width actual print width * @param height actual print height */ public void setAllocation (int width, int height) { setAllocation (new Rectangle(width, height)); } // setAllocation /** * Set Allocation (actual size) * @param allocation actual print size */ public void setAllocation(Rectangle allocation) { m_allocation = allocation; } // setAllocation /** * Get Allocation * @return actual print size or if not defined the renderer size */ public Rectangle getAllocation() { if (m_allocation == null) return new Rectangle((int)getWidth(), (int)getHeight()); return m_allocation; } // getAllocation /** * Fetches the attributes to use when rendering. At the root * level there are no attributes. If an attribute is resolved * up the view hierarchy this is the end of the line. * @return attribute set */ public AttributeSet getAttributes() { return null; } /** * Determines the preferred span for this view along an axis. * @param axis may be either X_AXIS or Y_AXIS * @return the span the view would like to be rendered into. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. */ public float getPreferredSpan(int axis) { if (axis == X_AXIS) { // width currently laid out to return m_width; } return m_view.getPreferredSpan(axis); } /** * Determines the minimum span for this view along an axis. * * @param axis may be either X_AXIS or Y_AXIS * @return the span the view would like to be rendered into. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. */ public float getMinimumSpan(int axis) { return m_view.getMinimumSpan(axis); } /** * Determines the maximum span for this view along an axis. * * @param axis may be either X_AXIS or Y_AXIS * @return the span the view would like to be rendered into. * Typically the view is told to render into the span * that is returned, although there is no guarantee. * The parent may choose to resize or break the view. */ public float getMaximumSpan(int axis) { return Integer.MAX_VALUE; } /** * Determines the desired alignment for this view along an axis. * * @param axis may be either X_AXIS or Y_AXIS * @return the desired alignment, where 0.0 indicates the origin * and 1.0 the full span away from the origin */ public float getAlignment(int axis) { return m_view.getAlignment(axis); } /** * Renders the view. * * @param g the graphics context * @param allocation the region to render into */ public void paint(Graphics g, Shape allocation) { Rectangle alloc = allocation.getBounds(); m_view.setSize(alloc.width, alloc.height); // layout Shape oldClip = g.getClip(); g.setClip(alloc); // limit print m_view.paint(g, allocation); g.setClip(oldClip); } // paint /** * Sets the view parent. * * @param parent the parent view */ public void setParent(View parent) { throw new Error("Can't set parent on root view"); } /** * Returns the number of views in this view. Since * this view simply wraps the root of the view hierarchy * it has exactly one child. * * @return the number of views * @see #getView */ public int getViewCount() { return 1; } /** * Gets the n-th view in this container. * * @param n the number of the view to get * @return the view */ public View getView(int n) { return m_view; } /** * Provides a mapping from the document model coordinate space * to the coordinate space of the view mapped to it. * * @param pos the position to convert * @param a the allocated region to render into * @param b position * @return the bounding box of the given position * @throws BadLocationException */ public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException { return m_view.modelToView(pos, a, b); } /** * Provides a mapping from the document model coordinate space * to the coordinate space of the view mapped to it. * * @param p0 the position to convert >= 0 * @param b0 the bias toward the previous character or the * next character represented by p0, in case the * position is a boundary of two views. * @param p1 the position to convert >= 0 * @param b1 the bias toward the previous character or the * next character represented by p1, in case the * position is a boundary of two views. * @param a the allocated region to render into * @return the bounding box of the given position is returned * @exception BadLocationException if the given position does * not represent a valid location in the associated document * @exception IllegalArgumentException for an invalid bias argument * @see javax.swing.text.View#viewToModel(float, float, java.awt.Shape, javax.swing.text.Position.Bias[]) */ public Shape modelToView(int p0, Position.Bias b0, int p1, Position.Bias b1, Shape a) throws BadLocationException { return m_view.modelToView(p0, b0, p1, b1, a); } /** * Provides a mapping from the view coordinate space to the logical * coordinate space of the model. * * @param x x coordinate of the view location to convert * @param y y coordinate of the view location to convert * @param a the allocated region to render into * @param bias bias * @return the location within the model that best represents the * given point in the view */ public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) { return m_view.viewToModel(x, y, a, bias); } /** * Returns the document model underlying the view. * * @return the model */ public Document getDocument() { return m_view.getDocument(); } /** * Returns the starting offset into the model for this view. * * @return the starting offset */ public int getStartOffset() { return m_view.getStartOffset(); } /** * Returns the ending offset into the model for this view. * * @return the ending offset */ public int getEndOffset() { return m_view.getEndOffset(); } /** * Gets the element that this view is mapped to. * * @return the view */ public Element getElement() { return m_view.getElement(); } /** * Sets the view size. * * @param width the width * @param height the height */ public void setSize(float width, float height) { this.m_width = (int) width; this.m_viewWidth = width; this.m_viewHeight = height; m_view.setSize(width, height); } /** * Fetches the factory to be used for building the * various view fragments that make up the view that * represents the model. This is what determines * how the model will be represented. This is implemented * to fetch the factory provided by the associated * EditorKit. * * @return the factory */ public ViewFactory getViewFactory() { return m_factory; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(m_element); out.writeObject(m_allocation); out.writeFloat(m_viewWidth); out.writeFloat(m_viewHeight); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { m_element = (Element) in.readObject(); m_allocation = (Rectangle) in.readObject(); HTMLEditorKit kit = new HTMLEditorKit(); m_factory = kit.getViewFactory(); m_view = m_factory.create(m_element); m_view.setParent(this); float width = in.readFloat(); float height = in.readFloat(); setSize(width, height); } @Override public Container getContainer() { return m_container; } } // HTMLRenderer