Пример #1
0
        public static void DrawHorizontalLine(IndexedImage image, int x, int y, int length, int argb, int width = 1)
        {
            if (x < 0)
            {
                length += x;
                x       = 0;
            }

            var maxLength = image.Size.Width - x;

            if (length >= maxLength)
            {
                length = maxLength;
            }

            var maxWidth = image.Size.Height - y;

            if (width > maxWidth)
            {
                width = maxWidth;
            }

            if (length <= 0 || y < 0 || y >= image.Size.Height)
            {
                return;
            }

            for (int i = 0, startIndex = y * image.Size.Width + x; i < width; i++, startIndex += image.Size.Width)
            {
                DrawLine(image, startIndex, startIndex + length, 1, argb);
            }
        }
Пример #2
0
        static Rectangle CorrectRect(IndexedImage image, Rectangle rect)
        {
            if (rect.Left < 0)
            {
                rect.Width += rect.Left;
                rect.Left   = 0;
            }
            if (rect.Top < 0)
            {
                rect.Height += rect.Top;
                rect.Top     = 0;
            }

            var maxWidth = image.Size.Width - rect.Left;

            if (rect.Width > maxWidth)
            {
                rect.Width = maxWidth;
            }

            var maxHeight = image.Size.Height - rect.Top;

            if (rect.Height > maxHeight)
            {
                rect.Height = maxHeight;
            }

            return(rect);
        }
Пример #3
0
        public void TestCropRect()
        {
            var srcImage = new IndexedImage {
                Size = new Size(5, 5)
            };

            int[] pixels;
            using (srcImage.LockPixels(out pixels))
            {
                for (int i = 0; i < pixels.Length; i++)
                {
                    pixels[i] = i;
                }
            }

            var dstImage = ImageCropper.Crop(srcImage, new Rectangle(2, 1, 2, 3), ImageCropper.CropKind.Rectangle);

            Assert.AreEqual(new Size(2, 3), dstImage.Size);
            using (dstImage.LockPixels(out pixels))
            {
                Assert.AreEqual(6, pixels.Length);
                Assert.AreEqual(7, pixels[0]);
                Assert.AreEqual(8, pixels[1]);
                Assert.AreEqual(12, pixels[2]);
                Assert.AreEqual(13, pixels[3]);
                Assert.AreEqual(17, pixels[4]);
                Assert.AreEqual(18, pixels[5]);
            }
        }
Пример #4
0
        public static void DrawVerticalLine(IndexedImage image, int x, int y, int length, int argb, int width = 1)
        {
            if (y < 0)
            {
                length += y;
                y       = 0;
            }

            var maxLength = image.Size.Height - y;

            if (length >= maxLength)
            {
                length = maxLength;
            }

            var maxWidth = image.Size.Width - x;

            if (width > maxWidth)
            {
                width = maxWidth;
            }

            if (length <= 0 || x < 0 || x >= image.Size.Width)
            {
                return;
            }

            for (int i = 0, startIndex = y * image.Size.Width + x, lastIndexExclusive = startIndex + length * image.Size.Width; i < width; i++, startIndex++, lastIndexExclusive++)
            {
                DrawLine(image, startIndex, lastIndexExclusive, image.Size.Width, argb);
            }
        }
Пример #5
0
    public static ImportResult ImportImage(ProjectTree projectTree, string imageFileName, string arrangerKey)
    {
        Console.Write($"Importing '{imageFileName}' to '{arrangerKey}'...");

        if (!File.Exists(imageFileName))
        {
            Console.WriteLine($"File does not exist");
            return(ImportResult.MissingFile);
        }

        if (!projectTree.TryGetItem(arrangerKey, out ScatteredArranger arranger))
        {
            Console.WriteLine($"Resource key does not exist or is not a {nameof(ScatteredArranger)}");
            return(ImportResult.BadResourceKey);
        }

        if (arranger.ColorType == PixelColorType.Indexed)
        {
            var image = new IndexedImage(arranger);
            image.ImportImage(imageFileName, new ImageSharpFileAdapter(), ColorMatchStrategy.Exact);
            image.SaveImage();
        }
        else if (arranger.ColorType == PixelColorType.Direct)
        {
            var image = new DirectImage(arranger);
            image.ImportImage(imageFileName, new ImageSharpFileAdapter());
            image.SaveImage();
        }

        Console.WriteLine("Completed successfully");
        return(ImportResult.Success);
    }
