Ejemplo n.º 1
0
 /**
  * Reads a binary CharString.
  */
 private Token ReadCharString(int length)
 {
     buffer.ReadByte(); // space
     byte[] data = new byte[length];
     buffer.Read(data);
     return(new Token(data, TokenKind.CHARSTRING));
 }
Ejemplo n.º 2
0
        public static ICCProfile Load(byte[] data)
        {
            var profile = new ICCProfile();
            var header  = new ICCHeader();
            var buffer  = new Bytes.Buffer(data);

            header.ProfileSize                  = buffer.ReadUnsignedInt();
            header.CMMTypeSignature             = buffer.ReadUnsignedInt();
            header.ProfileVersionNumber.Major   = (byte)buffer.ReadByte();
            header.ProfileVersionNumber.Minor   = (byte)buffer.ReadByte();
            header.ProfileVersionNumber.Reserv1 = (byte)buffer.ReadByte();
            header.ProfileVersionNumber.Reserv2 = (byte)buffer.ReadByte();
            header.ProfileDeviceClassSignature  = (ICCProfileDeviceSignatures)buffer.ReadUnsignedInt();
            header.ColorSpaceOfData             = (ICCColorSpaceSignatures)buffer.ReadUnsignedInt();
            header.ProfileConnectionSpace       = (ICCColorSpaceSignatures)buffer.ReadUnsignedInt();
            header.DateCreated.Load(buffer);
            header.acsp = buffer.ReadUnsignedInt();
            header.PrimaryPlatformSignature = (ICCPrimaryPlatformSignatures)buffer.ReadUnsignedInt();
            header.Flags = (ICCProfileFlags)buffer.ReadUnsignedInt();
            header.DeviceManufacturer = buffer.ReadUnsignedInt();
            header.DeviceModel        = buffer.ReadUnsignedInt();
            header.DeviceAttributes.Load(buffer);
            header.RenderingIntent.Intents  = buffer.ReadUnsignedShort();
            header.RenderingIntent.Reserved = buffer.ReadUnsignedShort();
            header.XYZ.Load(buffer);
            header.ProfileCreatorSignature = buffer.ReadUnsignedInt();
            header.FutureUse = new byte[44];
            buffer.Read(header.FutureUse);
            profile.Header = header;
            var tagCount = buffer.ReadUnsignedInt();

            for (int i = 0; i < tagCount; i++)
            {
                var tag = new ICCTagTable();
                tag.Signature               = (ICCTagTypes)buffer.ReadUnsignedInt();
                tag.Offset                  = buffer.ReadUnsignedInt();
                tag.ElementSize             = buffer.ReadUnsignedInt();
                profile.Tags[tag.Signature] = tag;
            }
            foreach (var tagTable in profile.Tags.Values)
            {
                buffer.Seek(tagTable.Offset);
                var key = buffer.ReadUnsignedInt();
                if (Types.TryGetValue(key, out var type))
                {
                    tagTable.Tag         = (ICCTag)Activator.CreateInstance(type, tagTable);
                    tagTable.Tag.Profile = profile;
                    tagTable.Tag.Load(buffer);
                }
            }
            return(profile);
        }
Ejemplo n.º 3
0
 /**
  * Read the pdf input.
  * @param in    The input.
  * @return Returns the pdf-array.
  * @throws IOException if an IO-error occurs.
  */
 private byte[] ReadPfbInput(Bytes.Buffer input)
 {
     // copy into an array
     using (var output = new MemoryStream())
     {
         byte[] tmpbuf     = new byte[BUFFER_SIZE];
         int    amountRead = -1;
         while ((amountRead = input.Read(tmpbuf)) > 0)
         {
             output.Write(tmpbuf, 0, amountRead);
         }
         return(output.ToArray());
     }
 }
Ejemplo n.º 4
0
        private long CopyBytes(Bytes.Buffer input, Stream os, long newOffset, long lastOffset, int count)
        {
            // skip over from last original offset
            long nskip = newOffset - lastOffset;

            if (nskip != input.Skip(nskip))
            {
                throw new EndOfStreamException("Unexpected EOF exception parsing glyphId of hmtx table.");
            }
            byte[] buf = new byte[count];
            if (count != input.Read(buf, 0, count))
            {
                throw new EndOfStreamException("Unexpected EOF exception parsing glyphId of hmtx table.");
            }
            os.Write(buf, 0, count);
            return(newOffset + count);
        }
Ejemplo n.º 5
0
        /**
         * Parse the pfb-array.
         * @param pfb   The pfb-Array
         * @throws IOException in an IO-error occurs.
         */
        private void ParsePfb(byte[] pfb)
        {
            using (var input = new Bytes.Buffer(pfb))
            {
                pfbdata = new byte[pfb.Length - PFB_HEADER_LENGTH];
                lengths = new int[PFB_RECORDS.Length];
                int pointer = 0;
                for (int records = 0; records < PFB_RECORDS.Length; records++)
                {
                    if (input.ReadByte() != START_MARKER)
                    {
                        throw new IOException("Start marker missing");
                    }

                    if (input.ReadByte() != PFB_RECORDS[records])
                    {
                        throw new IOException("Incorrect record type");
                    }

                    int size = input.ReadByte();
                    size            += input.ReadByte() << 8;
                    size            += input.ReadByte() << 16;
                    size            += input.ReadByte() << 24;
                    lengths[records] = size;
                    if (pointer >= pfbdata.Length)
                    {
                        throw new EndOfStreamException("attempted to read past EOF");
                    }
                    int got = input.Read(pfbdata, pointer, size);
                    if (got < 0)
                    {
                        throw new EndOfStreamException();
                    }
                    pointer += got;
                }
            }
        }
Ejemplo n.º 6
0
        // never returns null
        private byte[] BuildGlyfTable(long[] newOffsets)
        {
            GlyphTable g = ttf.Glyph;

            long[]       offsets = ttf.IndexToLocation.Offsets;
            MemoryStream bos     = new MemoryStream();

            using (Bytes.Buffer input = ttf.OriginalData)
            {
                long isResult = input.Skip(g.Offset);

                if (isResult.CompareTo(g.Offset) != 0)
                {
                    Debug.WriteLine($"debug: Tried skipping {g.Offset} bytes but skipped only {isResult} bytes");
                }

                long prevEnd   = 0;  // previously read glyph offset
                long newOffset = 0;  // new offset for the glyph in the subset font
                int  newGid    = 0;  // new GID in subset font

                // for each glyph in the subset
                foreach (int gid in glyphIds)
                {
                    long offset = offsets[gid];
                    long length = offsets[gid + 1] - offset;

                    newOffsets[newGid++] = newOffset;
                    isResult             = input.Skip(offset - prevEnd);

                    if (isResult.CompareTo(offset - prevEnd) != 0)
                    {
                        Debug.WriteLine($"debug: Tried skipping {(offset - prevEnd)} bytes but skipped only {isResult} bytes");
                    }

                    sbyte[] buf = new sbyte[(int)length];
                    isResult = input.Read(buf);

                    if (isResult.CompareTo(length) != 0)
                    {
                        Debug.WriteLine($"debug: Tried reading {length} bytes but only {isResult} bytes read");
                    }

                    // detect glyph type
                    if (buf.Length >= 2 && buf[0] == -1 && buf[1] == -1)
                    {
                        // compound glyph
                        int off = 2 * 5;
                        int flags;
                        do
                        {
                            // flags
                            flags = (buf[off] & 0xff) << 8 | buf[off + 1] & 0xff;
                            off  += 2;

                            // glyphIndex
                            int componentGid = (buf[off] & 0xff) << 8 | buf[off + 1] & 0xff;
                            if (!glyphIds.Contains(componentGid))
                            {
                                glyphIds.Add(componentGid);
                            }

                            int newComponentGid = GetNewGlyphId(componentGid);
                            buf[off]     = (sbyte)((uint)(newComponentGid) >> 8);
                            buf[off + 1] = (sbyte)newComponentGid;
                            off         += 2;

                            // ARG_1_AND_2_ARE_WORDS
                            if ((flags & 1 << 0) != 0)
                            {
                                off += 2 * 2;
                            }
                            else
                            {
                                off += 2;
                            }
                            // WE_HAVE_A_TWO_BY_TWO
                            if ((flags & 1 << 7) != 0)
                            {
                                off += 2 * 4;
                            }
                            // WE_HAVE_AN_X_AND_Y_SCALE
                            else if ((flags & 1 << 6) != 0)
                            {
                                off += 2 * 2;
                            }
                            // WE_HAVE_A_SCALE
                            else if ((flags & 1 << 3) != 0)
                            {
                                off += 2;
                            }
                        }while ((flags & 1 << 5) != 0); // MORE_COMPONENTS

                        // WE_HAVE_INSTRUCTIONS
                        if ((flags & 0x0100) == 0x0100)
                        {
                            // USHORT numInstr
                            int numInstr = (buf[off] & 0xff) << 8 | buf[off + 1] & 0xff;
                            off += 2;

                            // BYTE instr[numInstr]
                            off += numInstr;
                        }

                        // write the compound glyph
                        bos.Write((byte[])(Array)buf, 0, off);

                        // offset to start next glyph
                        newOffset += off;
                    }
                    else if (buf.Length > 0)
                    {
                        // copy the entire glyph
                        bos.Write((byte[])(Array)buf, 0, buf.Length);

                        // offset to start next glyph
                        newOffset += buf.Length;
                    }

                    // 4-byte alignment
                    if (newOffset % 4 != 0)
                    {
                        int len = 4 - (int)(newOffset % 4);
                        bos.Write(PAD_BUF, 0, len);
                        newOffset += len;
                    }

                    prevEnd = offset + length;
                }
                newOffsets[newGid++] = newOffset;
            }

            return(bos.ToArray());
        }
