예제 #1
0
        /// <summary>
        /// Gets the image entries to be written to the file
        /// </summary>
        /// <returns></returns>
        internal byte[] GetImageDict(long filePos, out int size)
        {
            MemoryStream ms = new MemoryStream();
            int          s;

            byte[] ba;
            foreach (PdfImageEntry ie in images.Values)
            {
                ObjectList objList = new ObjectList(ie.objectNum, filePos);
                ba = PdfUtility.GetUTF8Bytes(ie.imgDict, out s);
                ms.Write(ba, 0, ba.Length);
                filePos += s;

                ms.Write(ie.ba, 0, ie.ba.Length);                               // write out the image
                filePos += ie.ba.Length;

                ba = PdfUtility.GetUTF8Bytes("endstream\r\nendobj\r\n", out s);
                ms.Write(ba, 0, ba.Length);
                filePos += s;
                ie.xref.offsets.Add(objList);
            }

            ba   = ms.ToArray();
            size = ba.Length;
            return(ba);
        }
예제 #2
0
        public void Start()
        {
            // Create the anchor for all pdf objects
            CompressionConfig cc = RdlEngineConfig.GetCompression();

            anchor = new PdfAnchor(cc != null);

            //Create a PdfCatalog
            string lang;

            if (r.ReportDefinition.Language != null)
            {
                lang = r.ReportDefinition.Language.EvaluateString(this.r, null);
            }
            else
            {
                lang = null;
            }
            catalog = new PdfCatalog(anchor, lang);

            //Create a Page Tree Dictionary
            pageTree = new PdfPageTree(anchor);

            //Create a Font Dictionary
            fonts = new PdfFonts(anchor);

            //Create a Pattern Dictionary
            patterns = new PdfPattern(anchor);

            //Create an Image Dictionary
            images = new PdfImages(anchor);

            //Create an Outline Dictionary
            outline = new PdfOutline(anchor);

            //Create the info Dictionary
            info = new PdfInfo(anchor);

            //Set the info Dictionary.
            info.SetInfo(r.Name, r.Author, r.Description, "");  // title, author, subject, company

            //Create a utility object
            pdfUtility = new PdfUtility(anchor);

            //write out the header
            int size = 0;

            tw.Write(pdfUtility.GetHeader("1.5", out size), 0, size);
            //
            filesize = size;
        }