Пример #6
0
        public void TestFlipHorizontallyInPlace()
        {
            var srcImage = new IndexedImage {
                Size = new Size(3, 2)
            };

            int[] pixels;
            using (srcImage.LockPixels(out pixels))
            {
                for (int i = 0; i < pixels.Length; i++)
                {
                    pixels[i] = i;
                }
            }

            var dstImage = ImageRotator.FlipHorizontallyInPlace(srcImage);

            Assert.AreSame(srcImage, dstImage);
            Assert.AreEqual(new Size(3, 2), dstImage.Size);
            using (dstImage.LockPixels(out pixels))
            {
                Assert.AreEqual(2, pixels[0]);
                Assert.AreEqual(1, pixels[1]);
                Assert.AreEqual(0, pixels[2]);
                Assert.AreEqual(5, pixels[3]);
                Assert.AreEqual(4, pixels[4]);
                Assert.AreEqual(3, pixels[5]);
            }
        }
 public VisualPatternGridController(IImageProvider imageProvider, TrueTypeFont symbolsFont, IndexedImage whiteCrosses, Size imageBoxSize = default(Size))
     : base(imageProvider, imageBoxSize)
 {
     WhiteCrosses = whiteCrosses;
     SymbolsFont  = symbolsFont;
     imageProvider.Image.PixelChanged += Image_PixelChanged;
 }
Пример #8
0
        public void TestResampleWithCrop()
        {
            var sourceImage = new IndexedImage();

            sourceImage.Size = new Size(43, 37);
            var random = new Random();

            for (int i = 0; i < sourceImage.Pixels.Length; i++)
            {
                sourceImage.Pixels[i] = random.Next();
            }

            var newSize            = new Size(71, 59);
            var fullResampledImage = new ImageResampler().Resample(sourceImage, newSize, ImageResampler.FilterType.Lanczos3);

            Assert.AreEqual(newSize, fullResampledImage.Size);

            var frame = new Rectangle(7, 11, 23, 19);
            var croppedResampledImage = new ImageResampler().Resample(sourceImage, newSize, ImageResampler.FilterType.Lanczos3, frame);

            Assert.AreEqual(new Size(frame.Width, frame.Height), croppedResampledImage.Size);

            for (int y = 0; y < frame.Height; y++)
            {
                for (int x = 0; x < frame.Width; x++)
                {
                    Assert.AreEqual(fullResampledImage.Pixels[(y + frame.Top) * fullResampledImage.Size.Width + (x + frame.Left)], croppedResampledImage.Pixels[y * croppedResampledImage.Size.Width + x]);
                }
            }
        }
Пример #9
0
        public void TestDrawVerticalLine()
        {
            var image = new IndexedImage {
                Size = new Size(5, 5)
            };

            ImagePainter.DrawVerticalLine(image, 1, 1, 5, 1, 2);
            AssertImage(
                new[]
            {
                0, 0, 0, 0, 0,
                0, 1, 1, 0, 0,
                0, 1, 1, 0, 0,
                0, 1, 1, 0, 0,
                0, 1, 1, 0, 0
            },
                image);

            ImagePainter.DrawVerticalLine(image, 3, 0, 4, 2, 1);
            AssertImage(
                new[]
            {
                0, 0, 0, 2, 0,
                0, 1, 1, 2, 0,
                0, 1, 1, 2, 0,
                0, 1, 1, 2, 0,
                0, 1, 1, 0, 0
            },
                image);
        }
Пример #10
0
        void IPainter.PaintImage(IndexedImage image, Point atPoint)
        {
            var bitmap = ToBitmap(image);
            var xImage = XImage.FromGdiPlusImage(bitmap);

            PdfGraphics.DrawImage(xImage, new System.Drawing.Point(atPoint.X + Shift.Width, atPoint.Y + Shift.Height));
        }
