and especially, as for vertical writing a.k.a. "縦書き(tategaki)", we might need to know some information on the details of glyph with font architecture, such as typography.
I think this knowledge is helpful for eBook or something like that.
So today, I will post the article about I analyzed a font "meiryo" by WPF application.(C#)
OpenType specification
http://www.microsoft.com/typography/otspec/default.htm
Actually ,it's very easy to find a glyph index and the outline data by using of following methods.
CharacterToGlyphMap.TryGetValue (System.Windows.Media.GlyphTypeface)
GetGlyphOutline (System.Windows.Media.GlyphTypeface)
However, it seems there's no method to find the glyph index of vertical writing. ( as far as I know ).
So I tried scanning binary data of the font file according to the following steps.
For example : How to find vertical writing glyph index about a character 'a' (Unicode: U+0061)
1. Find glyph index about 'a' from cmap.
1-1.cmap Header
- filtering Encoding Record by EncodingID = 1 or EncodingID = 10 on PlatformID = 3
1-2.CmapFormat4 or CmapFormat12
The glyph index about 'a' is 0x0044 on Meiryo.
2. Find vertical glyph index about 'a' from GSUB
2-1.GSUB Header
2-2.FeatureList
- filtering by Feature Tag 'vert' or 'vrt2'
2-3.Feature
2-4.LookupList
2-5.Lookup
- filtering by lookupListIndex on Feature
- filtering by LookupType = 0x0001
2-6.SingleSubstitutionFormat1 or SingleSubstitutionFormat2
2-7.CoverageFormat1 or CoverageFormat2
The vertical glyph index about 'a' is 0x2793 on Meiryo.
* The application gets glyph data(points data for outline) from glyf ( Simple Glyph Description or Composite Glyph Description )
* And the application draws lines and bezier curves by use of the points.
Composite Glyph | Simple Glyph | Simple Glyph : multibyte character |
About endian
"endian" is important when a program is scanning the binary data, whether "big endian" or "little endian" is right on the computer.
public byte[] GetBytes(byte[] bytes, int startIndex, int length) { if(bytes != null) { if(index >= 0 && length > 0 && index + length < bytes.Length) { byte[] bytes0 = new byte[length]; for(int i=0;i<length;i++) bytes0[i] = bytes[startIndex + i]; if(BitConverter.IsLittleEndian) Array.Reverse(bytes0); return bytes0; } } throw new Exception("Exception is occurred on GetBytes"); }
then, available for type conversions like this.
public short GetShort(byte[] bytes, int startIndex, int length) { try { byte[] sBytes = GetBytes(bytes, startIndex, 2); return BitConverter.ToInt16(sBytes, 0); } catch(Exception ex) { throw new Exception(string.Format("Exception is occurred on GetShort(bytes, {0}, {1}): {2}", startIndex, length, ex.Message)); } }
Other tables except for cmap and GSUB have more informations about the font like baseline.
but it's not easy. I mean, I can't be bothered...
No comments:
Post a Comment