Пример #1
0
        public bool Paginate(Gtk.PrintContext context)
        {
            bool raw_ret = gtk_source_print_compositor_paginate(Handle, context == null ? IntPtr.Zero : context.Handle);
            bool ret     = raw_ret;

            return(ret);
        }
Пример #2
0
        static void DrawComment(Gtk.PrintContext context, double x, double y, double h, string comment, bool rotated)
        {
            if (string.IsNullOrEmpty(comment))
            {
                return;
            }

            Context cr = context.CairoContext;

            cr.Save();
            Pango.Layout          layout = context.CreatePangoLayout();
            Pango.FontDescription desc   = Pango.FontDescription.FromString("sans 14");
            layout.FontDescription = desc;
            layout.SetText(comment);
            int lay_w, lay_h;

            layout.GetPixelSize(out lay_w, out lay_h);
            double scale = h / lay_h;

            if (rotated)
            {
                cr.Translate(x - h, y + lay_w * scale);
                cr.Rotate(-Math.PI / 2);
            }
            else
            {
                cr.Translate(x - lay_w * scale, y - h);
            }
            cr.Scale(scale, scale);
            Pango.CairoHelper.ShowLayout(context.CairoContext, layout);
            cr.Restore();
        }
Пример #3
0
        private void OnBeginPrint(object sender, Gtk.BeginPrintArgs args)
        {
            Gtk.PrintOperation op      = (Gtk.PrintOperation)sender;
            Gtk.PrintContext   context = args.Context;
            timestamp_footer = CreateTimestampLayout(context);

            // FIXME: These should be configurable settings later (UI Change)
            margin_top    = CmToPixel(1.5, context.DpiY);
            margin_left   = CmToPixel(1, context.DpiX);
            margin_right  = CmToPixel(1, context.DpiX);
            margin_bottom = 0;
            double max_height = Pango.Units.FromPixels((int)context.Height -
                                                       margin_top - margin_bottom - ComputeFooterHeight(context));

            Gtk.TextIter position;
            Gtk.TextIter end_iter;
            Buffer.GetBounds(out position, out end_iter);

            double page_height = 0;
            bool   done        = position.Compare(end_iter) >= 0;

            while (!done)
            {
                Gtk.TextIter line_end = position;
                if (!line_end.EndsLine())
                {
                    line_end.ForwardToLineEnd();
                }

                int paragraph_number = position.Line;
                int indentation;
                using (Pango.Layout layout = CreateParagraphLayout(
                           context, position, line_end, out indentation)) {
                    Pango.Rectangle ink_rect     = Pango.Rectangle.Zero;
                    Pango.Rectangle logical_rect = Pango.Rectangle.Zero;
                    for (int line_in_paragraph = 0; line_in_paragraph < layout.LineCount;
                         line_in_paragraph++)
                    {
                        Pango.LayoutLine line = layout.GetLine(line_in_paragraph);
                        line.GetExtents(ref ink_rect, ref logical_rect);

                        if (page_height + logical_rect.Height >= max_height)
                        {
                            PageBreak page_break = new PageBreak(
                                paragraph_number, line_in_paragraph);
                            page_breaks.Add(page_break);

                            page_height = 0;
                        }
                        page_height += logical_rect.Height;
                    }

                    position.ForwardLine();
                    done = position.Compare(end_iter) >= 0;
                }
            }

            op.NPages = page_breaks.Count + 1;
        }
Пример #4
0
 public void Draw(Gtk.PrintContext context)
 {
     Console.WriteLine("Rowssssssssssss: " + this.rows.Count);
     foreach (Dictionary <string, Text> aRow in this.rows)
     {
         foreach (Text aField in aRow.Values)
         {
             aField.Draw(context);
         }
     }
 }
