Beispiel #1
0
        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;
            }
        }