如何从Android中的TTF文件中读取字距对表

时间:2016-01-26 09:19:58

标签: android fonts true-type-fonts android-fonts

我目前正在使用从TTF文件加载的外部(非标准)字体在Canvas上绘制文本。我想为我正在显示的文本启用字距调整。

我想知道的是,是否有可能使用Android API从字体中读取字距对。

2 个答案:

答案 0 :(得分:5)

  

我想知道的是,是否有可能使用Android API从字体中读取字距对。

没有公共API可以从TTF文件中读取字距调整对。但是,我从Apache FOP中提取了相关代码,您可以使用this library读取字距调整对。

使用示例:

TTFFile file = TTFFile.open(getAssets().open("fonts/font.ttf"));
Map<Integer, Map<Integer, Integer>> kerning = file.getKerning();

您还可以检索其他元数据。例如:

TTFFile ttfFile = TTFFile.open(new File("/system/fonts/Roboto-Regular.ttf"));

String name = ttfFile.getFullName();             // "Roboto Regular"
String family = ttfFile.getSubFamilyName();      // "Regular"
int fontWeight = ttfFile.getWeightClass();       // 400
String copyright = ttfFile.getCopyrightNotice(); // "Font data copyright Google 2014"
  

我想为我正在显示的文字启用字距调整。

查看:

How to adjust text kerning in Android TextView?

setLetterSpacing(float)

答案 1 :(得分:0)

我愿意在Windows上使用标准Java使用the parser described above。如果有人想这样做,则需要使用矩形而不是矩形。这只是次要的转换。我还删除了目录 jaredrummler ,因为目录太长了(尽管我将版权注释保留在文件的开头)。但是此解析器中有两个 TTFFile 类。这段代码:

TTFFile file;
File ttf = new File("C:\\Windows\\Fonts\\calibri.ttf" );
try { file = TTFFile.open(ttf); }
catch (IOException e) {e.printStackTrace(); }
Map<Integer, Map<Integer, Integer>> kerning = file.getKerning();

仅在导入正确的类文件时有效:

import com.fontreader.truetype.TTFFile;

最后,代码有效,但字距对返回的无效与您使用以下方式转换的路径:

void vectorize(Path2D.Float path, String s) {
    PathIterator pIter;
    FontRenderContext frc = new FontRenderContext(null,true,true);
    GlyphVector gv;
    Shape glyph;
    gv = font.createGlyphVector(frc, s);
    glyph = gv.getGlyphOutline(0);
    pIter = glyph.getPathIterator(null);
    while (!pIter.isDone()) {
        switch(pIter.currentSegment(points)) {
        case PathIterator.SEG_MOVETO:
            path.moveTo(points[0], points[1]);
            break;
        case PathIterator.SEG_LINETO :
            path.lineTo(points[0], points[1]);
            break;
        case PathIterator.SEG_QUADTO :
            path.quadTo(points[0], points[1], points[2], points[3]);
            break;
        case PathIterator.SEG_CUBICTO :
            path.curveTo(points[0], points[1], points[2], points[3], points[4], points[5]);
            break;
        case PathIterator.SEG_CLOSE :
            path.closePath();
        }
        pIter.next();
    } 
}

在以下代码中,长度由 lens 恢复:

double interchar = fontsize * 0.075;
int size = '}' - ' ' + 1;
Path2D.Float[] glyphs = new Path2D.Float[size];
double[] lens = new double[size];
String chars[] = new String[size];
int i; char c; 
char[] s = { '0' };
for (i = 0, c = ' '; c <= '}'; c++, i++) { s[0] = c; chars[i] = new String(s); }
for (i = 0; i < size; i++) {
    vectorize(glyphs[i] = new Path2D.Float(), chars[i], tx[i], 0f);
    lens[i] = glyphs[i].getBounds2D().getWidth() + interchar;
}

请清楚一点,我在Graphics2D中使用 fill 显示字形,并使用上面提到的长度将平移添加到由Apache FOP库返回的字距置换中,但是结果很糟糕。 。如本讨论中所述, fontsize 为标准1000,乘以字体大小后, interchar 结果为75。所有这些似乎都是正确的,但是我的手动字距调整对看起来比使用ttf文件中的字距调整对要好得多。

有没有受过此库培训的人能够告诉我们我们应该如何使用这些字距对?

对不起,您可能会稍微偏离最初的问题,但这可能会完善信息,因为一旦阅读了字距调整对,人们将如何在Windows或Android上正确使用它们?