⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fstextconstructor.java

📁 利用opensource的开源jar实现生成flash文件
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/*
 *  FSTextConstructor.java
 *  Transform Utilities
 *
 * Copyright (c) 2001-2006 Flagstone Software Ltd. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *  * 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.
 *  * Neither the name of Flagstone Software Ltd. nor the names of its contributors 
 *    may be used to endorse or promote products derived from this software 
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.flagstone.transform.util;

import com.flagstone.transform.*;

import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;

import java.io.*;
import java.util.*;
import java.util.zip.*;

/**
 * The FSTextConstructor class greatly simplifies the use of fonts and text when 
 * creating Flash files. Font definitions can be created in three ways:
 * 
 * <ol>
 * <li>Using TrueType or OpenType font definition stored in a file.</li>
 * <li>Using a font definition stored in an existing Flash file.</li>
 * <li>Using a given Java AWT font as a template.</li>
 * </ol>
 * 
 * <P>Font definitions from TrueType, OpenType or Flash files are created by 
 * specifying the name of the file:</p>
 * 
 * <pre>
 * FSTextConstructor font = new FSTextConstructor(id, trueTypeFile.getPath());
 * FSTextConstructor font = new FSTextConstructor(id, swfFile.getPath());
 * </pre>
 * 
 * <P>The OpenType or TrueType file is parsed to construct the font definition. 
 * Files with the extensions ".otf" or ".ttf" may be used. Files containing 
 * collections of fonts ".otc" are not currently supported. For Flash files the 
 * first font definition encountered is used and all the text definition objects 
 * associated with the font are used to obtain the advance information for each 
 * character. An example Flash file can be found in the resources directory 
 * included in this release.</p>
 * 
 * <P>Font definitions from AWT templates are created by passing a font object:</p>
 * 
 * <pre>
 * FSTextConstructor font = new FSTextConstructor(id, new Font("Arial", Font.PLAIN, 1));
 * </pre>
 * 
 * <p>Only the font or file name needs to specified. Unlike Java fonts, font 
 * definitions in Flash are size independent, the size and colour in which a 
 * given string in rendered is specified in the object  that defines the text to 
 * be displayed avoiding the need to create multiple font definitions for  the 
 * same font name.</p>
 *
 * <P>An array of FSGlyph objects are created from the font definition. Each 
 * object contains the glyph for the font, the associated character code and 
 * information used to lay out each glyph when it is displayed.</P>
 * 
 * <P>Once a font has been created text strings can be generated:</p>
 * 
 * <pre>
 *    int fontSize = 280; // twips
 *    FSColor fontColor = FSColorTable.black();
 *    FSDefineText2 aString = font.defineText("This is a string", fontSize, fontColor);
 * </pre>
 * 
 * <P>The defineText method returns FSDefineText2 objects since they support 
 * transparent colours, while FSDefineText only supports opaque colours.</P>
 *
 * <P>Once all the strings to be displayed have been generated the font 
 * definition object containing the glyphs can be generated.</p>
 * 
 * <pre>
 *    FSDefineFont2 defineFont = font.defineFont();
 * </pre>
 * 
 * <P>Remember however that objects in a Flash file must be defined before they 
 * are used so the font object must be added to the file before the first 
 * FSDefineText object that references the glyphs in the font.</p>
 * 
 * <P>To reduce the size of the Flash file only the glyphs actually displayed 
 * can be included in a font definition object. When a FSDefineText object is 
 * created the glyphs used are marked. This is why the text definition objects 
 * are generated before the font definition.</P>
 *
 * <P>Glyphs are included in the font in the order they are used with each 
 * FSDefineText2 object referencing a glyph by its position in the array of 
 * glyphs contained in a font definition. Any unused glyphs can then easily be 
 * omitted.</P>
 * 
 * <P>When the font definition is created only the glyphs used (up to that 
 * point) are included. If subsequent FSDefineText objects are generated that 
 * include glyphs not previously used then the text will not be displayed 
 * correctly.</p>
 *
 * <b>Text Fields</b><br/>
 *
 * <P>When creating text fields using the FSDefineTextField class, there are two 
 * options when specifying the font used to display the characters entered into 
 * the field:
 *
 * <ol>
 * <li>The glyphs for the font may be loaded from the host platform.</li>
 * <li>The glyphs for the font are taken from a font definition object.</li>
 * </ol>
 *
 * <P>Using the glyphs loaded from the host platform is by far the easiest way 
 * of using text fields. First a font definition is created that specifies only 
 * the name of the font which will be loaded from the host platform. Then 
 * creating the text fields set the useFontGlyphs attribute to false.</P>
 *
 * <pre>
 *    FSDefineFont2 fontDefinition = new FSDefineFont2(movie.newIdentifier(), "Arial");
 *
 *    FSDefineTextField textField = new FSDefineTextField(movie.newIdentifier(), bounds);
 *
 *    textField.setUseFontGlyphs(false);
 * </pre>
 *
 * <P>This approach only works if the font is defined on the host platform 
 * otherwise the Flash Player will substitute a default font.</P>
 *
 * <P>When using a font definition contained in the Flash file obviously the 
 * glyphs for all possible characters must be defined otherwise the character 
 * will not be displayed correctly. When using text fields the characters must 
 * be defined in the font, sorted by ascending character code, otherwise the
 * text will not be displayed correctly. To do this the FSCharacterTable class
 * provides arrays of characters sorted in the correct order. The array is 
 * passed to the willDisplay() method and the FSTextConstructor will add the 
 * glyphs for the characters in the order they appear in the array:</p>
 * 
 * <pre>
 *     char[] characterSet = FSCharacterTable.ascii();
 *     
 *     textConstructor.willDisplay(characterSet);
 * </pre>
 * 
 * <P>This will add ALL of the characters in the array to the font definition.
 * Several character sets are provided in the FSCharacterTable class but any 
 * array of characters could be passed to the willDisplay() method - allowing
 * smaller font definitions to be created when only a few characters are 
 * displayed.</p>
 *
 * <b>Missing Characters</b><br/>
 *
 * <P>Characters that cannot be displayed using the font are handled by a 
 * displaying a default glyph which typically represents a space or an empty 
 * box. Both Java AWT and True/Open Type definitions explicitly define the 
 * missing glyph. For fonts parsed from Flash files the missing glyph is assumed 
 * (by default) to be the first glyph in the font definition.</p>
 * 
 * <P>When a font is loaded the missing glyph is added automatically to the font 
 * definition so there is no need to explicitly include it by creating a text 
 * object to force it to be included. The missing glyph will always be the first 
 * glyph in the font definition generated by the FSTextConstructor object so it 
 * may be substituted by another suitable shape if required.</P>
 * 
 * <P>Whether a string can be displayed using a font can be determined by the 
 * <em>canDisplay()</em> method which returns the index of the first character 
 * that cannot be displayed (the missing glyph will be displayed instead) or -1 
 * if all the characters are represented in the font.</P>
 */
