Пример #1
0
 public override sealed void Render(Surface dst, Point offset)
 {
     if (ShouldRender())
     {
         using (RenderArgs ra = new RenderArgs(dst))
         {
             RenderToGraphics(ra.Graphics, offset);
         }
     }
 }
Пример #2
0
 private void OnThumbnailUpdated(DocumentWorkspace dw)
 {
     // We must double check that the DW is still around, because there's a chance
     // that the DW was been removed while the thumbnail was being rendered.
     if (this.dw2button.ContainsKey(dw))
     {
         ImageStrip.Item docButton = this.dw2button[dw];
         RenderArgs      docRA     = this.thumbs[dw];
         docButton.Image = docRA.Bitmap;
         docButton.Update();
     }
 }
Пример #3
0
        /// <summary>
        /// Causes the layer to render a given region of interest (roi) to the given destination surface.
        /// </summary>
        /// <param name="args">Contains information about which objects to use for rendering</param>
        /// <param name="roi">The region to be rendered.</param>
        public void Render(RenderArgs args, PdnRegion roi)
        {
            Rectangle roiBounds = roi.GetBoundsInt();

            if (!IsInBounds(roiBounds))
            {
                throw new ArgumentOutOfRangeException("roi");
            }

            Rectangle[] rects = roi.GetRegionScansReadOnlyInt();
            RenderImpl(args, rects);
        }
Пример #4
0
        public void Flatten(Surface dst)
        {
            if (dst.Size != this.Size)
            {
                throw new ArgumentOutOfRangeException("dst.Size must match this.Size");
            }

            dst.Clear(ColorBgra.White.NewAlpha(0));

            using (RenderArgs renderArgs = new RenderArgs(dst))
            {
                Render(renderArgs, true);
            }
        }
Пример #5
0
        /// <summary>
        /// Causes the layer to render a given rectangle of interest (roi) to the given destination surface.
        /// </summary>
        /// <param name="args">Contains information about which objects to use for rendering</param>
        /// <param name="roi">The rectangular region to be rendered.</param>
        public void Render(RenderArgs args, Rectangle roi)
        {
            // the bitmap we're rendering to must match the size of the layer we're rendering from
            if (args.Surface.Width != Width || args.Surface.Height != Height)
            {
                throw new ArgumentException();
            }

            // the region of interest can not be out of bounds!
            if (!IsInBounds(roi))
            {
                throw new ArgumentOutOfRangeException("roi");
            }

            RenderImpl(args, roi);
        }
Пример #6
0
        public static void Save(Document input, Stream output, Surface scratchSurface, ImageFormat format, ProgressEventHandler callback)
        {
            // flatten the document
            scratchSurface.Clear(ColorBgra.FromBgra(0, 0, 0, 0));

            using (RenderArgs ra = new RenderArgs(scratchSurface))
            {
                input.Render(ra, true);
            }

            using (Bitmap bitmap = scratchSurface.CreateAliasedBitmap())
            {
                LoadProperties(bitmap, input);
                bitmap.Save(output, format);
            }
        }
Пример #7
0
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this.backBuffer != null)
                {
                    this.backBuffer.Dispose();
                    this.backBuffer = null;
                }

                if (this.backBufferSurface != null)
                {
                    this.backBufferSurface.Dispose();
                    this.backBufferSurface = null;
                }
            }

            base.Dispose(disposing);
        }
