Created
August 21, 2015 16:32
-
-
Save Saqoosha/b557906eae258120ab47 to your computer and use it in GitHub Desktop.
OpenType フォントのカーニング情報をぶっこぬく ref: http://qiita.com/Saqoosha/items/8a9bb825e02db770408e
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(OTF | |
(OffsetTable | |
(sfnt-version 20308.21583) | |
(numTables 25) | |
(searchRange 256) | |
(enterSelector 4) | |
(rangeShift 384)) | |
(Table 0 (tag "BASE" #x42415345) | |
(checkSum 6962C672) (offset #x00000430) (length: #x000001C8)) | |
(Table 1 (tag "CFF " #x43464620) | |
(checkSum 0BDFCA60) (offset #x0034700C) (length: #x0080F295)) | |
(Table 2 (tag "EBDT" #x45424454) | |
(checkSum E109E7DA) (offset #x00213B60) (length: #x001334AA)) | |
(Table 3 (tag "EBLC" #x45424C43) | |
(checkSum 81D5AE36) (offset #x00002A58) (length: #x0001064C)) | |
(Table 4 (tag "GPOS" #x47504F53) | |
(checkSum D6E4B8CC) (offset #x00036E04) (length: #x00015098)) | |
(Table 5 (tag "GSUB" #x47535542) | |
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include "otf.h" | |
#include <ft2build.h> | |
#include FT_FREETYPE_H | |
int glyph_contains(OTF_Coverage *coverage, OTF_GlyphID glyph_id) { | |
if (coverage->CoverageFormat == 1) { | |
for (int i = 0; i < coverage->Count; i++) { | |
if (coverage->table.GlyphArray[i] == glyph_id) { | |
return i; | |
} | |
} | |
} else if (coverage->CoverageFormat == 2) { | |
for (int i = 0; i < coverage->Count; i++) { | |
OTF_RangeRecord *range = coverage->table.RangeRecord + i; | |
for (int j = range->Start; j <= range->End; j++) { | |
if (j == glyph_id) { | |
return j; | |
} | |
} | |
} | |
} | |
// ふくまれてない | |
return -1; | |
} | |
OTF_PairValueRecord *get_pair_set(OTF_LookupSubTableGPOS *sub_table, OTF_GlyphID left, OTF_GlyphID right) { | |
// printf("Coverage Format: %d, Count: %d, left: %d, right: %d\n", sub_table->Coverage.CoverageFormat, | |
// sub_table->Coverage.Count, glyph_contains(&sub_table->Coverage, left), glyph_contains(&sub_table->Coverage, | |
// right)); | |
int pair_set_index = glyph_contains(&sub_table->Coverage, left); | |
if (pair_set_index < 0) { | |
// この sub table には left の情報無い | |
return NULL; | |
} | |
OTF_PairSet *pair_set = &sub_table->u.pair1.PairSet[pair_set_index]; | |
for (int i = 0; i < pair_set->PairValueCount; i++) { | |
if (pair_set->PairValueRecord[i].SecondGlyph == right) { | |
return &pair_set->PairValueRecord[i]; | |
} | |
} | |
// right との情報無い | |
return NULL; | |
} | |
int get_kerning_value(OTF *otf, OTF_GlyphString *gstring) { | |
char name[5]; | |
OTF_Tag kern = OTF_tag("kern"); | |
// OTF_Tag palt = OTF_tag("palt"); | |
// よくわからんので最初の Script | |
OTF_LangSys *lang_sys = &otf->gpos->ScriptList.Script[0].DefaultLangSys; | |
for (int i = 0; i < lang_sys->FeatureCount; i++) { | |
int featureIndex = lang_sys->FeatureIndex[i]; | |
OTF_Feature *feature = &otf->gpos->FeatureList.Feature[featureIndex]; | |
OTF_tag_name(feature->FeatureTag, name); | |
// printf("%d: %d, %s\n", i, featureIndex, name); | |
if (feature->FeatureTag != kern) continue; | |
// LookupListIndex ながさ 1 なので最初のやつ。複数はいってることってあるの? | |
unsigned int lookupIndex = feature->LookupListIndex[0]; | |
// printf("%i: %s, %d\n", i, name, lookupIndex); | |
// このへんもリストの最初だけ | |
OTF_PairValueRecord *value = get_pair_set(&otf->gpos->LookupList.Lookup[lookupIndex].SubTable.gpos[0], gstring->glyphs[0].glyph_id, gstring->glyphs[1].glyph_id); | |
if (value) { | |
// XAdvance 以外に値はいってることあるの? | |
return value->Value1.XAdvance; | |
} | |
} | |
return 0; | |
} | |
int main(int argc, const char *argv[]) { | |
OTF *otf = OTF_open("/Library/Fonts/ヒラギノ明朝 Pro W6.otf"); | |
OTF_get_table(otf, "GPOS"); | |
OTF_GlyphString gstring; | |
gstring.size = 2; | |
gstring.used = 2; | |
gstring.glyphs = (OTF_Glyph *)calloc(gstring.size, sizeof(OTF_Glyph)); | |
gstring.glyphs[0].c = 0x3042; // あ | |
gstring.glyphs[1].c = 0x3062; // ぢ | |
OTF_drive_cmap(otf, &gstring); | |
printf("Left glyph=0x%04x, Right glyph=0x%04x\n", gstring.glyphs[0].glyph_id, gstring.glyphs[1].glyph_id); | |
int kerning_value = get_kerning_value(otf, &gstring); | |
printf("Kerning value=%d\n", kerning_value); | |
free(gstring.glyphs); | |
OTF_close(otf); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment