Пример #1
0
        protected override void OnFillRegionComputed(Point[][] polygonSet)
        {
            using (PdnGraphicsPath path = new PdnGraphicsPath())
            {
                path.AddPolygons(polygonSet);

                using (PdnRegion fillRegion = new PdnRegion(path))
                {
                    Rectangle boundingBox = fillRegion.GetBoundsInt();

                    Surface        surface = ((BitmapLayer)ActiveLayer).Surface;
                    RenderArgs     ra      = new RenderArgs(surface);
                    HistoryMemento ha;

                    using (PdnRegion affected = Utility.SimplifyAndInflateRegion(fillRegion))
                    {
                        ha = new BitmapHistoryMemento(Name, Image, DocumentWorkspace, DocumentWorkspace.ActiveLayerIndex, affected);
                    }

                    ra.Graphics.CompositingMode = AppEnvironment.GetCompositingMode();
                    ra.Graphics.FillRegion(brush, fillRegion.GetRegionReadOnly());

                    HistoryStack.PushNewMemento(ha);
                    ActiveLayer.Invalidate(boundingBox);
                    Update();
                }
            }
        }
Пример #2
0
        protected override void OnStylusMove(StylusEventArgs e)
        {
            base.OnStylusMove(e);
            PointF currMouseXY = new PointF(e.Fx, e.Fy);

            if (mouseDown && ((e.Button & mouseButton) != MouseButtons.None))
            {
                float      pressure = GetWidth(e.Pressure);
                float      length;
                PointF     a   = lastMouseXY;
                PointF     b   = currMouseXY;
                PointF     dir = new PointF(b.X - a.X, b.Y - a.Y);
                PointF     norm;
                PointF[]   poly;
                RectangleF dotRect = Utility.RectangleFromCenter(currMouseXY, pressure);

                if (pressure > 0.5f)
                {
                    renderArgs.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
                }
                else
                {
                    renderArgs.Graphics.PixelOffsetMode = PixelOffsetMode.None;
                }

                // save direction before normalizing
                lastDir = dir;

                // normalize
                length = Utility.Magnitude(dir);
                dir.X /= length;
                dir.Y /= length;

                // compute normal vector, calculate perpendicular offest from stroke for width
                norm    = new PointF(dir.Y, -dir.X);
                norm.X *= pressure;
                norm.Y *= pressure;

                a.X -= dir.X * 0.1666f;
                a.Y -= dir.Y * 0.1666f;

                lastNorm = norm;

                poly = MakePolygon(
                    new PointF(a.X - lastNorm.X, a.Y - lastNorm.Y),
                    new PointF(a.X + lastNorm.X, a.Y + lastNorm.Y),
                    new PointF(b.X + norm.X, b.Y + norm.Y),
                    new PointF(b.X - norm.X, b.Y - norm.Y));

                RectangleF saveRect = RectangleF.Union(
                    dotRect,
                    RectangleF.Union(
                        Utility.PointsToRectangle(poly[0], poly[1]),
                        Utility.PointsToRectangle(poly[2], poly[3])));

                saveRect.Inflate(2.0f, 2.0f); // account for anti-aliasing

                saveRect.Intersect(ActiveLayer.Bounds);

                // drawing outside of the canvas is a no-op, so don't do anything in that case!
                // also make sure we're within the clip region
                if (saveRect.Width > 0 && saveRect.Height > 0 && renderArgs.Graphics.IsVisible(saveRect))
                {
                    Rectangle saveRectRounded = Utility.RoundRectangle(saveRect);
                    saveRectRounded.Intersect(ActiveLayer.Bounds);

                    if (saveRectRounded.Width > 0 && saveRectRounded.Height > 0)
                    {
                        SaveRegion(null, saveRectRounded);
                        this.savedRects.Add(saveRectRounded);

                        if (AppEnvironment.AntiAliasing)
                        {
                            renderArgs.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                        }
                        else
                        {
                            renderArgs.Graphics.SmoothingMode = SmoothingMode.None;
                        }

                        renderArgs.Graphics.CompositingMode = AppEnvironment.GetCompositingMode();

                        renderArgs.Graphics.FillEllipse(brush, dotRect);

                        // bail out early if the mouse hasn't even moved. If we don't bail out, we'll get a 0-distance move, which will result in a div-by-0
                        if (lastMouseXY != currMouseXY)
                        {
                            renderArgs.Graphics.FillPolygon(brush, poly, FillMode.Winding);
                        }
                    }

                    bitmapLayer.Invalidate(saveRectRounded);
                }

                lastNorm    = norm;
                lastMouseXY = currMouseXY;
            }
            else
            {
                lastMouseXY = currMouseXY;
                lastNorm    = PointF.Empty;
                lastDir     = PointF.Empty;
                this.previewRenderer.BrushSize = AppEnvironment.PenInfo.Width / 2.0f;
            }

            this.previewRenderer.BrushLocation = currMouseXY;
        }
