Пример #1
0
        public unsafe override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            Tank tank   = renderTask.Tank;
            var  bounds =
                Mode == ClipMode.ByPixels
                    ? layer.PreciseSize(PixelAlphaThreshold)
                : Mode == ClipMode.ByLayerBounds
                    ? PixelRect.FromMixed(0, 0, layer.Width, layer.Height)
                    : PixelRect.FromMixed(0, 0, Layer.ParentStyle.IconWidth, Layer.ParentStyle.IconHeight);

            using (layer.UseWrite())
            {
                int   count;
                byte *ptr;
                // Clip Top
                for (int y = 0; y < bounds.Top + ClipTop && y < layer.Height; y++)
                {
                    Ut.MemSet(layer.Data + y * layer.Stride, 0, layer.Width * 4);
                }
                // Clip Bottom
                for (int y = layer.Height - 1; y > bounds.Bottom - ClipBottom && y >= 0; y--)
                {
                    Ut.MemSet(layer.Data + y * layer.Stride, 0, layer.Width * 4);
                }
                // Clip Left
                count = Math.Min(bounds.Left + ClipLeft, layer.Width) * 4;
                ptr   = layer.Data;
                if (count > 0)
                {
                    for (int y = 0; y < layer.Height; y++, ptr += layer.Stride)
                    {
                        Ut.MemSet(ptr, 0, count);
                    }
                }
                // Clip Right
                count = Math.Min(layer.Width - 1 - bounds.Right + ClipRight, layer.Width) * 4;
                ptr   = layer.Data + layer.Width * 4 - count;
                if (count > 0)
                {
                    for (int y = 0; y < layer.Height; y++, ptr += layer.Stride)
                    {
                        Ut.MemSet(ptr, 0, count);
                    }
                }
            }
            return(layer);
        }