Пример #5
0
        /// <summary>
        /// OnDrawPage - Draws the Content of each Page to be printed
        /// </summary>
        /// <param name="obj">The Print Operation</param>
        /// <param name="args">The DrawPageArgs passed by the Print Operation</param>
        private void OnDrawPage(object obj, Gtk.DrawPageArgs args)
        {
            // Create a Print Context from the Print Operation
            Gtk.PrintContext context = args.Context;

            // Create a Cairo Context from the Print Context
            Cairo.Context cr = context.CairoContext;

            Poppler.Page pg = this.pdf.GetPage(args.PageNr);
            pg.RenderForPrintingWithOptions(cr, Poppler.PrintFlags.Document);
        }
Пример #6
0
        private Pango.Layout CreateParagraphLayout(Gtk.PrintContext context,
                                                   Gtk.TextIter p_start,
                                                   Gtk.TextIter p_end,
                                                   out int indentation)
        {
            Pango.Layout layout = context.CreatePangoLayout();
            layout.FontDescription = Window.Editor.Style.FontDesc;
            int start_index = p_start.LineIndex;

            indentation = 0;

            double dpiX = context.DpiX;

            using (Pango.AttrList attr_list = new Pango.AttrList()) {
                Gtk.TextIter segm_start = p_start;
                Gtk.TextIter segm_end;

                while (segm_start.Compare(p_end) < 0)
                {
                    segm_end = segm_start;
                    IEnumerable <Pango.Attribute> attrs =
                        GetParagraphAttributes(
                            layout, dpiX, out indentation,
                            ref segm_end, p_end);

                    uint si = (uint)(segm_start.LineIndex - start_index);
                    uint ei = (uint)(segm_end.LineIndex - start_index);

                    foreach (Pango.Attribute a in attrs)
                    {
                        a.StartIndex = si;
                        a.EndIndex   = ei;
                        attr_list.Insert(a);
                    }
                    segm_start = segm_end;
                }

                layout.Attributes = attr_list;
            }

            DepthNoteTag depth = Buffer.FindDepthTag(p_start);

            if (depth != null)
            {
                indentation += ((int)(dpiX / 3)) * depth.Depth;
            }

            layout.Width = Pango.Units.FromPixels((int)context.Width -
                                                  margin_left - margin_right - indentation);
            layout.Wrap = Pango.WrapMode.WordChar;
            layout.SetText(Buffer.GetSlice(p_start, p_end, false));
            return(layout);
        }
Пример #7
0
        private int ComputeFooterHeight(Gtk.PrintContext context)
        {
            using (Pango.Layout layout = CreateTimestampLayout(context)) {
                Pango.Rectangle ink_rect;
                Pango.Rectangle logical_rect;
                layout.GetExtents(out ink_rect, out logical_rect);

                // Compute the footer height, include the space for the horizontal line
                return(Pango.Units.ToPixels(ink_rect.Height) +
                       CmToPixel(0.5, context.DpiY));
            }
        }
Пример #8
0
//		public double X1
//		{
//			get { return this.x1; }
//			set { this.x1 = value; }
//		}
//
//		public double Y1
//		{
//			get { return this.y1; }
//			set { this.y1 = value; }
//		}
//
//		public double X2
//		{
//			get { return this.x2; }
//			set { this.x2 = value; }
//		}
//
//		public double Y2
//		{
//			get { return this.y2; }
//			set { this.y2 = value; }
//		}

//		public double[] StrokeColor
//		{
//			get { return this.strokeColor; }
//			set { this.strokeColor = value; }
//		}

//		public double StrokeOpacity
//		{
//			get { return this.strokeOpacity; }
//			set { this.strokeOpacity = value; }
//		}

//		public double StrokeWidth
//		{
//			get { return this.strokeWidth; }
//			set { this.strokeWidth = value; }
//		}

        public void Draw(Gtk.PrintContext context)
        {
            Cairo.Context con = context.CairoContext;

            con.LineWidth = this.strokeWidth;
            con.Color     = new Cairo.Color(this.strokeColor[0],
                                            this.strokeColor[1],
                                            this.strokeColor[2],
                                            this.strokeOpacity);

            con.MoveTo(this.x1, this.y1);
            con.LineTo(this.x2, this.y2);

            con.Stroke();
        }
