using System;
using System.Runtime.InteropServices;
namespace FastReport.Fonts
{
///
/// OS/2 and Windows Metrics table
///
public class OS2WindowsMetricsClass : TrueTypeTable
{
#region "Type definition"
///
/// Description of FontTextMetric structure
///
[StructLayout(LayoutKind.Sequential)]
public struct FontTextMetric
{
public int tmHeight;
public int tmAscent;
public int tmDescent;
public int tmInternalLeading;
public int tmExternalLeading;
public int tmAveCharWidth;
public int tmMaxCharWidth;
public int tmWeight;
public int tmOverhang;
public int tmDigitizedAspectX;
public int tmDigitizedAspectY;
public char tmFirstChar;
public char tmLastChar;
public char tmDefaultChar;
public char tmBreakChar;
public byte tmItalic;
public byte tmUnderlined;
public byte tmStruckOut;
public byte tmPitchAndFamily;
public byte tmCharSet;
}
///
/// Description of FontPanose structure
///
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct FontPanose
{
public byte bFamilyType;
public byte bSerifStyle;
public byte bWeight;
public byte bProportion;
public byte bContrast;
public byte bStrokeVariation;
public byte ArmStyle;
public byte bLetterform;
public byte bMidline;
public byte bXHeight;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct OS2WindowsMetrics
{
public ushort Version; // version number 0x0004
public short xAvgCharWidth;
public ushort usWeightClass;
public ushort usWidthClass;
public ushort fsType;
public short ySubscriptXSize;
public short ySubscriptYSize;
public short ySubscriptXOffset;
public short ySubscriptYOffset;
public short ySuperscriptXSize;
public short ySuperscriptYSize;
public short ySuperscriptXOffset;
public short ySuperscriptYOffset;
public short yStrikeoutSize;
public short yStrikeoutPosition;
public short sFamilyClass;
#if false
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] panose; // = new byte[10];
#else
public FontPanose panose;
#endif
public uint ulUnicodeRange1;
public uint ulUnicodeRange2;
public uint ulUnicodeRange3;
public uint ulUnicodeRange4;
#if true
public byte achVendID1;
public byte achVendID2;
public byte achVendID3;
public byte achVendID4;
#else
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] achVendID; // = new vyte[4];
#endif
public ushort fsSelection;
public ushort usFirstCharIndex;
public ushort usLastCharIndex;
public short sTypoAscender;
public short sTypoDescender;
public short sTypoLineGap;
public ushort usWinAscent;
public ushort usWinDescent;
public uint ulCodePageRange1;
public uint ulCodePageRange2;
public short sxHeight;
public short sCapHeight;
public ushort usDefaultChar;
public ushort usBreakChar;
public ushort usMaxContext;
}
#endregion
internal OS2WindowsMetrics win_metrix;
internal override void Load(FontStream stream)
{
stream.Position = this.Offset;
win_metrix.Version = stream.ReadUInt16(); // version number 0x0004
//public short
win_metrix.xAvgCharWidth = stream.ReadInt16();
win_metrix.usWeightClass = stream.ReadUInt16();
win_metrix.usWidthClass = stream.ReadUInt16();
win_metrix.fsType = stream.ReadUInt16();
win_metrix.ySubscriptXSize = stream.ReadInt16();
win_metrix.ySubscriptYSize = stream.ReadInt16();
win_metrix.ySubscriptXOffset = stream.ReadInt16();
win_metrix.ySubscriptYOffset = stream.ReadInt16();
win_metrix.ySuperscriptXSize = stream.ReadInt16();
win_metrix.ySuperscriptYSize = stream.ReadInt16();
win_metrix.ySuperscriptXOffset = stream.ReadInt16();
win_metrix.ySuperscriptYOffset = stream.ReadInt16();
win_metrix.yStrikeoutSize = stream.ReadInt16();
win_metrix.yStrikeoutPosition = stream.ReadInt16();
win_metrix.sFamilyClass = stream.ReadInt16();
//FontPanose
win_metrix.panose.bFamilyType = stream.ReadByte();
win_metrix.panose.bSerifStyle = stream.ReadByte();
win_metrix.panose.bWeight = stream.ReadByte();
win_metrix.panose.bProportion = stream.ReadByte();
win_metrix.panose.bContrast = stream.ReadByte();
win_metrix.panose.bStrokeVariation = stream.ReadByte();
win_metrix.panose.ArmStyle = stream.ReadByte();
win_metrix.panose.bLetterform = stream.ReadByte();
win_metrix.panose.bMidline = stream.ReadByte();
win_metrix.panose.bXHeight = stream.ReadByte();
win_metrix.ulUnicodeRange1 = stream.ReadUInt32();
win_metrix.ulUnicodeRange2 = stream.ReadUInt32();
win_metrix.ulUnicodeRange3 = stream.ReadUInt32();
win_metrix.ulUnicodeRange4 = stream.ReadUInt32();
win_metrix.achVendID1 = stream.ReadByte();
win_metrix.achVendID2 = stream.ReadByte();
win_metrix.achVendID3 = stream.ReadByte();
win_metrix.achVendID4 = stream.ReadByte();
win_metrix.fsSelection = stream.ReadUInt16();
win_metrix.usFirstCharIndex = stream.ReadUInt16();
win_metrix.usLastCharIndex = stream.ReadUInt16();
win_metrix.sTypoAscender = stream.ReadInt16();
win_metrix.sTypoDescender = stream.ReadInt16();
win_metrix.sTypoLineGap = stream.ReadInt16();
win_metrix.usWinAscent = stream.ReadUInt16();
win_metrix.usWinDescent = stream.ReadUInt16();
win_metrix.ulCodePageRange1 = stream.ReadUInt32();
win_metrix.ulCodePageRange2 = stream.ReadUInt32();
win_metrix.sxHeight = stream.ReadInt16();
win_metrix.sCapHeight = stream.ReadInt16();
win_metrix.usDefaultChar = stream.ReadUInt16();
win_metrix.usBreakChar = stream.ReadUInt16();
win_metrix.usMaxContext = stream.ReadUInt16();
}
internal override uint Save(FontStream source_not_used, FontStream stream, uint offset)
{
stream.Position = offset;
stream.WriteUInt16(win_metrix.Version); // version number 0x0004
stream.WriteInt16(win_metrix.xAvgCharWidth);
stream.WriteUInt16(win_metrix.usWeightClass);
stream.WriteUInt16(win_metrix.usWidthClass);
stream.WriteUInt16(win_metrix.fsType);
stream.WriteInt16(win_metrix.ySubscriptXSize);
stream.WriteInt16(win_metrix.ySubscriptYSize);
stream.WriteInt16(win_metrix.ySubscriptXOffset);
stream.WriteInt16(win_metrix.ySubscriptYOffset);
stream.WriteInt16(win_metrix.ySuperscriptXSize);
stream.WriteInt16(win_metrix.ySuperscriptYSize);
stream.WriteInt16(win_metrix.ySuperscriptXOffset);
stream.WriteInt16(win_metrix.ySuperscriptYOffset);
stream.WriteInt16(win_metrix.yStrikeoutSize);
stream.WriteInt16(win_metrix.yStrikeoutPosition);
stream.WriteInt16(win_metrix.sFamilyClass);
stream.WriteByte(win_metrix.panose.bFamilyType);
stream.WriteByte(win_metrix.panose.bSerifStyle);
stream.WriteByte(win_metrix.panose.bWeight);
stream.WriteByte(win_metrix.panose.bProportion);
stream.WriteByte(win_metrix.panose.bContrast);
stream.WriteByte(win_metrix.panose.bStrokeVariation);
stream.WriteByte(win_metrix.panose.ArmStyle);
stream.WriteByte(win_metrix.panose.bLetterform);
stream.WriteByte(win_metrix.panose.bMidline);
stream.WriteByte(win_metrix.panose.bXHeight);
stream.WriteUInt32(win_metrix.ulUnicodeRange1);
stream.WriteUInt32(win_metrix.ulUnicodeRange2);
stream.WriteUInt32(win_metrix.ulUnicodeRange3);
stream.WriteUInt32(win_metrix.ulUnicodeRange4);
#if true
stream.WriteByte(win_metrix.achVendID1);
stream.WriteByte(win_metrix.achVendID2);
stream.WriteByte(win_metrix.achVendID3);
stream.WriteByte(win_metrix.achVendID4);
#else
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] achVendID; // = new vyte[4];
#endif
stream.WriteUInt16(win_metrix.fsSelection);
stream.WriteUInt16(win_metrix.usFirstCharIndex);
stream.WriteUInt16(win_metrix.usLastCharIndex);
stream.WriteInt16(win_metrix.sTypoAscender);
stream.WriteInt16(win_metrix.sTypoDescender);
stream.WriteInt16(win_metrix.sTypoLineGap);
stream.WriteUInt16(win_metrix.usWinAscent);
stream.WriteUInt16(win_metrix.usWinDescent);
stream.WriteUInt32(win_metrix.ulCodePageRange1);
stream.WriteUInt32(win_metrix.ulCodePageRange2);
stream.WriteInt16(win_metrix.sxHeight);
stream.WriteInt16(win_metrix.sCapHeight);
stream.WriteUInt16(win_metrix.usDefaultChar);
stream.WriteUInt16(win_metrix.usBreakChar);
stream.WriteUInt16(win_metrix.usMaxContext);
offset = (offset + this.Length + 3) & 0xfffffffc;
return offset;
}
// Public properties
#pragma warning disable CS3001, CS3002, CS3003, CS1591
public bool IsBold
{
get
{
// return win_metrix.usWeightClass >= 700;
return (win_metrix.fsSelection & 0x20) != 0;
}
}
public ushort Ascent { get { return win_metrix.usWinAscent; } }
public ushort Descent { get { return win_metrix.usWinDescent; } }
public short LineGap { get { return win_metrix.sTypoLineGap; } }
public short AvgCharWidth { get { return win_metrix.xAvgCharWidth; } }
public ushort Weight { get { return win_metrix.usWeightClass; } }
public ushort WidthClass { get { return win_metrix.usWidthClass; } }
public short Height { get { return win_metrix.sxHeight; } }
public ushort BreakChar { get { return win_metrix.usBreakChar; } }
public ushort DefaultChar { get { return win_metrix.usDefaultChar; } }
public ushort FirstCharIndex { get { return win_metrix.usFirstCharIndex; } }
public ushort LastCharIndex { get { return win_metrix.usLastCharIndex; } }
public ushort LicensingRights { get { return win_metrix.fsType; } }
public OS2WindowsMetricsClass.FontPanose Panose { get { return win_metrix.panose; } }
public OS2WindowsMetricsClass(TrueTypeTable src) : base(src) { }
public uint UnicodeRange1 { get { return win_metrix.ulUnicodeRange1; } }
public uint UnicodeRange2 { get { return win_metrix.ulUnicodeRange2; } }
public uint UnicodeRange3 { get { return win_metrix.ulUnicodeRange3; } }
public uint UnicodeRange4 { get { return win_metrix.ulUnicodeRange4; } }
public short FamilyClass { get { return win_metrix.sFamilyClass; } }
public ushort Selection { get { return win_metrix.fsSelection; } }
public uint CodepageRange1 { get { return win_metrix.ulCodePageRange1; } }
public uint CodepageRange2 { get { return win_metrix.ulCodePageRange2; } }
public string VendorID
{
get
{
return "" +
(char)win_metrix.achVendID1 +
(char)win_metrix.achVendID2 +
(char)win_metrix.achVendID3 +
(char)win_metrix.achVendID4;
}
}
#pragma warning restore
}
}