Пример #3
0
        private void RenderGradient()
        {
            ColorBgra startColor = AppEnvironment.PrimaryColor;
            ColorBgra endColor   = AppEnvironment.SecondaryColor;

            if (this.shouldSwapColors)
            {
                if (AppEnvironment.GradientInfo.AlphaOnly)
                {
                    // In transparency mode, the color values don't matter. We just need to reverse
                    // and invert the alpha values.
                    byte startAlpha = startColor.A;
                    startColor.A = (byte)(255 - endColor.A);
                    endColor.A   = (byte)(255 - startAlpha);
                }
                else
                {
                    Utility.Swap(ref startColor, ref endColor);
                }
            }

            PointF startPointF = this.startPoint;
            PointF endPointF   = this.endPoint;

            if (this.shouldConstrain)
            {
                if (this.mouseNub == this.startNub)
                {
                    ConstrainPoints(endPointF, ref startPointF);
                }
                else
                {
                    ConstrainPoints(startPointF, ref endPointF);
                }
            }

            RestoreSavedRegion();

            Surface   surface    = ((BitmapLayer)DocumentWorkspace.ActiveLayer).Surface;
            PdnRegion clipRegion = DocumentWorkspace.Selection.CreateRegion();

            SaveRegion(clipRegion, clipRegion.GetBoundsInt());

            RenderGradient(surface, clipRegion, AppEnvironment.GetCompositingMode(), startPointF, startColor, endPointF, endColor);

            using (PdnRegion simplified = Utility.SimplifyAndInflateRegion(clipRegion, Utility.DefaultSimplificationFactor, 0))
            {
                DocumentWorkspace.ActiveLayer.Invalidate(simplified);
            }

            clipRegion.Dispose();

            // Set up status bar text
            double          angle                = -180.0 * Math.Atan2(endPointF.Y - startPointF.Y, endPointF.X - startPointF.X) / Math.PI;
            MeasurementUnit units                = AppWorkspace.Units;
            double          offsetXPhysical      = Document.PixelToPhysicalX(endPointF.X - startPointF.X, units);
            double          offsetYPhysical      = Document.PixelToPhysicalY(endPointF.Y - startPointF.Y, units);
            double          offsetLengthPhysical = Math.Sqrt(offsetXPhysical * offsetXPhysical + offsetYPhysical * offsetYPhysical);

            string numberFormat;
            string unitsAbbreviation;

            if (units != MeasurementUnit.Pixel)
            {
                string unitsAbbreviationName = "MeasurementUnit." + units.ToString() + ".Abbreviation";
                unitsAbbreviation = PdnResources.GetString(unitsAbbreviationName);
                numberFormat      = "F2";
            }
            else
            {
                unitsAbbreviation = string.Empty;
                numberFormat      = "F0";
            }

            string unitsString = PdnResources.GetString("MeasurementUnit." + units.ToString() + ".Plural");

            string statusText = string.Format(
                this.helpTextWhileAdjustingFormat,
                offsetXPhysical.ToString(numberFormat),
                unitsAbbreviation,
                offsetYPhysical.ToString(numberFormat),
                unitsAbbreviation,
                offsetLengthPhysical.ToString("F2"),
                unitsString,
                angle.ToString("F2"));

            SetStatus(this.toolIcon, statusText);

            // Make sure everything is on screen.
            Update();
        }