Пример #9
0
        private Pango.Layout CreatePagenumbersLayout(Gtk.PrintContext context,
                                                     int page_number, int total_pages)
        {
            Pango.Layout layout = context.CreatePangoLayout();
            layout.FontDescription        = Window.Editor.Style.FontDesc;
            layout.Width                  = Pango.Units.FromPixels((int)context.Width);
            layout.FontDescription.Style  = Pango.Style.Normal;
            layout.FontDescription.Weight = Pango.Weight.Light;

            string footer_left = string.Format(Catalog.GetString("Page {0} of {1}"),
                                               page_number, total_pages);

            layout.Alignment = Pango.Alignment.Left;
            layout.SetText(footer_left);

            return(layout);
        }
Пример #10
0
        public void Draw(Gtk.PrintContext context)
        {
            Cairo.Context con    = context.CairoContext;
            Pango.Layout  layout = context.CreatePangoLayout();

            layout.SetText(this.textValue);
            layout.FontDescription = Pango.FontDescription.FromString(this.FontDescription);

            int pixelSizeWidth, pixelSizeHeight;

            layout.GetPixelSize(out pixelSizeWidth, out pixelSizeHeight);

            Console.WriteLine("   Text value: " + this.textValue);
            Console.WriteLine("   Pixel size width: " + pixelSizeWidth);
            Console.WriteLine("   Pixel size height: " + pixelSizeHeight);
            Console.WriteLine("   Text X position: " + this.x);
            Console.WriteLine("   Text Y position: " + this.y);

            double x_offset = pixelSizeWidth * 0;           // Disabled
            double y_offset = pixelSizeHeight * 0.83;

            Console.WriteLine("width: " + x_offset);
            Console.WriteLine("height: " + y_offset);

            /// Alignment
            /// If text.Alignment == "center", then x coordinate is indicating
            /// the center, not the left side. That's way we add pixelSizeWidth/2
            /// to x_offset
            if (this.alignment.Equals("center"))
            {
                layout.Alignment = Pango.Alignment.Center;
                x_offset        += pixelSizeWidth / 2;
            }

            con.MoveTo(this.x - x_offset, this.y - y_offset);
            Pango.CairoHelper.ShowLayout(con, layout);

//			con.MoveTo(text.X, text.Y - y_offset);
//			con.LineTo(text.X + 100, text.Y - y_offset);
//			con.Stroke();
//
//			con.MoveTo(text.X, 38.4376957919563);
//			con.LineTo(text.X + 100, 38.4376957919563);
//			con.Stroke();
        }
Пример #11
0
        private Pango.Layout CreateTimestampLayout(Gtk.PrintContext context)
        {
            Pango.Layout layout = context.CreatePangoLayout();
            layout.FontDescription        = Window.Editor.Style.FontDesc;
            layout.Width                  = Pango.Units.FromPixels((int)context.Width);
            layout.FontDescription.Style  = Pango.Style.Normal;
            layout.FontDescription.Weight = Pango.Weight.Light;

            string footer_right = DateTime.Now.ToString(

                /* Translators: Explanation of the date and time format specifications can be found here:
                * http://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx */
                Catalog.GetString("dddd MM/dd/yyyy, hh:mm:ss tt"));

            layout.Alignment = Pango.Alignment.Right;
            layout.SetText(footer_right);

            return(layout);
        }
