Package org.jnode.awt.font.spi

Source Code of org.jnode.awt.font.spi.AbstractFontProvider$Size

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* 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; either version 2.1 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.awt.font.spi;

import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.jnode.awt.font.FontProvider;
import org.jnode.awt.font.TextRenderer;
import org.jnode.awt.font.renderer.RenderCache;
import org.jnode.awt.font.renderer.RenderContext;

/**
* @author epr
* @author Fabien DUMINY (fduminy@jnode.org)
*/
public abstract class AbstractFontProvider<F extends Font, FD> implements FontProvider<F> {

    /**
     * My logger
     */
    private static final Logger log = Logger.getLogger(AbstractFontProvider.class);

    static {
        log.setLevel(Level.DEBUG);
    }

    /**
     * Cache font renderers
     */
    private final HashMap<Font, TextRenderer> renderers = new HashMap<Font, TextRenderer>();
   
    /**
     * Cache font metrics
     */
    private final HashMap<Font, FontMetrics> metrics = new HashMap<Font, FontMetrics>();
   
    /**
     * All loaded fonts (name, Font)
     */
    private final HashMap<String, F> fontsByName = new HashMap<String, F>();
   
    /**
     * Have the system fonts been loaded yet
     */
    private boolean fontsLoaded = false;
   
    private final RenderContext context = new RenderContext();
   
    /**
     * The render cache
     */
    private final RenderCache renderCache = new RenderCache(context);

    private final String name;
   
    private final Class<F> fontClass;
   
    private final List<FD> userFontDatas = new Vector<FD>();

    private Map<FD, Size> maxCharBounds = new HashMap<FD, Size>();
       
    protected AbstractFontProvider(Class<F> fontClass, String name) {
        this.name = name;
        this.fontClass = fontClass;
    }


    /**
     * Give the name of the font (used for setting the first provider to use
     * among all available ones)
     */
    public final String getName() {
        return name;
    }


    /**
     * Does this provides provide the given font?
     *
     * @param font
     * @return {@code true} if this provider provides the given font, {@code false} otherwise
     */
    public final boolean provides(Font font) {
        if (font == null) return false; // don't provide default (null) fonts

        loadFonts();
        return (getCompatibleFont(font) != null);
    }

    /**
     * Returns a set containing a one-point size instance of all fonts available
     * in this provider. Typical usage would be to allow a user to select a particular
     * font. Then, the application can size the font and set various font attributes
     * by calling the deriveFont method on the choosen instance.
     * This method provides for the application the most precise control over which
     * Font instance is used to render text. If a font in this provider has multiple
     * programmable variations, only one instance of that Font is returned in the set,
     * and other variations must be derived by the application. If a font in this provider
     * has multiple programmable variations, such as Multiple-Master fonts, only
     * one instance of that font is returned in the Font set. The other variations
     * must be derived by the application.
     *
     * @return The set containing all fonts provides by this provider.
     */
    public final Set<F> getAllFonts() {
        loadFonts();
        return new HashSet<F>(fontsByName.values());
    }

    /**
     * Gets a text renderer for the given font.
     *
     * @param font
     * @return The renderer
     */
    @Override
    public final TextRenderer getTextRenderer(Font font) {
        TextRenderer r = renderers.get(font);
        if (r == null) {
            r = createTextRenderer(renderCache, font);
            renderers.put(font, r);
        }
        return r;
    }

    protected abstract TextRenderer createTextRenderer(RenderCache renderCache, Font font);

    /**
     * Gets the font metrics for the given font.
     *
     * @param font
     * @return The metrics
     */
    public final FontMetrics getFontMetrics(Font font) {
        FontMetrics fm = metrics.get(font);
       
        if (fm == null) {
            try {
                fm = createFontMetrics(font);
                metrics.put(font, fm);
            } catch (IOException ex) {
                log.error("Cannot create font metrics for " + font, ex);
            }
        }
       
        return fm;
    }
   
   /*
    * Load all default fonts.
    */
    private final void loadFonts() {
        if (!fontsLoaded) {
            loadFontsImpl();
            fontsLoaded = true;
        }
    }

    protected abstract FontMetrics createFontMetrics(Font font) throws IOException;
   
    /**
     * Load all default fonts.
     */
    protected abstract void loadFontsImpl();

    /**
     * Translates the font into a font that is provided by this provider.
     *
     * @param font
     * @return the compatible font
     */
    @Override
    public final F getCompatibleFont(Font font) {
        F f = null;
       
        if (fontClass.isInstance(font)) {
            f = fontClass.cast(font);
        }
       
        if (f == null) {
            f = fontsByName.get(font.getFamily());
        }
       
        if (f == null) {
            f = fontsByName.get(font.getName());
        }

        if (f == null) {
            f = fontsByName.get(font.getFontName());
        }

        if ((f == null) && (fontsByName.size() > 0)) {
            f = fontsByName.values().iterator().next();
        }
       
        return f;
    }
   
    protected void addUserFontData(FD data) {
        userFontDatas.add(data);
    }
   
    protected List<FD> getUserFontDatas() {
        return userFontDatas;
    }
   
    protected void addFont(F font) {
        //fontsByName.put(font.getName(), font);
        fontsByName.put(font.getFamily(), font);
        //fontsByName.put(font.getFontName(), font);       
    }
   
//    /**
//     * Load all default fonts.
//     */
//    private final void loadFonts() {
//        for (String font : getSystemFonts()) {
//            loadFont(font);
//        }
//        fontsLoaded = true;
//    }
//
//    private final void loadFont(String resName) {
//        try {
//            final ClassLoader cl = Thread.currentThread().getContextClassLoader();
//            final URL url = cl.getResource(resName);
//            if (url != null) {
//                final F font = loadFont(url);
//                //fontsByName.put(font.getName(), font);
//                fontsByName.put(font.getFamily(), font);
//                //fontsByName.put(font.getFontName(), font);
//            } else {
//                log.error("Cannot find font resource " + resName);
//            }
//        } catch (IOException ex) {
//            log.error("Cannot find font " + resName + ": " + ex.getMessage());
//        } catch (Throwable ex) {
//            log.error("Cannot find font " + resName, ex);
//        }
//    }
   
    public Rectangle2D getMaxCharBounds(FD container) {
        Size size = maxCharBounds.get(container);
               
        if (size == null) {
            size = getMaxCharSize(container);
            maxCharBounds.put(container, size);
        }
       
        return new Rectangle2D.Double(0, 0, size.maxCharWidth, size.maxCharHeight);               
    }
   
    protected abstract Size getMaxCharSize(FD fontData);
   
    public static class Size {
        public int maxCharWidth = 0;
        public int maxCharHeight = 0;
    }
}
TOP

Related Classes of org.jnode.awt.font.spi.AbstractFontProvider$Size

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.