Beispiel #1
0
        public static bool Load(FontParser parser, FontFace font, bool full)
        {
            font.RequiresLoad = !full;
            font.Parser       = parser;

            // Read the version:
            int dec;
            int version = parser.ReadFixed(out dec);

            if (version == 1 && dec == 0)
            {
                // TTF outline format.
            }
            else
            {
                // Reset to start:
                parser.Position = 0;

                // OpenType. Read the tag (right at the start):
                string openTypeVersion = parser.ReadTag();

                if (openTypeVersion == "OTTO")
                {
                    // CFF outline format.
                }
                else
                {
                    // Unsupported format.
                    return(false);
                }
            }

            // Table count:
            int numTables = parser.ReadUInt16();

            // Move to p12:
            parser.Position = 12;

            for (int i = 0; i < numTables; i++)
            {
                // Read the tables tag:
                string tag = parser.ReadTag();

                // Move parser along:
                parser.Position += 4;

                // Read the offset:
                int offset = (int)parser.ReadUInt32();

                // Grab the position - this allows the tables to mess it up:
                int basePosition = parser.Position;

                switch (tag)
                {
                case "cmap":

                    parser.CmapOffset = offset;

                    break;

                case "head":

                    // Load the header:
                    if (!HeaderTables.Load(parser, offset, font, out parser.IndexToLocFormat))
                    {
                        return(false);
                    }

                    break;

                case "hhea":

                    parser.HheaOffset = offset;

                    break;

                case "hmtx":
                    parser.HmtxOffset = offset;
                    break;

                case "maxp":

                    // Maxp table:
                    MaxpTables.Load(parser, offset, font, out parser.GlyphCount);

                    break;

                case "name":

                    // General meta:
                    NameTables.Load(parser, offset, font);

                    break;

                case "OS/2":

                    // OS2 table:
                    OS2Tables.Load(parser, offset, font);

                    break;

                case "post":

                    // Postscript info table:
                    parser.PostOffset = offset;

                    break;

                case "glyf":
                    parser.GlyfOffset = offset;
                    break;

                case "loca":
                    parser.LocaOffset = offset;
                    break;

                case "GSUB":

                    // Gsub(stitute) table. Ligatures fall through here.
                    GsubTables.Load(parser, offset, font);

                    break;

                case "CFF ":
                    parser.CffOffset = offset;
                    break;

                case "kern":

                    parser.KernOffset = offset;

                    break;

                case "GPOS":

                    parser.GposOffset = offset;

                    break;
                }

                // Skip meta:
                parser.Position = basePosition + 4;
            }

            if (full)
            {
                return(ReadTables(parser, font));
            }

            return(true);
        }
Beispiel #2
0
        public static void Load(FontParser parser, int offset, FontFace font)
        {
            // Got OS2:
            parser.ReadOS2 = true;

            // Seek:
            parser.Position = offset;

            // version
            int version = parser.ReadUInt16();

            // xAvgCharWidth
            parser.ReadInt16();

            // usWeightClass
            int weight = parser.ReadUInt16();

            // usWidthClass
            parser.ReadUInt16();

            // fsType
            parser.ReadUInt16();

            // ySubscriptXSize
            parser.ReadInt16();

            // ySubscriptYSize
            parser.ReadInt16();

            // ySubscriptXOffset
            parser.ReadInt16();

            // ySubscriptYOffset
            parser.ReadInt16();

            // ySuperscriptXSize
            parser.ReadInt16();

            // ySuperscriptYSize
            parser.ReadInt16();

            // ySuperscriptXOffset
            parser.ReadInt16();

            // ySuperscriptYOffset
            parser.ReadInt16();

            // yStrikeoutSize
            font.StrikeSize = (float)parser.ReadInt16() / font.UnitsPerEmF;

            // yStrikeoutPosition
            font.StrikeOffset = (float)parser.ReadInt16() / font.UnitsPerEmF;

            // sFamilyClass
            parser.ReadInt16();

            // panose:

            /*
             * byte panose=new byte[10];
             *
             * for(int i=0;i<10;i++){
             *      panose[i]=parser.ReadByte();
             * }
             */
            parser.Position += 10;

            // ulUnicodeRange1
            parser.ReadUInt32();

            // ulUnicodeRange2
            parser.ReadUInt32();

            // ulUnicodeRange3
            parser.ReadUInt32();

            // ulUnicodeRange4
            parser.ReadUInt32();

            // achVendID
            parser.ReadTag();

            // fsSelection
            int type = parser.ReadUInt16();

            bool italic = ((type & 1) == 1);
            // bool strikeout=((type&16)==16);
            // bool underscore=((type&2)==2);
            bool oblique = ((type & 512) == 512);
            bool bold    = ((type & 32) == 32);
            bool regular = ((type & 64) == 64);
            bool useTypo = ((type & 128) == 128);

            if (!bold || regular)
            {
                // Must be regular:
                weight = 400;
            }
            else if (weight == 0)
            {
                weight = 700;
            }

            font.SetFlags(italic || oblique, weight);

            // usFirstCharIndex
            parser.ReadUInt16();

            // usLastCharIndex
            parser.ReadUInt16();

            // sTypoAscender
            float ascender = (float)parser.ReadInt16() / font.UnitsPerEmF;

            // sTypoDescender
            float descender = (float)parser.ReadInt16() / font.UnitsPerEmF;

            // sTypoLineGap
            float lineGap = ((float)parser.ReadInt16() / font.UnitsPerEmF);

            // usWinAscent
            float wAscender = (float)parser.ReadUInt16() / font.UnitsPerEmF;

            // usWinDescent
            float wDescender = (float)parser.ReadUInt16() / font.UnitsPerEmF;

            // This is an awkward spec hack due to most windows programs
            // providing the wrong typo descender values.

            if (Fonts.UseOS2Metrics)
            {
                if (useTypo)
                {
                    float halfGap = lineGap / 2f;

                    font.Ascender  = ascender + halfGap;
                    font.Descender = halfGap - descender;

                    font.LineGap = font.Ascender + font.Descender;
                }
                else
                {
                    font.Ascender  = wAscender;
                    font.Descender = wDescender;

                    font.LineGap = font.Ascender + font.Descender;
                }
            }


            if (version >= 1)
            {
                // ulCodePageRange1
                parser.ReadUInt32();

                // ulCodePageRange2
                parser.ReadUInt32();
            }

            if (version >= 2)
            {
                // sxHeight
                parser.ReadInt16();

                // sCapHeight
                parser.ReadInt16();

                // usDefaultChar
                parser.ReadUInt16();

                // usBreakChar
                parser.ReadUInt16();

                // usMaxContent
                parser.ReadUInt16();
            }
        }
//--------------------------------------
        public static bool Load(FontParser parser, FontFace font, bool full)
        {
            font.RequiresLoad = !full;
            font.Parser       = parser;

            // Read the magic number:
            uint magic = parser.ReadUInt32();

            if (magic == 0x00010000)
            {
                // TTF outline format.
            }
            else if (magic == 0x774F4646)
            {
                // WOFF 1
                return(WoffLoader.Load(1, parser, font));
            }
            else if (magic == 0x774F4632)
            {
                // WOFF 2
                return(WoffLoader.Load(2, parser, font));
            }
            else
            {
                // OpenType (probably) 0x4F54544F

                // Reset to start:
                parser.Position = 0;

                // OpenType. Read the tag (right at the start):
                string openTypeVersion = parser.ReadTag();

                if (openTypeVersion == "OTTO")
                {
                    // CFF outline format.
                }
                else
                {
                    // Unsupported format.
                    return(false);
                }
            }

            // Table count:
            int numTables = parser.ReadUInt16();

            // Move to p12:
            parser.Position = 12;

            for (int i = 0; i < numTables; i++)
            {
                // Read the tables tag (e.g. GPOS):
                string tag = parser.ReadTag();

                // Move parser along:
                parser.Position += 4;

                // Read the offset:
                int offset = (int)parser.ReadUInt32();

                // Grab the position - this allows the tables to mess it up:
                int basePosition = parser.Position;

                // Handle the table now:
                if (!parser.HandleTable(tag, offset, font))
                {
                    return(false);
                }

                // Skip meta:
                parser.Position = basePosition + 4;
            }

            if (full)
            {
                return(ReadTables(parser, font));
            }

            return(true);
        }
Beispiel #5
0
        public static void Load(FontParser parser, int offset, FontFace font)
        {
            // Seek:
            parser.Position = offset;

            // version
            int version = parser.ReadUInt16();

            // xAvgCharWidth
            parser.ReadInt16();

            // usWeightClass
            int weight = parser.ReadUInt16();

            // usWidthClass
            int stretch = parser.ReadUInt16();

            // fsType
            parser.ReadUInt16();

            // ySubscriptXSize
            parser.ReadInt16();

            // ySubscriptYSize
            parser.ReadInt16();

            // ySubscriptXOffset
            parser.ReadInt16();

            // ySubscriptYOffset
            parser.ReadInt16();

            // ySuperscriptXSize
            parser.ReadInt16();

            // ySuperscriptYSize
            parser.ReadInt16();

            // ySuperscriptXOffset
            parser.ReadInt16();

            // ySuperscriptYOffset
            parser.ReadInt16();

            // yStrikeoutSize
            font.StrikeSize = (float)parser.ReadInt16() / font.UnitsPerEmF;

            // yStrikeoutPosition
            font.StrikeOffset = (float)parser.ReadInt16() / font.UnitsPerEmF;

            // sFamilyClass
            parser.ReadInt16();

            // panose:

            /*
             * byte panose=new byte[10];
             *
             * for(int i=0;i<10;i++){
             *      panose[i]=parser.ReadByte();
             * }
             */
            parser.Position += 10;

            // ulUnicodeRange1
            parser.ReadUInt32();

            // ulUnicodeRange2
            parser.ReadUInt32();

            // ulUnicodeRange3
            parser.ReadUInt32();

            // ulUnicodeRange4
            parser.ReadUInt32();

            // achVendID
            parser.ReadTag();

            // fsSelection
            int type = parser.ReadUInt16();

            bool italic = ((type & 1) == 1);
            // bool strikeout=((type&16)==16);
            // bool underscore=((type&2)==2);
            bool oblique = ((type & 512) == 512);
            bool bold    = ((type & 32) == 32);
            bool regular = ((type & 64) == 64);
            bool useTypo = ((type & 128) == 128);

            if (!bold || regular)
            {
                // Must be regular:
                weight = 400;
            }
            else if (weight == 0)
            {
                weight = 700;
            }

            int styleCode = 0;

            if (italic)
            {
                styleCode = FontFaceFlags.Italic;
            }
            else if (oblique)
            {
                styleCode = FontFaceFlags.Oblique;
            }

            font.SetFlags(styleCode, weight, stretch);

            // usFirstCharIndex
            parser.ReadUInt16();

            // usLastCharIndex
            parser.ReadUInt16();

            // sTypoAscender
            float ascender = (float)parser.ReadInt16() / font.UnitsPerEmF;

            // sTypoDescender
            float descender = (float)parser.ReadInt16() / font.UnitsPerEmF;

            // sTypoLineGap
            float lineGap = ((float)parser.ReadInt16() / font.UnitsPerEmF);

            // We'll now always use OS/2 unless this table isn't present, in which case HHEA takes over.
            // (The W3C suggested approach).
            if (Fonts.AlwaysUseTypo || useTypo)
            {
                // Apply as-is:
                font.Ascender  = ascender;
                font.Descender = -descender;
                font.LineGap   = lineGap;

                // Remove internal leading if there is one:
                float internalLeading = (ascender - descender) - 1f;

                if (internalLeading != 0f)
                {
                    // Add to lineGap:
                    font.Ascender -= internalLeading;
                    font.LineGap  += internalLeading;
                }

                // Skip windows ascent/descent
                parser.Position += 4;
            }
            else
            {
                // usWinAscent
                parser.usWinAscent = (float)parser.ReadUInt16() / font.UnitsPerEmF;

                // usWinDescent
                parser.usWinDescent = (float)parser.ReadUInt16() / font.UnitsPerEmF;
            }

            if (version >= 1)
            {
                // ulCodePageRange1
                parser.ReadUInt32();

                // ulCodePageRange2
                parser.ReadUInt32();
            }

            if (version >= 2)
            {
                // sxHeight
                parser.ReadInt16();

                // sCapHeight
                parser.ReadInt16();

                // usDefaultChar
                parser.ReadUInt16();

                // usBreakChar
                parser.ReadUInt16();

                // usMaxContent
                parser.ReadUInt16();
            }
        }