Пример #12
0
//		public double Width
//		{
//			get { return this.width; }
//			set { this.width = value; }
//		}
//
//		public double Height
//		{
//			get { return this.height; }
//			set { this.height = value; }
//		}
//
//		public double X
//		{
//			get { return this.x; }
//			set { this.x = value; }
//		}
//
//		public double Y
//		{
//			get { return this.y; }
//			set { this.y = value; }
//		}
//
//		public double LineWidth
//		{
//			get { return this.lineWidth; }
//			set { this.lineWidth = value; }
//		}
//
//		public double[] FillColor
//		{
//			get { return this.fillColor; }
//			set { this.fillColor = value; }
//		}
//
//		public double FillOpacity
//		{
//			get { return this.fillOpacity; }
//			set { this.fillOpacity = value; }
//		}
//
//		public double[] StrokeColor
//		{
//			get { return this.strokeColor; }
//			set { this.strokeColor = value; }
//		}
//
//		public double StrokeOpacity
//		{
//			get { return this.strokeOpacity; }
//			set { this.strokeOpacity = value; }
//		}

        public void Draw(Gtk.PrintContext context)
        {
            Cairo.Context con = context.CairoContext;

            Cairo.Rectangle cairoRectangle =
                new Cairo.Rectangle(new Cairo.Point((int)this.x,
                                                    (int)this.y),
                                    this.width,
                                    this.height);

            con.Rectangle(cairoRectangle);
            con.Color = new Cairo.Color(this.fillColor[0],
                                        this.fillColor[1],
                                        this.fillColor[2],
                                        this.fillOpacity);
            con.FillPreserve();

            con.LineWidth = this.lineWidth;
            con.Color     = new Cairo.Color(this.strokeColor[0],
                                            this.strokeColor[1],
                                            this.strokeColor[2],
                                            this.strokeOpacity);
            con.Stroke();
        }
Пример #13
0
        protected override void OnDrawPage(Gtk.PrintContext context, int page_nr)
        {
            base.OnDrawPage(context, page_nr);
            Context cr = context.CairoContext;

            int ppx, ppy;

            switch (photos_per_page)
            {
            default:
            case 1: ppx = ppy = 1; break;

            case 2: ppx = 1; ppy = 2; break;

            case 4: ppx = ppy = 2; break;

            case 9: ppx = ppy = 3; break;

            case 12: ppx = 3; ppy = 4; break;

            case 20: ppx = 4; ppy = 5; break;

            case 30: ppx = 5; ppy = 6; break;
            }

            //FIXME: if paper is landscape, swap ppx with ppy

            double w = context.Width / ppx;
            double h = context.Height / ppy;

            // compute picture size using 4800DPI
            double mx = (w / 25.4) * 4800, my = (h / 25.4) * 4800;

            for (int x = 0; x <= ppx; x++)
            {
                for (int y = 0; y <= ppy; y++)
                {
                    int p_index = repeat ? page_nr : page_nr * photos_per_page + y * ppx + x;
                    if (crop_marks)
                    {
                        DrawCropMarks(cr, x * w, y * h, w * .1);
                    }
                    if (x == ppx || y == ppy || p_index >= selected_photos.Length)
                    {
                        continue;
                    }
                    using (var img = ImageFile.Create(selected_photos[p_index].DefaultVersion.Uri))
                    {
                        Gdk.Pixbuf pixbuf;
                        try {
                            pixbuf = img.Load((int)mx, (int)my);
                            Cms.Profile printer_profile;
                            if (ColorManagement.Profiles.TryGetValue(Preferences.Get <string> (Preferences.COLOR_MANAGEMENT_OUTPUT_PROFILE), out printer_profile))
                            {
                                ColorManagement.ApplyProfile(pixbuf, img.GetProfile(), printer_profile);
                            }
                        } catch (Exception e) {
                            Log.Exception("Unable to load image " + selected_photos[p_index].DefaultVersion.Uri + "\n", e);
                            // If the image is not found load error pixbuf
                            pixbuf = new Gdk.Pixbuf(PixbufUtils.ErrorPixbuf, 0, 0,
                                                    PixbufUtils.ErrorPixbuf.Width,
                                                    PixbufUtils.ErrorPixbuf.Height);
                        }
                        //Gdk.Pixbuf pixbuf = img.Load (100, 100);
                        bool rotated = false;
                        if (Math.Sign((double)pixbuf.Width / pixbuf.Height - 1.0) != Math.Sign(w / h - 1.0))
                        {
                            Gdk.Pixbuf d_pixbuf = pixbuf.RotateSimple(Gdk.PixbufRotation.Counterclockwise);
                            pixbuf.Dispose();
                            pixbuf  = d_pixbuf;
                            rotated = true;
                        }

                        DrawImage(cr, pixbuf, x * w, y * h, w, h);

                        string tag_string = "";
                        foreach (Tag t in selected_photos[p_index].Tags)
                        {
                            tag_string = String.Concat(tag_string, t.Name);
                        }

                        string label = String.Format(print_label_format,
                                                     comment,
                                                     selected_photos[p_index].Name,
                                                     selected_photos[p_index].Time.ToLocalTime().ToShortDateString(),
                                                     selected_photos[p_index].Time.ToLocalTime().ToShortTimeString(),
                                                     tag_string,
                                                     selected_photos[p_index].Description);

                        DrawComment(context, (x + 1) * w, (rotated ? y : y + 1) * h, (rotated ? w : h) * .025, label, rotated);

                        pixbuf.Dispose();
                    }
                }
            }
        }
