public static uint ReadOffset(TTF.TTFReader r, int offSize) { if (offSize == 1) { return((uint)(r.ReadUInt8() << 0)); } else if (offSize == 2) { return((uint)((r.ReadUInt8() << 8) | (r.ReadUInt8() << 0))); } else if (offSize == 3) { return((uint)((r.ReadUInt8() << 16) | (r.ReadUInt8() << 8) | (r.ReadUInt8() << 0))); } else { return((uint)((r.ReadUInt8() << 24) | (r.ReadUInt8() << 16) | (r.ReadUInt8() << 8) | (r.ReadUInt8() << 0))); } }
public uint ReadOffset(TTF.TTFReader r) { byte c = ReadOffSize(r); if (c == 1) { return((uint)(r.ReadUInt8() << 0)); } else if (c == 2) { return((uint)((r.ReadUInt8() << 8) | (r.ReadUInt8() << 0))); } else if (c == 3) { return((uint)((r.ReadUInt8() << 16) | (r.ReadUInt8() << 8) | (r.ReadUInt8() << 0))); } else { return((uint)((r.ReadUInt8() << 24) | (r.ReadUInt8() << 16) | (r.ReadUInt8() << 8) | (r.ReadUInt8() << 0))); } }
static public byte ReadOffSize(TTF.TTFReader r) { return(r.ReadUInt8()); }
// duplicate of TTFReader.ReadUInt16() static public ushort ReadCard16(TTF.TTFReader r) { return((ushort)(r.ReadUInt8() << 8 | r.ReadUInt8())); }
static public byte ReadCard8(TTF.TTFReader r) { return(r.ReadUInt8()); }
/// <summary> /// Read an operand value from a Charstring Type 2 byte array.. /// </summary> /// <param name="r">The reader, with the read position at the Charstring Operand to read.</param> /// <returns>The loaded operand.</returns> /// /// <remarks>This is for Charstring data. For other similar formats such as CFFs or CFF2s, make sure /// the correct Read*() function is used.</remarks> public static Operand ReadType2Op(TTF.TTFReader r) { byte b0 = r.ReadUInt8(); if (b0 <= 11) { return(new Operand(b0, Type.Operator)); } if (b0 == 12) { byte b1 = r.ReadUInt8(); return(new Operand((b0 << 8) | b1, Type.Operator)); } if (b0 <= 18) { return(new Operand(b0, Type.Operator)); } // hintmask and cntrmask if (b0 <= 20) { return(new Operand(b0, Type.Operator)); } if (b0 <= 27) { return(new Operand(b0, Type.Operator)); } if (b0 == 28) { byte b1 = r.ReadUInt8(); byte b2 = r.ReadUInt8(); // This is a two's complement signed number, so we can't just // shift and OR them as an int, but also have to be weary of // the sign bit and two's complement conversion if it's negative. short merged = (short)(b1 << 8 | b2); return(new Operand(merged)); } if (b0 <= 31) { return(new Operand(b0, Type.Operator)); } if (b0 <= 246) { return(new Operand(b0 - 139, Type.Int)); } if (b0 <= 250) { int b1 = r.ReadUInt8(); return(new Operand((b0 - 247) * 256 + b1 + 108)); } if (b0 <= 254) { int b1 = r.ReadUInt8(); return(new Operand(-(b0 - 251) * 256 - b1 - 108)); } if (b0 == 255) { // Doc says this is 16-bit signed integer with 16 bits of fraction. // So this might actually be a fixed point float. int b1 = r.ReadUInt8(); int b2 = r.ReadUInt8(); int b3 = r.ReadUInt8(); int b4 = r.ReadUInt8(); return(new Operand((b1 << 24) | (b2 << 16) | (b3 << 8) | (b4 << 0))); } // This really isn't possible, all 255 value of the byte should be covered. return(Error()); }
/// <summary> /// Read an operand value from a CFF file. /// </summary> /// <param name="r">The reader, with the read position at the Operand to read.</param> /// <returns>The loaded Operand value.</returns> /// <remarks>This is for CFF (DICT) values. For other similar formats such as CFF2s or Charstrings, make sure /// the correct Read*() function is used.</remarks> public static Operand Read(TTF.TTFReader r) { // The results are all signed, so might as well // work on an int level from the beginning. // Personal note - this compressed number representation is // pure insanity. // (12/24/2020) byte b0 = r.ReadUInt8(); if (b0 <= 21) { if (b0 == 12) { return(new Operand((b0 << 8) | r.ReadUInt8(), Type.Operator)); } else { return(new Operand(b0, Type.Operator)); } } else if (b0 == 30) { // AUGHHHHHHHHHH! Who thinks of this!? The code isn't going to // even try to be clever or optimized, we're just "getting by" // with these floating point values... string str = ""; bool cont = true; while (cont) { const int upperBitMask = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7); const int lowerBitMask = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3); int c = r.ReadUInt8(); int upperBit = (c & upperBitMask) >> 4; int lowerBit = c & lowerBitMask; foreach (int i in new int[] { upperBit, lowerBit }) { switch (i) { case 0: str += '0'; break; case 1: str += '1'; break; case 2: str += '2'; break; case 3: str += '3'; break; case 4: str += '4'; break; case 5: str += '5'; break; case 6: str += '6'; break; case 7: str += '7'; break; case 8: str += '8'; break; case 9: str += '9'; break; case 10: str += '.'; break; // a case 11: str += 'E'; break; // b case 12: str += "E-"; break; // c case 13: break; // d (reserved) case 14: str += '-'; break; // e case 15: // f cont = false; break; } } } float f; float.TryParse(str, out f); return(new Operand(f)); } if (b0 == 28) { int b1 = r.ReadUInt8(); int b2 = r.ReadUInt8(); return(new Operand(b1 << 8 | b2)); } else if (b0 == 29) { int b1 = r.ReadUInt8(); int b2 = r.ReadUInt8(); int b3 = r.ReadUInt8(); int b4 = r.ReadUInt8(); return(new Operand((b1 << 24) | (b2 << 16) | (b3 << 8) | (b4 << 0))); } else if (b0 >= 32 && b0 <= 246) { return(new Operand(b0 - 139)); } else if (b0 >= 247 && b0 <= 250) { int b1 = r.ReadUInt8(); return(new Operand((b0 - 247) * 256 + b1 + 108)); } else if (b0 >= 251 && b0 <= 254) { int b1 = r.ReadUInt8(); return(new Operand(-(b0 - 251) * 256 - b1 - 108)); } return(Error()); }