Пример #11
0
        public void TestNewColor()
        {
            CodedPalette palette =
                new CodedPalette
            {
                new Color(1),
                new CodedColor(2)
            };

            Assert.AreEqual(typeof(CodedColor), palette[1].GetType());
            Assert.AreEqual(typeof(CodedColor), palette[2].GetType());

            IndexedImage image = new IndexedImage {
                Size = new Size(2, 2)
            };

            int[] pixels;
            using (image.LockPixels(out pixels))
            {
                pixels[0] = 0;
                pixels[1] = 1;
                pixels[2] = 2;
                pixels[3] = 1;
            }

            image.Palette = new CodedPalette();
            image.CompletePalette();

            Assert.AreEqual(3, image.Palette.Count);
            foreach (var color in image.Palette)
            {
                Assert.AreEqual(typeof(CodedColor), color.GetType());
            }
        }
Пример #12
0
        void AssertShiftPixels(IndexedImage image, int dx, int dy, bool shouldBeSame)
        {
            var sourcePixels = new int[image.Pixels.Length];

            image.Pixels.CopyTo(sourcePixels, 0);

            ImageShifter.ShiftPixels(image, dx, dy);

            for (int y = 0; y < image.Size.Height; y++)
            {
                for (int x = 0; x < image.Size.Width; x++)
                {
                    var srcIndex = y * image.Size.Width + x;

                    if (shouldBeSame)
                    {
                        Assert.AreEqual(sourcePixels[srcIndex], image.Pixels[srcIndex]);
                    }
                    else
                    {
                        var sy = y + dy;
                        var sx = x + dx;
                        if (sy >= 0 && sy < image.Size.Height && sx >= 0 && sx < image.Size.Width)
                        {
                            var dstIndex = sy * image.Size.Width + sx;
                            Assert.AreEqual(sourcePixels[srcIndex], image.Pixels[dstIndex]);
                        }
                    }
                }
            }
        }
Пример #13
0
        public void TestShiftPixels()
        {
            var srcImage = new IndexedImage {
                Size = new Size(10, 8)
            };

            for (int y = 0; y < srcImage.Size.Height; y++)
            {
                for (int x = 0; x < srcImage.Size.Width; x++)
                {
                    srcImage.Pixels[y * srcImage.Size.Width + x] = y * 100 + x;
                }
            }

            AssertShiftPixels(srcImage, 0, 0, true);

            AssertShiftPixels(srcImage, 0, 3, false);
            AssertShiftPixels(srcImage, 0, -3, false);
            AssertShiftPixels(srcImage, 2, 0, false);
            AssertShiftPixels(srcImage, 2, 3, false);
            AssertShiftPixels(srcImage, 2, -3, false);
            AssertShiftPixels(srcImage, -2, 0, false);
            AssertShiftPixels(srcImage, -2, 3, false);
            AssertShiftPixels(srcImage, -2, -3, false);

            AssertShiftPixels(srcImage, 10, 0, true);
            AssertShiftPixels(srcImage, -10, 0, true);
            AssertShiftPixels(srcImage, 0, 8, true);
            AssertShiftPixels(srcImage, 0, -8, true);
        }
Пример #14
0
        /// <summary>
        /// Creates cropped copy of source picture.
        /// </summary>
        /// <param name="sourceImage">Source picture instance.</param>
        /// <param name="cropRect">Rectange with cropping bounds.</param>
        /// <param name="cropKind">Cropping method.</param>
        /// <param name="destImage">Destionation <see cref="IndexedImage"/> object or null.</param>
        /// <returns>New or updated <see cref="IndexedImage"/> object with cropped picture.</returns>
        public static IndexedImage Crop(IndexedImage sourceImage, Rectangle cropRect, CropKind cropKind = CropKind.Rectangle, IndexedImage destImage = null)
        {
            Debug.Assert(destImage != sourceImage, "It's impossible to crop image into itself.");

            if (destImage == null)
            {
                destImage = new IndexedImage();
            }

            if (cropKind == CropKind.None)
            {
                destImage.Size = sourceImage.Size;
                sourceImage.Pixels.CopyTo(destImage.Pixels, 0);
            }
            else
            {
                destImage.Size = new Size(cropRect.Width, cropRect.Height);
                switch (cropKind)
                {
                case CropKind.Arc:
                    CropArc(sourceImage.Pixels, destImage.Pixels, sourceImage.Size, cropRect);
                    break;

                case CropKind.Rectangle:
                default:
                    CropRect(sourceImage.Pixels, destImage.Pixels, sourceImage.Size, cropRect);
                    break;
                }
            }

            return(destImage);
        }