Пример #4
0
        protected void RenderShape()
        {
            // create the Pen we will use to draw with
            Pen       outlinePen    = null;
            Brush     interiorBrush = null;
            PenInfo   pi            = AppEnvironment.PenInfo;
            BrushInfo bi            = AppEnvironment.BrushInfo;

            ColorBgra primary   = AppEnvironment.PrimaryColor;
            ColorBgra secondary = AppEnvironment.SecondaryColor;

            if (!ForceShapeDrawType && AppEnvironment.ShapeDrawType == ShapeDrawType.Interior)
            {
                Utility.Swap(ref primary, ref secondary);
            }

            // Initialize pens and brushes to the correct colors
            if ((mouseButton & MouseButtons.Left) == MouseButtons.Left)
            {
                outlinePen    = pi.CreatePen(AppEnvironment.BrushInfo, primary.ToColor(), secondary.ToColor());
                interiorBrush = bi.CreateBrush(secondary.ToColor(), primary.ToColor());
            }
            else if ((mouseButton & MouseButtons.Right) == MouseButtons.Right)
            {
                outlinePen    = pi.CreatePen(AppEnvironment.BrushInfo, secondary.ToColor(), primary.ToColor());
                interiorBrush = bi.CreateBrush(primary.ToColor(), secondary.ToColor());
            }

            if (!this.UseDashStyle)
            {
                outlinePen.DashStyle = DashStyle.Solid;
            }

            outlinePen.LineJoin   = LineJoin.MiterClipped;
            outlinePen.MiterLimit = 2;

            // redraw the old saveSurface
            if (interiorSaveRegion != null)
            {
                RestoreRegion(interiorSaveRegion);
                interiorSaveRegion.Dispose();
                interiorSaveRegion = null;
            }

            if (outlineSaveRegion != null)
            {
                RestoreRegion(outlineSaveRegion);
                outlineSaveRegion.Dispose();
                outlineSaveRegion = null;
            }

            // anti-aliasing? Don't mind if I do
            if (AppEnvironment.AntiAliasing)
            {
                renderArgs.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            }
            else
            {
                renderArgs.Graphics.SmoothingMode = SmoothingMode.None;
            }

            // also set the pixel offset mode
            renderArgs.Graphics.PixelOffsetMode = GetPixelOffsetMode();

            // figure out how we're going to draw
            ShapeDrawType drawType;

            if (ForceShapeDrawType)
            {
                drawType = ForcedShapeDrawType;
            }
            else
            {
                drawType = AppEnvironment.ShapeDrawType;
            }

            // get the region we want to save
            points = this.TrimShapePath(points);
            PointF[]        pointsArray = points.ToArray();
            PdnGraphicsPath shapePath   = CreateShapePath(pointsArray);

            if (shapePath != null)
            {
                // create non-optimized interior region
                PdnRegion interiorRegion = new PdnRegion(shapePath);

                // create non-optimized outline region
                PdnRegion outlineRegion;

                using (PdnGraphicsPath outlinePath = (PdnGraphicsPath)shapePath.Clone())
                {
                    try
                    {
                        outlinePath.Widen(outlinePen);
                        outlineRegion = new PdnRegion(outlinePath);
                    }

                    // Sometimes GDI+ gets cranky if we have a very small shape (e.g. all points
                    // are coincident).
                    catch (OutOfMemoryException)
                    {
                        outlineRegion = new PdnRegion(shapePath);
                    }
                }

                // create optimized outlineRegion for purposes of rendering, if it is possible to do so
                // shapes will often provide an "optimized" region that circumvents the fact that
                // we'd otherwise get a region that encompasses the outline *and* the interior, thus
                // slowing rendering significantly in many cases.
                RectangleF[] optimizedOutlineRegion = GetOptimizedShapeOutlineRegion(pointsArray, shapePath);
                PdnRegion    invalidOutlineRegion;

                if (optimizedOutlineRegion != null)
                {
                    Utility.InflateRectanglesInPlace(optimizedOutlineRegion, (int)(outlinePen.Width + 2));
                    invalidOutlineRegion = Utility.RectanglesToRegion(optimizedOutlineRegion);
                }
                else
                {
                    invalidOutlineRegion = Utility.SimplifyAndInflateRegion(outlineRegion, Utility.DefaultSimplificationFactor, (int)(outlinePen.Width + 2));
                }

                // create optimized interior region
                PdnRegion invalidInteriorRegion = Utility.SimplifyAndInflateRegion(interiorRegion, Utility.DefaultSimplificationFactor, 3);

                PdnRegion invalidRegion = new PdnRegion();
                invalidRegion.MakeEmpty();

                // set up alpha blending
                renderArgs.Graphics.CompositingMode = AppEnvironment.GetCompositingMode();

                SaveRegion(invalidOutlineRegion, invalidOutlineRegion.GetBoundsInt());
                this.outlineSaveRegion = invalidOutlineRegion;
                if ((drawType & ShapeDrawType.Outline) != 0)
                {
                    shapePath.Draw(renderArgs.Graphics, outlinePen);
                }

                invalidRegion.Union(invalidOutlineRegion);

                // draw shape
                if ((drawType & ShapeDrawType.Interior) != 0)
                {
                    SaveRegion(invalidInteriorRegion, invalidInteriorRegion.GetBoundsInt());
                    this.interiorSaveRegion = invalidInteriorRegion;
                    renderArgs.Graphics.FillPath(interiorBrush, shapePath);
                    invalidRegion.Union(invalidInteriorRegion);
                }
                else
                {
                    invalidInteriorRegion.Dispose();
                    invalidInteriorRegion = null;
                }

                bitmapLayer.Invalidate(invalidRegion);

                invalidRegion.Dispose();
                invalidRegion = null;

                outlineRegion.Dispose();
                outlineRegion = null;

                interiorRegion.Dispose();
                interiorRegion = null;
            }

            Update();

            if (shapePath != null)
            {
                shapePath.Dispose();
                shapePath = null;
            }

            outlinePen.Dispose();
            interiorBrush.Dispose();
        }