public static Encoding ReadEncoding(CompactFontFormatData data, ICompactFontFormatCharset charset, IReadOnlyList <string> stringIndex) { if (data == null) { throw new ArgumentNullException(nameof(data)); } var format = data.ReadCard8(); // A few fonts have multiply encoded glyphs which are indicated by setting the high order bit of the format byte. // To get the real format out & with 0111 1111 (0x7f). var baseFormat = format & 0x7f; switch (baseFormat) { case 0: return(ReadFormat0Encoding(data, charset, stringIndex, format)); case 1: return(ReadFormat1Encoding(data, charset, stringIndex, format)); default: throw new InvalidFontFormatException($"The provided format {format} for this Compact Font Format encoding was invalid."); } }
public CompactFontFormatFont(CompactFontFormatTopLevelDictionary topDictionary, CompactFontFormatPrivateDictionary privateDictionary, ICompactFontFormatCharset charset, Union <Type1CharStrings, Type2CharStrings> charStrings) { TopDictionary = topDictionary; PrivateDictionary = privateDictionary; Charset = charset; CharStrings = charStrings; }
internal CompactFontFormatFont(CompactFontFormatTopLevelDictionary topDictionary, CompactFontFormatPrivateDictionary privateDictionary, ICompactFontFormatCharset charset, Union <Type1CharStrings, Type2CharStrings> charStrings, Encoding fontEncoding) { TopDictionary = topDictionary; PrivateDictionary = privateDictionary; Charset = charset; CharStrings = charStrings; Encoding = fontEncoding; }
public CompactFontFormatCidFont(CompactFontFormatTopLevelDictionary topDictionary, CompactFontFormatPrivateDictionary privateDictionary, ICompactFontFormatCharset charset, Union <Type1CharStrings, Type2CharStrings> charStrings, IReadOnlyList <CompactFontFormatTopLevelDictionary> fontDictionaries, IReadOnlyList <CompactFontFormatPrivateDictionary> privateDictionaries, ICompactFontFormatFdSelect fdSelect) : base(topDictionary, privateDictionary, charset, charStrings, null) { FontDictionaries = fontDictionaries; PrivateDictionaries = privateDictionaries; FdSelect = fdSelect; }
private static Type2CharStrings ReadCharStrings(CompactFontFormatData data, CompactFontFormatTopLevelDictionary topDictionary, CompactFontFormatIndex charStringIndex, CompactFontFormatSubroutinesSelector subroutinesSelector, ICompactFontFormatCharset charset) { data.Seek(topDictionary.CharStringsOffset); switch (topDictionary.CharStringType) { case CompactFontFormatCharStringType.Type1: throw new NotImplementedException("Type 1 CharStrings are not currently supported in CFF font."); case CompactFontFormatCharStringType.Type2: return(Type2CharStringParser.Parse(charStringIndex, subroutinesSelector, charset)); default: throw new ArgumentOutOfRangeException($"Unexpected CharString type in CFF font: {topDictionary.CharStringType}."); } }
private CompactFontFormatCidFont ReadCidFont(CompactFontFormatData data, CompactFontFormatTopLevelDictionary topLevelDictionary, int numberOfGlyphs, IReadOnlyList <string> stringIndex, CompactFontFormatPrivateDictionary privateDictionary, ICompactFontFormatCharset charset, CompactFontFormatIndex globalSubroutines, CompactFontFormatIndex localSubroutinesTop, CompactFontFormatIndex charStringIndex) { var offset = topLevelDictionary.CidFontOperators.FontDictionaryArray; data.Seek(offset); var fontDict = CompactFontFormatIndexReader.ReadDictionaryData(data); var privateDictionaries = new List <CompactFontFormatPrivateDictionary>(); var fontDictionaries = new List <CompactFontFormatTopLevelDictionary>(); var fontLocalSubroutines = new List <CompactFontFormatIndex>(); foreach (var index in fontDict) { var topLevelDictionaryCid = topLevelDictionaryReader.Read(new CompactFontFormatData(index), stringIndex); if (!topLevelDictionaryCid.PrivateDictionaryLocation.HasValue) { throw new InvalidFontFormatException("The CID keyed Compact Font Format font did not contain a private dictionary for the font dictionary."); } var privateDictionaryBytes = data.SnapshotPortion(topLevelDictionaryCid.PrivateDictionaryLocation.Value.Offset, topLevelDictionaryCid.PrivateDictionaryLocation.Value.Size); var privateDictionaryCid = privateDictionaryReader.Read(privateDictionaryBytes, stringIndex); // CFFParser.java line 625 - read the local subroutines. if (privateDictionaryCid.LocalSubroutineOffset.HasValue && privateDictionaryCid.LocalSubroutineOffset.Value > 0) { data.Seek(topLevelDictionaryCid.PrivateDictionaryLocation.Value.Offset + privateDictionaryCid.LocalSubroutineOffset.Value); var localSubroutines = CompactFontFormatIndexReader.ReadDictionaryData(data); fontLocalSubroutines.Add(localSubroutines); } else { fontLocalSubroutines.Add(null); } fontDictionaries.Add(topLevelDictionaryCid); privateDictionaries.Add(privateDictionaryCid); } data.Seek(topLevelDictionary.CidFontOperators.FontDictionarySelect); var format = data.ReadCard8(); ICompactFontFormatFdSelect fdSelect; switch (format) { case 0: { fdSelect = ReadFormat0FdSelect(data, numberOfGlyphs, topLevelDictionary.CidFontOperators.Ros); break; } case 3: { fdSelect = ReadFormat3FdSelect(data, topLevelDictionary.CidFontOperators.Ros); break; } default: throw new InvalidFontFormatException($"Invalid Font Dictionary Select format: {format}."); } var subroutineSelector = new CompactFontFormatSubroutinesSelector(globalSubroutines, localSubroutinesTop, fdSelect, fontLocalSubroutines); var charStrings = ReadCharStrings(data, topLevelDictionary, charStringIndex, subroutineSelector, charset); var union = Union <Type1CharStrings, Type2CharStrings> .Two(charStrings); return(new CompactFontFormatCidFont(topLevelDictionary, privateDictionary, charset, union, fontDictionaries, privateDictionaries, fdSelect)); }
private static CompactFontFormatFormat1Encoding ReadFormat1Encoding(CompactFontFormatData data, ICompactFontFormatCharset charset, IReadOnlyList <string> stringIndex, byte format) { var numberOfRanges = data.ReadCard8(); var fromRanges = new List <(int code, int sid, string str)>(); var gid = 1; for (var i = 0; i < numberOfRanges; i++) { int rangeFirst = data.ReadCard8(); int rangeLeft = data.ReadCard8(); for (var j = 0; j < 1 + rangeLeft; j++) { var sid = charset.GetStringIdByGlyphId(gid); var code = rangeFirst + j; var str = ReadString(sid, stringIndex); fromRanges.Add((code, sid, str)); gid++; } } IReadOnlyList <CompactFontFormatBuiltInEncoding.Supplement> supplements = new List <CompactFontFormatBuiltInEncoding.Supplement>(); if (HasSupplement(format)) { supplements = ReadSupplement(data, stringIndex); } return(new CompactFontFormatFormat1Encoding(numberOfRanges, fromRanges, supplements)); }
private static CompactFontFormatFormat0Encoding ReadFormat0Encoding(CompactFontFormatData data, ICompactFontFormatCharset charset, IReadOnlyList <string> stringIndex, byte format) { var numberOfCodes = data.ReadCard8(); var values = new List <(int code, int sid, string str)>(); for (var i = 1; i <= numberOfCodes; i++) { var code = data.ReadCard8(); var sid = charset.GetStringIdByGlyphId(i); var str = ReadString(sid, stringIndex); values.Add((code, sid, str)); } IReadOnlyList <CompactFontFormatBuiltInEncoding.Supplement> supplements = new List <CompactFontFormatBuiltInEncoding.Supplement>(); if (HasSupplement(format)) { supplements = ReadSupplement(data, stringIndex); } return(new CompactFontFormatFormat0Encoding(values, supplements)); }
public CompactFontFormatFont Parse(CompactFontFormatData data, string name, IReadOnlyList <byte> topDictionaryIndex, IReadOnlyList <string> stringIndex, CompactFontFormatIndex globalSubroutineIndex) { var individualData = new CompactFontFormatData(topDictionaryIndex.ToArray()); var topDictionary = topLevelDictionaryReader.Read(individualData, stringIndex); var privateDictionary = CompactFontFormatPrivateDictionary.GetDefault(); if (topDictionary.PrivateDictionaryLocation.HasValue) { var privateDictionaryBytes = data.SnapshotPortion(topDictionary.PrivateDictionaryLocation.Value.Offset, topDictionary.PrivateDictionaryLocation.Value.Size); privateDictionary = privateDictionaryReader.Read(privateDictionaryBytes, stringIndex); } if (topDictionary.CharStringsOffset < 0) { throw new InvalidOperationException("Expected CFF to contain a CharString offset."); } var localSubroutines = CompactFontFormatIndex.None; if (privateDictionary.LocalSubroutineOffset.HasValue && topDictionary.PrivateDictionaryLocation.HasValue) { data.Seek(privateDictionary.LocalSubroutineOffset.Value + topDictionary.PrivateDictionaryLocation.Value.Offset); localSubroutines = indexReader.ReadDictionaryData(data); } data.Seek(topDictionary.CharStringsOffset); var charStringIndex = indexReader.ReadDictionaryData(data); ICompactFontFormatCharset charset = null; if (topDictionary.IsCidFont && topDictionary.CharSetOffset >= 0 && topDictionary.CharSetOffset <= 2) { switch (topDictionary.CharSetOffset) { case 0: charset = CompactFontFormatIsoAdobeCharset.Value; break; case 1: charset = CompactFontFormatExpertCharset.Value; break; case 2: charset = CompactFontFormatExpertSubsetCharset.Value; break; } } else { data.Seek(topDictionary.CharSetOffset); var format = data.ReadCard8(); switch (format) { case 0: { var glyphToNamesAndStringId = new List <(int glyphId, int stringId, string name)>(); for (var glyphId = 1; glyphId < charStringIndex.Count; glyphId++) { var stringId = data.ReadSid(); glyphToNamesAndStringId.Add((glyphId, stringId, ReadString(stringId, stringIndex))); } charset = new CompactFontFormatFormat0Charset(glyphToNamesAndStringId); break; } case 1: case 2: { var glyphToNamesAndStringId = new List <(int glyphId, int stringId, string name)>(); for (var glyphId = 1; glyphId < charStringIndex.Count; glyphId++) { var firstSid = data.ReadSid(); var numberInRange = format == 1 ? data.ReadCard8() : data.ReadCard16(); glyphToNamesAndStringId.Add((glyphId, firstSid, ReadString(firstSid, stringIndex))); for (var i = 0; i < numberInRange; i++) { glyphId++; var sid = firstSid + i + 1; glyphToNamesAndStringId.Add((glyphId, sid, ReadString(sid, stringIndex))); } } if (format == 1) { charset = new CompactFontFormatFormat1Charset(glyphToNamesAndStringId); } else { charset = new CompactFontFormatFormat2Charset(glyphToNamesAndStringId); } break; } default: throw new InvalidOperationException($"Unrecognized format for the Charset table in a CFF font. Got: {format}."); } } data.Seek(topDictionary.CharStringsOffset); Type2CharStrings charStrings; switch (topDictionary.CharStringType) { case CompactFontFormatCharStringType.Type1: throw new NotImplementedException(); case CompactFontFormatCharStringType.Type2: charStrings = Type2CharStringParser.Parse(charStringIndex, localSubroutines, globalSubroutineIndex, charset); break; default: throw new ArgumentOutOfRangeException($"Unexpected CharString type in CFF font: {topDictionary.CharStringType}."); } return(new CompactFontFormatFont(topDictionary, privateDictionary, charset, Union <Type1CharStrings, Type2CharStrings> .Two(charStrings))); }