All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.code.appengine.awt.font.sfntly.SfntlyFontPeer Maven / Gradle / Ivy

The newest version!
package com.google.code.appengine.awt.font.sfntly;

import java.io.IOException;
import java.io.InputStream;

import org.apache.harmony.awt.gl.font.FontExtraMetrics;
import org.apache.harmony.awt.gl.font.FontPeerImpl;
import org.apache.harmony.awt.gl.font.Glyph;
import org.apache.harmony.awt.gl.font.LineMetricsImpl;

import com.google.code.appengine.awt.font.FontRenderContext;
import com.google.code.appengine.awt.font.LineMetrics;
import com.google.code.appengine.awt.geom.AffineTransform;
import com.google.typography.font.sfntly.Font;
import com.google.typography.font.sfntly.FontFactory;
import com.google.typography.font.sfntly.Tag;
import com.google.typography.font.sfntly.table.core.CMap;
import com.google.typography.font.sfntly.table.core.CMapTable;
import com.google.typography.font.sfntly.table.core.CMapTable.CMapId;
import com.google.typography.font.sfntly.table.core.FontHeaderTable;
import com.google.typography.font.sfntly.table.core.HorizontalHeaderTable;
import com.google.typography.font.sfntly.table.core.HorizontalMetricsTable;
import com.google.typography.font.sfntly.table.truetype.GlyphTable;
import com.google.typography.font.sfntly.table.truetype.LocaTable;

public class SfntlyFontPeer extends FontPeerImpl {

	private Font font;
	private float unitsPerEm;
	private int yMin;
	private int yMax;
	
	public SfntlyFontPeer(String name, int style, int size) {
		this.name = name;
		this.style = style;
		this.size = size;
		
		try {
			InputStream ttfInput = getClass().getResourceAsStream("OpenSans-Regular.ttf");
			if(ttfInput == null) {
				throw new RuntimeException("Couldn't open the font file");
			}
			font = FontFactory.getInstance().loadFonts(ttfInput)[0];
		} catch (IOException e) {
			throw new RuntimeException("Could not load font: " + name, e);
		}
		
		FontHeaderTable head = font.getTable(Tag.head);
		unitsPerEm = head.unitsPerEm();
		yMin = head.yMin();
		yMax = head.yMax();
	}

	@Override
	public FontExtraMetrics getExtraMetrics() {
		return new FontExtraMetrics();
	}

	@Override
	public LineMetrics getLineMetrics(String str, FontRenderContext frc,
			AffineTransform at) {
		
		HorizontalHeaderTable hhead = font.getTable(Tag.hhea);
		int numChars = str.length();
		return new LineMetricsImpl(
				numChars,
				0, // baseline index
				new float[numChars], // baseline offsets
				0, // underline thickness,
				0, //_underlineOffset
				0, //_strikethroughThickness,
				0, //_strikethroughOffset,
				toPixels(hhead.lineGap()),
				toPixels(hhead.lineGap() + hhead.ascender() + hhead.descender()),
				toPixels(hhead.ascender()),
				toPixels(hhead.descender()),
				toPixels(0)); // _maxCharWidth
	}
	
	private float toPixels(double sizeInUnits) {
		return (float) (sizeInUnits / unitsPerEm * size);
	}

	@Override
	public String getPSName() {
		return psName;
	}

	@Override
	public int getMissingGlyphCode() {
		return (int)'?';
	}

	@Override
	public Glyph getGlyph(char ch) {
		int glyphIndex = lookupGlyphIndex(ch);
		com.google.typography.font.sfntly.table.truetype.Glyph glyph = getGlyph(glyphIndex);

		
	    HorizontalMetricsTable hmtx = font.getTable(Tag.hmtx);
	    
	    double width = toPixels(glyph.xMax() - glyph.xMin());
	    double height = toPixels(glyph.yMax() - glyph.yMin());
	    double advance = toPixels(hmtx.advanceWidth(glyphIndex));
	    
	    SfntlyGlyph sfntlyGlyph = new SfntlyGlyph(advance, width, height, glyph);
	    sfntlyGlyph.setScale(size / unitsPerEm);
	    sfntlyGlyph.setYBounds(yMin, yMax);
	    sfntlyGlyph.setFontSize(size);
	    sfntlyGlyph.setChar(ch);
		return sfntlyGlyph;
	}

	private com.google.typography.font.sfntly.table.truetype.Glyph getGlyph(int glyphId) {
	    LocaTable locaTable = font.getTable(Tag.loca);
	    GlyphTable glyphTable = font.getTable(Tag.glyf);
	    int offset = locaTable.glyphOffset(glyphId);
	    int length = locaTable.glyphLength(glyphId);
	    
	    com.google.typography.font.sfntly.table.truetype.Glyph glyph = glyphTable.glyph(offset, length);
		return glyph;
	}

	private int lookupGlyphIndex(char ch) {
		CMapTable cmapTable = font.getTable(Tag.cmap);
	    CMap cmap = cmapTable.cmap(CMapId.WINDOWS_BMP);
	    int glyphId = cmap.glyphId(ch);
		return glyphId;
	}
	
	@Override
	public void dispose() {
	}

	@Override
	public Glyph getDefaultGlyph() {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean canDisplay(char c) {
		return lookupGlyphIndex(c) != CMapTable.NOTDEF;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy