private static void AppendAntialiasing(BitArray antialiasingData, CharacterImportInfo import) { Contract.Requires(antialiasingData != null, "Antialiasing data cannot be null."); Contract.Requires(import != null, "Import cannot be null."); antialiasingData.Add(import.AntialiasData); }
private void FillOpenType(TinyFont font) { HashSet <ushort> userGlyphs = new HashSet <ushort>(); foreach (CharacterImportInfo info in EnumerateAllImports()) { if (info.Mapping.Glyph.HasValue) { userGlyphs.Add(info.Mapping.Glyph.Value); } } Dictionary <ushort, BuilderState> allGeneratedGlyphs = new Dictionary <ushort, BuilderState>(); foreach (FeatureImportInfo feature in _features.Where(f => f.Type == FeatureImportType.Substitution)) { foreach (ushort generatedGlyph in _compiler.GetGeneratedGlyphIds(feature.BuilderState.GlyphTypeface, feature.Script, feature.Language, feature.Feature)) { allGeneratedGlyphs[generatedGlyph] = feature.BuilderState; } } GlyphClassesAppendix classes = font.GetOrAddNewAppendix <GlyphClassesAppendix>(); SubstitutionAppendix substitution = font.GetOrAddNewAppendix <SubstitutionAppendix>(); PositioningAppendix positioning = font.GetOrAddNewAppendix <PositioningAppendix>(); Dictionary <ushort, BuilderState> glyphsToAdd = new Dictionary <ushort, BuilderState>(); foreach (FeatureImportInfo feature in _features.Where(f => f.Type == FeatureImportType.Substitution)) { foreach (ushort generatedGlyph in _compiler.CompileFeature(feature.BuilderState.GlyphTypeface, feature.Script, feature.Language, feature.Feature, substitution, classes, allGeneratedGlyphs.Keys.Concat(userGlyphs))) { glyphsToAdd[generatedGlyph] = feature.BuilderState; } } foreach (KeyValuePair <ushort, BuilderState> toAddPair in glyphsToAdd) { if (!userGlyphs.Contains(toAddPair.Key)) { int character; if (toAddPair.Value.GlyphToCharacterMap.TryGetValue(toAddPair.Key, out character)) { _characterImportList[character] = new CharacterImportInfo(toAddPair.Value, new CharacterGlyphPair(character, toAddPair.Key)); } else if (toAddPair.Key < toAddPair.Value.GlyphTypeface.GlyphCount) { _glyphImportList.Add(new CharacterImportInfo(toAddPair.Value, new CharacterGlyphPair(null, toAddPair.Key))); } userGlyphs.Add(toAddPair.Key); } } foreach (FeatureImportInfo feature in _features.Where(f => f.Type == FeatureImportType.Positioning)) { _compiler.CompileFeature(feature.BuilderState.GlyphTypeface, feature.Script, feature.Language, feature.Feature, positioning, classes, allGeneratedGlyphs.Keys.Concat(userGlyphs), feature.BuilderState.EmSize); } }
private static void AppendBitmap(IList <BitArray> bitmapData, CharacterImportInfo import) { Contract.Requires(import != null, "Import cannot be null."); Contract.Requires(bitmapData != null, "Bitmap data cannot be null."); Contract.Requires(bitmapData.Count > 0, "Bitmap data does not contain any rows."); Contract.Ensures(bitmapData.Min(row => row.Count) == bitmapData.Max(row => row.Count), "Bitmap data row lengths corrupted."); if (import.BitmapData == null) { return; } int srcY = import.InkBox.Y; int srcX = import.InkBox.X; int destY = import.InkBox.Y; // bitmapData are already baseline aligned int destX = bitmapData[0].Length; int width = import.InkBox.Width; int height = import.InkBox.Height; if (destY + height > bitmapData.Count) { // bigger glyph than the font height, need to accomodate // this can happen when glyph transform is applied // or when glyph has out of metrics overhangs for (int y = bitmapData.Count; y < destY + height; y++) { bitmapData.Add(new BitArray(destX)); } //bitmapData.Insert(0, new BitArray(destX)); // no need to update first non-blank line because current is the new first due to resizing } for (int i = 0; i < bitmapData.Count; i++) { bitmapData[i].Length += width; } for (int y = 0; y < height; y++) { BitArray bitmapDataRow = bitmapData[destY + y]; for (int x = 0; x < width; x++) { bitmapDataRow[destX + x] = import.BitmapData[srcY + y][srcX + x]; } } }