Пример #15
0
        public void TestColorUsageOccurrences()
        {
            IndexedImage image = new IndexedImage {
                Size = new Size(3, 2)
            };

            image.Pixels[0] = 1;
            image.Pixels[1] = 2;
            image.Pixels[2] = 3;
            image.Pixels[3] = 1;
            image.Pixels[4] = 4;
            image.Pixels[5] = 2;
            image.CompletePalette();

            Assert.AreEqual(4, image.Palette.Count);
            PaletteTest.AssertColorInPalette(image.Palette, 1, 1, 0, 3);
            PaletteTest.AssertColorInPalette(image.Palette, 2, 2, 1, 5);
            PaletteTest.AssertColorInPalette(image.Palette, 3, 3, 2);
            PaletteTest.AssertColorInPalette(image.Palette, 4, 4, 4);

            image[1, 1] = new Color(1);

            Assert.AreEqual(3, image.Palette.Count);
            PaletteTest.AssertColorInPalette(image.Palette, 1, 1, 0, 3, 4);

            image[1, 1] = new Color(5);

            Assert.AreEqual(4, image.Palette.Count);
            PaletteTest.AssertColorInPalette(image.Palette, 1, 1, 0, 3);
            PaletteTest.AssertColorInPalette(image.Palette, 5, 5, 4);
        }
Пример #16
0
        public void TestPixels()
        {
            IndexedImage image = new IndexedImage {
                Size = new Size(3, 2)
            };

            image.Pixels[0] = 1;
            image.Pixels[1] = 2;
            image.Pixels[2] = 3;
            image.Pixels[3] = 4;
            image.Pixels[4] = 5;
            image.Pixels[5] = 6;
            image.CompletePalette();

            Assert.AreEqual(1, image[0, 0].Argb);
            Assert.AreEqual(2, image[1, 0].Argb);
            Assert.AreEqual(3, image[2, 0].Argb);
            Assert.AreEqual(4, image[0, 1].Argb);
            Assert.AreEqual(5, image[1, 1].Argb);
            Assert.AreEqual(6, image[2, 1].Argb);

            image[0, 0] = new Color(100);
            image[1, 0] = new Color(200);
            image[2, 0] = new Color(400);
            image[0, 1] = new Color(800);
            image[1, 1] = new Color(1600);
            image[2, 1] = new Color(3200);

            Assert.AreEqual(100, image.Pixels[0]);
            Assert.AreEqual(200, image.Pixels[1]);
            Assert.AreEqual(400, image.Pixels[2]);
            Assert.AreEqual(800, image.Pixels[3]);
            Assert.AreEqual(1600, image.Pixels[4]);
            Assert.AreEqual(3200, image.Pixels[5]);
        }
Пример #17
0
        private IndexedImage CreateNewImageWithPalette(IndexedImage sourceImage, Palette palette, IndexedImage destImage)
        {
            if (destImage == null)
            {
                destImage = sourceImage.Clone(false);
            }
            destImage.Size    = sourceImage.Size;
            destImage.Palette = palette.Clone();

            var destPixels = destImage.Pixels;

            var searcher = new PaletteQuickColorSearcher(palette);

            Parallel.ForEach(sourceImage.Palette,
                             sourceColor =>
            {
                Color substColor = searcher.SearchSubstitute(sourceColor);
                Debug.Assert(substColor != null, "Substitute color was not found.");
                foreach (int occurrence in sourceColor.UsageOccurrences)
                {
                    destPixels[occurrence] = substColor.Argb;
                }
            });

            return(destImage);
        }
Пример #18
0
    public static MagitekResult CopyPixels(IndexedImage source, DirectImage dest, Point sourceStart, Point destStart, int copyWidth, int copyHeight)
    {
        var dimensionResult = CanCopyPixelDimensions(source, dest, sourceStart, destStart, copyWidth, copyHeight);

        if (dimensionResult.Value is MagitekResult.Failed)
        {
            return(dimensionResult);
        }

        if (ImageRegionContainsInvalidElements(source, sourceStart, copyWidth, copyHeight))
        {
            return(new MagitekResult.Failed($"Source image copy region contains blank elements"));
        }

        if (ImageRegionContainsInvalidElements(dest, destStart, copyWidth, copyHeight))
        {
            return(new MagitekResult.Failed($"Destination image paste region contains blank elements"));
        }

        for (int y = 0; y < copyHeight; y++)
        {
            for (int x = 0; x < copyWidth; x++)
            {
                var color = source.GetPixelColor(x + sourceStart.X, y + sourceStart.Y);
                dest.SetPixel(x + destStart.X, y + destStart.Y, color);
            }
        }

        return(MagitekResult.SuccessResult);
    }