public class FSTextConstructor
{
    private static final int OS_2 = 0x4F532F32;
    private static final int HEAD = 0x68656164;
    private static final int HHEA = 0x68686561;
    private static final int MAXP = 0x6D617870;
    private static final int LOCA = 0x6C6F6361;
    private static final int CMAP = 0x636D6170;
    private static final int HMTX = 0x686D7478;
    private static final int NAME = 0x6E616D65;
    private static final int GLYF = 0x676C7966;

    private static final int ITLF_SHORT = 0;
    private static final int ITLF_LONG  = 1;
    
    private static final int FONT_WEIGHT_THIN       = 100;
    private static final int FONT_WEIGHT_EXTRALIGHT = 200;
    private static final int FONT_WEIGHT_LIGHT      = 300;
    private static final int FONT_WEIGHT_NORMAL     = 400;
    private static final int FONT_WEIGHT_MEDIUM     = 500;
    private static final int FONT_WEIGHT_SEMIBOLD   = 600;
    private static final int FONT_WEIGHT_BOLD       = 700;
    private static final int FONT_WEIGHT_EXTRABOLD  = 800;
    private static final int FONT_WEIGHT_BLACK      = 900;
    
    private static final int ON_CURVE    = 0x01;
    private static final int X_SHORT     = 0x02;
    private static final int Y_SHORT     = 0x04;
    private static final int REPEAT_FLAG = 0x08;
    private static final int X_SAME      = 0x10;
    private static final int Y_SAME      = 0x20;
    private static final int X_POSITIVE  = 0x10;
    private static final int Y_POSITIVE  = 0x20;
    