Пример #14
0
 protected override void OnEndPrint(Gtk.PrintContext context)
 {
     base.OnEndPrint(context);
     context.Dispose();
 }
Пример #15
0
 protected override void OnRequestPageSetup(Gtk.PrintContext context, int page_nr, Gtk.PageSetup setup)
 {
     base.OnRequestPageSetup(context, page_nr, setup);
 }
Пример #16
0
 protected override void OnBeginPrint(Gtk.PrintContext context)
 {
     base.OnBeginPrint(context);
 }
Пример #17
0
 public void DrawPage(Gtk.PrintContext context, int page_nr)
 {
     gtk_source_print_compositor_draw_page(Handle, context == null ? IntPtr.Zero : context.Handle, page_nr);
 }
Пример #18
0
 public void Draw(Gtk.PrintContext context)
 {
     throw new NotImplementedException();
 }
Пример #19
0
        public void OnDrawPage(object sender, Gtk.DrawPageArgs args)
        {
            using (Cairo.Context cr = args.Context.CairoContext) {
                cr.MoveTo(margin_left, margin_top);

                PageBreak start;
                if (args.PageNr == 0)
                {
                    start = new PageBreak(0, 0);
                }
                else
                {
                    start = page_breaks [args.PageNr - 1];
                }

                PageBreak end;
                if (args.PageNr < page_breaks.Count)
                {
                    end = page_breaks [args.PageNr];
                }
                else
                {
                    end = new PageBreak(-1, -1);
                }

                Gtk.PrintContext context = args.Context;
                Gtk.TextIter     position;
                Gtk.TextIter     end_iter;
                Buffer.GetBounds(out position, out end_iter);

                // Fast-forward to the right starting paragraph
                while (position.Line < start.Paragraph)
                {
                    position.ForwardLine();
                }

                bool done = position.Compare(end_iter) >= 0;
                while (!done)
                {
                    Gtk.TextIter line_end = position;
                    if (!line_end.EndsLine())
                    {
                        line_end.ForwardToLineEnd();
                    }

                    int paragraph_number = position.Line;
                    int indentation;
                    using (Pango.Layout layout = CreateParagraphLayout(
                               context, position, line_end, out indentation)) {
                        for (int line_number = 0;
                             line_number < layout.LineCount && !done;
                             line_number++)
                        {
                            // Skip the lines up to the starting line in the
                            // first paragraph on this page
                            if ((paragraph_number == start.Paragraph) &&
                                (line_number < start.Line))
                            {
                                continue;
                            }

                            // Break as soon as we hit the end line
                            if ((paragraph_number == end.Paragraph) &&
                                (line_number == end.Line))
                            {
                                done = true;
                                break;
                            }

                            Pango.LayoutLine line         = layout.Lines [line_number];
                            Pango.Rectangle  ink_rect     = Pango.Rectangle.Zero;
                            Pango.Rectangle  logical_rect = Pango.Rectangle.Zero;
                            line.GetExtents(ref ink_rect, ref logical_rect);

                            cr.MoveTo(margin_left + indentation,
                                      cr.CurrentPoint.Y);
                            int line_height = Pango.Units.ToPixels(logical_rect.Height);

                            Cairo.PointD new_line_point = new Cairo.PointD(
                                margin_left + indentation,
                                cr.CurrentPoint.Y + line_height);

                            Pango.CairoHelper.ShowLayoutLine(cr, line);
                            cr.MoveTo(new_line_point);
                        }
                    }

                    position.ForwardLine();
                    done = done || position.Compare(end_iter) >= 0;
                }

                int total_height  = (int)args.Context.Height;
                int total_width   = (int)args.Context.Width;
                int footer_height = 0;

                Cairo.PointD footer_anchor;
                using (Pango.Layout pages_footer = CreatePagenumbersLayout(
                           args.Context, args.PageNr + 1, page_breaks.Count + 1)) {
                    Pango.Rectangle ink_footer_rect;
                    Pango.Rectangle logical_footer_rect;
                    pages_footer.GetExtents(out ink_footer_rect, out logical_footer_rect);

                    footer_anchor = new Cairo.PointD(
                        CmToPixel(0.5, args.Context.DpiX),
                        total_height - margin_bottom);
                    footer_height = Pango.Units.ToPixels(logical_footer_rect.Height);

                    cr.MoveTo(
                        total_width - Pango.Units.ToPixels(logical_footer_rect.Width) -
                        CmToPixel(0.5, args.Context.DpiX),
                        footer_anchor.Y);

                    Pango.CairoHelper.ShowLayoutLine(cr, pages_footer.Lines [0]);
                }

                cr.MoveTo(footer_anchor);
                Pango.CairoHelper.ShowLayoutLine(cr, timestamp_footer.Lines [0]);

                cr.MoveTo(CmToPixel(0.5, args.Context.DpiX),
                          total_height - margin_bottom - footer_height);
                cr.LineTo(total_width - CmToPixel(0.5, args.Context.DpiX),
                          total_height - margin_bottom - footer_height);
                cr.Stroke();
            }
        }
