Package flash.fonts

Source Code of flash.fonts.CachedFontManager$FontFileCache

/*
*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*/

package flash.fonts;

import flash.swf.TagValues;
import flash.swf.builder.tags.FontBuilder;
import flash.swf.tags.DefineFont;
import flash.swf.tags.DefineFont3;
import flash.swf.types.GlyphEntry;
import flash.util.LRUCache;

import java.net.URL;
import java.util.Map;

/**
* Provides a simple LRU caching mechanism for Font Manager implementations.
*
* A manager's caches and cache's members should be thread safe.
*
* @author Peter Farland
*/
@SuppressWarnings("unchecked")
public abstract class CachedFontManager extends FontManager
{
    public static final short PURGE_SIZE = 2;
    public static final float DEFAULT_FONT_SIZE = 240f; //12pt * 20 - authoring tool multiplies size by 20 to increase granularity in twips
    public static final Float DEFAULT_FONT_SIZE_OBJECT = new Float(DEFAULT_FONT_SIZE);
    public static final String DEFAULT_FONT_SIZE_STRING = "240";
  public static final String COMPATIBILITY_VERSION = "CompatibilityVersion";

    public static final String MAX_CACHED_FONTS_KEY = "max-cached-fonts";
    public static final String MAX_GLYPHS_PER_FACE_KEY = "max-glyphs-per-face";

    public short maxEntries = 20;
    public short maxGlyphsPerFace = 1000;
    public short maxFacesPerFont = 4; // Note that Flash only supports PLAIN, BOLD, ITALIC, and BOLD+ITALIC

    private FontCache fontCache;
    private FontFileCache fontFileCache;

    protected CachedFontManager()
    {
        super();
    }

    public void initialize(Map map)
    {
        super.initialize(map);

        if (map != null)
        {
            String prop = (String)map.get(MAX_CACHED_FONTS_KEY);
            if (prop != null)
            {
                try
                {
                    maxEntries = Short.parseShort(prop);
                }
                catch (Throwable t)
                {
                }
            }

            prop = (String)map.get(MAX_GLYPHS_PER_FACE_KEY);
            if (prop != null)
            {
                try
                {
                    maxGlyphsPerFace = Short.parseShort(prop);
                }
                catch (Throwable t)
                {
                }
            }
        }

        fontCache = new FontCache(this);
        fontFileCache = new FontFileCache(this);
    }

    public DefineFont createDefineFont(int tagCode, FontDescription font)
    {
        FontFace fontFace;
        boolean useTwips = (tagCode == TagValues.stagDefineFont3);
        if (font.source instanceof URL)
        {
            URL location = (URL)font.source;
            fontFace = getEntryFromLocation(location, font.style, useTwips);
            if (font.alias == null)
                font.alias = fontFace.getFamily();

            if (fontFace == null)
                FontManager.throwFontNotFound(font.alias, null, font.style, location.toString());
        }
        else
        {
            String fontFamily = font.source.toString();
            fontFace = getEntryFromSystem(fontFamily, font.style, useTwips);
            if (font.alias == null)
                font.alias = fontFace.getFamily();

            if (fontFace == null)
                FontManager.throwFontNotFound(font.alias, fontFamily, font.style, null);
        }

        FontBuilder builder = new FontBuilder(tagCode, fontFace, font.alias, font.advancedAntiAliasing);

        // Add characters for unicode-range
        int[][] ranges = getUnicodeRanges(font.unicodeRanges);
        if (ranges != null)
        {
            for (int i = 0; i < ranges.length; i++)
            {
                int[] range = ranges[i];
                if (range != null && range.length == 2)
                {
                    int count = range[1] - range[0] + 1; // Inclusive range
                    builder.addCharset(range[0], count);
                }
            }
        }
        else
        {
            builder.addAllChars();
        }

        return (DefineFont)builder.build();
    }

    public void loadDefineFont(DefineFont tag, Object location)
    {
        if (tag instanceof DefineFont3)
        {
            loadDefineFont3((DefineFont3)tag, location);
        }
    }

    protected void loadDefineFont3(DefineFont3 tag, Object location)
    {
        String family = null;
        String locationKey = null;

        if (location != null)
        {
            if (location instanceof URL)
                locationKey = ((URL)location).toExternalForm();
            else
                locationKey = location.toString();

            family = (String)getFontFileCache().get(locationKey);
        }

        if (family == null)
        {
            family = DefineFont3Face.getFamily(tag);

            if (locationKey != null)
                getFontFileCache().put(locationKey, family);
        }

        int style = DefineFont3Face.getStyle(tag);

        // Look for whether we've got a FontSet for this family...
        FontSet fontSet = (FontSet)getFontCache().get(family);
        if (fontSet == null)
        {
            fontSet = new FontSet(maxFacesPerFont);
            getFontCache().put(family, fontSet);
        }

        // Look to see whether we've got a FontFace for this style....
        FontFace face = fontSet.get(style);
        if (face == null)
        {
            face = new DefineFont3Face(tag);
            fontSet.put(style, face);
        }
        else
        {
            // We already have a FontFace for this style, if it's a
            // CachedFontFace, try to update the existing cache with any
            // extra glyphs present on this tag...
            if (face instanceof CachedFontFace)
            {
                CachedFontFace cachedFontFace = (CachedFontFace)face;
                char[] codepoints = tag.codeTable;
                if (codepoints != null)
                {
                    for (char i = 0; i < codepoints.length; i++)
                    {
                        char c = codepoints[i];
                        GlyphEntry ge = cachedFontFace.getGlyphEntry(c);
                        if (ge == null)
                        {
                            ge = DefineFont3Face.createGlyphEntryFromDefineFont(c, i, tag);
                            cachedFontFace.glyphCache.put(c, ge);
                        }
                    }
                }
            }
        }
    }
   
    protected FontCache getFontCache()
    {
        if (fontCache == null)
            initialize(null);

        return fontCache;
    }

    protected FontFileCache getFontFileCache()
    {
        if (fontFileCache == null)
            initialize(null);

        return fontFileCache;
    }

    protected abstract String createFontFromLocation(Object location, int style, boolean useTwips);
  protected abstract FontSet createSetForSystemFont(String family, int style, boolean useTwips);

    /**
     * A cache that maps font family names to a <code>FontSet</code> - a set
     * of derived styles from the base family font.
     */
    static class FontCache extends LRUCache
    {
        private static final long serialVersionUID = -2402480346505475961L;

        FontCache(CachedFontManager manager)
        {
            super(manager.maxEntries / 2, manager.maxEntries, PURGE_SIZE);
        }

        /**
         * We don't know whether we're looking by location or os family name, so
         * we fail fast and don't attempt to fetch.
         *
         * @param key the font family name
         * @return null
         */
        protected Object fetch(Object key)
        {
            return null;
        }
    }

    /**
     * A cache mapping a font file location to a family name. If the location
     * new, it will load the file to determine the family name and create an
     * entry in the main fontCache.
     */
    static class FontFileCache extends LRUCache
    {
        private static final long serialVersionUID = 5379979428987581921L;

        FontFileCache(CachedFontManager manager)
        {
            super(manager.maxEntries / 2, manager.maxEntries, PURGE_SIZE);
        }

        /**
         * We fail fast if we've not seen this location because
         * we don't know whether the location will match
         * requested style...
         *
         * @param key the location of the font file
         */
        protected Object fetch(Object key)
        {
            return null;
        }
    }
}
TOP

Related Classes of flash.fonts.CachedFontManager$FontFileCache

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.