Пример #8
0
        /// <summary>
        /// Draws an area of the SurfaceBox.
        /// </summary>
        /// <param name="ra">The rendering surface object to draw to.</param>
        /// <param name="offset">The virtual offset of ra, in client (destination) coordinates.</param>
        /// <remarks>
        /// If drawing to ra.Surface or ra.Bitmap, copy the roi of the source surface to (0,0) of ra.Surface or ra.Bitmap
        /// If drawing to ra.Graphics, copy the roi of the surface to (roi.X, roi.Y) of ra.Graphics
        /// </remarks>
        private unsafe void DrawArea(RenderArgs ra, Point offset)
        {
            if (surface == null)
            {
                return;
            }

            if (renderContext == null || (renderContext.windows != null && renderContext.windows.Length != Processor.LogicalCpuCount))
            {
                renderContext              = new RenderContext();
                renderContext.owner        = this;
                renderContext.waitCallback = new WaitCallback(renderContext.RenderThreadMethod);
                renderContext.windows      = new Surface[Processor.LogicalCpuCount];
                renderContext.offsets      = new Point[Processor.LogicalCpuCount];
                renderContext.rects        = new Rectangle[Processor.LogicalCpuCount];
            }

            Utility.SplitRectangle(ra.Bounds, renderContext.rects);

            for (int i = 0; i < renderContext.rects.Length; ++i)
            {
                if (renderContext.rects[i].Width > 0 && renderContext.rects[i].Height > 0)
                {
                    renderContext.offsets[i] = new Point(renderContext.rects[i].X + offset.X, renderContext.rects[i].Y + offset.Y);
                    renderContext.windows[i] = ra.Surface.CreateWindow(renderContext.rects[i]);
                }
                else
                {
                    renderContext.windows[i] = null;
                }
            }

            for (int i = 0; i < renderContext.windows.Length; ++i)
            {
                if (renderContext.windows[i] != null)
                {
                    this.threadPool.QueueUserWorkItem(renderContext.waitCallback, BoxedConstants.GetInt32(i));
                }
            }

            this.threadPool.Drain();
        }
Пример #9
0
        private void OnPaintImpl(PaintEventArgs2 e)
        {
            using (Surface doubleBuffer = GetDoubleBuffer(e.ClipRectangle.Size))
            {
                using (RenderArgs renderArgs = new RenderArgs(doubleBuffer))
                {
                    OnPrePaint(e);
                    DrawArea(renderArgs, e.ClipRectangle.Location);
                    OnPainted(e);

                    IntPtr tracking;
                    Point  childOffset;
                    Size   parentSize;
                    doubleBuffer.GetDrawBitmapInfo(out tracking, out childOffset, out parentSize);

                    PdnGraphics.DrawBitmap(e.Graphics, e.ClipRectangle, e.Graphics.Transform,
                                           tracking, childOffset.X, childOffset.Y);
                }
            }
        }
Пример #10
0
        public void Render(RenderArgs args, Rectangle[] roi, int startIndex, int length, bool clearBackground)
        {
            int startLayerIndex;

            if (clearBackground)
            {
                BitmapLayer layer0;
                layer0 = this.layers[0] as BitmapLayer;

                // Special case: if the first layer is a visible BitmapLayer with full opacity using
                // the default blend op, we can just copy the pixels straight over
                if (layer0 != null &&
                    layer0.Visible &&
                    layer0.Opacity == 255 &&
                    layer0.BlendOp.GetType() == UserBlendOps.GetDefaultBlendOp())
                {
                    args.Surface.CopySurface(layer0.Surface, roi, startIndex, length);
                    startLayerIndex = 1;
                }
                else
                {
                    ClearBackground(args.Surface, roi, startIndex, length);
                    startLayerIndex = 0;
                }
            }
            else
            {
                startLayerIndex = 0;
            }

            for (int i = startLayerIndex; i < this.layers.Count; ++i)
            {
                Layer layer = (Layer)this.layers[i];

                if (layer.Visible)
                {
                    layer.RenderUnchecked(args, roi, startIndex, length);
                }
            }
        }
Пример #11
0
        protected override void OnSaveT(Document input, Stream output, PropertyBasedSaveConfigToken token, Surface scratchSurface, ProgressEventHandler progressCallback)
        {
            int quality = token.GetProperty <Int32Property>(PropertyNames.Quality).Value;

            ImageCodecInfo    icf   = GdiPlusFileType.GetImageCodecInfo(ImageFormat.Jpeg);
            EncoderParameters parms = new EncoderParameters(1);
            EncoderParameter  parm  = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);

            parms.Param[0] = parm;

            scratchSurface.Clear(ColorBgra.White);

            using (RenderArgs ra = new RenderArgs(scratchSurface))
            {
                input.Render(ra, false);
            }

            using (Bitmap bitmap = scratchSurface.CreateAliasedBitmap())
            {
                GdiPlusFileType.LoadProperties(bitmap, input);
                bitmap.Save(output, icf, parms);
            }
        }
Пример #12
0
        public void RemoveDocumentWorkspace(DocumentWorkspace removeMe)
        {
            removeMe.CompositionUpdated -= Workspace_CompositionUpdated;

            if (this.selectedDocument == removeMe)
            {
                this.selectedDocument = null;
            }

            removeMe.DocumentChanging -= Workspace_DocumentChanging;
            removeMe.DocumentChanged  -= Workspace_DocumentChanged;

            if (removeMe.Document != null)
            {
                removeMe.Document.DirtyChanged -= Document_DirtyChanged;
            }

            this.documents.Remove(removeMe);
            this.thumbnailManager.RemoveFromQueue(removeMe);

            ImageStrip.Item docButton = this.dw2button[removeMe];
            this.RemoveItem(docButton);
            this.dw2button.Remove(removeMe);
            this.documentButtons.Remove(docButton);

            if (this.thumbs.ContainsKey(removeMe))
            {
                RenderArgs thumbRA = this.thumbs[removeMe];
                Surface    surface = thumbRA.Surface;
                thumbRA.Dispose();
                this.thumbs.Remove(removeMe);
                surface.Dispose();
            }

            OnDocumentListChanged();
        }
Пример #13
0
        private void DrawGradient(Graphics g)
        {
            g.PixelOffsetMode = PixelOffsetMode.Half;
            Rectangle gradientRect;

            float gradientAngle;

            switch (this.orientation)
            {
            case Orientation.Horizontal:
                gradientAngle = 180.0f;
                break;

            case Orientation.Vertical:
                gradientAngle = 90.0f;
                break;

            default:
                throw new InvalidEnumArgumentException();
            }

            // draw gradient
            gradientRect = ClientRectangle;

            switch (this.orientation)
            {
            case Orientation.Horizontal:
                gradientRect.Inflate(-triangleHalfLength, -triangleSize + 3);
                break;

            case Orientation.Vertical:
                gradientRect.Inflate(-triangleSize + 3, -triangleHalfLength);
                break;

            default:
                throw new InvalidEnumArgumentException();
            }

            if (this.customGradient != null && gradientRect.Width > 1 && gradientRect.Height > 1)
            {
                Surface gradientSurface = new Surface(gradientRect.Size);

                using (RenderArgs ra = new RenderArgs(gradientSurface))
                {
                    Utility.DrawColorRectangle(ra.Graphics, ra.Bounds, Color.Transparent, false);

                    if (Orientation == Orientation.Horizontal)
                    {
                        for (int x = 0; x < gradientSurface.Width; ++x)
                        {
                            // TODO: refactor, double buffer, save this computation in a bitmap somewhere
                            double index  = (double)(x * (this.customGradient.Length - 1)) / (double)(gradientSurface.Width - 1);
                            int    indexL = (int)Math.Floor(index);
                            double t      = 1.0 - (index - indexL);
                            int    indexR = (int)Math.Min(this.customGradient.Length - 1, Math.Ceiling(index));
                            Color  colorL = this.customGradient[indexL];
                            Color  colorR = this.customGradient[indexR];

                            double a1 = colorL.A / 255.0;
                            double r1 = colorL.R / 255.0;
                            double g1 = colorL.G / 255.0;
                            double b1 = colorL.B / 255.0;

                            double a2 = colorR.A / 255.0;
                            double r2 = colorR.R / 255.0;
                            double g2 = colorR.G / 255.0;
                            double b2 = colorR.B / 255.0;

                            double at = (t * a1) + ((1.0 - t) * a2);

                            double rt;
                            double gt;
                            double bt;
                            if (at == 0)
                            {
                                rt = 0;
                                gt = 0;
                                bt = 0;
                            }
                            else
                            {
                                rt = ((t * a1 * r1) + ((1.0 - t) * a2 * r2)) / at;
                                gt = ((t * a1 * g1) + ((1.0 - t) * a2 * g2)) / at;
                                bt = ((t * a1 * b1) + ((1.0 - t) * a2 * b2)) / at;
                            }

                            int ap = Utility.Clamp((int)Math.Round(at * 255.0), 0, 255);
                            int rp = Utility.Clamp((int)Math.Round(rt * 255.0), 0, 255);
                            int gp = Utility.Clamp((int)Math.Round(gt * 255.0), 0, 255);
                            int bp = Utility.Clamp((int)Math.Round(bt * 255.0), 0, 255);

                            for (int y = 0; y < gradientSurface.Height; ++y)
                            {
                                ColorBgra src = gradientSurface[x, y];

                                // we are assuming that src.A = 255

                                int rd = ((rp * ap) + (src.R * (255 - ap))) / 255;
                                int gd = ((gp * ap) + (src.G * (255 - ap))) / 255;
                                int bd = ((bp * ap) + (src.B * (255 - ap))) / 255;

                                // TODO: proper alpha blending!
                                gradientSurface[x, y] = ColorBgra.FromBgra((byte)bd, (byte)gd, (byte)rd, 255);
                            }
                        }

                        g.DrawImage(ra.Bitmap, gradientRect, ra.Bounds, GraphicsUnit.Pixel);
                    }
                    else if (Orientation == Orientation.Vertical)
                    {
                        // TODO
                    }
                    else
                    {
                        throw new InvalidEnumArgumentException();
                    }
                }

                gradientSurface.Dispose();
            }
            else
            {
                using (LinearGradientBrush lgb = new LinearGradientBrush(this.ClientRectangle,
                                                                         maxColor, minColor, gradientAngle, false))
                {
                    g.FillRectangle(lgb, gradientRect);
                }
            }

            // fill background
            using (PdnRegion nonGradientRegion = new PdnRegion())
            {
                nonGradientRegion.MakeInfinite();
                nonGradientRegion.Exclude(gradientRect);

                using (SolidBrush sb = new SolidBrush(this.BackColor))
                {
                    g.FillRegion(sb, nonGradientRegion.GetRegionReadOnly());
                }
            }

            // draw value triangles
            for (int i = 0; i < this.vals.Length; i++)
            {
                int   pos = ValueToPosition(vals[i]);
                Brush brush;
                Pen   pen;

                if (i == highlight)
                {
                    brush = Brushes.Blue;
                    pen   = (Pen)Pens.White.Clone();
                }
                else
                {
                    brush = Brushes.Black;
                    pen   = (Pen)Pens.Gray.Clone();
                }

                g.SmoothingMode = SmoothingMode.AntiAlias;

                Point a1;
                Point b1;
                Point c1;

                Point a2;
                Point b2;
                Point c2;

                switch (this.orientation)
                {
                case Orientation.Horizontal:
                    a1 = new Point(pos - triangleHalfLength, 0);
                    b1 = new Point(pos, triangleSize - 1);
                    c1 = new Point(pos + triangleHalfLength, 0);

                    a2 = new Point(a1.X, Height - 1 - a1.Y);
                    b2 = new Point(b1.X, Height - 1 - b1.Y);
                    c2 = new Point(c1.X, Height - 1 - c1.Y);
                    break;

                case Orientation.Vertical:
                    a1 = new Point(0, pos - triangleHalfLength);
                    b1 = new Point(triangleSize - 1, pos);
                    c1 = new Point(0, pos + triangleHalfLength);

                    a2 = new Point(Width - 1 - a1.X, a1.Y);
                    b2 = new Point(Width - 1 - b1.X, b1.Y);
                    c2 = new Point(Width - 1 - c1.X, c1.Y);
                    break;

                default:
                    throw new InvalidEnumArgumentException();
                }

                if (this.drawNearNub)
                {
                    g.FillPolygon(brush, new Point[] { a1, b1, c1, a1 });
                }

                if (this.drawFarNub)
                {
                    g.FillPolygon(brush, new Point[] { a2, b2, c2, a2 });
                }

                if (pen != null)
                {
                    if (this.drawNearNub)
                    {
                        g.DrawPolygon(pen, new Point[] { a1, b1, c1, a1 });
                    }

                    if (this.drawFarNub)
                    {
                        g.DrawPolygon(pen, new Point[] { a2, b2, c2, a2 });
                    }

                    pen.Dispose();
                }
            }
        }