Пример #2
0
        public override BitmapBase Apply(RenderTask renderTask, BitmapBase layer)
        {
            var calculator = new SizeCalculator(renderTask, layer);
            Func <string, string> describe = property =>
                                             "*{0}:* {1}\n".Fmt(EggsML.Escape(App.Translation.Calculator.ErrLabel_Layer), EggsML.Escape((string.IsNullOrEmpty(Layer.Name) ? "" : (Layer.Name + " – ")) + Layer.TypeName)) +
                                             "*{0}:* {1}\n".Fmt(EggsML.Escape(App.Translation.Calculator.ErrLabel_Effect), EggsML.Escape((string.IsNullOrEmpty(Name) ? "" : (Name + " – ")) + TypeName)) +
                                             "*{0}:* {1}".Fmt(EggsML.Escape(App.Translation.Calculator.ErrLabel_Property), EggsML.Escape(property));

            double ParsedWidth  = Math.Max(0, calculator.Parse(Width, describe(WidthTr(App.Translation).DisplayName))),
                   ParsedHeight = Math.Max(0, calculator.Parse(Height, describe(HeightTr(App.Translation).DisplayName))),
                   ParsedX      = calculator.Parse(X, describe(XTr(App.Translation).DisplayName)),
                   ParsedY      = calculator.Parse(Y, describe(YTr(App.Translation).DisplayName));

            Tank tank   = renderTask.Tank;
            var  pixels = PixelRect.FromMixed(0, 0, layer.Width, layer.Height);

            if (ShowPixelBorders || PositionByPixels || (SizeByPixels && SizeMode2 != SizeMode2.NoChange && SizeMode2 != SizeMode2.ByPercentage))
            {
                pixels = layer.PreciseSize(PixelAlphaThreshold);
            }
            bool emptyPixels = pixels.Width <= 0 || pixels.Height <= 0;

            if (emptyPixels)
            {
                pixels = PixelRect.FromMixed(0, 0, layer.Width, layer.Height);
            }

            double scaleWidth, scaleHeight;
            int    sourceWidth  = SizeByPixels ? pixels.Width : layer.Width;
            int    sourceHeight = SizeByPixels ? pixels.Height : layer.Height;

            switch (SizeMode2)
            {
            case SizeMode2.NoChange:
                scaleWidth = scaleHeight = 1;
                break;

            case SizeMode2.ByPercentage:
                scaleWidth = scaleHeight = Percentage / 100.0;
                break;

            case SizeMode2.BySizeWidthOnly:
                scaleWidth = scaleHeight = ParsedWidth / (double)sourceWidth;
                break;

            case SizeMode2.BySizeHeightOnly:
                scaleWidth = scaleHeight = ParsedHeight / (double)sourceHeight;
                break;

            case SizeMode2.BySizeFit:
                scaleWidth = scaleHeight = Math.Min(ParsedWidth / (double)sourceWidth, ParsedHeight / (double)sourceHeight);
                break;

            case SizeMode2.BySizeStretch:
                scaleWidth  = ParsedWidth / (double)sourceWidth;
                scaleHeight = ParsedHeight / (double)sourceHeight;
                break;

            default:
                throw new Exception("7924688");
            }

            if (GrowShrinkMode == GrowShrinkMode.GrowOnly)
            {
                scaleWidth  = Math.Max(1.0, scaleWidth);
                scaleHeight = Math.Max(1.0, scaleHeight);
            }
            else if (GrowShrinkMode == GrowShrinkMode.ShrinkOnly)
            {
                scaleWidth  = Math.Min(1.0, scaleWidth);
                scaleHeight = Math.Min(1.0, scaleHeight);
            }

            var anchor       = (AnchorRaw)Anchor;
            int anchorWidth  = (int)Math.Ceiling((PositionByPixels ? pixels.Width : layer.Width) * scaleWidth);
            int anchorHeight = (int)Math.Ceiling((PositionByPixels ? pixels.Height : layer.Height) * scaleHeight);
            // Location of the top left corner of the anchored rectangle
            int tgtX = (int)ParsedX - (anchor.HasFlag(AnchorRaw.Right) ? anchorWidth - 1 : anchor.HasFlag(AnchorRaw.Center) ? (anchorWidth - 1) / 2 : 0);
            int tgtY = (int)ParsedY - (anchor.HasFlag(AnchorRaw.Bottom) ? anchorHeight - 1 : anchor.HasFlag(AnchorRaw.Mid) ? (anchorHeight - 1) / 2 : 0);
            // Location of the top left corner of the whole scaled layer image
            double x       = tgtX - (PositionByPixels ? pixels.Left * scaleWidth : 0);
            double y       = tgtY - (PositionByPixels ? pixels.Top * scaleHeight : 0);
            int    offsetX = (PositionByPixels ? pixels.Left : 0);
            int    offsetY = (PositionByPixels ? pixels.Top : 0);

            if (ShowLayerBorders || ShowPixelBorders)
            {
                using (var image = layer.ToMagickImage())
                {
                    image.Settings.StrokeWidth = 1;
                    if (ShowLayerBorders)
                    {
                        image.Settings.FillColor   = ImageMagick.MagickColors.Transparent;
                        image.Settings.StrokeColor = new ImageMagick.MagickColor("aqua");
                        image.Draw(new ImageMagick.DrawableRectangle(0, 0, layer.Width - 1, layer.Height - 1));
                    }
                    if (ShowPixelBorders && !emptyPixels)
                    {
                        image.Settings.FillColor   = ImageMagick.MagickColors.Transparent;
                        image.Settings.StrokeColor = new ImageMagick.MagickColor("red");
                        image.Draw(new ImageMagick.DrawableRectangle(pixels.Left, pixels.Top, pixels.Right, pixels.Bottom));
                    }
                    layer.CopyPixelsFrom(image.ToBitmapSource());
                }
            }
            BitmapResampler.Filter filter;
            switch (Filter)
            {
            case Filter.Auto: filter = null; break;

            case Filter.Mitchell: filter = new BitmapResampler.MitchellFilter(); break;

            case Filter.Bicubic: filter = new BitmapResampler.CatmullRomFilter(); break;

            case Filter.Lanczos: filter = new BitmapResampler.LanczosFilter(); break;

            case Filter.Sinc256: filter = new BitmapResampler.LanczosFilter(8); break;

            case Filter.Sinc1024: filter = new BitmapResampler.LanczosFilter(16); break;

            default: throw new Exception("SizePosEffect.Filter 4107");
            }
            layer = BitmapResampler.SizePos(layer, scaleWidth, scaleHeight, offsetX, offsetY, tgtX, tgtY, Math.Max(layer.Width, Layer.ParentStyle.IconWidth), Math.Max(layer.Height, Layer.ParentStyle.IconHeight), filter);
            if (ShowAnchor)
            {
                using (var image = layer.ToMagickImage())
                {
                    image.Settings.StrokeWidth = 1;
                    image.Settings.StrokeColor = new ImageMagick.MagickColor(255, 255, 0, 120);
                    image.Draw(new ImageMagick.DrawableLine((int)ParsedX - 1, (int)ParsedY, (int)ParsedX + 1, (int)ParsedY));
                    image.Draw(new ImageMagick.DrawableLine((int)ParsedX, (int)ParsedY - 1, (int)ParsedX, (int)ParsedY + 1));
                    layer.CopyPixelsFrom(image.ToBitmapSource());
                }
            }
            return(layer);
        }