    private static final int ARG_1_AND_2_ARE_WORDS    = 0x01;
    private static final int ARGS_ARE_XY_VALUES       = 0x02;
    private static final int WE_HAVE_A_SCALE          = 0x08;
    private static final int WE_HAVE_AN_X_AND_Y_SCALE = 0x40;
    private static final int WE_HAVE_A_TWO_BY_TWO     = 0x80;
    private static final int MORE_COMPONENTS          = 0x10;
    
    private static final int NUMBER_OF_METRICS = 0;
    private static final int SCALE = 1;
    private static final int GLYPH_OFFSET_SIZE = 2;
    
    private class FSGlyph
    {
        FSShape shape = null;
        FSBounds bounds = new FSBounds(0, 0, 0, 0);
        int advance = 0;

        int[] xCoordinates = null;
        int[] yCoordinates = null;
        boolean[] onCurve = null;
        int[] endPoints = null;
        
        FSGlyph()
        {
            shape = new FSShape();
            bounds = new FSBounds(0, 0, 0, 0);
            advance = 0;
            
            xCoordinates = new int[] {};
            yCoordinates = new int[] {};
            onCurve = new boolean[] {};
            endPoints = new int[] {};
        }

        FSGlyph(FSShape aShape, FSBounds aBounds)
        {
            shape = aShape;
            bounds = aBounds;
            advance = 0;
            
            xCoordinates = new int[] {};
            yCoordinates = new int[] {};
            onCurve = new boolean[] {};
            endPoints = new int[] {};
        }
    };
    
    private int identifier = 0;
    private String name = "";
    private int encoding = 0;
    private float size = 0.0f;
    private boolean isBold = false;
    private boolean isItalic = false;

    private int baseline = 0;
    private float ascent = 0;
    private float descent = 0;
    private float leading = 0;
    
    private short[] orderTable = new short[65536];
    private short[] characterTable = new short[65536];
    private FSGlyph[] glyphTable = null;
    
    private int numberOfGlyphs = 0;
    private int missingGlyph = 0;
    
    private ArrayList kernings = new ArrayList();
    private int[] attributes = new int[8];

    /**
     * Creates a new FSTextConstructor object using the specified font.
     * 
     * <P>The fontName can be used to identify a particular font in two ways, 
     * either specifying:
     * 
     * <ol>
     * <li>the name of a file containing a TrueType or OpenType font definition.</li>
     * <li>the name of a Flash file containing font definition.</li>
     * </ol>
     *
     * IMPORTANT: This method previously allowed the name of a AWT Font to be 
     * specified as an argument. This will no longer be supported in future 
     * releases, use the FSTextCOnstructor(int, Font) method instead.
     * 
     * @param anIdentifier a unique identifier that will be assigned to the 
     * font definition object generated and referenced by all the text object
     * generated.
     * 
     * @param filename either the name of a Flash, TrueType or OpenType file 
     * containing an existing font definition.
     * 
     * @throws FileNotFoundException if the fontName specifies a file and the 
     * file cannot be found or opened.
     * 
     * @throws IOException if the fontName specifies a file and an error occurs while
     * reading the file from disk.
     * 
     * @throws DataFormatException if the fontName specifies a file and an error occurs while 
     * parsing the font definition.
     */
    public FSTextConstructor(int anIdentifier, String filename) throws IOException, DataFormatException
    {
        identifier = anIdentifier; 
        
        for (int i=0; i<65536; i++)
            orderTable[i] = -1;
            
        if (filename.toLowerCase().endsWith(".swf"))
            decodeSWFFont(filename);
        else if (filename.toLowerCase().endsWith(".otf"))
            decodeOpenTypeFont(filename);
        else if (filename.toLowerCase().endsWith(".ttf"))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -