예제 #1
0
        public void Write(Stream file, Document doc)
        {
            ObjectReference fileref = doc.GetReference(this);

            fileref.ByteOffset = file.Position;

            StringBuilder sb = new StringBuilder();

            sb.Append(fileref.Id);
            sb.Append(" obj\r\n<<");
            sb.Append("/Filter /FlateDecode\r\n");

            Stream compressed = Compression.Compress(_bits);

            sb.Append("/Length ");
            sb.Append(compressed.Length);
            sb.Append(" /Length1 ");
            sb.Append(compressed.Length);
            sb.Append(">>\r\n");

            sb.Append("stream\r\n");
            Document.WriteData(file, sb.ToString());

            compressed.CopyTo(file);

            sb.Clear();
            sb.Append("\r\nendstream\r\nendobj\r\n");
            Document.WriteData(file, sb.ToString());
        }
예제 #2
0
        public void Write(Stream file, Document doc, ushort unitsPerEm)
        {
            ObjectReference wref = doc.GetReference(this);

            wref.ByteOffset = file.Position;

            StringBuilder sb = new StringBuilder();

            sb.Append(wref.Id);
            sb.Append(" obj\r\n[ ");

            //	Each entry in the array is of one of these formats:
            //
            //		c [ w1 w2 ... wn ]		- for individual widths
            //		c1 cn w					- for a range of same widths
            //
            //	At least for the proof of concept let's just do it
            //	the easy way and specify each individual width.
            for (int x = 0; x < _widths.Length; ++x)
            {
                sb.Append(x);
                sb.Append("[");
                //	The raw widths are in font units, but we want thousandths
                //	of a text unit in the dictionary. See page 414.
                sb.Append(_widths[x] * 1000 / unitsPerEm);
                sb.Append("] ");
            }

            sb.Append(" ]\r\nendobj\r\n");
            Document.WriteData(file, sb.ToString());
        }
예제 #3
0
        public void Write(Stream file, ObjectReference reference, Document doc)
        {
            reference.ByteOffset = file.Position;

            StringBuilder sb = new StringBuilder();

            sb.Append(reference.Id);
            sb.Append(" obj\r\n");
            sb.Append("<<\r\n");
            sb.Append("/Type /Pages\r\n");

            sb.Append("/Kids [ ");
            foreach (Page page in this)
            {
                ObjectReference pageref = doc.GetReference(page);
                sb.Append(pageref.Reference);
                sb.Append(" ");
            }
            sb.Append(" ]\r\n");

            sb.Append("/Count ");
            sb.Append(this.Count);
            sb.Append("\r\n");

//			sb.Append("/MediaBox ");
//			sb.Append(generator.Document.DefaultPageSize.Specification);
//			sb.Append("\r\n");

            sb.Append(">>\r\n");
            sb.Append("endobj\r\n");

            Document.WriteData(file, sb.ToString());
        }
예제 #4
0
        public void Write(Stream file, ObjectReference streamRef, List <ContentFragment> fragments)
        {
            streamRef.ByteOffset = file.Position;

            //	We need to know the full length of the stream so that we can
            //	write it into the object header
            byte[] fullStream = new byte[0];
            foreach (ContentFragment fragment in fragments)
            {
                int    pos        = fullStream.Length;
                byte[] fragStream = fragment.GetStream();
                int    length     = fullStream.Length + fragStream.Length;
                System.Array.Resize(ref fullStream, length);
                fragStream.CopyTo(fullStream, pos);
            }


            StringBuilder sb = new StringBuilder();

            sb.Append(streamRef.Id);
            sb.Append(" obj\r\n<</Length ");
            sb.Append(fullStream.Length);
            sb.Append(">>\r\nstream\r\n");
            Document.WriteData(file, sb.ToString());

            file.Write(fullStream, 0, fullStream.Length);
            Document.WriteData(file, "\r\nendstream\r\nendobj\r\n");
        }
예제 #5
0
        public override void Write(Stream file, Document doc)
        {
            ObjectReference fontref = doc.GetReference(this);

            fontref.ByteOffset = file.Position;

            StringBuilder sb = new StringBuilder();

            sb.Append(fontref.Id);
            sb.Append(" obj\r\n");
            sb.Append("<<\r\n/Type /Font\r\n");
            sb.Append("/Subtype /Type1\r\n");

            //	/Name is obsolete - see page 413 in the PDF spec
//			sb.Append("/Name /");
//			sb.Append(_name); //TODO: escape spaces etc.
//			sb.Append("\r\n");

            sb.Append("/BaseFont /");
            sb.Append(_underlying.PostScriptName);             //TODO: escape spaces etc.
            sb.Append("\r\n");

            //	Specify no encoding for "symbolic" fonts
            if (_underlying.Encoding != null)
            {
                sb.Append("/Encoding /");
                sb.Append(_underlying.Encoding);
                sb.Append("\r\n");
            }

            sb.Append("/FontDescriptor ");
            sb.Append(doc.GetReference(_descriptor).Reference);
            sb.Append("\r\n");

            sb.Append("/FirstChar ");
            sb.Append(_underlying.FirstChar);
            sb.Append("\r\n");

            sb.Append("/LastChar ");
            sb.Append(_underlying.LastChar);
            sb.Append("\r\n");

            sb.Append("/Widths ");
            sb.Append(doc.GetReference(_widths).Reference);
            sb.Append("\r\n");

            sb.Append(">>\r\nendobj\r\n");
            Document.WriteData(file, sb.ToString());

            _descriptor.Write(file, doc);
            //_fontFile?.Write(file,generator); in a Type 1 font there is no font file
            _widths.Write(file, doc, _underlying.UnitsPerEm);

            //	Typically a Type 1 font doesn't need a ToUnicode map because
            //	it uses a standard encoding
            //_toUnicode.Write(file,generator);
        }
예제 #6
0
        public void Write(Stream file, Document doc)
        {
            ObjectReference thisref = doc.GetReference(this);

            thisref.ByteOffset = file.Position;

            ObjectReference realref = doc.GetReference(_realFont);

            StringBuilder sb = new StringBuilder();

            sb.Append(thisref.Id);
            sb.Append(" obj\r\n<<\r\n");

            sb.Append("/Type /Font\r\n");
            sb.Append("/Subtype /CIDFontType2\r\n");

            sb.Append("/BaseFont /");
            sb.Append(_realFont.PostScriptName);
            sb.Append("\r\n");

            sb.Append("/CIDSystemInfo <</Ordering(Identity) /Registry(Adobe) /Supplement 0>>\r\n");

            //	Use the real font's descriptor
            ObjectReference descref = doc.GetReference(_realFont.Descriptor);

            sb.Append("/FontDescriptor ");
            sb.Append(descref.Reference);
            sb.Append("\r\n");

            sb.Append("/CIDToGIDMap /Identity\r\n");

            //	If we haven't already got our widths, get them now
            if (_widths == null)
            {
                int      count  = _realFont.Widths.Count;
                ushort[] widths = new ushort[count];
                for (int x = 0; x < count; ++x)
                {
                    widths[x] = _realFont.Widths[x];
                }
                _widths = new CIDFontWidths(widths);
            }

            //	The widths array here is in a special CIDFont format. The data are
            //	the same as on the real font.
            ObjectReference wref = doc.GetReference(_widths);

            sb.Append("/W ");
            sb.Append(wref.Reference);
            sb.Append("\r\n");

            sb.Append(">>\r\nendobj\r\n");
            Document.WriteData(file, sb.ToString());

            _widths.Write(file, doc, _realFont.UnitsPerEm);
        }
예제 #7
0
        public void Write(Stream file, ObjectReference pageref, ObjectReference parent, Document doc)
        {
            pageref.ByteOffset = file.Position;

            StringBuilder sb = new StringBuilder();

            sb.Append(pageref.Id);
            sb.Append(" obj\r\n");
            sb.Append("<<\r\n");
            sb.Append("/Type /Page\r\n");

            //	We have a flat page structure, so the parent is always the catalog
            sb.Append("/Parent ");
            sb.Append(parent.Reference);
            sb.Append("\r\n");

            sb.Append("/MediaBox ");
            sb.Append(_mediaBox.Specification);
            sb.Append("\r\n");

            //	Write the string now because we want to write the resources and
            //	content directly to the file
            Document.WriteData(file, sb.ToString());
            sb.Clear();

            WriteResources(file, doc);

            //	Construct a content stream and write its reference to the file,
            //	but don't write its contents inside the page dictionary
            ContentStream   stream = new ContentStream();
            ObjectReference cref   = doc.GetReference(stream);

            Document.WriteData(file, "/Contents ");
            Document.WriteData(file, cref.Reference);
            Document.WriteData(file, "\r\n");

            //	Close the page object
            Document.WriteData(file, ">>\r\nendobj\r\n");

            //	Write the content stream, outside the page dictionary
            stream.Write(file, cref, _content);

            //	Write the images
            foreach (Image image in _images)
            {
                ObjectReference imageRef = doc.GetReference(image);
                ObjectReference maskRef  = null;
                if (image.Mask != null)
                {
                    maskRef = doc.GetReference(image.Mask);
                }
                image.Write(file, imageRef, maskRef);
            }
        }
예제 #8
0
        public void Write(Stream file)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("/ProcSet [ ");
            foreach (string name in _names)
            {
                sb.Append("/");
                sb.Append(name);
                sb.Append(" ");
            }
            sb.Append("]\r\n");

            Document.WriteData(file, sb.ToString());
        }
예제 #9
0
        private void WriteResources(Stream file, Document doc)
        {
            Document.WriteData(file, "/Resources\r\n<<\r\n");
            _procSet.Write(file);

            //	Font references. The fonts themselves are written directly by the generator.
            if (_fonts.Fonts.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("/Font <<");
                foreach (Font font in _fonts.Fonts)
                {
                    FontReference fontref = new FontReference(doc.GetReference(font));
                    sb.Append(fontref.AliasReference);
                    sb.Append(" ");

                    TrueTypeFont ttf = font as TrueTypeFont;
                    if (ttf != null)
                    {
                        fontref = new FontReference(doc.GetReference(ttf.RootFont));
                        sb.Append(fontref.AliasReference);
                        sb.Append(" ");
                    }
                }
                sb.Append(">>\r\n");
                Document.WriteData(file, sb.ToString());
            }

            //	Image references. The images themselves are written elsewhere.
            if (_images.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("/XObject << ");
                foreach (Image img in _images)
                {
                    ObjectReference imgRef = doc.GetReference(img);
                    sb.Append("/");
                    sb.Append(img.Name);
                    sb.Append(" ");
                    sb.Append(imgRef.Reference);
                    sb.Append(" ");
                }
                sb.Append(">>\r\n");
                Document.WriteData(file, sb.ToString());
            }

            Document.WriteData(file, ">>\r\n");
        }
예제 #10
0
        public override void Write(Stream file, Document doc)
        {
            ObjectReference fontref = doc.GetReference(this);

            fontref.ByteOffset = file.Position;

            StringBuilder sb = new StringBuilder();

            sb.Append(fontref.Id);
            sb.Append(" obj\r\n");
            sb.Append("<< /Type /Font\r\n");
            sb.Append("/Subtype /Type0\r\n");

            sb.Append("/BaseFont /");
            sb.Append(_descendant.PostScriptName);
            sb.Append("\r\n");

            sb.Append("/Encoding /Identity-H\r\n");

            //	The Type 0 font has a one-element array of descendant fonts.
            //	The descendant font is a CIDFont (in our case, subtype
            //	CIDFontType2.) The CIDFont points to the same descriptor
            //	as the True Type font.

            ObjectReference cidref = doc.GetReference(_cidFont);

            //	DescendantFonts is a one-element array, that one entry
            //	being a reference to the descendant font
            sb.Append("/DescendantFonts [ ");
            sb.Append(cidref.Reference);
            sb.Append(" ]\r\n");

            ObjectReference uniref = doc.GetReference(_descendant.ToUnicode);

            sb.Append("/ToUnicode ");
            sb.Append(uniref.Reference);
            sb.Append("\r\n");

            sb.Append(">>\r\nendobj\r\n");
            Document.WriteData(file, sb.ToString());

            _cidFont.Write(file, doc);
        }
예제 #11
0
        public void Write(Stream file, Document doc, ushort unitsPerEm)
        {
            ObjectReference wref = doc.GetReference(this);

            wref.ByteOffset = file.Position;

            StringBuilder sb = new StringBuilder();

            sb.Append(wref.Id);
            sb.Append(" obj\r\n[ ");
            for (int x = 0; x < _underlying.Count; ++x)
            {
                //	The raw widths are in font units, but we want thousandths
                //	of a text unit in the dictionary. See page 414.
                sb.Append(_underlying[x] * 1000 / unitsPerEm);
                sb.Append(" ");
            }
            sb.Append("]\r\nendobj\r\n");
            Document.WriteData(file, sb.ToString());
        }
예제 #12
0
        public void Write(Stream file, ObjectReference dictRef)
        {
            dictRef.ByteOffset = file.Position;

            StringBuilder sb = new StringBuilder();

            sb.Append(dictRef.Id);
            sb.Append(" obj\r\n<<");

            foreach (KeyValuePair <string, string> item in _info)
            {
                sb.Append("/");
                sb.Append(item.Key);
                sb.Append(" (");
                sb.Append(item.Value);
                sb.Append(")\r\n");
            }

            sb.Append(">>\r\n");
            sb.Append("endobj\r\n");
            Document.WriteData(file, sb.ToString());
        }
예제 #13
0
        public void Write(Stream file, ObjectReference reference, Document doc)
        {
            reference.ByteOffset = file.Position;

            StringBuilder sb = new StringBuilder();

            sb.Append(reference.Id);
            sb.Append(" obj\r\n<<\r\n/Type /Catalog\r\n");

            ObjectReference pages = doc.GetReference(doc.Pages);

            sb.Append("/Pages ");
            sb.Append(pages.Reference);
            sb.Append("\r\n");

//			Dictionary names = new Dictionary(this);
//			_catalog.AddEntry("/Names",names);

//			Dictionary metadata = new Dictionary(this);
//			_catalog.AddEntry("/Metadata",metadata);

            sb.Append(">>\r\nendobj\r\n");
            Document.WriteData(file, sb.ToString());
        }
예제 #14
0
        public void Write(Stream file, ObjectReference imageRef, ObjectReference maskRef)
        {
            imageRef.ByteOffset = file.Position;

            StringBuilder sb = new StringBuilder();

            sb.Append(imageRef.Id);
            sb.Append(" obj\r\n<<");
            sb.Append("/Type /XObject\r\n");
            sb.Append("/Subtype /Image\r\n");

            sb.Append("/Width ");
            sb.Append(_size.Width);
            sb.Append("\r\n");

            sb.Append("/Height ");
            sb.Append(_size.Height);
            sb.Append("\r\n");

            sb.Append("/Length ");
            sb.Append(_bits.Length);
            sb.Append("\r\n");

            sb.Append("/BitsPerComponent ");
            sb.Append(_bitsPerPixel);
            sb.Append("\r\n");

            switch (_colorSpace)
            {
            case ColorSpace.DeviceRGB:
                sb.Append("/ColorSpace /DeviceRGB\r\n");
                break;

            case ColorSpace.DeviceGray:
                sb.Append("/ColorSpace /DeviceGray\r\n");
                break;
            }

            switch (_filter)
            {
            case Filter.DCT:
                sb.Append("/Filter /DCTDecode\r\n");
                break;

            case Filter.Flate:
                sb.Append("/Filter /FlateDecode\r\n");
                break;
            }
            if (maskRef != null)
            {
                sb.Append("/SMask ");
                sb.Append(maskRef.Reference);
                sb.Append("\r\n");
            }

            sb.Append(">>\r\n");

            sb.Append("stream\r\n");

            //	Write the string now so that we can write the binary data
            Document.WriteData(file, sb.ToString());
            sb.Clear();

            file.Write(_bits, 0, _bits.Length);

            sb.Append("\r\nendstream\r\n");
            sb.Append("endobj\r\n");
            Document.WriteData(file, sb.ToString());
        }
