📄 font.java
字号:
/****************************************************************
* Copyright (c) 2001, David N. Main, 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 java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import com.anotherbigidea.flash.SWFConstants;
import com.anotherbigidea.flash.interfaces.SWFTagTypes;
import com.anotherbigidea.flash.interfaces.SWFVectors;
import com.anotherbigidea.flash.structs.Rect;
/**
* A Font Symbol.
*
* The Font references a FontDefinition object from which it takes the glyph
* definitions it needs.
*/
public class Font extends Symbol
{
public class NoGlyphException extends Exception
{
public int code;
public NoGlyphException( int code )
{
super( "The font does not have a glyph definition for code " + code );
this.code = code;
}
}
/**
* A set of contiguous characters in one font.
*/
public class Chars
{
protected String chars;
protected double size;
protected int[] indices;
protected int[] advances;
protected double totalAdvance; //total advance
protected double ascent;
protected double descent;
protected double leftMargin;
protected double rightMargin;
public String toString() { return chars; }
public Font getFont() { return Font.this; }
public double getSize() { return size; }
public double getTotalAdvance() { return totalAdvance; }
public double getAscent() { return ascent; }
public double getDescent() { return descent; }
/**
* The left margin is the difference between the origin of the
* first glyph and the left edge of its geometry
*/
public double getLeftMargin() { return leftMargin; }
/**
* The right margin is the different between the total advance and
* the right edge of the geometry of the last glyph
*/
public double getRightMargin() { return rightMargin; }
/**
* @param chars the characters to display (displayable chars only - i.e. no newlines, tabs etc..)
* @param font may be null if no change of font is required
* @param size point-size - only relevant if font is not null
* @param color may be null if no color change is required. May be AlphaColor.
* @param x new X position for text - only valid if hasX is true
* @param y new Y position for text - only valid if hasY is true
*/
protected Chars( String chars, double size ) throws NoGlyphException
{
this.chars = chars;
this.size = size;
init();
}
protected void init() throws NoGlyphException
{
//--Figure out the indices and advances
char[] codes = chars.toCharArray();
indices = new int[ codes.length ];
advances = new int[ codes.length ];
double maxAscent = 0.0;
double maxDescent = 0.0;
double scale = size * SWFConstants.TWIPS / 1024.0;
for( int i = 0; i < codes.length; i++ )
{
int code = (int)codes[i];
int[] index = new int[1];
FontDefinition.Glyph glyph = getGlyph( code, index );
indices[i] = index[0];
if( glyph != null )
{
Shape shape = glyph.getShape();
double[] outline = shape.getBoundingRectangle();
double x1 = outline[0] * scale;
double y1 = outline[1] * scale;
double x2 = outline[2] * scale;
double y2 = outline[3] * scale;
if( maxAscent < -y1 ) maxAscent = -y1;
if( maxDescent < y2 ) maxDescent = y2;
double advance = glyph.getAdvance() * scale;
if( advance == 0 ) advance = x2 - x1;
//Kerning adjustment
if( i < codes.length-1 )
{
advance += (fontDef.getKerningOffset( code, (int)codes[i+1] ) * scale );
}
totalAdvance += advance;
advances[i] = (int)(advance * SWFConstants.TWIPS);
if( i == 0 ) leftMargin = -y1;
if( i == codes.length - 1 ) rightMargin = x2 - advance;
}
}
ascent = fontDef.getAscent() * scale;
if( ascent == 0.0 ) ascent = maxAscent;
descent = fontDef.getDescent() * scale;
if( descent == 0.0 ) descent = maxDescent;
}
}
protected Object font1Key = new Object(); //used in movie defined symbols lookup
protected Object font2Key = new Object(); //used in movie defined symbols lookup
protected FontDefinition fontDef;
protected HashMap glyphs = new HashMap(); //glyphs used by this font
protected HashMap indices = new HashMap(); //glyph indices
protected ArrayList glyphList = new ArrayList();
protected int languageCode = SWFConstants.LANGUAGE_CODE_NONE;
public int getLanguageCode() { return languageCode; }
public void setLanguageCode( int code ) { languageCode = code; }
public FontDefinition getDefinition() { return fontDef; }
public Font( FontDefinition fontDef )
{
this.fontDef = fontDef;
}
public List getGlyphList() { return glyphList; }
/**
* Load the glyphs for the characters in the given string from the
* FontDefinition into this font.
* @exception NoGlyphException
*/
public void loadGlyphs( String chars ) throws NoGlyphException
{
char[] chs = chars.toCharArray();
for( int i = 0; i < chs.length; i++ )
{
getGlyph( chs[i], null );
}
}
/**
* Load all glyphs from the font definition
*/
public void loadAllGlyphs()
{
ArrayList list = fontDef.getGlyphList();
for( Iterator it = list.iterator(); it.hasNext(); )
{
FontDefinition.Glyph g = (FontDefinition.Glyph)it.next();
addGlyph( g );
}
}
/**
* Get the Chars instance for the given string at the given font size
*/
public Chars chars( String chars, double fontSize )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -