FileDocCategorySizeDatePackage
CompositeFont.javaAPI DocAndroid 1.5 API15498Wed May 06 22:41:54 BST 2009org.apache.harmony.awt.gl.font

CompositeFont

public class CompositeFont extends org.apache.harmony.awt.gl.font.FontPeerImpl
CompositeFont class is the implementation of logical font classes. Every logical font consists of several physical fonts that described in font.properties file according to the face name of this logical font.

Fields Summary
int
numFonts
String
family
String
face
String[]
fontNames
org.apache.harmony.awt.gl.font.FontProperty[]
fontProperties
public org.apache.harmony.awt.gl.font.FontPeerImpl[]
fPhysicalFonts
int
missingGlyphCode
LineMetricsImpl
nlm
int
cachedNumGlyphs
Constructors Summary
public CompositeFont(String familyName, String faceName, int _style, int _size, org.apache.harmony.awt.gl.font.FontProperty[] fProperties, org.apache.harmony.awt.gl.font.FontPeerImpl[] physFonts)
Creates CompositeFont object that is corresponding to the specified logical family name.

param
familyName logical family name CompositeFont is to be created from
param
faceName logical face name CompositeFont is to be created from
param
_style style of the CompositeFont to be created
param
_size size of the CompositeFont to be created
param
fProperties an array of FontProperties describing physical fonts - parts of logical font
param
physFonts an array of physical font peers related to the CompositeFont to be created

                                                                                              
                
        this.size = _size;
        this.name = faceName;
        this.family = familyName;
        this.style = _style;
        this.face = faceName;
        this.psName = faceName;
        this.fontProperties = fProperties;// !! Supposed that fProperties parameter != null
        fPhysicalFonts = physFonts;
        numFonts = fPhysicalFonts.length; 
        setDefaultLineMetrics("", null); //$NON-NLS-1$
        this.uniformLM = false;
    
Methods Summary
public booleancanDisplay(char chr)
Returns true if one of the physical fonts composing this font CompositeFont can display specified character.

param
chr specified character

        return (getCharFontIndex(chr) != -1);
    
public intcharWidth(int ind)
Returns width of the char with specified index.

param
ind specified index of the character

        return charWidth((char)ind);
    
public intcharWidth(char c)
Returns width of the specified char.

param
c specified character

        Glyph gl = this.getGlyph(c);
        return (int)gl.getGlyphPointMetrics().getAdvanceX();
    
public voiddispose()
Disposes CompositeFont object's resources.

        // Nothing to dispose
    
public intgetAscent()
Returns logical ascent (in pixels)

        return nlm.getLogicalAscent();
    
public intgetCharFontIndex(char chr)
Returns the index of the FontPeer in array of physical fonts that is applicable for the given character. This font has to have the highest priority among fonts that can display this character and don't have exclusion range covering specified character. If there is no desired fonts -1 is returned.

param
chr specified character
return
index of the font from the array of physical fonts that will be used during processing of the specified character.

        for (int i = 0; i < numFonts; i++){
            if (fontProperties[i].isCharExcluded(chr)){
                continue;
            }
            if (fPhysicalFonts[i].canDisplay(chr)){
                return i;
            }
        }

        return -1;
    
public intgetCharFontIndex(char chr, int defaultValue)
Returns the index of the FontPeer in array of physical fonts that is applicable for the given character. This font has to have the highest priority among fonts that can display this character and don't have exclusion range covering specified character. If there is no desired fonts default value is returned.

param
chr specified character
param
defaultValue default index that is returned if the necessary font couldn't be found.
return
index of the font from the array of physical fonts that will be used during processing of the specified character.

        for (int i = 0; i < numFonts; i++){
            if (fontProperties[i].isCharExcluded(chr)){
                continue;
            }
            if (fPhysicalFonts[i].canDisplay(chr)){
                return i;
            }
        }

        return defaultValue;
    
public GlyphgetDefaultGlyph()
Returns Glyph object corresponding to the default glyph.

        // !! only first physical font used to get this value
        return fPhysicalFonts[0].getDefaultGlyph();
    