예제 #15
0
        public void Write(Stream file, Document doc)
        {
            if (this.Count == 0)
            {
                return;
            }

            ObjectReference uniref = doc.GetReference(this);

            uniref.ByteOffset = file.Position;

            //	Prepare the stream so that we can find its length.
            //	The /Length value must be the length of the stream
            //	contents, starting after "stream\r\n" and ending
            //	before "\r\nendstream".
            StringBuilder sb = new StringBuilder();

            sb.Append("/CIDInit /ProcSet findresource\r\n");
            sb.Append("begin\r\n");
            sb.Append("12 dict\r\n");
            sb.Append("begin\r\n");
            sb.Append("begincmap\r\n");
            sb.Append("/CIDSystemInfo<</Registry(Adobe)/Ordering(UCS)/Supplement 0>>\r\n");
            sb.Append("def\r\n");
            sb.Append("/CMapName /Adobe-Identity-UCS\r\n");
            sb.Append("def\r\n");
            sb.Append("/CMapType 2\r\n");
            sb.Append("def\r\n");

            List <ushort> indices = new List <ushort>(this.Keys);

            indices.Sort();
            sb.Append("1 begincodespacerange\r\n");
            sb.Append("<");
            sb.Append(Helpers.Hex(indices[0]));
            sb.Append("><");
            sb.Append(Helpers.Hex(indices[indices.Count - 1]));
            sb.Append(">\r\n");
            sb.Append("endcodespacerange\r\n");

//			sb.Append("2 beginbfrange\r\n");
//			< 0000 >< 005E >< 0020 >
//			< 005F >< 0061 >[ < 00660066 > < 00660069 > < 00660066006C > ]
//			sb.Append("endbfrange\r\n");

            //TODO: collect the mappings into contiguous ranges and encode
            //them more efficiently with beginbfrange/endbfrange
            foreach (ushort glyphIndex in indices)
            {
                sb.Append("1 beginbfchar\r\n");
                sb.Append("<");
                sb.Append(Helpers.Hex(glyphIndex));
                sb.Append("><");
                sb.Append(Helpers.Hex(this[glyphIndex]));
                sb.Append(">\r\n");
                sb.Append("endbfchar\r\n");
            }

            sb.Append("endcmap\r\n");
            sb.Append("CMapName currentdict /CMap defineresource pop\r\n");
            sb.Append("end\r\n");
            sb.Append("end");

            byte[] stream = Encoding.UTF8.GetBytes(sb.ToString());

            //	Write the stream to the PDF
            sb.Clear();
            sb.Append(uniref.Id);
            sb.Append(" obj\r\n");
            sb.Append("<</Length ");
            sb.Append(stream.Length);
            sb.Append(">>\r\n");
            sb.Append("stream\r\n");
            Document.WriteData(file, sb.ToString());

            file.Write(stream, 0, stream.Length);

            sb.Clear();
            sb.Append("\r\nendstream\r\n");
            sb.Append("\r\nendobj\r\n");
            Document.WriteData(file, sb.ToString());
        }
