private void ReadExtendedFrom(BinaryReader reader) { _characterAntialiasingMetrics.ReadFrom(reader); _characterRangesAntialiasing.Clear(); _characterRangesAntialiasing.Capacity = _description.Ranges; for (int i = 0; i < _description.Ranges; i++) { CharacterRangeAntialiasing range = new CharacterRangeAntialiasing(); range.ReadFrom(reader); _characterRangesAntialiasing.Add(range); } _charactersAntialiasing.Clear(); _charactersAntialiasing.Capacity = _description.Characters; for (int i = 0; i < _description.Characters; i++) { CharacterAntialiasing character = new CharacterAntialiasing(); character.ReadFrom(reader); _charactersAntialiasing.Add(character); } if (_description.Characters % 2 == 1) { reader.ReadBytes(2); } _characterAntialiasingData = reader.ReadBytes((int)_characterAntialiasingMetrics.Size); int padding = 4 - (int)_characterAntialiasingMetrics.Size % 4; if (padding < 4) { reader.ReadBytes(padding); } }
private void FillCharacters(TinyFont font, IEnumerable <CharacterImportInfo> imports, ushort planeNumber) { Contract.Requires(font != null, "Font cannot be null."); Contract.Requires(font.Metrics != null, "Font metrics cannot be null."); if (font.Metrics.Height == 0) { Trace.TraceEvent(TraceEventType.Warning, 0, "TinyFont has a height of zero. No glyphs will be included."); return; } FontPlane plane = planeNumber == 0 ? font.FontPlanes[0] : new FontPlane(); Contract.Requires(plane != null, "Plane cannot be null."); FillDescription(plane.Description); uint numberOfCharacters = 0; bool antialiasing = font.Description.IsExtended; short firstNonBlankLine = short.MaxValue; int maxCharacterWidth = font.Metrics.MaximumCharacterWidth; BitArray antialiasingData = new BitArray(0); List <BitArray> bitmapData = new List <BitArray>(font.Metrics.Height); for (int i = 0; i < font.Metrics.Height; i++) { bitmapData.Add(new BitArray(0)); } int lastCharacter = -1; CharacterRangeDescription rangeDescription = null; CharacterRangeAntialiasing rangeAntialiasing = null; foreach (CharacterImportInfo import in imports) { Contract.Assert(import.Mapping.Character.Value >= 0 && import.Mapping.Character.Value <= LastPlaneLastCharacter, "All content must have valid two bytes characters."); Contract.Assert(import.Mapping.Character.Value > lastCharacter, "Content must be ordered by characters and cannot overlap."); int character = import.Mapping.Character.Value; // If character does not belong to this plane, skip it if ((character >> 16) != planeNumber) { continue; } if (lastCharacter != (character - 1)) { if (rangeDescription != null) { rangeDescription.LastCharacter = (char)lastCharacter; plane.CharacterRanges.Add(rangeDescription); if (antialiasing) { plane.CharacterRangesAntialiasing.Add(rangeAntialiasing); } } rangeDescription = new CharacterRangeDescription(); rangeDescription.Offset = (uint)bitmapData[0].Length; rangeDescription.FirstCharacter = (char)character; rangeDescription.IndexOfFirstCharacter = numberOfCharacters; if (antialiasing) { rangeAntialiasing = new CharacterRangeAntialiasing(); rangeAntialiasing.Offset = (uint)(antialiasingData.Length / BitsPerByte); } } lastCharacter = character; maxCharacterWidth = Math.Max(maxCharacterWidth, import.InkBox.Width); ++numberOfCharacters; CharacterDescription characterDescription = new CharacterDescription(); characterDescription.LeftMargin = Helper.FitIntoInt8(import.EmSideBearing.Left, Trace); characterDescription.RightMargin = Helper.FitIntoInt8(import.EmSideBearing.Right, Trace); characterDescription.Offset = checked ((ushort)(bitmapData[0].Length - rangeDescription.Offset)); plane.Characters.Add(characterDescription); if (import.BitmapData != null) { AppendBitmap(bitmapData, import); short glyphFirstNonBlankLine = Helper.FitIntoInt16(import.InkBox.Y, Trace); if (firstNonBlankLine > glyphFirstNonBlankLine) { firstNonBlankLine = glyphFirstNonBlankLine; } } if (antialiasing) { CharacterAntialiasing characterAntialiasing = new CharacterAntialiasing(); characterAntialiasing.Offset = import.AntialiasData == null ? CharacterAntialiasing.NoData : checked ((ushort)(antialiasingData.Length / BitsPerByte - rangeAntialiasing.Offset)); plane.CharactersAntialiasing.Add(characterAntialiasing); if (import.AntialiasData != null) { AppendAntialiasing(antialiasingData, import); int bitPadding = antialiasingData.Length % BitsPerByte; if (bitPadding > 0) { antialiasingData.Length += BitsPerByte - bitPadding; } } } } if (numberOfCharacters > 0) { if (rangeDescription != null) { rangeDescription.LastCharacter = (char)lastCharacter; plane.CharacterRanges.Add(rangeDescription); if (antialiasing) { plane.CharacterRangesAntialiasing.Add(rangeAntialiasing); } } plane.Metrics.Offset = firstNonBlankLine; plane.CharacterBitmap.Width = (uint)bitmapData[0].Length; plane.CharacterBitmap.Height = (uint)(bitmapData.Count - firstNonBlankLine); plane.CharacterBitmap.BitsPerPixel = 1; plane.CharacterBitmapData = ToBitmapData(bitmapData, firstNonBlankLine); if (antialiasing) { plane.CharacterAntialiasingData = ToAntialiasingData(antialiasingData); plane.CharacterAntialiasingMetrics.Size = (uint)plane.CharacterAntialiasingData.Length; } font.Metrics.MaximumCharacterWidth = Helper.FitIntoInt16(maxCharacterWidth, Trace); font.FontPlanes[planeNumber] = plane; } }