Пример #14
0
        protected unsafe override sealed void OnSaveT(
            Document input,
            Stream output,
            PropertyBasedSaveConfigToken token,
            Surface scratchSurface,
            ProgressEventHandler progressCallback)
        {
            // flatten the document -- render w/ transparent background
            scratchSurface.Clear(ColorBgra.Transparent);

            using (RenderArgs ra = new RenderArgs(scratchSurface))
            {
                input.Render(ra, false);
            }

            // load properties from token
            int thresholdFromToken = GetThresholdFromToken(token);
            int ditherLevel        = GetDitherLevelFromToken(token);

            Set <SavableBitDepths> allowedBitDepths = CreateAllowedBitDepthListFromToken(token);

            if (allowedBitDepths.Count == 0)
            {
                throw new ArgumentException("there must be at least 1 element returned from CreateAllowedBitDepthListFromToken()");
            }

            // allowedBitDepths.Count >= 1

            // set to 1 unless allowedBitDepths contains only Rgb8 and Rgba8
            int threshold;

            if (allowedBitDepths.IsSubsetOf(Set.Create(SavableBitDepths.Rgb8, SavableBitDepths.Rgba8)))
            {
                threshold = thresholdFromToken;
            }
            else
            {
                threshold = 1;
            }

            // Analyze image, try to detect what bit-depth or whatever to use, based on allowedBitDepths
            bool allOpaque;
            bool all0or255Alpha;
            int  uniqueColorCount;

            Analyze(scratchSurface, out allOpaque, out all0or255Alpha, out uniqueColorCount);

            Set <SavableBitDepths> losslessBitDepths = new Set <SavableBitDepths>();

            losslessBitDepths.Add(SavableBitDepths.Rgba32);

            if (allOpaque)
            {
                losslessBitDepths.Add(SavableBitDepths.Rgb24);

                if (uniqueColorCount <= 256)
                {
                    losslessBitDepths.Add(SavableBitDepths.Rgb8);
                }
            }
            else if (all0or255Alpha && uniqueColorCount < 256)
            {
                losslessBitDepths.Add(SavableBitDepths.Rgba8);
            }

            SavableBitDepths bitDepth = ChooseBitDepth(allowedBitDepths, losslessBitDepths, allOpaque, all0or255Alpha, uniqueColorCount);

            if (bitDepth == SavableBitDepths.Rgba8 && threshold == 0 && allowedBitDepths.Contains(SavableBitDepths.Rgba8) && allowedBitDepths.Contains(SavableBitDepths.Rgb8))
            {
                // threshold of 0 should effectively force full 256 color palette, instead of 255+1 transparent
                bitDepth = SavableBitDepths.Rgb8;
            }

            // if bit depth is 24 or 8, then we have to do away with the alpha channel
            // for 8-bit, we must have pixels that have either 0 or 255 alpha
            if (bitDepth == SavableBitDepths.Rgb8 ||
                bitDepth == SavableBitDepths.Rgba8 ||
                bitDepth == SavableBitDepths.Rgb24)
            {
                UserBlendOps.NormalBlendOp blendOp = new UserBlendOps.NormalBlendOp();

                for (int y = 0; y < scratchSurface.Height; ++y)
                {
                    for (int x = 0; x < scratchSurface.Width; ++x)
                    {
                        ColorBgra p = scratchSurface[x, y];

                        if (p.A < threshold && bitDepth == SavableBitDepths.Rgba8)
                        {
                            p = ColorBgra.FromBgra(0, 0, 0, 0);
                        }
                        else
                        {
                            p = blendOp.Apply(ColorBgra.White, p);
                        }

                        scratchSurface[x, y] = p;
                    }
                }
            }

            Tracing.Ping("Chose " + bitDepth + ", ditherLevel=" + ditherLevel + ", threshold=" + threshold);

            // finally, do the save.
            FinalSave(input, output, scratchSurface, ditherLevel, bitDepth, token, progressCallback);
        }