public FontExtraMetricsgetExtraMetrics()
Returns FontExtraMetrics object with extra metrics related to this CompositeFont.

        // Returns FontExtraMetrics instanse of the first physical 
        // Font from the array of fonts.
        return fPhysicalFonts[0].getExtraMetrics();
    
public java.lang.StringgetFamily()
Returns font family name.

        return family;
    
public java.lang.StringgetFontName()
Returns font name.

        return face;
    
public GlyphgetGlyph(char ch)
Returns Glyph object corresponding to the specified character.

param
ch specified char

        for (int i = 0; i < numFonts; i++){
            if (fontProperties[i].isCharExcluded(ch)){
                    continue;
            }
            
            /* Control symbols considered to be supported by the font peer */
            if ((ch < 0x20) || fPhysicalFonts[i].canDisplay(ch)){
                return fPhysicalFonts[i].getGlyph(ch);
            }
        }
        return getDefaultGlyph();
    
public floatgetItalicAngle()
Returns the italic angle of this object.

        // !! only first physical font used to get this value
        return fPhysicalFonts[0].getItalicAngle();
    
public java.awt.font.LineMetricsgetLineMetrics(java.lang.String str, java.awt.font.FontRenderContext frc, java.awt.geom.AffineTransform at)
Returns LineMetrics instance scaled according to the specified transform.

param
str specified String
param
frc specified FontRenderContext
param
at specified AffineTransform

        LineMetricsImpl lm = (LineMetricsImpl)(this.nlm.clone());
        lm.setNumChars(str.length());

        if ((at != null) && (!at.isIdentity())){
            lm.scale((float)at.getScaleX(), (float)at.getScaleY());
        }

        return lm;
    
public java.awt.font.LineMetricsgetLineMetrics()
Returns cached LineMetrics instance for the null string or creates it if it wasn't cached yet.

        if (nlm == null){
            setDefaultLineMetrics("", null); //$NON-NLS-1$
        }

        return this.nlm;
    
public java.awt.geom.Rectangle2DgetMaxCharBounds(java.awt.font.FontRenderContext frc)
Returns maximum rectangle that encloses all maximum char bounds of physical fonts composing this CompositeFont.

param
frc specified FontRenderContext


        Rectangle2D rect2D = fPhysicalFonts[0].getMaxCharBounds(frc);
        float minY = (float)rect2D.getY();
        float maxWidth = (float)rect2D.getWidth();
        float maxHeight = (float)rect2D.getHeight();
        if (numFonts == 1){
            return rect2D;
        }

        for (int i = 1; i < numFonts; i++){
            if (fPhysicalFonts[i] != null){
                rect2D = fPhysicalFonts[i].getMaxCharBounds(frc);
                float y = (float)rect2D.getY();
                float mWidth = (float)rect2D.getWidth();
                float mHeight = (float)rect2D.getHeight();
                if (y < minY){
                    minY = y;
                }
                if (mWidth > maxWidth){
                    maxHeight = mWidth;
                }
                
                if (mHeight > maxHeight){
                    maxHeight = mHeight;
                }
            }
        }

        rect2D = new Rectangle2D.Float(0, minY, maxWidth, maxHeight);

        return rect2D;
    
public intgetMissingGlyphCode()
Returns the code of the missing glyph.

        // !! only first physical font used to get this value
        return fPhysicalFonts[0].getMissingGlyphCode();
    
public intgetNumGlyphs()
Returns the number of glyphs in this CompositeFont object.

        if (this.cachedNumGlyphs == -1){

            this.cachedNumGlyphs = 0;

            for (int i = 0; i < numFonts; i++){
                this.cachedNumGlyphs += fPhysicalFonts[i].getNumGlyphs();
            }
        }

        return this.cachedNumGlyphs;
    
public java.lang.StringgetPSName()
Returns font postscript name.

        return psName;
    
public java.awt.geom.Rectangle2DgetStringBounds(char[] chars, int start, int end, java.awt.font.FontRenderContext frc)
Returns rectangle that bounds the specified string in terms of composite line metrics.