예제 #3
0
        /// <summary>
        /// Page Text element at the X Y position; multiple lines handled
        /// </summary>
        /// <returns></returns>
        internal void AddText(float x, float y, float height, float width, string[] sa,
                              StyleInfo si, PdfFonts fonts, float[] tw, bool bWrap, string url, bool bNoClip, string tooltip)
        {
            // Calculate the RGB colors e.g. RGB(255, 0, 0) = red = 1 0 0 rg
            double r = si.Color.R;
            double g = si.Color.G;
            double b = si.Color.B;

            r = Math.Round((r / 255), 3);
            g = Math.Round((g / 255), 3);
            b = Math.Round((b / 255), 3);

            string pdfFont = fonts.GetPdfFont(si);              // get the pdf font resource name

            // Loop thru the lines of text
            for (int i = 0; i < sa.Length; i++)
            {
                string text      = sa[i];
                float  textwidth = tw[i];
                // Calculate the x position
                float startX = x + si.PaddingLeft;                                      // TODO: handle tb_rl
                float startY = y + si.PaddingTop + (i * si.FontSize);                   // TODO: handle tb_rl

                if (si.WritingMode == WritingModeEnum.lr_tb)
                {                       // TODO: not sure what alignment means with tb_lr so I'll leave it out for now
                    switch (si.TextAlign)
                    {
                    case TextAlignEnum.Center:
                        if (width > 0)
                        {
                            startX = x + si.PaddingLeft + (width - si.PaddingLeft - si.PaddingRight) / 2 - textwidth / 2;
                        }
                        break;

                    case TextAlignEnum.Right:
                        if (width > 0)
                        {
                            startX = x + width - textwidth - si.PaddingRight;
                        }
                        break;

                    case TextAlignEnum.Left:
                    default:
                        break;
                    }

                    // Calculate the y position
                    switch (si.VerticalAlign)
                    {
                    case VerticalAlignEnum.Middle:
                        if (height <= 0)
                        {
                            break;
                        }

                        // calculate the middle of the region
                        startY = y + si.PaddingTop + (height - si.PaddingTop - si.PaddingBottom) / 2 - si.FontSize / 2;
                        // now go up or down depending on which line
                        if (sa.Length == 1)
                        {
                            break;
                        }
                        if (sa.Length % 2 == 0)                                 // even number
                        {
                            startY = startY - ((sa.Length / 2 - i) * si.FontSize) + si.FontSize / 2;
                        }
                        else
                        {
                            startY = startY - ((sa.Length / 2 - i) * si.FontSize);
                        }
                        break;

                    case VerticalAlignEnum.Bottom:
                        if (height <= 0)
                        {
                            break;
                        }

                        startY = y + height - si.PaddingBottom - (si.FontSize * (sa.Length - i));
                        break;

                    case VerticalAlignEnum.Top:
                    default:
                        break;
                    }
                }
                else
                {
                    //25072008 GJL - Move x in a little - it draws to close to the edge of the rectangle (25% of the font size seems to work!) and Center or right align vertical text
                    startX += si.FontSize / 4;

                    switch (si.TextAlign)
                    {
                    case TextAlignEnum.Center:
                        if (height > 0)
                        {
                            startY = y + si.PaddingLeft + (height - si.PaddingLeft - si.PaddingRight) / 2 - textwidth / 2;
                        }
                        break;

                    case TextAlignEnum.Right:
                        if (width > 0)
                        {
                            startY = y + height - textwidth - si.PaddingRight;
                        }
                        break;

                    case TextAlignEnum.Left:
                    default:
                        break;
                    }
                }

                // Draw background rectangle if needed (only put out on the first line, since we do whole rectangle)
                if (!si.BackgroundColor.IsEmpty && height > 0 && width > 0 && i == 0)
                {                       // background color, height and width are specified
                    AddFillRect(x, y, width, height, si.BackgroundColor);
                }

                // Set the clipping path
                if (height > 0 && width > 0)
                {
                    if (bNoClip)                        // no clipping but we still want URL checking
                    {
                        elements.Append("\r\nq\t");
                    }
                    else
                    {
                        elements.AppendFormat(NumberFormatInfo.InvariantInfo,
                                              "\r\nq\t{0} {1} {2} {3} re W n",
                                              x, pSize.yHeight - y - height, width, height);
                    }
                    if (url != null)
                    {
                        p.AddHyperlink(x, pSize.yHeight - y, height, width, url);
                    }
                    if (tooltip != null)
                    {
                        p.AddToolTip(x, pSize.yHeight - y, height, width, tooltip);
                    }
                }
                else
                {
                    elements.Append("\r\nq\t");
                }

                // Escape the text
                string newtext = PdfUtility.UTF16StringQuoter(text);
                //string newtext = text.Replace("\\", "\\\\");
                //newtext = newtext.Replace("(", "\\(");
                //newtext = newtext.Replace(")", "\\)");
                if (si.WritingMode == WritingModeEnum.lr_tb)
                {
                    elements.AppendFormat(NumberFormatInfo.InvariantInfo,
                                          "\r\nBT/{0} {1} Tf\t{5} {6} {7} rg\t{2} {3} Td \t({4}) Tj\tET\tQ\t",
                                          pdfFont, si.FontSize, startX, (pSize.yHeight - startY - si.FontSize), newtext, r, g, b);
                }
                else
                {                       // Rotate text -90 degrees=-.5 radians (this works for english don't know about true tb-rl language)
                                        //   had to play with reader to find best approximation for this rotation; didn't do what I expected
                                        //    see pdf spec section 4.2.2 pg 141  "Common Transformations"

                    elements.AppendFormat(NumberFormatInfo.InvariantInfo,
                                          "\r\nBT/{0} {1} Tf\t{5} {6} {7} rg\t{8} {9} {10} {11} {2} {3} Tm \t({4}) Tj\tET\tQ\t",
                                          pdfFont, si.FontSize, startX, (pSize.yHeight - startY), newtext, r, g, b,
                                          radsCos, radsSin, -radsSin, radsCos);
                }

                // Handle underlining etc.
                float maxX;
                switch (si.TextDecoration)
                {
                case TextDecorationEnum.Underline:
                    maxX = width > 0? Math.Min(x + width, startX + textwidth): startX + textwidth;
                    AddLine(startX, startY + si.FontSize + 1, maxX, startY + si.FontSize + 1, 1, si.Color, BorderStyleEnum.Solid);
                    break;

                case TextDecorationEnum.LineThrough:
                    maxX = width > 0? Math.Min(x + width, startX + textwidth): startX + textwidth;
                    AddLine(startX, startY + (si.FontSize / 2) + 1, maxX, startY + (si.FontSize / 2) + 1, 1, si.Color, BorderStyleEnum.Solid);
                    break;

                case TextDecorationEnum.Overline:
                    maxX = width > 0? Math.Min(x + width, startX + textwidth): startX + textwidth;
                    AddLine(startX, startY + 1, maxX, startY + 1, 1, si.Color, BorderStyleEnum.Solid);
                    break;

                case TextDecorationEnum.None:
                default:
                    break;
                }
            }

            AddBorder(si, x, y, height, width);                                 // add any required border

            return;
        }
