Пример #1
0
        /// <summary>
        /// Creates new instance of Character Info.
        /// </summary>
        /// <param name="font">Tiny Font containing character.</param>
        /// <param name="rangeIndex">Index to character range containing this character.</param>
        /// <param name="c">Characeter.</param>
        /// <param name="plane">Font plane describing plane to which this character belongs.</param>
        /// <param name="planeNumber">Number of <paramref name="plane"/> containg this character.</param>
        internal CharacterInfo(TinyFont font, int rangeIndex, char c, FontPlane plane, int planeNumber)
        {
            Contract.Assert(plane != null, "Plane for specified character does not exists.");

            _font = font;
            _characterAntialiasingData = plane.CharacterAntialiasingData;
            _characterBitmapData       = plane.CharacterBitmapData;
            _c           = (char)c;
            _planeNumber = planeNumber;

            _rangeIndex = rangeIndex;
            _range      = plane.CharacterRanges[_rangeIndex];

            checked
            {
                _characterIndex = (int)_range.IndexOfFirstCharacter + _c - _range.FirstCharacter;
                _character      = plane.Characters[_characterIndex];

                _offset = (int)(_range.Offset + _character.Offset);

                if (_font.Description.IsExtended)
                {
                    _antialiasOffset = (int)(plane.CharacterRangesAntialiasing[_rangeIndex].Offset + plane.CharactersAntialiasing[_characterIndex].Offset);
                }
                else
                {
                    _antialiasOffset = -1;
                }
            }
        }
Пример #2
0
        private void ReadBasicFrom(BinaryReader reader)
        {
            _characterRanges.Clear();
            _characterRanges.Capacity = _description.Ranges;
            for (int i = 0; i < _description.Ranges; i++)
            {
                CharacterRangeDescription range = new CharacterRangeDescription();
                range.ReadFrom(reader);

                _characterRanges.Add(range);
            }
            _characterRanges.Sentinel = new CharacterRangeDescription();
            _characterRanges.Sentinel.ReadFrom(reader);

            _characters.Clear();
            _characters.Capacity = _description.Characters;
            for (int i = 0; i < _description.Characters; i++)
            {
                CharacterDescription character = new CharacterDescription();
                character.ReadFrom(reader);

                _characters.Add(character);
            }
            _characters.Sentinel = new CharacterDescription();
            _characters.Sentinel.ReadFrom(reader);

            int wordwidth = (int)((_characterBitmapDescription.Width * _characterBitmapDescription.BitsPerPixel + 31) / 32 * _characterBitmapDescription.Height * 4);

            _characterBitmapData = reader.ReadBytes(wordwidth);
        }
Пример #3
0
 public int Compare(char character, CharacterRangeDescription range)
 {
     if (character < range.FirstCharacter)
     {
         return(-1);
     }
     if (character > range.LastCharacter)
     {
         return(1);
     }
     return(0);
 }
Пример #4
0
 /// <summary>
 /// Enumerates thru all characters saved in Tiny Font accross all font planes sorted by font plane in ascending order.
 /// </summary>
 /// <returns>Character information.</returns>
 public IEnumerable <CharacterInfo> EnumerateAllCharacterInfos()
 {
     for (int planeNumber = 0; planeNumber <= LastPlane; planeNumber++)
     {
         FontPlane plane = FontPlanes[planeNumber];
         if (plane != null)
         {
             for (int r = 0; r < plane.CharacterRanges.ItemsCount; r++)
             {
                 CharacterRangeDescription range = plane.CharacterRanges[r];
                 for (char c = range.FirstCharacter; c <= range.LastCharacter; c++)
                 {
                     yield return(new CharacterInfo(this, r, c, plane, planeNumber));
                 }
             }
         }
     }
 }
Пример #5
0
        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;
            }
        }