Пример #19
0
        public void TestFillRect()
        {
            var image = new IndexedImage {
                Size = new Size(5, 5)
            };

            ImagePainter.FillRect(image, new Rectangle(2, 1, 4, 2), 1);
            AssertImage(
                new[]
            {
                0, 0, 0, 0, 0,
                0, 0, 1, 1, 1,
                0, 0, 1, 1, 1,
                0, 0, 0, 0, 0,
                0, 0, 0, 0, 0
            },
                image);

            ImagePainter.FillRect(image, new Rectangle(1, 2, 2, 2), 2);
            AssertImage(
                new[]
            {
                0, 0, 0, 0, 0,
                0, 0, 1, 1, 1,
                0, 2, 2, 1, 1,
                0, 2, 2, 0, 0,
                0, 0, 0, 0, 0
            },
                image);
        }
Пример #20
0
        /// <summary>
        /// Converts <see cref="Ravlyk.Drawing.IndexedImage"/> object to <see cref="System.Drawing.Bitmap"/> one with explicit operation.
        /// </summary>
        /// <param name="image">Source <see cref="Ravlyk.Drawing.IndexedImage"/> object.</param>
        /// <returns>New <see cref="System.Drawing.Bitmap"/> object with pixels copied from source image.</returns>
        public static Bitmap ToBitmap(this IndexedImage image)
        {
            Bitmap bitmap = new Bitmap(image.Size.Width, image.Size.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            UpdateBitmap(image, bitmap);
            return(bitmap);
        }
Пример #21
0
        public void TestCropArc()
        {
            var srcImage = new IndexedImage {
                Size = new Size(10, 10)
            };

            int[] pixels;
            using (srcImage.LockPixels(out pixels))
            {
                for (int i = 0; i < pixels.Length; i++)
                {
                    pixels[i] = 100;
                }
            }

            var dstImage = ImageCropper.Crop(srcImage, new Rectangle(1, 1, 8, 8), ImageCropper.CropKind.Arc);

            dstImage.CompletePalette();

            Assert.AreEqual(new Size(8, 8), dstImage.Size);
            Assert.AreEqual(new Color(255, 255, 255), dstImage[0, 0]);
            Assert.AreEqual(new Color(255, 255, 255), dstImage[0, 7]);
            Assert.AreEqual(new Color(255, 255, 255), dstImage[7, 0]);
            Assert.AreEqual(new Color(255, 255, 255), dstImage[7, 7]);
            Assert.AreEqual(new Color(100), dstImage[4, 4], "Some point in the centre");
        }
Пример #22
0
 static void DrawLine(IndexedImage image, int startIndex, int lastIndexExclusive, int step, int argb)
 {
     for (int index = startIndex; index < lastIndexExclusive; index += step)
     {
         image.Pixels[index] = argb;
     }
 }
Пример #23
0
        public void TestOnPixelChanged()
        {
            var image = new IndexedImage {
                Size = new Size(2, 3)
            };

            image.Palette = new Palette();
            image[1, 2]   = new Color(1, 2, 3);

            bool eventFired = false;

            image.PixelChanged +=
                (sender, e) =>
            {
                eventFired = true;
                Assert.AreSame(image, sender);
                Assert.AreEqual(1, e.X);
                Assert.AreEqual(2, e.Y);
                Assert.AreEqual(new Color(1, 2, 3), e.OldColor);
                Assert.AreEqual(new Color(10, 20, 30), e.NewColor);
            };

            Assert.IsFalse(eventFired, "Precondition");
            image[1, 2] = new Color(10, 20, 30);
            Assert.IsTrue(eventFired);
        }
Пример #24
0
 void IPainter.PaintImage(IndexedImage image, Point atPoint)
 {
     using (var bitmap = ToBitmap(image))
     {
         GdiGraphics.DrawImage(bitmap, new GdiPoint(atPoint.X + Shift.Width, atPoint.Y + Shift.Height));
     }
 }
Пример #25
0
 public void PaintSymbol(char c, IndexedImage image, Point atPoint, Rectangle clipRect = default(Rectangle), int fontRgb = 0, int backgroundRgb = 0x00ffffff)
 {
     int[] imagePixels;
     using (image.LockPixels(out imagePixels))
     {
         PaintSymbol(c, imagePixels, image.Size, atPoint, clipRect, fontRgb, backgroundRgb);
     }
 }
Пример #26
0
 public void PaintText(string text, IndexedImage image, Point startPoint, Rectangle clipRect = default(Rectangle), int spaceBetweenCharacters = 1, int fontRgb = 0, TextDirection direction = TextDirection.LeftToRight, bool multithread = false)
 {
     int[] imagePixels;
     using (image.LockPixels(out imagePixels))
     {
         PaintText(text, imagePixels, image.Size, startPoint, clipRect, spaceBetweenCharacters, fontRgb, direction, multithread);
     }
 }
Пример #27
0
 void AssertImage(int[] expectedPixels, IndexedImage image)
 {
     Assert.AreEqual(expectedPixels.Length, image.Pixels.Length);
     for (int i = 0; i < expectedPixels.Length; i++)
     {
         Assert.AreEqual(expectedPixels[i], image.Pixels[i], "Pixel in position " + i);
     }
 }
Пример #28
0
        public CrossPainter(int pixelHeight, IndexedImage whiteCrosses, Palette allColors)
        {
            Debug.Assert(whiteCrosses != null, "whiteCrosses should not be null");

            PixelHeight  = pixelHeight;
            WhiteCrosses = new ImageResampler().Resample(whiteCrosses, new Size(CrossesPerWhiteImageGridSize * pixelHeight, CrossesPerWhiteImageGridSize * pixelHeight), ImageResampler.FilterType.Lanczos3);

            InitializeCrossesForAllColors(allColors);
        }
Пример #29
0
    public IndexedBitmapAdapter(IndexedImage image)
    {
        Image  = image;
        Width  = Image.Width;
        Height = Image.Height;

        Bitmap = new WriteableBitmap(Width, Height, DpiX, DpiY, PixelFormat, null);
        Invalidate();
    }
Пример #30
0
        internal void ShiftImageAndUpdateRest(IPainter painter, IndexedImage canvas, Point imageStartPoint, Size shiftDelta)
        {
            var pixelShift = new Size(shiftDelta.Width * CellSize, shiftDelta.Height * CellSize);

            ImageShifter.ShiftPixels(canvas, -pixelShift.Width, -pixelShift.Height);

            if (shiftDelta.Height != 0)
            {
                if (shiftDelta.Height < 0)                 // Shifting down - repaint rows at top
                {
                    using (painter.Clip(new Rectangle(0, 0, canvas.Size.Width, RulerWidth - pixelShift.Height)))
                    {
                        Paint(painter, canvas.Size, painter.ClipRect, imageStartPoint);
                    }
                }
                else                 // Shifting up - repaint rows at bottom
                {
                    using (painter.Clip(new Rectangle(0, canvas.Size.Height - pixelShift.Height, canvas.Size.Width, pixelShift.Height)))
                    {
                        Paint(painter, canvas.Size, painter.ClipRect, imageStartPoint);
                    }
                    if (ShowRulers)
                    {
                        using (painter.Clip(new Rectangle(0, 0, canvas.Size.Width, RulerWidth)))
                        {
                            Paint(painter, canvas.Size, painter.ClipRect, imageStartPoint);
                        }
                    }
                }
            }

            if (shiftDelta.Width != 0)
            {
                if (shiftDelta.Width < 0)                 // Shifting right - repaint columns at left
                {
                    using (painter.Clip(new Rectangle(0, 0, RulerWidth - pixelShift.Width, canvas.Size.Height)))
                    {
                        Paint(painter, canvas.Size, painter.ClipRect, imageStartPoint);
                    }
                }
                else                 // Shift left - repaint columns at right
                {
                    using (painter.Clip(new Rectangle(canvas.Size.Width - pixelShift.Width, 0, pixelShift.Width, canvas.Size.Height)))
                    {
                        Paint(painter, canvas.Size, painter.ClipRect, imageStartPoint);
                    }
                    if (ShowRulers)
                    {
                        using (painter.Clip(new Rectangle(0, 0, RulerWidth, canvas.Size.Height)))
                        {
                            Paint(painter, canvas.Size, painter.ClipRect, imageStartPoint);
                        }
                    }
                }
            }
        }