예제 #16
0
        public override void Write(Stream file, Document doc)
        {
//			RootFont.Write(file,generator);

            ObjectReference fontref = doc.GetReference(this);

            fontref.ByteOffset = file.Position;

            StringBuilder sb = new StringBuilder();

            sb.Append(fontref.Id);
            sb.Append(" obj\r\n");
            sb.Append("<< /Type /Font\r\n");
            sb.Append("/Subtype /TrueType\r\n");

            //	/Name is obsolete - see page 413 in the PDF spec
//			sb.Append("/Name /");
//			sb.Append(_name); //TODO: escape spaces etc.
//			sb.Append("\r\n");

            sb.Append("/BaseFont /");
            sb.Append(PostScriptName);             //TODO: escape spaces etc.
            sb.Append("\r\n");

//			//	Specify no encoding for "symbolic" fonts
//			if(_encoding != null)
//			{
//				sb.Append("/Encoding /");
//				sb.Append(_encoding);
//				sb.Append("\r\n");
//			}

            sb.Append("/FontDescriptor ");
            sb.Append(doc.GetReference(_descriptor).Reference);
            sb.Append("\r\n");

            sb.Append("/FirstChar ");
            sb.Append(_underlying.FirstCharIndex);
            sb.Append("\r\n");

            sb.Append("/LastChar ");
            sb.Append(_underlying.LastCharIndex);
            sb.Append("\r\n");

            sb.Append("/Widths ");
            sb.Append(doc.GetReference(_widths).Reference);
            sb.Append("\r\n");

            sb.Append(">>\r\nendobj\r\n");
            Document.WriteData(file, sb.ToString());

            _descriptor.Write(file, doc);
            _fontStream?.Write(file, doc);
            _widths.Write(file, doc, UnitsPerEm);

            foreach (KeyValuePair <char, ushort> glyph in _underlying.GlyphIndices) // <char, index>
            {
                _toUnicode.Add(glyph.Value, glyph.Key);                             // <index, char>
            }
            _toUnicode.Write(file, doc);
        }
예제 #17
0
        public void Write(Stream file, Document doc)
        {
            ObjectReference descref = doc.GetReference(this);

            descref.ByteOffset = file.Position;

            StringBuilder sb = new StringBuilder();

            sb.Append(descref.Id);
            sb.Append(" obj\r\n");
            sb.Append("<< /Type /FontDescriptor\r\n");
            sb.Append("/FontName /");
            sb.Append(_fontName);
            sb.Append("\r\n");

            sb.Append("/Flags ");
            sb.Append(_flags);
            sb.Append("\r\n");

            sb.Append("/ItalicAngle ");
            sb.Append(_italicAngle);
            sb.Append("\r\n");

            sb.Append("/Ascent ");
            sb.Append(_ascent);
            sb.Append("\r\n");

            sb.Append("/Descent ");
            sb.Append(_descent);
            sb.Append("\r\n");

            sb.Append("/CapHeight ");
            sb.Append(_capHeight);
            sb.Append("\r\n");

            sb.Append("/AvgWidth ");
            sb.Append(_avgWidth);
            sb.Append("\r\n");

            sb.Append("/MaxWidth ");
            sb.Append(_maxWidth);
            sb.Append("\r\n");

            sb.Append("/FontWeight ");
            sb.Append(_fontWeight);
            sb.Append("\r\n");

            sb.Append("/XHeight ");
            sb.Append(_xHeight);
            sb.Append("\r\n");

            sb.Append("/StemV ");
            sb.Append(_stemV);
            sb.Append("\r\n");

            sb.Append("/FontBBox ");
            sb.Append(_bbox.Specification);
            sb.Append("\r\n");

            if (_fontFile != null)
            {
                //TODO: consider compressing the font file

                sb.Append("/FontFile2 ");
                sb.Append(doc.GetReference(_fontFile).Reference);
                sb.Append("\r\n");
            }

            sb.Append(">>\r\nendobj\r\n");
            Document.WriteData(file, sb.ToString());
        }