예제 #4
0
        /// <summary>
        /// Content object
        /// </summary>
        /// <summary>
        /// Get the Content Dictionary
        /// </summary>
        internal byte[] GetContentDict(long filePos, out int size)
        {
            // When no compression
            if (!CanCompress)
            {
                content = string.Format("\r\n{0} 0 obj<</Length {1}>>stream\r{2}\rendstream\rendobj\r",
                                        this.objectNum, contentStream.Length, contentStream);

                return(GetUTF8Bytes(content, filePos, out size));
            }

            // Try to use compression; could still fail in which case fall back to uncompressed
            Stream       strm = null;
            MemoryStream cs   = null;

            try
            {
                CompressionConfig cc = RdlEngineConfig.GetCompression();
                cs = new MemoryStream();                        // this will contain the content stream
                if (cc != null)
                {
                    strm = cc.GetStream(cs);
                }

                if (strm == null)
                {                       // can't compress string
                    cs.Close();

                    content = string.Format("\r\n{0} 0 obj<</Length {1}>>stream\r{2}\rendstream\rendobj\r",
                                            this.objectNum, contentStream.Length, contentStream);

                    return(GetUTF8Bytes(content, filePos, out size));
                }

                // Compress the contents
                int    cssize;
                byte[] ca = PdfUtility.GetUTF8Bytes(contentStream, out cssize);
                strm.Write(ca, 0, cssize);
                strm.Flush();
                cc.CallStreamFinish(strm);

                // Now output the PDF command
                MemoryStream ms = new MemoryStream();
                int          s;
                byte[]       ba;

                // get the compressed data;  we need the lenght now
                byte[] cmpData = cc.GetArray(cs);

                // write the beginning portion of the PDF object
                string ws = string.Format("\r\n{0} 0 obj<< /Filter /FlateDecode /Length {1}>>stream\r",
                                          this.objectNum, cmpData.Length);

                ba = GetUTF8Bytes(ws, filePos, out s);                  // this will also register the object
                ms.Write(ba, 0, ba.Length);
                filePos += s;

                // write the Compressed data
                ms.Write(cmpData, 0, cmpData.Length);
                filePos += ba.Length;

                // write the end portion of the PDF object
                ba = PdfUtility.GetUTF8Bytes("\rendstream\rendobj\r", out s);
                ms.Write(ba, 0, ba.Length);
                filePos += s;

                // now the final output array
                ba   = ms.ToArray();
                size = ba.Length;
                return(ba);
            }
            finally
            {
                if (strm != null)
                {
                    strm.Close();
                }
            }
        }