Пример #20
0
        public void Draw(Gtk.PrintContext context,
                         Dictionary <string, string> data,
                         Dictionary <string, DataTable> dataTables,
                         double maxYToDraw,
                         bool reallyDraw)
        {
            foreach (IShape aShape in this.shapesInSection)
            {
                if (aShape is Text)
                {
                    Text aText = (Text)aShape;
                    Console.WriteLine(aText.TextValue);

                    if (data.ContainsKey(aText.Id))
                    {
                        aText.TextValue = data[aText.Id];
                    }
                }

                else if (aShape is Table)
                {
                    Table aTable = (Table)aShape;

                    /* If the table has no data, don't draw it */
                    if (!dataTables.ContainsKey(aTable.Id))
                    {
                        continue;
                    }

                    // DataTable corresponding to the Table object
                    DataTable dataTable = dataTables[aTable.Id];

                    if (this.datarowsToDraw == null)
                    {
                        this.datarowsToDraw = new List <DataRow>();

                        // Add all DataRows
                        foreach (DataRow dr in dataTable.Rows)
                        {
                            this.datarowsToDraw.Add(dr);
                        }

                        this.originalNumberOfDataRows = this.datarowsToDraw.Count;
                    }

                    Console.WriteLine("Procesando un DataTable...");

                    Text           textTemp      = null;
                    List <Text>    textRow       = new List <Text>(aTable.NumberOfColumns);
                    List <DataRow> datarowsDrawn = new List <DataRow>();

                    foreach (DataRow dataRow in this.datarowsToDraw)
                    {
                        foreach (Text aText in aTable.LastRowAdded)
                        {
                            Console.WriteLine("   Text: " + aText.TextValue);

                            textTemp           = (Text)aText.Clone();
                            textTemp.TextValue =
                                dataRow[textTemp.Id].ToString();
                            textTemp.Y = textTemp.Y +
                                         Utils.GetPixelHeightSize(textTemp,
                                                                  context.CreatePangoLayout());

                            textRow.Add(textTemp);
                        }

                        /* We stop drawing rows if we have reached the end
                         * of the section (the start of the next one) */
                        double heightOfLastText =
                            textTemp.Y + Utils.GetPixelHeightSize(textTemp,
                                                                  context.CreatePangoLayout());
                        if (heightOfLastText > maxYToDraw)
                        {
                            break;
                        }

                        aTable.AddRow(textRow);
                        textRow.Clear();

                        /* I add the DataRow to remove it later.
                         * This is for multipage reports, where there is a lot
                         * of data. Next call to this function we will draw
                         * remaning shapes */
                        datarowsDrawn.Add(dataRow);
                    }

                    // Remove already drawn datarows
                    foreach (DataRow dr in datarowsDrawn)
                    {
                        this.datarowsToDraw.Remove(dr);
                    }
                }

                // Draw the Shape
                if (reallyDraw)
                {
                    aShape.Draw(context);
                }

                // Let's reset all tables for next iteration
                if (aShape is Table)
                {
                    (aShape as Table).Reset();
                }
            }
        }
