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