예제 #1
0
 /// <summary>
 /// Initializes this reader to decode the naming table of the supplied font.
 /// </summary>
 /// <param name="openType">The font to decode.</param>
 public void Setup(OpenType openType)
 {
     this.openType = openType;
     name          = openType.GetName();
     index         = -1;
     count         = openType.ReadUInt16(name, 2);
     stringOffset  = name.offset + openType.ReadUInt16(name, 4);
 }
예제 #2
0
 /// <summary>
 /// Initializes this reader to iterate over the supplied glyph.
 /// </summary>
 /// <param name="openType">The font containing the glyph.</param>
 /// <param name="pixelSize">The size in pixels of the font.</param>
 /// <param name="glyphIndex">The index of the glyph in <paramref name="openType"/>.</param>
 /// <returns><c>true</c> if the glyph can be read.</returns>
 public bool Setup(OpenType openType, double pixelSize, int glyphIndex)
 {
     currentDecoder = (openType.GetGlyphOutlineKind()) switch
     {
         GlyphOutlineKind.Ttf => trueTypeGlyphDecoder,
         GlyphOutlineKind.Cff => cffGlyphDecoder,
         _ => throw new InvalidOperationException("Glyph outline kind: " + openType.GetGlyphOutlineKind()),
     };
     return(currentDecoder.Setup(openType, pixelSize, (uint)glyphIndex));
 }
예제 #3
0
        /// <summary>
        /// Reads a font collection using a supplied stream in OpenType format.
        /// </summary>
        /// <param name="stream">The input stream.</param>
        /// <returns>A font collection.</returns>
        public static OpenType[] Load(Stream stream)
        {
            byte[] data;
            try
            {
                var length = (int)stream.Length;
                data = new byte[length];
                var offset = 0;
                int read;
                while ((read = stream.Read(data, offset, length)) != 0)
                {
                    offset += read;
                    length -= read;
                }
            }
            catch
            {
                var memoryStream = new MemoryStream();
                stream.CopyTo(memoryStream);
                data = memoryStream.ToArray();
            }

            try
            {
                if (data[0] == 't' && data[1] == 't' && data[2] == 'c' && data[3] == 'f')
                {
                    var version = ReadUInt32(data, 4);
                    if (version != 0x00010000 && version != 0x00020000)
                    {
                        throw new InvalidOperationException(Resources.FormatMessage(Resources.Key.UnsupportedFontCollectionVersion, version));
                    }
                    var fontCount = ReadUInt32(data, 8);
                    var infos     = new OpenType[fontCount];
                    for (uint i = 0; i < fontCount; i++)
                    {
                        infos[i] = new OpenType(data, ReadUInt32(data, 12u + i * 4u));
                    }
                    return(infos);
                }
                else
                {
                    return(new OpenType[] { new OpenType(data, 0) });
                }
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException(Resources.GetMessage(Resources.Key.UnexpectedEndOfFile));
            }
        }
예제 #4
0
        internal override bool Setup(OpenType openType, double pixelSize, uint glyphIndex)
        {
            Reset();
            if (openType.GetGlyphOutlineKind() != GlyphOutlineKind.Cff)
            {
                throw new ArgumentException(nameof(openType));
            }
            this.openType = openType;
            globalSubrs   = openType.GetGlobalSubrs();
            subrs         = openType.GetGlyphSubrs(glyphIndex);
            charString    = openType.GetCharString(glyphIndex);
            Scale         = pixelSize / openType.GetUnitsPerEm();

            bool first = true;

            XMin = 0;
            XMax = 0;
            YMin = 0;
            YMax = 0;
            while (Move())
            {
                if (first)
                {
                    first = false;
                    XMin  = X;
                    YMin  = Y;
                    XMax  = X;
                    YMax  = Y;
                }
                else
                {
                    if (X < XMin)
                    {
                        XMin = X;
                    }
                    else if (X > XMax)
                    {
                        XMax = X;
                    }
                    if (Y < YMin)
                    {
                        YMin = Y;
                    }
                    else if (Y > YMax)
                    {
                        YMax = Y;
                    }
                }
                switch (PathCommand)
                {
                case PathCommand.MoveTo:
                    break;

                case PathCommand.LineTo:
                    break;

                case PathCommand.CubicBezierTo:
                    if (Cx1 < XMin)
                    {
                        XMin = Cx1;
                    }
                    else if (Cx1 > XMax)
                    {
                        XMax = Cx1;
                    }
                    if (Cy1 < YMin)
                    {
                        YMin = Cy1;
                    }
                    else if (Cy1 > YMax)
                    {
                        YMax = Cy1;
                    }
                    goto case PathCommand.QuadraticBezierTo;

                case PathCommand.QuadraticBezierTo:
                    if (Cx < XMin)
                    {
                        XMin = Cx;
                    }
                    else if (Cx > XMax)
                    {
                        XMax = Cx;
                    }
                    if (Cy < YMin)
                    {
                        YMin = Cy;
                    }
                    else if (Cy > YMax)
                    {
                        YMax = Cy;
                    }
                    break;
                }
            }
            Reset();
            return(XMin != 0 || XMax != 0);
        }