Package com.anotherbigidea.flash.movie

Source Code of com.anotherbigidea.flash.movie.SystemFontDefinition

/****************************************************************
* Copyright (c) 2001, Joachim Sauer, All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. The name of the author may not be used to endorse or
* promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************/

package com.anotherbigidea.flash.movie;

import com.anotherbigidea.flash.SWFConstants;

import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.HashMap;

/**
* A Font Definition that can referenced by Font symbols. It reads the
* required font- and glyph-information from the provided java.awt.Font
* object.
*
* This class can't currently handle complex Layout, but I don't know
* if SWF can handle it at all. It is not possible to use multiple Glyphs
* to create a Character and it is not possible to use one Glyph for multiple
* Characters.
*
* @author Joachim Sauer <saua@gmx.net>
*/
public class SystemFontDefinition extends FontDefinition
{
    private static FontRenderContext frc;
    private static Graphics2D g2d;
   
    private static final boolean DEBUG_GETSHAPE = false;
    private static final boolean DEBUG_KERNING = true;
   
    private static final float HUGE_FONT_SIZE = 512f;
   
    static
    {
        BufferedImage dummyImage = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
        g2d = (Graphics2D) dummyImage.getGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        frc = g2d.getFontRenderContext();
       
        if (DEBUG_GETSHAPE) System.out.println("DEUB_GETSHAPE activated");
        if (DEBUG_KERNING) System.out.println("DEBUG_KERNING activated");
    }
   
    private FontMetrics metrics;
    private java.awt.Font font;
    private AffineTransform trans;
    private double scale;
   
    public SystemFontDefinition(java.awt.Font sfont)
    {
        super();
        //create a huge Version of this Font, to get accurate Measurement even
        //in ints
        font = sfont.deriveFont(HUGE_FONT_SIZE);
        metrics = g2d.getFontMetrics(font);
       
        double maxHeight = metrics.getAscent();
       
        /* the SWF-EM-Square is always 1024x1024 and
         * 1.0f Units is 1 Pixel which in turn is 20 TWIPS
         * therefore we scale to 1024 / SWFConstants.TWIPS
         */
        //TODO: correct scaling
        scale = (1024.0 / SWFConstants.TWIPS) / maxHeight;
       
        trans = AffineTransform.getScaleInstance(scale, scale);
       
        setName(font.getName());
        setFontFlags(true, false, false, font.isItalic(), font.isBold(), true);
        setAscent(metrics.getAscent() * scale);
        setDescent(metrics.getDescent() * scale);
        setLeading(metrics.getLeading() * scale);
    }
   
    /**
     * Creates a glyphs by code.
     * @param code the Unicode index of the requested Glyph.
     * @return null if the code has no glyph
     */
    private Glyph createGlyph(int code)
    {
        char[] chars = { (char) code };
       
        if (!font.canDisplay((char) code))
            return null;
       
        GlyphVector gv = font.createGlyphVector(frc, chars);
        Shape glyph_shape = new Shape();
        glyph_shape.drawAWTPathIterator(gv.getGlyphOutline(0).getPathIterator(trans));
        GlyphMetrics gm = gv.getGlyphMetrics(0);
       
        //    FontDefinition.Glyph g = new FontDefinition.Glyph(s, metrics.charWidth(chars[0]) * scale, code);
        FontDefinition.Glyph g = new FontDefinition.Glyph(glyph_shape, gm.getAdvanceX() * scale, code);
       
        return g;
    }
   
    /**
     * Look up a glyph by code.
     * @param code the Unicode index of the requested Glyph.
     * @return null if the code has no glyph
     */
    public Glyph getGlyph(int code)
    {
        Glyph ret;
       
        ret = super.getGlyph(code);
       
        if (ret != null)
            return ret;
       
        ret = createGlyph(code);
       
        if (ret == null)
        {
            glyphs.add(ret);
            glyphLookup.put(new Integer(code), ret);
        }
       
        return ret;
    }
   
    /**
     * Get the kerning adjustment required between the two given codes
     */
    public double getKerningOffset(int code1, int code2)
    {
        double ret;
       
        Integer i1 = new Integer(code1);
        Integer i2 = new Integer(code2);
       
        if (kernLookup == null)
        {
            kernLookup = new HashMap();
           
            if (kerning.size() != 0)
                throw new IllegalStateException("Internal Error in SystemFontDefinition: no kernLookup, but kerning contains entries!");
        }
        else
        {
            HashMap kerns = (HashMap) kernLookup.get(i1);
            if (kerns != null)
            {
                KerningPair pair = (KerningPair) kerns.get(i2);
                if (pair != null)
                {
                    return pair.getAdjustment();
                }
            }
        }
       
        ret = calculateKerningOffset(code1, code2);
       
        HashMap kerns = (HashMap) kernLookup.get(i1);
        if (kerns == null)
        {
            kerns = new HashMap();
            kernLookup.put(i1, kerns);
        }
       
        kerns.put(i2, new KerningPair(code1, code2, ret));
       
        return ret;
    }
   
    /**
     * Calculate the Kerning Offset of the specified characters. This is a hack,
     * because the Java Font API doesn't expose Kerning information directly.
     * @return adjustment needed between this two codes.
     */
    private double calculateKerningOffset(int code1, int code2)
    {
        char[] chars =
        { (char) code1, (char) code2 };
        GlyphVector gv = font.createGlyphVector(frc, chars);
       
        //        double adj = (gv.getGlyphPosition(1).getX() - metrics.charWidth(chars[0])) * scale;
        double adj = (gv.getGlyphPosition(1).getX() - gv.getGlyphMetrics(0).getAdvanceX()) * scale;
       
        if (DEBUG_KERNING) System.out.println("Kerning for '" + (char) code1 + (char) code2 + "': " + adj);
       
        return adj;
    }
}
TOP

Related Classes of com.anotherbigidea.flash.movie.SystemFontDefinition

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.