Пример #1
0
    // Throws exception if pixmap and bitmap differ.
    void check(mupdf.Pixmap pixmap, System.Drawing.Bitmap bitmap, int pixmap_bytes_per_pixel)
    {
        long samples = pixmap.pixmap_samples_int();

        if (pixmap.pixmap_width() != bitmap.Width || pixmap.pixmap_height() != bitmap.Height)
        {
            throw new System.Exception("Inconsistent sizes:"
                                       + " pixmap=(" + pixmap.pixmap_width() + " " + pixmap.pixmap_height()
                                       + " bitmap=(" + bitmap.Width + " " + bitmap.Height
                                       );
        }
        int stride = pixmap.pixmap_stride();

        for (int x = 0; x < bitmap.Width; x += 1)
        {
            for (int y = 0; y < bitmap.Height; y += 1)
            {
                unsafe
                {
                    byte *sample = (byte *)samples + stride * y + pixmap_bytes_per_pixel * x;
                    System.Drawing.Color color = bitmap.GetPixel(x, y);
                    if (color.R != sample[0] || color.G != sample[1] || color.B != sample[2])
                    {
                        string pixmap_pixel_text = "";
                        for (int i = 0; i < pixmap_bytes_per_pixel; ++i)
                        {
                            if (i > 0)
                            {
                                pixmap_pixel_text += " ";
                            }
                            pixmap_pixel_text += sample[i];
                        }
                        throw new System.Exception("Pixels differ: (" + x + " " + y + "):"
                                                   + " pixmap: (" + pixmap_pixel_text + ")"
                                                   + " bitmap: " + color);
                    }
                }
            }
        }
    }
Пример #2
0
    // Shows page. If width and/or height are zero we use .Width and/or .Height.
    //
    // To preserve current page and/or zoom, use .page_number and/or .zoom.
    //
    public void goto_page(int page_number, double zoom)
    {
        if (page_number < 0 || page_number >= document.count_pages())
        {
            return;
        }

        this.zoom        = zoom;
        this.page_number = page_number;
        this.page        = document.load_page(page_number);

        var z = System.Math.Pow(2, this.zoom / this.zoom_multiple);

        /* For now we always use 'fit width' view semantics. */
        var page_rect     = this.page.bound_page();
        var vscroll_width = System.Windows.Forms.SystemInformation.VerticalScrollBarWidth;

        z *= (this.ClientSize.Width - vscroll_width) / (page_rect.x1 - page_rect.x0);

        if (System.Type.GetType("Mono.Runtime") != null)
        {
            /* Use pixmap data without copying. This does not work on
             * Windows.
             *
             * It looks like it's important to use MuPDF Fixed_RGB with
             * alpha=1, and C#'s Format32bppRgb. Other combinations,
             * e.g. (Fixed_RGB with alpha=0) and Format24bppRgb, result in a
             * blank display. */
            var stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Reset();
            stopwatch.Start();
            this.pixmap = this.page.new_pixmap_from_page_contents(
                new mupdf.Matrix((float)z, 0, 0, (float)z, 0, 0),
                new mupdf.Colorspace(mupdf.Colorspace.Fixed.Fixed_RGB),
                1     /*alpha*/
                );
            stopwatch.Stop();
            var t_pixmap = stopwatch.Elapsed;

            stopwatch.Reset();
            stopwatch.Start();
            this.bitmap = new System.Drawing.Bitmap(
                this.pixmap.pixmap_width(),
                this.pixmap.pixmap_height(),
                this.pixmap.pixmap_stride(),
                System.Drawing.Imaging.PixelFormat.Format32bppRgb,
                (System.IntPtr) this.pixmap.pixmap_samples_int()
                );
            stopwatch.Stop();
            var t_bitmap = stopwatch.Elapsed;

            stopwatch.Reset();
            stopwatch.Start();
            // This is slow for large pixmaps/bitmaps.
            //check(pixmap, bitmap, 4);
            stopwatch.Stop();
            var t_check = stopwatch.Elapsed;

            /*System.Console.WriteLine(""
             + " t_pixmap=" + t_pixmap
             + " t_bitmap=" + t_bitmap
             + " t_check=" + t_check
             +      );*/
        }
        else
        {
            /* Copy pixmap's pixels into bitmap. This works on both Linux
             * (Mono) and Windows.
             *
             * Unlike above, it seems that we need to use MuPDF Fixed_RGB with
             * alpha=0, and C#'s Format32bppRgb. Other combinations give a
             * blank display (possibly with alpha=0 for each pixel). */
            this.pixmap = this.page.new_pixmap_from_page_contents(
                new mupdf.Matrix((float)z, 0, 0, (float)z, 0, 0),
                new mupdf.Colorspace(mupdf.Colorspace.Fixed.Fixed_RGB),
                0     /*alpha*/
                );

            this.bitmap = new System.Drawing.Bitmap(
                this.pixmap.pixmap_width(),
                this.pixmap.pixmap_height(),
                System.Drawing.Imaging.PixelFormat.Format32bppRgb
                );
            long samples = pixmap.pixmap_samples_int();
            int  stride  = pixmap.pixmap_stride();
            for (int x = 0; x < bitmap.Width; x += 1)
            {
                for (int y = 0; y < bitmap.Height; y += 1)
                {
                    unsafe
                    {
                        byte *sample = (byte *)samples + stride * y + 3 * x;
                        var   color  = System.Drawing.Color.FromArgb(sample[0], sample[1], sample[2]);
                        this.bitmap.SetPixel(x, y, color);
                    }
                }
            }
            //check(pixmap, bitmap, 3);
        }
        this.picture_box.Image = this.bitmap;
    }