Ejemplo n.º 7
0
        /**
         * Resolve compound glyph references.
         */
        private void AddCompoundReferences()
        {
            if (hasAddedCompoundReferences)
            {
                return;
            }
            hasAddedCompoundReferences = true;

            bool hasNested;

            do
            {
                GlyphTable   g             = ttf.Glyph;
                long[]       offsets       = ttf.IndexToLocation.Offsets;
                Bytes.Buffer input         = ttf.OriginalData;
                ISet <int>   glyphIdsToAdd = null;
                try
                {
                    long isResult = input.Skip(g.Offset);

                    if (isResult.CompareTo(g.Offset) != 0)
                    {
                        Debug.WriteLine($"debug: Tried skipping {g.Offset} bytes but skipped only {isResult} bytes");
                    }

                    long lastOff = 0L;
                    foreach (int glyphId in glyphIds)
                    {
                        long offset = offsets[glyphId];
                        long len    = offsets[glyphId + 1] - offset;
                        isResult = input.Skip(offset - lastOff);

                        if (isResult.CompareTo(offset - lastOff) != 0)
                        {
                            Debug.WriteLine($"debug: Tried skipping {(offset - lastOff)} bytes but skipped only {isResult} bytes");
                        }

                        sbyte[] buf = new sbyte[(int)len];
                        isResult = input.Read(buf);

                        if (isResult.CompareTo(len) != 0)
                        {
                            Debug.WriteLine($"debug: Tried reading {len} bytes but only {isResult} bytes read");
                        }

                        // rewrite glyphIds for compound glyphs
                        if (buf.Length >= 2 && buf[0] == -1 && buf[1] == -1)
                        {
                            int off = 2 * 5;
                            int flags;
                            do
                            {
                                flags = (buf[off] & 0xff) << 8 | buf[off + 1] & 0xff;
                                off  += 2;
                                int ogid = (buf[off] & 0xff) << 8 | buf[off + 1] & 0xff;
                                if (!glyphIds.Contains(ogid))
                                {
                                    if (glyphIdsToAdd == null)
                                    {
                                        glyphIdsToAdd = new HashSet <int>();
                                    }
                                    glyphIdsToAdd.Add(ogid);
                                }
                                off += 2;
                                // ARG_1_AND_2_ARE_WORDS
                                if ((flags & 1 << 0) != 0)
                                {
                                    off += 2 * 2;
                                }
                                else
                                {
                                    off += 2;
                                }
                                // WE_HAVE_A_TWO_BY_TWO
                                if ((flags & 1 << 7) != 0)
                                {
                                    off += 2 * 4;
                                }
                                // WE_HAVE_AN_X_AND_Y_SCALE
                                else if ((flags & 1 << 6) != 0)
                                {
                                    off += 2 * 2;
                                }
                                // WE_HAVE_A_SCALE
                                else if ((flags & 1 << 3) != 0)
                                {
                                    off += 2;
                                }
                            }while ((flags & 1 << 5) != 0); // MORE_COMPONENTS
                        }
                        lastOff = offsets[glyphId + 1];
                    }
                }
                finally
                {
                    input.Dispose();
                }
                if (glyphIdsToAdd != null)
                {
                    glyphIds.AddAll(glyphIdsToAdd);
                }
                hasNested = glyphIdsToAdd != null;
            }while (hasNested);
        }