Package org.geotools.renderer.style

Source Code of org.geotools.renderer.style.TTFMarkFactory

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation;
*    version 2.1 of the License.
*
*    This library 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
*    Lesser General Public License for more details.
*/
package org.geotools.renderer.style;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.logging.Logger;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;

import org.geotools.renderer.style.shape.ExplicitBoundsShape;
import org.opengis.feature.Feature;
import org.opengis.filter.expression.Expression;

/**
* This factory accepts mark paths in the <code>ttf://fontName#code</code>
* format, where fontName is the name of a TrueType font installed in the
* system, or a URL to a TTF file, and the code is the character code, which may
* be expressed in decimal, hexadecimal (e.g. <code>0x10</code>) octal (e.g.
* <code>045</code>) form, as well as Unicode codes (e.g. <code>U+F054</code>
* or <code>\uF054</code>).
*
* @author Andrea Aime - TOPP
*
*
*
*
* @source $URL$
*/
public class TTFMarkFactory implements MarkFactory {

    /** The logger for the rendering module. */
    private static final Logger LOGGER = org.geotools.util.logging.Logging
            .getLogger("org.geotools.rendering.style.TTFMarkFactory");

    private static FontRenderContext FONT_RENDER_CONTEXT = new FontRenderContext(
            new AffineTransform(), false, false);

    public Shape getShape(Graphics2D graphics, Expression symbolUrl, Feature feature)
            throws Exception {
        String markUrl = symbolUrl.evaluate(feature, String.class);

        // if it does not start with the right prefix, it's not our business
        if (!markUrl.startsWith("ttf://"))
            return null;

        // if it does not match the expected format, complain before exiting
        if (!markUrl.matches("ttf://.+#.+")) {
            throw new IllegalArgumentException(
                    "Mark URL font found, but does not match the required "
                            + "structure font://<fontName>#<charNumber>, e.g., ttf://wingdigs#0x7B. You specified "
                            + markUrl);
        }
        String[] fontElements = markUrl.substring(6).split("#");

        // look up the font
        Font font = FontCache.getDefaultInsance().getFont(fontElements[0]);
        if (font == null) {
            throw new IllegalArgumentException("Unknown font " + fontElements[0]);
        }

        // get the symbol number
        String code = fontElements[1];
        char character;
        try {
            // see if a unicode escape sequence has been used
            if (code.startsWith("U+") || code.startsWith("\\u"))
                code = "0x" + code.substring(2);
           
            // this will handle most numeric formats like decimal, hex and octal
            character = (char) Integer.decode(code).intValue();
           
            // handle charmap code reporting issues
            if(!font.canDisplay(character))
                character = (char) (0xF000 | character);
           
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(
                    "Invalid character specification " + fontElements[1], e);
        }

        // build the shape out of the font
        GlyphVector textGlyphVector = font.createGlyphVector(FONT_RENDER_CONTEXT,
                new char[] { (char) character });
        Shape s = textGlyphVector.getOutline();
       
        // have the shape be centered in the origin, and sitting in a square of side 1
        Rectangle2D bounds = s.getBounds2D();
        AffineTransform tx = new AffineTransform();
        double max = Math.max(bounds.getWidth(), bounds.getHeight());
        // all shapes are defined looking "upwards" (see ShapeMarkFactory or WellKnownMarkFactory)
        // but the fonts ones are flipped to compensate for the fact the y coords grow from top
        // to bottom on the screen. We have to flip the symbol so that it conforms to the
        // other marks convention
        tx.scale(1 / max, -1 / max);
        tx.translate(-bounds.getCenterX(), -bounds.getCenterY());
        ExplicitBoundsShape shape = new ExplicitBoundsShape(tx.createTransformedShape(s));
        shape.setBounds(new Rectangle2D.Double(-0.5,0.5,1.0,1.0));
        return shape;
    }

    public static void main(String[] args) {
        BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics2D g2d = (Graphics2D) image.getGraphics();
        g2d.setColor(Color.BLACK);

        char c = 0xF041;
        System.out.println((int) c);

        Font font = new Font("Wingdings", Font.PLAIN, 60);
        for (int i = 0; i < 65536; i++)
            if (font.canDisplay(i))
                System.out.println(((int) i) + ": " + Long.toHexString(i));
        GlyphVector textGlyphVector = font.createGlyphVector(FONT_RENDER_CONTEXT, new char[] { c });
        Shape shape = textGlyphVector.getOutline();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.translate(150, 150);
        g2d.setColor(Color.BLUE);
        g2d.fill(shape);

        g2d.setColor(Color.BLACK);
        g2d.setFont(font);
        g2d.drawString(new String(new char[] { c }), 0, 50);

        g2d.dispose();
        JFrame frame = new JFrame("Test");
        frame.setContentPane(new JLabel(new ImageIcon(image)));
        frame.pack();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}
TOP

Related Classes of org.geotools.renderer.style.TTFMarkFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.