private unsafe FamilyCollection.CachedCharacterMetrics *LookupMetrics(int unicodeScalar) { if (unicodeScalar >= 0 && unicodeScalar <= FontFamilyMap.LastUnicodeScalar) { int pageTableOffset = _deviceFont->OffsetToCharacterMap; int *pageTable = (int *)CheckedPointer.Probe( pageTableOffset, CharacterMetricsDictionary.PageCount * sizeof(int) ); int i = pageTable[unicodeScalar >> CharacterMetricsDictionary.PageShift]; if (i != 0) { int *page = (int *)CheckedPointer.Probe( pageTableOffset + (i * sizeof(int)), CharacterMetricsDictionary.PageSize * sizeof(int) ); int offset = page[unicodeScalar & CharacterMetricsDictionary.PageMask]; if (offset != 0) { return((FamilyCollection.CachedCharacterMetrics *)CheckedPointer.Probe( offset, sizeof(FamilyCollection.CachedCharacterMetrics) )); } } } return(null); }
private static int ReadOpenTypeLong(CheckedPointer pointer) { unsafe { byte *readBuffer = (byte *)pointer.Probe(0, 4); int result = (int)((((((readBuffer[0] << 8) + readBuffer[1]) << 8) + readBuffer[2]) << 8) + readBuffer[3]); return(result); } }
/// <summary> /// The follwoing APIs extract OpenType variable types from OpenType font /// files. OpenType variables are stored big-endian, and the type are named /// as follows: /// Byte - signed 8 bit /// UShort - unsigned 16 bit /// Short - signed 16 bit /// ULong - unsigned 32 bit /// Long - signed 32 bit /// </summary> private static ushort ReadOpenTypeUShort(CheckedPointer pointer) { unsafe { byte * readBuffer = (byte *)pointer.Probe(0, 2); ushort result = (ushort)((readBuffer[0] << 8) + readBuffer[1]); return(result); } }
internal DeviceFont(CachedFontFamily cachedFamily, CheckedPointer deviceFont) { unsafe { _cachedFamily = cachedFamily; _deviceFont = (FamilyCollection.CachedDeviceFont *)deviceFont.Probe(0, sizeof(FamilyCollection.CachedDeviceFont)); _sizeInBytes = deviceFont.Size; } }
internal TrueTypeFontDriver(UnmanagedMemoryStream unmanagedMemoryStream, Uri sourceUri) { _sourceUri = sourceUri; _unmanagedMemoryStream = unmanagedMemoryStream; _fileStream = new CheckedPointer(unmanagedMemoryStream); try { CheckedPointer seekPosition = _fileStream; TrueTypeTags typeTag = (TrueTypeTags)ReadOpenTypeLong(seekPosition); seekPosition += 4; if (typeTag == TrueTypeTags.TTC_TTCF) { // this is a TTC file, we need to decode the ttc header _technology = FontTechnology.TrueTypeCollection; seekPosition += 4; // skip version _numFaces = ReadOpenTypeLong(seekPosition); } else if (typeTag == TrueTypeTags.OTTO) { _technology = FontTechnology.PostscriptOpenType; _numFaces = 1; } else { _technology = FontTechnology.TrueType; _numFaces = 1; } } catch (ArgumentOutOfRangeException e) { // convert exceptions from CheckedPointer to FileFormatException throw new FileFormatException(SourceUri, e); } }
private static int ReadOpenTypeLong(CheckedPointer pointer) { unsafe { byte * readBuffer = (byte *)pointer.Probe(0, 4); int result = (int)((((((readBuffer[0] << 8) + readBuffer[1]) << 8) + readBuffer[2]) << 8) + readBuffer[3]); return result; } }
private static ushort ReadOpenTypeUShort(CheckedPointer pointer) { unsafe { byte * readBuffer = (byte *)pointer.Probe(0, 2); ushort result = (ushort)((readBuffer[0] << 8) + readBuffer[1]); return result; } }
internal void SetFace(int faceIndex) { if (_technology == FontTechnology.TrueTypeCollection) { if (faceIndex < 0 || faceIndex >= _numFaces) { throw new ArgumentOutOfRangeException("faceIndex"); } } else { if (faceIndex != 0) { throw new ArgumentOutOfRangeException("faceIndex", SR.Get(SRID.FaceIndexValidOnlyForTTC)); } } try { CheckedPointer seekPosition = _fileStream + 4; if (_technology == FontTechnology.TrueTypeCollection) { // this is a TTC file, we need to decode the ttc header // skip version, num faces, OffsetTable array seekPosition += (4 + 4 + 4 * faceIndex); _directoryOffset = ReadOpenTypeLong(seekPosition); seekPosition = _fileStream + (_directoryOffset + 4); // 4 means that we skip the version number } _faceIndex = faceIndex; int numTables = ReadOpenTypeUShort(seekPosition); seekPosition += 2; // quick check for malformed fonts, see if numTables is too large // file size should be >= sizeof(offset table) + numTables * (sizeof(directory entry) + minimum table size (4)) long minimumFileSize = (4 + 2 + 2 + 2 + 2) + numTables * (4 + 4 + 4 + 4 + 4); if (_fileStream.Size < minimumFileSize) { throw new FileFormatException(SourceUri); } _tableDirectory = new DirectoryEntry[numTables]; // skip searchRange, entrySelector and rangeShift seekPosition += 6; // I can't use foreach here because C# disallows modifying the current value for (int i = 0; i < _tableDirectory.Length; ++i) { _tableDirectory[i].tag = (TrueTypeTags)ReadOpenTypeLong(seekPosition); seekPosition += 8; // skip checksum int offset = ReadOpenTypeLong(seekPosition); seekPosition += 4; int length = ReadOpenTypeLong(seekPosition); seekPosition += 4; _tableDirectory[i].pointer = _fileStream.CheckedProbe(offset, length); } } catch (ArgumentOutOfRangeException e) { // convert exceptions from CheckedPointer to FileFormatException throw new FileFormatException(SourceUri, e); } }
internal unsafe CheckedUShortPointer(ushort * pointer, int length) { _checkedPointer = new CheckedPointer(pointer, length * sizeof(ushort)); }
internal unsafe CheckedIntPointer(int * pointer, int length) { _checkedPointer = new CheckedPointer(pointer, length * sizeof(int)); }
internal unsafe CheckedCharPointer(char * pointer, int length) { _checkedPointer = new CheckedPointer(pointer, length * sizeof(char)); }
internal unsafe CheckedUShortPointer(ushort *pointer, int length) { _checkedPointer = new CheckedPointer(pointer, length * sizeof(ushort)); }
internal unsafe CheckedIntPointer(int *pointer, int length) { _checkedPointer = new CheckedPointer(pointer, length * sizeof(int)); }
internal unsafe CheckedCharPointer(char *pointer, int length) { _checkedPointer = new CheckedPointer(pointer, length * sizeof(char)); }