Пример #15
0
 public void Render(RenderArgs args, bool clearBackground)
 {
     Render(args, args.Surface.Bounds, clearBackground);
 }
Пример #16
0
 public void Render(RenderArgs args)
 {
     Render(args, args.Surface.Bounds);
 }
Пример #17
0
        private void OnPaintButtonImpl(Graphics g, PushButtonState state, bool drawFocusCues, bool drawKeyboardCues)
        {
            Color backColor;
            Color outlineColor;
            Color arrowFillColor;
            Color arrowOutlineColor;

            switch (state)
            {
            case PushButtonState.Disabled:
                backColor         = Color.Transparent;
                outlineColor      = BackColor;
                arrowFillColor    = Color.Gray;
                arrowOutlineColor = Color.Black;
                break;

            case PushButtonState.Hot:
                backColor         = Color.FromArgb(64, SystemColors.HotTrack);
                outlineColor      = backColor;
                arrowFillColor    = Color.Blue;
                arrowOutlineColor = Color.White;
                break;

            case PushButtonState.Default:
            case PushButtonState.Normal:
                backColor         = Color.Transparent;
                outlineColor      = Color.Transparent;
                arrowFillColor    = Color.Black;
                arrowOutlineColor = Color.White;
                break;

            case PushButtonState.Pressed:
                backColor         = Color.FromArgb(192, SystemColors.Highlight);
                outlineColor      = Color.FromArgb(192, SystemColors.Highlight);
                arrowFillColor    = Color.Blue;
                arrowOutlineColor = Color.White;
                break;

            default:
                throw new InvalidEnumArgumentException("buttonState");
            }

            // Draw parent background
            IPaintBackground asIpb = Parent as IPaintBackground;

            if (!this.drawWithGradient || asIpb == null)
            {
                if (asIpb != null)
                {
                    Rectangle screenRect = RectangleToScreen(ClientRectangle);
                    Rectangle parentRect = Parent.RectangleToClient(screenRect);

                    g.TranslateTransform(-Left, -Top, MatrixOrder.Append);
                    asIpb.PaintBackground(g, parentRect);
                    g.TranslateTransform(+Left, +Top, MatrixOrder.Append);
                }
                else
                {
                    using (SolidBrush backBrush = new SolidBrush(BackColor))
                    {
                        g.FillRectangle(backBrush, ClientRectangle);
                    }
                }
            }
            else
            {
                if (this.backBufferSurface != null &&
                    (this.backBufferSurface.Width != ClientSize.Width || this.backBufferSurface.Height != ClientSize.Height))
                {
                    this.backBuffer.Dispose();
                    this.backBuffer = null;

                    this.backBufferSurface.Dispose();
                    this.backBufferSurface = null;
                }

                if (this.backBufferSurface == null)
                {
                    this.backBufferSurface = new Surface(ClientSize.Width, ClientSize.Height);
                    this.backBuffer        = new RenderArgs(this.backBufferSurface);
                }

                Rectangle screenRect = RectangleToScreen(ClientRectangle);
                Rectangle parentRect = Parent.RectangleToClient(screenRect);

                using (Graphics bg = Graphics.FromImage(this.backBuffer.Bitmap))
                {
                    bg.TranslateTransform(-Left, -Top, MatrixOrder.Append);
                    asIpb.PaintBackground(bg, parentRect);
                }

                BitmapData bitmapData = this.backBuffer.Bitmap.LockBits(
                    new Rectangle(0, 0, this.backBuffer.Bitmap.Width, this.backBuffer.Bitmap.Height),
                    ImageLockMode.ReadWrite,
                    PixelFormat.Format32bppArgb);

                int startAlpha;
                int finishAlpha;

                if (this.arrowDirection == ArrowDirection.Left || this.arrowDirection == ArrowDirection.Up)
                {
                    startAlpha  = 255;
                    finishAlpha = 0;
                }
                else if (this.arrowDirection == ArrowDirection.Right || this.ArrowDirection == ArrowDirection.Down)
                {
                    startAlpha  = 0;
                    finishAlpha = 255;
                }
                else
                {
                    throw new InvalidEnumArgumentException("this.arrowDirection");
                }

                unsafe
                {
                    if (this.arrowDirection == ArrowDirection.Left || this.arrowDirection == ArrowDirection.Right)
                    {
                        for (int x = 0; x < this.backBuffer.Bitmap.Width; ++x)
                        {
                            float lerp = (float)x / (float)(this.backBuffer.Bitmap.Width - 1);

                            if (this.arrowDirection == ArrowDirection.Left)
                            {
                                lerp = 1.0f - (float)Math.Cos(lerp * (Math.PI / 2.0));
                            }
                            else
                            {
                                lerp = (float)Math.Sin(lerp * (Math.PI / 2.0));
                            }

                            byte  alpha = (byte)(startAlpha + ((int)(lerp * (finishAlpha - startAlpha))));
                            byte *pb    = (byte *)bitmapData.Scan0.ToPointer() + (x * 4) + 3; // *4 because 4-bytes per pixel, +3 to get to alpha channel

                            for (int y = 0; y < this.backBuffer.Bitmap.Height; ++y)
                            {
                                *pb = alpha;
                                pb += bitmapData.Stride;
                            }
                        }
                    }
                    else if (this.arrowDirection == ArrowDirection.Up || this.arrowDirection == ArrowDirection.Down)
                    {
                        for (int y = 0; y < this.backBuffer.Bitmap.Height; ++y)
                        {
                            float lerp = (float)y / (float)(this.backBuffer.Bitmap.Height - 1);
                            lerp = 1.0f - (float)Math.Cos(lerp * (Math.PI / 2.0));

                            byte  alpha = (byte)(startAlpha + ((int)(lerp * (finishAlpha - startAlpha))));
                            byte *pb    = (byte *)bitmapData.Scan0.ToPointer() + (y * bitmapData.Stride) + 3; // *Stride for access to start of row, +3 to get to alpha channel

                            for (int x = 0; x < this.backBuffer.Bitmap.Width; ++x)
                            {
                                *pb = alpha;
                                pb += 4; // 4 for byte size of pixel
                            }
                        }
                    }
                }

                this.backBuffer.Bitmap.UnlockBits(bitmapData);
                bitmapData = null;

                g.DrawImage(this.backBuffer.Bitmap, new Point(0, 0));
            }

            using (SolidBrush fillBrush = new SolidBrush(backColor))
            {
                g.FillRectangle(fillBrush, ClientRectangle);
            }

            // Draw outline
            using (Pen outlinePen = new Pen(outlineColor))
            {
                g.DrawRectangle(outlinePen, new Rectangle(0, 0, ClientSize.Width - 1, ClientSize.Height - 1));
            }

            // Draw button
            g.SmoothingMode = SmoothingMode.AntiAlias;

            const int arrowInset = 3;
            int       arrowSize  = Math.Min(ClientSize.Width - arrowInset * 2, ClientSize.Height - arrowInset * 2) - 1;

            PointF a;
            PointF b;
            PointF c;

            switch (this.arrowDirection)
            {
            case ArrowDirection.Left:
                a = new PointF(arrowInset, ClientSize.Height / 2);
                b = new PointF(ClientSize.Width - arrowInset, (ClientSize.Height - arrowSize) / 2);
                c = new PointF(ClientSize.Width - arrowInset, (ClientSize.Height + arrowSize) / 2);
                break;

            case ArrowDirection.Right:
                a = new PointF(ClientSize.Width - arrowInset, ClientSize.Height / 2);
                b = new PointF(arrowInset, (ClientSize.Height - arrowSize) / 2);
                c = new PointF(arrowInset, (ClientSize.Height + arrowSize) / 2);
                break;

            case ArrowDirection.Up:
                a = new PointF(ClientSize.Width / 2, (ClientSize.Height - arrowSize) / 2);
                b = new PointF((ClientSize.Width - arrowSize) / 2, (ClientSize.Height + arrowSize) / 2);
                c = new PointF((ClientSize.Width + arrowSize) / 2, (ClientSize.Height + arrowSize) / 2);
                break;

            case ArrowDirection.Down:
                a = new PointF(ClientSize.Width / 2, (ClientSize.Height + arrowSize) / 2);
                b = new PointF((ClientSize.Width - arrowSize) / 2, (ClientSize.Height - arrowSize) / 2);
                c = new PointF((ClientSize.Width + arrowSize) / 2, (ClientSize.Height - arrowSize) / 2);
                break;

            default:
                throw new InvalidEnumArgumentException("this.arrowDirection");
            }

            // SPIKE in order to get this rendering correctly right away
            if (this.arrowDirection == ArrowDirection.Down)
            {
                SmoothingMode oldSM = g.SmoothingMode;
                g.SmoothingMode = SmoothingMode.None;

                float top         = b.Y - 2;
                float left        = b.X;
                float right       = c.X;
                int   squareCount = (int)((right - left) / 3);

                Brush outlineBrush  = new SolidBrush(arrowOutlineColor);
                Brush interiorBrush = new SolidBrush(arrowFillColor);

                g.FillRectangle(interiorBrush, left, top, right - left + 1, 3);

                ++left;
                while (left < right)
                {
                    RectangleF rect = new RectangleF(left, top + 1, 1, 1);
                    g.FillRectangle(outlineBrush, rect);
                    left += 2;
                }

                outlineBrush.Dispose();
                outlineBrush = null;

                interiorBrush.Dispose();
                interiorBrush = null;

                a.Y += 2;
                b.Y += 2;
                c.Y += 2;

                g.SmoothingMode = oldSM;
            }

            if (this.reverseArrowColors)
            {
                Utility.Swap(ref arrowFillColor, ref arrowOutlineColor);
            }

            using (Brush buttonBrush = new SolidBrush(arrowFillColor))
            {
                g.FillPolygon(buttonBrush, new PointF[] { a, b, c });
            }

            using (Pen buttonPen = new Pen(arrowOutlineColor, this.arrowOutlineWidth))
            {
                g.DrawPolygon(buttonPen, new PointF[] { a, b, c });
            }
        }
