/* TeXIcon.java * ========================================================================= * This file is originally part of the JMathTeX Library - http://jmathtex.sourceforge.net * * Copyright (C) 2004-2007 Universiteit Gent * Copyright (C) 2009 DENIZET Calixte * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * 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. * * A copy of the GNU General Public License can be found in the file * LICENSE.txt provided with the source distribution of this program (see * the META-INF directory in the source jar). This license can also be * found on the GNU website at http://www.gnu.org/licenses/gpl.html. * * If you did not receive a copy of the GNU General Public License along * with this program, contact the lead developer, or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. * * Linking this library statically or dynamically with other modules * is making a combined work based on this library. Thus, the terms * and conditions of the GNU General Public License cover the whole * combination. * * As a special exception, the copyright holders of this library give you * permission to link this library with independent modules to produce * an executable, regardless of the license terms of these independent * modules, and to copy and distribute the resulting executable under terms * of your choice, provided that you also meet, for each linked independent * module, the terms and conditions of the license of that module. * An independent module is a module which is not derived from or based * on this library. If you modify this library, you may extend this exception * to your version of the library, but you are not obliged to do so. * If you do not wish to do so, delete this exception statement from your * version. * */ /* Modified by Calixte Denizet */ package com.himamis.retex.renderer.share; import com.himamis.retex.renderer.share.platform.graphics.Color; import com.himamis.retex.renderer.share.platform.graphics.Graphics2DInterface; import com.himamis.retex.renderer.share.platform.graphics.HasForegroundColor; import com.himamis.retex.renderer.share.platform.graphics.Icon; import com.himamis.retex.renderer.share.platform.graphics.Insets; import com.himamis.retex.renderer.share.platform.graphics.RenderingHints; /** * An {@link javax.swing.Icon} implementation that will paint the TeXFormula * that created it. * <p> * This class cannot be instantiated directly. It can be constructed from a * TeXFormula using the {@link TeXFormula#createTeXIcon(int,double)} method. * * @author Kurt Vermeulen */ public class TeXIcon implements Icon { private static final Color defaultColor = ColorUtil.BLACK; public static double defaultSize = -1; public static double magFactor = 0; private Box box; private final double size; private Insets insets = new Insets(0, 0, 0, 0); private Color fg = null; public boolean isColored = false; /** * Creates a new icon that will paint the given formula box in the given point size. * * @param b the formula box to be painted * @param size the point size */ protected TeXIcon(Box b, double size) { this(b, size, false); } protected TeXIcon(Box b, double size, boolean trueValues) { box = b; double size1 = defaultSize != -1 ? defaultSize : size; if (magFactor != 0) { this.size = size1 * Math.abs(magFactor); } else { this.size = size1; } /* I add this little value because it seems that tftopl calculates badly the height and the depth of certains characters. */ if (!trueValues) { insets.top += (int) (0.18f * size1); insets.bottom += (int) (0.18f * size1); insets.left += (int) (0.18f * size1); insets.right += (int) (0.18f * size1); } } public void setForeground(Color fg) { this.fg = fg; } /** * Get the insets of the TeXIcon. * * @return the insets */ public Insets getInsets() { return insets; } /** * Set the insets of the TeXIcon. * * @param insets the insets * @param trueValues true to force the true values */ public void setInsets(Insets insets, boolean trueValues) { this.insets = insets; if (!trueValues) { this.insets.top += (int)(0.18f * size); this.insets.bottom += (int)(0.18f * size); this.insets.left += (int)(0.18f * size); this.insets.right += (int)(0.18f * size); } } /** * Set the insets of the TeXIcon. * * @param insets the insets */ public void setInsets(Insets insets) { setInsets(insets, false); } /** * Change the width of the TeXIcon. The new width must be greater than the current * width, otherwise the icon will remain unchanged. The formula will be aligned to the * left ({@linkplain TeXConstants#ALIGN_LEFT}), to the right * ({@linkplain TeXConstants#ALIGN_RIGHT}) or will be centered * in the middle ({@linkplain TeXConstants#ALIGN_CENTER}). * * @param width the new width of the TeXIcon * @param alignment a horizontal alignment constant: LEFT, RIGHT or CENTER */ public void setIconWidth(int width, int alignment) { double diff = width - getIconWidth(); if (diff > 0) { box = new HorizontalBox(box, box.getWidth() + diff, alignment); } } /** * Change the height of the TeXIcon. The new height must be greater than the current * height, otherwise the icon will remain unchanged. The formula will be aligned on top * (TeXConstants.TOP), at the bottom (TeXConstants.BOTTOM) or will be centered * in the middle (TeXConstants.CENTER). * * @param height the new height of the TeXIcon * @param alignment a vertical alignment constant: TOP, BOTTOM or CENTER */ public void setIconHeight(int height, int alignment) { double diff = height - getIconHeight(); if (diff > 0) { box = new VerticalBox(box, diff, alignment); } } /** * Get the total height of the TeXIcon. This also includes the insets. */ @Override public int getIconHeight() { return ((int) ((box.getHeight()) * size + 0.99 + insets.top)) + ((int) ((box.getDepth()) * size + 0.99 + insets.bottom)); } /** * Get the total height of the TeXIcon. This also includes the insets. */ public int getIconDepth() { return (int) (box.getDepth() * size + 0.99 + insets.bottom); } /** * Get the total width of the TeXIcon. This also includes the insets. */ @Override public int getIconWidth() { return (int) (box.getWidth() * size + 0.99 + insets.left + insets.right); } public double getTrueIconHeight() { return (box.getHeight() + box.getDepth()) * size; } /** * Get the total height of the TeXIcon. This also includes the insets. */ public double getTrueIconDepth() { return box.getDepth() * size; } /** * Get the total width of the TeXIcon. This also includes the insets. */ public double getTrueIconWidth() { return box.getWidth() * size; } public double getBaseLine() { return ( (box.getHeight() * size + 0.99 + insets.top) / ((box.getHeight() + box.getDepth()) * size + 0.99 + insets.top + insets.bottom)); } public Box getBox() { return box; } /** * Paint the {@link TeXFormula} that created this icon. */ @Override public void paintIcon(HasForegroundColor c, Graphics2DInterface g2, int x, int y) { // copy graphics settings // TODO implement getRenderingHints //RenderingHints oldHints = g2.getRenderingHints(); g2.saveTransformation(); Color oldColor = g2.getColor(); // new settings g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2.scale(size, size); // the point size if (fg != null) { g2.setColor(fg); } else if (c != null) { g2.setColor(c.getForegroundColor()); // foreground will be used as default painting color } else { g2.setColor(defaultColor); } // draw formula box box.draw(g2, (x + insets.left) / size, (y + insets.top) / size+ box.getHeight()); // quick fix for export problem // restore graphics settings //g2.setRenderingHints(oldHints); g2.restoreTransformation(); g2.setColor(oldColor); } }