۱۳۹۰/۰۹/۱۵

نمايش گراديان در iTextSharp


كتابخانه iTextSharp نمايش گرادياني از رنگ‌ها را هم پشتيباني مي‌كند و بديهي است اين نمايش برداري است. روش استفاده از آن هم بسيار ساده است؛ مثلا:

PdfShading shading = PdfShading.SimpleAxial(pdfWriter, x0, y0, x1, y1, BaseColor.YELLOW, BaseColor.RED);
PdfShadingPattern pattern = new PdfShadingPattern(shading);
ShadingColor color = new ShadingColor(pattern);

متد PdfShading.SimpleAxial بر اساس شيء PdfWriter كه توسط آن به Canvas صفحه دسترسي پيدا مي‌كند، در مختصاتي مشخص، يك طيف رنگي را ايجاد مي‌كند. بر اين اساس مي‌توان به يك ShadingColor هم رسيد كه از آن مثلا به عنوان BackgroundColor يك PdfPCell قابل استفاده است.
تا اينجا ساده به نظر مي‌رسد اما واقعيت اين است كه مختصات ذكر شده، مهم است و آن‌را در مورد مثلا سلول‌هاي يك جدول تنها در زمان تهيه نهايي يك جدول مي‌توان به دست آورد. البته اگر شيء ساده‌اي را روي صفحه رسم كنيم، اين مورد بر اساس مختصات ابتدايي شيء واضح به نظر مي‌رسد.
براي حل اين مشكل در مورد جداول و سلول‌هاي آن خاصيتي به نام CellEvent وجود دارد كه از نوع IPdfPCellEvent است. به عبارتي با ارسال يك وهله از كلاسي كه اينترفيس IPdfPCellEvent را پياده سازي مي‌كند، مي‌توان در زمان نمايش نهايي يك سلول به مختصات دقيق آن دسترسي پيدا كرد.
يك مثال كامل را در مورد پياده سازي IPdfPCellEvent و استفاده از آن جهت نمايش گراديان در Header و footer يك جدول، در ادامه مشاهده خواهيد نمود:

using System.Diagnostics;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace iTextSharpGradientTest
{
    public class GradientCellEvent : IPdfPCellEvent
    {
        public void CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
        {
            var cb = canvases[PdfPTable.BACKGROUNDCANVAS];
            cb.SaveState();

            var shading = PdfShading.SimpleAxial(
                                    cb.PdfWriter,
                                    position.Left, position.Top, position.Left, position.Bottom,
                                    BaseColor.YELLOW, BaseColor.ORANGE);
            var shadingPattern = new PdfShadingPattern(shading);

            cb.SetShadingFill(shadingPattern);
            cb.Rectangle(position.Left, position.Bottom, position.Width, position.Height);
            cb.Fill();

            cb.RestoreState();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var pdfDoc = new Document(PageSize.A4))
            {
                var pdfWriter = PdfWriter.GetInstance(pdfDoc, new FileStream("Test.pdf", FileMode.Create));
                pdfDoc.Open();

                var table1 = new PdfPTable(1);
                table1.HeaderRows = 2;
                table1.FooterRows = 1;

                //header row  
                var headerCell = new PdfPCell(new Phrase("header"))
                {
                    HorizontalAlignment = Element.ALIGN_CENTER,
                    Border = 0
                };
                headerCell.CellEvent = new GradientCellEvent();
                table1.AddCell(headerCell);

                //footer row  
                var footerCell = new PdfPCell(new Phrase("footer"))
                {
                    HorizontalAlignment = Element.ALIGN_CENTER,
                    Border = 0
                };
                footerCell.CellEvent = new GradientCellEvent();
                table1.AddCell(footerCell);

                //adding some rows  
                for (int i = 0; i < 70; i++)
                {
                    var rowCell = new PdfPCell(new Phrase("Row " + i)) { BorderColor = BaseColor.LIGHT_GRAY };
                    table1.AddCell(rowCell);
                }

                pdfDoc.Add(table1);
            }

            //open the final file with adobe reader for instance.  
            Process.Start("Test.pdf");
        }
    }
}

با خروجي:


نكته مهم اين مثال نحوه مقدار دهي CellEvent است. به اين ترتيب در زمان نمايش نهايي يك سلول مي‌توان در متد CellLayout، به خواص فقط خواندني آن سلول دسترسي يافت. مثلا position، مختصات نهايي مستطيل مرتبط با سلول جاري را بر مي‌گرداند؛ يا از طريق canvases مي‌توان براي آخرين بار فرصت يافت تا در يك سلول نقاشي كرد.