Пример #21
0
        protected override void OnDrawPage(Gtk.PrintContext context, int page_nr)
        {
            base.OnDrawPage(context, page_nr);
            Context cr = context.CairoContext;

            int ppx, ppy;

            switch (photos_per_page)
            {
            default:
            case 1: ppx = ppy = 1; break;

            case 2: ppx = 1; ppy = 2; break;

            case 4: ppx = ppy = 2; break;

            case 9: ppx = ppy = 3; break;
            }

            //FIXME: if paper is landscape, swap ppx with ppy

            double w = context.Width / ppx;
            double h = context.Height / ppy;

            for (int x = 0; x <= ppx; x++)
            {
                for (int y = 0; y <= ppy; y++)
                {
                    int p_index = repeat ? page_nr : page_nr * photos_per_page + y * ppx + x;
                    if (crop_marks)
                    {
                        DrawCropMarks(cr, x * w, y * h, w * .1);
                    }
                    if (x == ppx || y == ppy || p_index >= selected_photos.Length)
                    {
                        continue;
                    }
                    using (ImageFile img = new ImageFile(selected_photos[p_index].DefaultVersionUri))
                    {
                        Gdk.Pixbuf pixbuf;
                        try {
                            pixbuf = img.Load();
                            FSpot.ColorManagement.ApplyPrinterProfile(pixbuf, img.GetProfile());
                        } catch (Exception e) {
                            Log.Exception("Unable to load image " + selected_photos[p_index].DefaultVersionUri + "\n", e);
                            // If the image is not found load error pixbuf
                            pixbuf = new Gdk.Pixbuf(PixbufUtils.ErrorPixbuf, 0, 0,
                                                    PixbufUtils.ErrorPixbuf.Width,
                                                    PixbufUtils.ErrorPixbuf.Height);
                        }
                        //Gdk.Pixbuf pixbuf = img.Load (100, 100);
                        bool rotated = false;
                        if (Math.Sign((double)pixbuf.Width / pixbuf.Height - 1.0) != Math.Sign(w / h - 1.0))
                        {
                            Gdk.Pixbuf d_pixbuf = pixbuf.RotateSimple(Gdk.PixbufRotation.Counterclockwise);
                            pixbuf.Dispose();
                            pixbuf  = d_pixbuf;
                            rotated = true;
                        }

                        DrawImage(cr, pixbuf, x * w, y * h, w, h);
                        DrawComment(context, (x + 1) * w, (rotated ? y : y + 1) * h, (rotated ? w : h) * .025, comment, rotated);
                        pixbuf.Dispose();
                    }
                }
            }
        }