/// <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); }
/// <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)); }
/// <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)); } }
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); }