Пример #18
0
 public void Render(RenderArgs args, Rectangle roi)
 {
     Render(args, roi, false);
 }
Пример #19
0
 public void RenderUnchecked(RenderArgs args, Rectangle[] roi, int startIndex, int length)
 {
     RenderImpl(args, roi, startIndex, length);
 }
Пример #20
0
 public void Render(RenderArgs args, Rectangle[] roi, bool clearBackground)
 {
     this.Render(args, roi, 0, roi.Length, clearBackground);
 }
Пример #21
0
 /// <summary>
 /// Override this method to provide your layer's rendering capabilities.
 /// </summary>
 /// <param name="args">Contains information about which objects to use for rendering</param>
 /// <param name="roi">The rectangular region to be rendered.</param>
 protected abstract void RenderImpl(RenderArgs args, Rectangle roi);
Пример #22
0
        /// <summary>
        /// Creates a document that consists of one BitmapLayer.
        /// </summary>
        /// <param name="image">The Image to make a copy of that will be the first layer ("Background") in the document.</param>
        public static Document FromImage(Image image)
        {
            if (image == null)
            {
                throw new ArgumentNullException("image");
            }

            Document    document = new Document(image.Width, image.Height);
            BitmapLayer layer    = Layer.CreateBackgroundLayer(image.Width, image.Height);

            layer.Surface.Clear(ColorBgra.FromBgra(0, 0, 0, 0));

            Bitmap asBitmap = image as Bitmap;

            // Copy pixels
            if (asBitmap != null && asBitmap.PixelFormat == PixelFormat.Format32bppArgb)
            {
                unsafe
                {
                    BitmapData bData = asBitmap.LockBits(new Rectangle(0, 0, asBitmap.Width, asBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

                    try
                    {
                        for (int y = 0; y < bData.Height; ++y)
                        {
                            uint *     srcPtr = (uint *)((byte *)bData.Scan0.ToPointer() + (y * bData.Stride));
                            ColorBgra *dstPtr = layer.Surface.GetRowAddress(y);

                            for (int x = 0; x < bData.Width; ++x)
                            {
                                dstPtr->Bgra = *srcPtr;
                                ++srcPtr;
                                ++dstPtr;
                            }
                        }
                    }

                    finally
                    {
                        asBitmap.UnlockBits(bData);
                        bData = null;
                    }
                }
            }
            else if (asBitmap != null && asBitmap.PixelFormat == PixelFormat.Format24bppRgb)
            {
                unsafe
                {
                    BitmapData bData = asBitmap.LockBits(new Rectangle(0, 0, asBitmap.Width, asBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

                    try
                    {
                        for (int y = 0; y < bData.Height; ++y)
                        {
                            byte *     srcPtr = (byte *)bData.Scan0.ToPointer() + (y * bData.Stride);
                            ColorBgra *dstPtr = layer.Surface.GetRowAddress(y);

                            for (int x = 0; x < bData.Width; ++x)
                            {
                                byte b = *srcPtr;
                                byte g = *(srcPtr + 1);
                                byte r = *(srcPtr + 2);
                                byte a = 255;

                                *dstPtr = ColorBgra.FromBgra(b, g, r, a);

                                srcPtr += 3;
                                ++dstPtr;
                            }
                        }
                    }

                    finally
                    {
                        asBitmap.UnlockBits(bData);
                        bData = null;
                    }
                }
            }
            else
            {
                using (RenderArgs args = new RenderArgs(layer.Surface))
                {
                    args.Graphics.CompositingMode = CompositingMode.SourceCopy;
                    args.Graphics.SmoothingMode   = SmoothingMode.None;
                    args.Graphics.DrawImage(image, args.Bounds, args.Bounds, GraphicsUnit.Pixel);
                }
            }

            // Transfer metadata

            PropertyItem[] pis;

            try
            {
                pis = image.PropertyItems;
            }

            catch (Exception ex)
            {
                Tracing.Ping("Exception while retreiving image's PropertyItems: " + ex.ToString());
                pis = null;
                // ignore the error and continue on
            }

            if (pis != null)
            {
                for (int i = 0; i < pis.Length; ++i)
                {
                    document.Metadata.AddExifValues(new PropertyItem[] { pis[i] });
                }
            }

            // Finish up
            document.Layers.Add(layer);
            document.Invalidate();
            return(document);
        }
Пример #23
0
 protected void RenderImpl(RenderArgs args, Rectangle[] roi)
 {
     RenderImpl(args, roi, 0, roi.Length);
 }