param
chars an array of chars
param
start the initial offset in array of chars
param
end the end offset in array of chars
param
frc specified FontRenderContext


        LineMetrics lm = getLineMetrics();
        float minY = -lm.getAscent();
        float minX = 0;
        float height = lm.getHeight();
        float width = 0;

        for (int i = start; i < end; i++){
            width += charWidth(chars[i]);
        }

        Rectangle2D rect2D = new Rectangle2D.Float(minX, minY, width, height);
        return rect2D;

    
private voidsetDefaultLineMetrics(java.lang.String str, java.awt.font.FontRenderContext frc)
Creates LineMetrics instance and set cached LineMetrics field to it. Created LineMetrics has maximum values of the idividual metrics of all composing physical fonts. If there is only one physical font - it's LineMetrics object is returned.

param
str specified String
param
frc specified FontRenderContext

        LineMetrics lm = fPhysicalFonts[0].getLineMetrics(str, frc, null);
        float maxCharWidth = (float)fPhysicalFonts[0].getMaxCharBounds(frc).getWidth();

        if (numFonts == 1) {
            this.nlm = (LineMetricsImpl)lm;
            return;
        }

        float[] baselineOffsets = lm.getBaselineOffsets();
        int numChars = str.length();

        // XXX: default value - common for all Fonts
        int baseLineIndex = lm.getBaselineIndex();

        float maxUnderlineThickness = lm.getUnderlineThickness();
        float maxUnderlineOffset = lm.getUnderlineOffset();
        float maxStrikethroughThickness = lm.getStrikethroughThickness();
        float minStrikethroughOffset = lm.getStrikethroughOffset();
        float maxLeading = lm.getLeading();  // External leading
        float maxHeight = lm.getHeight();   // Height of the font ( == (ascent + descent + leading))
        float maxAscent = lm.getAscent();   // Ascent of the font
        float maxDescent = lm.getDescent(); // Descent of the font

        for (int i = 1; i < numFonts; i++){
            lm = fPhysicalFonts[i].getLineMetrics(str, frc, null);
            if (maxUnderlineThickness < lm.getUnderlineThickness()){
                maxUnderlineThickness = lm.getUnderlineThickness();
            }

            if (maxUnderlineOffset < lm.getUnderlineOffset()){
                maxUnderlineOffset = lm.getUnderlineOffset();
            }

            if (maxStrikethroughThickness < lm.getStrikethroughThickness()){
                maxStrikethroughThickness = lm.getStrikethroughThickness();
            }

            if (minStrikethroughOffset > lm.getStrikethroughOffset()){
                minStrikethroughOffset = lm.getStrikethroughOffset();
            }

            if (maxLeading < lm.getLeading()){
                maxLeading = lm.getLeading();
            }

            if (maxAscent < lm.getAscent()){
                maxAscent = lm.getAscent();
            }

            if (maxDescent < lm.getDescent()){
                maxDescent = lm.getDescent();
            }

            float width = (float)fPhysicalFonts[i].getMaxCharBounds(frc).getWidth();
            if(maxCharWidth < width){
                maxCharWidth = width;
            }
            for (int j =0; j < baselineOffsets.length; j++){
                float[] offsets = lm.getBaselineOffsets();
                if (baselineOffsets[j] > offsets[j]){
                    baselineOffsets[j] = offsets[j];
                }
            }

        }
        maxHeight = maxAscent + maxDescent + maxLeading;

        this.nlm =  new LineMetricsImpl(
                numChars,
                baseLineIndex,
                baselineOffsets,
                maxUnderlineThickness,
                maxUnderlineOffset,
                maxStrikethroughThickness,
                minStrikethroughOffset,
                maxLeading,
                maxHeight,
                maxAscent,
                maxDescent,
                maxCharWidth);

    
public java.lang.StringtoString()
Returns debug information about this class.

    return new String(this.getClass().getName() +
            "[name=" + this.name + //$NON-NLS-1$
            ",style="+ this.style + //$NON-NLS-1$
            ",fps=" + this.fontProperties + "]"); //$NON-NLS-1$ //$NON-NLS-2$