Beispiel #6
0
        public static bool Load(int version, FontParser parser, FontFace font)
        {
            // Load the V1/V2 header:
            ushort numTables;

            LoadHeader(version, parser, out numTables);

            if (version == 1)
            {
                MemoryStream ms = new MemoryStream(parser.Data);

                // Get the ZLIB compression helper:
                Compressor zLib = Compression.Get("zlib");

                // Read each table next.
                for (int i = 0; i < numTables; i++)
                {
                    string tag        = parser.ReadTag();
                    uint   offset     = parser.ReadUInt32();
                    uint   compLength = parser.ReadUInt32();
                    uint   origLength = parser.ReadUInt32();
                    parser.ReadUInt32();                     // origChecksum

                    // Cache position:
                    int pos = parser.Position;

                    if (compLength != origLength)
                    {
                        // Decompress the table now (zlib)

                        // Seek to table:
                        ms.Position = (int)offset;

                        // Decompressed data:
                        byte[] decompressedTable = new byte[(int)origLength];

                        // Decompress now into our target bytes:
                        zLib.Decompress(ms, decompressedTable);
                    }
                    else
                    {
                        // Ordinary table.
                        parser.HandleTable(tag, (int)offset, font);
                    }

                    // Restore position:
                    parser.Position = pos;
                }
            }
            else if (version == 2)
            {
                // Read each table entry next. The data here is compressed as one single block after the table meta.
                Woff2Table[] tableHeaders = new Woff2Table[numTables];
                int          offset       = 0;

                for (int i = 0; i < numTables; i++)
                {
                    // Read the table entry:
                    byte flags = parser.ReadByte();

                    string tag;

                    int tagFlag = (flags & 63);

                    if (tagFlag == 63)
                    {
                        tag = parser.ReadTag();
                    }
                    else
                    {
                        tag = TagLookup[tagFlag];
                    }

                    ulong origLength      = parser.ReadBase128();
                    ulong transformLength = 0;

                    int transformVersion = (flags >> 6);                   //0-3

                    if (tag == "glyf" || tag == "loca")
                    {
                        // transform length:
                        transformLength = parser.ReadBase128();
                    }

                    offset += (int)origLength;

                    tableHeaders[i] = new Woff2Table(tag, offset, (int)transformLength, transformVersion);
                }
            }

            // All ok:
            return(true);
        }
		public static void Load(FontParser parser,int offset,FontFace font){
			
			// Got OS2:
			parser.ReadOS2=true;
			
			// Seek:
			parser.Position=offset;
			
			// version
			int version=parser.ReadUInt16();
			
			// xAvgCharWidth
			parser.ReadInt16();
			
			// usWeightClass
			int weight=parser.ReadUInt16();
			
			// usWidthClass
			parser.ReadUInt16();
			
			// fsType
			parser.ReadUInt16();
			
			// ySubscriptXSize
			parser.ReadInt16();
			
			// ySubscriptYSize
			parser.ReadInt16();
			
			// ySubscriptXOffset
			parser.ReadInt16();
			
			// ySubscriptYOffset
			parser.ReadInt16();
			
			// ySuperscriptXSize
			parser.ReadInt16();
			
			// ySuperscriptYSize
			parser.ReadInt16();
			
			// ySuperscriptXOffset
			parser.ReadInt16();
			
			// ySuperscriptYOffset
			parser.ReadInt16();
			
			// yStrikeoutSize
			font.StrikeSize=(float)parser.ReadInt16()/font.UnitsPerEmF;
			
			// yStrikeoutPosition
			font.StrikeOffset=(float)parser.ReadInt16()/font.UnitsPerEmF;
			
			// sFamilyClass
			parser.ReadInt16();
			
			// panose:
			/*
			byte panose=new byte[10];
			
			for(int i=0;i<10;i++){
				panose[i]=parser.ReadByte();
			}
			*/
			parser.Position+=10;
			
			// ulUnicodeRange1
			parser.ReadUInt32();
			
			// ulUnicodeRange2
			parser.ReadUInt32();
			
			// ulUnicodeRange3
			parser.ReadUInt32();
			
			// ulUnicodeRange4
			parser.ReadUInt32();
			
			// achVendID
			parser.ReadTag();
			
			// fsSelection
			int type=parser.ReadUInt16();
			
			bool italic=((type&1)==1);
			// bool strikeout=((type&16)==16);
			// bool underscore=((type&2)==2);
			bool oblique=((type&512)==512);
			bool bold=((type&32)==32);
			bool regular=((type&64)==64);
			bool useTypo=((type&128)==128);
			
			if(!bold || regular){
				// Must be regular:
				weight=400;
			}else if(weight==0){
				weight=700;
			}
			
			font.SetFlags(italic || oblique,weight);
			
			// usFirstCharIndex
			parser.ReadUInt16();
			
			// usLastCharIndex
			parser.ReadUInt16();
			
			// sTypoAscender
			float ascender=(float)parser.ReadInt16()/font.UnitsPerEmF;
			
			// sTypoDescender
			float descender=(float)parser.ReadInt16()/font.UnitsPerEmF;
			
			// sTypoLineGap
			float lineGap=((float)parser.ReadInt16()/font.UnitsPerEmF);
			
			// usWinAscent
			float wAscender=(float)parser.ReadUInt16()/font.UnitsPerEmF;
			
			// usWinDescent
			float wDescender=(float)parser.ReadUInt16()/font.UnitsPerEmF;
			
			// This is an awkward spec hack due to most windows programs
			// providing the wrong typo descender values.
		
			if(Fonts.UseOS2Metrics){
				
				if(useTypo){
					
					float halfGap=lineGap/2f;
				
					font.Ascender=ascender + halfGap;
					font.Descender=halfGap-descender;
					
					font.LineGap=font.Ascender + font.Descender;
					
				}else{
					font.Ascender=wAscender;
					font.Descender=wDescender;
					
					font.LineGap=font.Ascender + font.Descender;
				}
				
			}
			
			
			if (version >= 1){
				// ulCodePageRange1
				parser.ReadUInt32();
				
				// ulCodePageRange2
				parser.ReadUInt32();
			}
			
			if (version >= 2){
				// sxHeight
				parser.ReadInt16();
				
				// sCapHeight
				parser.ReadInt16();
				
				// usDefaultChar
				parser.ReadUInt16();
				
				// usBreakChar
				parser.ReadUInt16();
				
				// usMaxContent
				parser.ReadUInt16();
			}
			
			
		}