public CloudsEffectConfigDialog() { // Required for Windows Form Designer support InitializeComponent(); this.Text = CloudsEffect.StaticName; this.Amount1Label = PdnResources.GetString("CloudsEffect.ConfigDialog.ScaleLabel"); this.Amount1Minimum = 2; this.Amount1Maximum = 1000; this.Amount1Default = 250; this.Amount2Label = PdnResources.GetString("CloudsEffect.ConfigDialog.RoughnessLabel"); this.Amount2Minimum = 0; this.Amount2Maximum = 100; this.Amount2Default = 50; this.Icon = Utility.ImageToIcon(CloudsEffect.StaticImage); this.seedHeader.Text = PdnResources.GetString("CloudsEffect.ConfigDialog.SeedHeader.Text"); this.headerBlendMode.Text = PdnResources.GetString("CloudsEffect.ConfigDialog.BlendModeHeader.Text"); this.reseedButton.Text = PdnResources.GetString("CloudsEffect.ConfigDialog.ReseedButton.Text"); this.usageLabel.Text = PdnResources.GetString("CloudsEffect.ConfigDialog.UsageLabel"); // populate the blendOpComboBox with all the blend modes they're allowed to use foreach (Type type in UserBlendOps.GetBlendOps()) { this.comboBlendModes.Items.Add(UserBlendOps.CreateBlendOp(type)); } }
protected override ControlInfo OnCreateConfigUI(PropertyCollection props) { ControlInfo configUI = CreateDefaultConfigUI(props); configUI.SetPropertyControlValue(PropertyNames.Scale, ControlInfoPropertyNames.DisplayName, PdnResources.GetString("CloudsEffect.ConfigDialog.ScaleLabel")); configUI.SetPropertyControlValue(PropertyNames.Power, ControlInfoPropertyNames.DisplayName, PdnResources.GetString("CloudsEffect.ConfigDialog.RoughnessLabel")); configUI.SetPropertyControlValue(PropertyNames.Power, ControlInfoPropertyNames.SliderLargeChange, 0.25); configUI.SetPropertyControlValue(PropertyNames.Power, ControlInfoPropertyNames.SliderSmallChange, 0.05); configUI.SetPropertyControlValue(PropertyNames.Power, ControlInfoPropertyNames.UpDownIncrement, 0.01); PropertyControlInfo blendOpControl = configUI.FindControlForPropertyName(PropertyNames.BlendOp); blendOpControl.ControlProperties[ControlInfoPropertyNames.DisplayName].Value = PdnResources.GetString("CloudsEffect.ConfigDialog.BlendModeHeader.Text"); Type[] blendOpTypes = UserBlendOps.GetBlendOps(); foreach (Type blendOpType in blendOpTypes) { string blendOpDisplayName = UserBlendOps.GetBlendOpFriendlyName(blendOpType); blendOpControl.SetValueDisplayName(blendOpType, blendOpDisplayName); } configUI.SetPropertyControlType(PropertyNames.Seed, PropertyControlType.IncrementButton); configUI.SetPropertyControlValue(PropertyNames.Seed, ControlInfoPropertyNames.DisplayName, PdnResources.GetString("CloudsEffect.ConfigDialog.SeedHeader.Text")); configUI.SetPropertyControlValue(PropertyNames.Seed, ControlInfoPropertyNames.ButtonText, PdnResources.GetString("CloudsEffect.ConfigDialog.ReseedButton.Text")); configUI.SetPropertyControlValue(PropertyNames.Seed, ControlInfoPropertyNames.Description, PdnResources.GetString("CloudsEffect.ConfigDialog.UsageLabel")); return(configUI); }
public BitmapLayer(int width, int height, ColorBgra fillColor) : base(width, height) { this.surface = new Surface(width, height); // clear to see-through white, 0x00ffffff this.Surface.Clear(fillColor); this.properties = new BitmapLayerProperties(UserBlendOps.CreateDefaultBlendOp()); }
static CloudsData() { BlendOps = new Dictionary <string, object> (); foreach (string name in UserBlendOps.GetAllBlendModeNames()) { BlendOps.Add(name, UserBlendOps.GetBlendModeByName(name)); } defaultBlendOp = UserBlendOps.GetBlendModeName(Pinta.Core.BlendMode.Normal); }
protected override void Render (ImageSurface src, ImageSurface dst, Gdk.Rectangle roi) { RenderClouds(dst, roi, Data.Scale, (byte)(Data.Seed ^ instanceSeed), Data.Power/100.0, PintaCore.Palette.PrimaryColor.ToColorBgra (), PintaCore.Palette.SecondaryColor.ToColorBgra ()); Type blendOpType = (Type)CloudsData.BlendOps[Data.BlendMode]; var blendOp = UserBlendOps.CreateBlendOp(blendOpType); if (blendOp != null) { blendOp.Apply (dst, roi.Location, src, roi.Location, dst, roi.Location, roi.Size); } }
private void OnBlendModeChanged(object sender, EventArgs e) { blendmode = UserBlendOps.GetBlendModeByName(blendComboBox.ActiveText); PintaCore.Layers.CurrentLayer.BlendMode = blendmode; if (PintaCore.Layers.SelectionLayer != null) { //Update BlendMode for SelectionLayer and force redraw PintaCore.Layers.SelectionLayer.BlendMode = PintaCore.Layers.CurrentLayer.BlendMode; } PintaCore.Workspace.Invalidate(); }
static CloudsData () { Type[] blendOpTypes = UserBlendOps.GetBlendOps (); BlendOps = new Dictionary<string, object> (); foreach (Type myType in blendOpTypes) { string blendOpDisplayName = UserBlendOps.GetBlendOpFriendlyName (myType); BlendOps.Add (blendOpDisplayName, myType); } defaultBlendOp = UserBlendOps.GetBlendOpFriendlyName (UserBlendOps.GetDefaultBlendOp ()); }
private void CompileBlendOp() { bool isDefaultOp = (properties.blendOp.GetType() == UserBlendOps.GetDefaultBlendOp()); if (this.Opacity == 255) { this.compiledBlendOp = properties.blendOp; } else { this.compiledBlendOp = properties.blendOp.CreateWithOpacity(this.Opacity); } }
private void OnBlendModeChanged(object?sender, EventArgs e) { var doc = PintaCore.Workspace.ActiveDocument; blendmode = UserBlendOps.GetBlendModeByName(blendComboBox.ActiveText); doc.Layers.CurrentUserLayer.BlendMode = blendmode; if (doc.Layers.SelectionLayer != null) { //Update BlendMode for SelectionLayer and force redraw doc.Layers.SelectionLayer.BlendMode = doc.Layers.CurrentUserLayer.BlendMode; } PintaCore.Workspace.Invalidate(); }
/// <summary> /// Creates a new BitmapLayer of the same size as the given Surface, and either /// copies the pixels of the given Surface or takes ownership of it. /// </summary> /// <param name="surface">The Surface.</param> /// <param name="takeOwnership"> /// true to take ownership of the surface (make sure to Dispose() it yourself), or /// false to copy its pixels /// </param> public BitmapLayer(Surface surface, bool takeOwnership) : base(surface.Width, surface.Height) { if (takeOwnership) { this.surface = surface; } else { this.surface = surface.Clone(); } this.properties = new BitmapLayerProperties(UserBlendOps.CreateDefaultBlendOp()); }
public BitmapLayerPropertiesDialog() { // This call is required by the Windows Form Designer. InitializeComponent(); this._blendingHeader.Text = PdnResources.GetString("BitmapLayerPropertiesDialog.BlendingHeader.Text"); this.blendModeLabel.Text = PdnResources.GetString("BitmapLayerPropertiesDialog.BlendModeLabel.Text"); this.opacityLabel.Text = PdnResources.GetString("BitmapLayerPropertiesDialog.OpacityLabel.Text"); // populate the blendOpComboBox with all the blend modes they're allowed to use foreach (Type type in UserBlendOps.GetBlendOps()) { blendOpComboBox.Items.Add(UserBlendOps.CreateBlendOp(type)); } }
protected override PropertyCollection OnCreatePropertyCollection() { List <Property> props = new List <Property>(); props.Add(new Int32Property(PropertyNames.Scale, 250, 2, 1000)); props.Add(new DoubleProperty(PropertyNames.Power, 0.5, 0.0, 1.0)); Type[] blendOpTypes = UserBlendOps.GetBlendOps(); int defaultBlendOpIndex = Array.IndexOf(blendOpTypes, UserBlendOps.GetDefaultBlendOp()); props.Add(new StaticListChoiceProperty(PropertyNames.BlendOp, blendOpTypes, 0, false)); props.Add(new Int32Property(PropertyNames.Seed, 0, 0, 255)); return(new PropertyCollection(props)); }
public LayerPropertiesDialog() : base(Translations.GetString("Layer Properties"), PintaCore.Chrome.MainWindow, DialogFlags.Modal, Core.GtkExtensions.DialogButtonsCancelOk()) { var doc = PintaCore.Workspace.ActiveDocument; Build(); IconName = Resources.Icons.LayerProperties; name = doc.Layers.CurrentUserLayer.Name; hidden = doc.Layers.CurrentUserLayer.Hidden; opacity = doc.Layers.CurrentUserLayer.Opacity; blendmode = doc.Layers.CurrentUserLayer.BlendMode; initial_properties = new LayerProperties( name, hidden, opacity, blendmode); layerNameEntry.Text = initial_properties.Name; visibilityCheckbox.Active = !initial_properties.Hidden; opacitySpinner.Value = (int)(initial_properties.Opacity * 100); opacitySlider.Value = (int)(initial_properties.Opacity * 100); var all_blendmodes = UserBlendOps.GetAllBlendModeNames().ToList(); var index = all_blendmodes.IndexOf(UserBlendOps.GetBlendModeName(blendmode)); blendComboBox.Active = index; layerNameEntry.Changed += OnLayerNameChanged; visibilityCheckbox.Toggled += OnVisibilityToggled; opacitySpinner.ValueChanged += new EventHandler(OnOpacitySpinnerChanged); opacitySlider.ValueChanged += new EventHandler(OnOpacitySliderChanged); blendComboBox.Changed += OnBlendModeChanged; DefaultResponse = Gtk.ResponseType.Ok; layerNameEntry.ActivatesDefault = true; opacitySpinner.ActivatesDefault = true; }
public void SetParameters(int scale, byte seed, double power, Type blendOpType, ColorBgra primaryColor, ColorBgra secondaryColor) { this.scale = scale; int intSeed = seed; this.power = power; this.seed = (byte)(intSeed ^ instanceSeed); this.blendOp = UserBlendOps.CreateBlendOp(blendOpType); this.primaryColor = primaryColor; this.secondaryColor = secondaryColor; if (this.blendOp is UserBlendOps.NormalBlendOp && primaryColor.A == 255 && secondaryColor.A == 255) { // this is just an optimization this.blendOp = null; } }
public LayerPropertiesDialog() : base(Mono.Unix.Catalog.GetString("Layer Properties"), PintaCore.Chrome.MainWindow, DialogFlags.Modal, Stock.Cancel, ResponseType.Cancel, Stock.Ok, ResponseType.Ok) { Build(); this.Icon = PintaCore.Resources.GetIcon("Menu.Layers.LayerProperties.png"); name = PintaCore.Layers.CurrentLayer.Name; hidden = PintaCore.Layers.CurrentLayer.Hidden; opacity = PintaCore.Layers.CurrentLayer.Opacity; blendmode = PintaCore.Layers.CurrentLayer.BlendMode; initial_properties = new LayerProperties( name, hidden, opacity, blendmode); layerNameEntry.Text = initial_properties.Name; visibilityCheckbox.Active = !initial_properties.Hidden; opacitySpinner.Value = (int)(initial_properties.Opacity * 100); opacitySlider.Value = (int)(initial_properties.Opacity * 100); var all_blendmodes = UserBlendOps.GetAllBlendModeNames().ToList(); var index = all_blendmodes.IndexOf(UserBlendOps.GetBlendModeName(blendmode)); blendComboBox.Active = index; layerNameEntry.Changed += OnLayerNameChanged; visibilityCheckbox.Toggled += OnVisibilityToggled; opacitySpinner.ValueChanged += new EventHandler(OnOpacitySpinnerChanged); opacitySlider.ValueChanged += new EventHandler(OnOpacitySliderChanged); blendComboBox.Changed += OnBlendModeChanged; AlternativeButtonOrder = new int[] { (int)Gtk.ResponseType.Ok, (int)Gtk.ResponseType.Cancel }; DefaultResponse = Gtk.ResponseType.Ok; layerNameEntry.ActivatesDefault = true; opacitySpinner.ActivatesDefault = true; }
protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs) { this.scale = newToken.GetProperty <Int32Property>(PropertyNames.Scale).Value; int intSeed = newToken.GetProperty <Int32Property>(PropertyNames.Seed).Value; this.seed = (byte)(intSeed ^ instanceSeed); this.power = newToken.GetProperty <DoubleProperty>(PropertyNames.Power).Value; Type blendOpType = (Type)newToken.GetProperty <StaticListChoiceProperty>(PropertyNames.BlendOp).Value; this.blendOp = UserBlendOps.CreateBlendOp(blendOpType); if (this.blendOp is UserBlendOps.NormalBlendOp && EnvironmentParameters.PrimaryColor.A == 255 && EnvironmentParameters.SecondaryColor.A == 255) { // this is just an optimization this.blendOp = null; } base.OnSetRenderInfo(newToken, dstArgs, srcArgs); }
private UserBlendOp BlendModeKeyToBlendOp(PhotoshopFile.Layer layer) { UserBlendOp blendOp = UserBlendOps.CreateBlendOp(typeof(UserBlendOps.NormalBlendOp)); switch (layer.BlendModeKey) { case "norm": blendOp = UserBlendOps.CreateBlendOp(typeof(UserBlendOps.NormalBlendOp)); break; case "dark": blendOp = UserBlendOps.CreateBlendOp(typeof(UserBlendOps.DarkenBlendOp)); break; case "lite": blendOp = UserBlendOps.CreateBlendOp(typeof(UserBlendOps.LightenBlendOp)); break; case "hue ": break; case "sat ": break; case "colr": break; case "lum ": break; case "mul ": blendOp = UserBlendOps.CreateBlendOp(typeof(UserBlendOps.MultiplyBlendOp)); break; case "scrn": blendOp = UserBlendOps.CreateBlendOp(typeof(UserBlendOps.ScreenBlendOp)); break; case "diss": break; case "over": blendOp = UserBlendOps.CreateBlendOp(typeof(UserBlendOps.OverlayBlendOp)); break; case "hLit": break; case "sLit": break; case "diff": blendOp = UserBlendOps.CreateBlendOp(typeof(UserBlendOps.DifferenceBlendOp)); break; case "smud": break; case "div ": blendOp = UserBlendOps.CreateBlendOp(typeof(UserBlendOps.ColorDodgeBlendOp)); break; case "idiv": blendOp = UserBlendOps.CreateBlendOp(typeof(UserBlendOps.ColorBurnBlendOp)); break; } return(blendOp); }
private void Build() { DefaultWidth = 349; DefaultHeight = 224; BorderWidth = 6; VBox.Spacing = 10; // Layer name var box1 = new HBox(); box1.Spacing = 6; box1.PackStart(new Label(Mono.Unix.Catalog.GetString("Name:")), false, false, 0); layerNameEntry = new Entry(); box1.PackStart(layerNameEntry); VBox.PackStart(box1, false, false, 0); // Visible checkbox visibilityCheckbox = new CheckButton(Mono.Unix.Catalog.GetString("Visible")); VBox.PackStart(visibilityCheckbox, false, false, 0); // Horizontal separator VBox.PackStart(new HSeparator(), false, false, 0); // Blend mode var box2 = new HBox(); box2.Spacing = 6; box2.PackStart(new Label(Mono.Unix.Catalog.GetString("Blend Mode") + ":"), false, false, 0); blendComboBox = new ComboBox(UserBlendOps.GetAllBlendModeNames().ToArray()); box2.PackStart(blendComboBox); VBox.PackStart(box2, false, false, 0); // Opacity var box3 = new HBox(); box3.Spacing = 6; box3.PackStart(new Label(Mono.Unix.Catalog.GetString("Opacity:")), false, false, 0); opacitySpinner = new SpinButton(0, 100, 1); opacitySpinner.Adjustment.PageIncrement = 10; opacitySpinner.ClimbRate = 1; box3.PackStart(opacitySpinner, false, false, 0); opacitySlider = new HScale(0, 100, 1); opacitySlider.Digits = 0; opacitySlider.Adjustment.PageIncrement = 10; box3.PackStart(opacitySlider, true, true, 0); VBox.PackStart(box3, false, false, 0); // Finish up VBox.ShowAll(); AlternativeButtonOrder = new int[] { (int)ResponseType.Ok, (int)ResponseType.Cancel }; DefaultResponse = ResponseType.Ok; }
private void OnBlendModeChanged(object sender, EventArgs e) { blendmode = UserBlendOps.GetBlendModeByName(blendComboBox.ActiveText); PintaCore.Layers.CurrentLayer.BlendMode = blendmode; }
private void Build() { DefaultWidth = 349; DefaultHeight = 224; BorderWidth = 6; ContentArea.Spacing = 10; // Layer name var box1 = new HBox(); box1.Spacing = 6; box1.PackStart(new Label(Translations.GetString("Name:")), false, false, 0); layerNameEntry = new Entry(); box1.PackStart(layerNameEntry, true, true, 0); ContentArea.PackStart(box1, false, false, 0); // Visible checkbox visibilityCheckbox = new CheckButton(Translations.GetString("Visible")); ContentArea.PackStart(visibilityCheckbox, false, false, 0); // Horizontal separator ContentArea.PackStart(new HSeparator(), false, false, 0); // Blend mode var box2 = new HBox(); box2.Spacing = 6; box2.PackStart(new Label(Translations.GetString("Blend Mode") + ":"), false, false, 0); blendComboBox = new ComboBoxText(); foreach (string name in UserBlendOps.GetAllBlendModeNames()) { blendComboBox.AppendText(name); } box2.PackStart(blendComboBox, true, true, 0); ContentArea.PackStart(box2, false, false, 0); // Opacity var box3 = new HBox(); box3.Spacing = 6; box3.PackStart(new Label(Translations.GetString("Opacity:")), false, false, 0); opacitySpinner = new SpinButton(0, 100, 1); opacitySpinner.Adjustment.PageIncrement = 10; opacitySpinner.ClimbRate = 1; box3.PackStart(opacitySpinner, false, false, 0); opacitySlider = new HScale(0, 100, 1); opacitySlider.Digits = 0; opacitySlider.Adjustment.PageIncrement = 10; box3.PackStart(opacitySlider, true, true, 0); ContentArea.PackStart(box3, false, false, 0); // Finish up ContentArea.ShowAll(); DefaultResponse = ResponseType.Ok; }
private unsafe void RenderZoomOut(List <Layer> layers, Cairo.ImageSurface dst, Gdk.Point offset, Gdk.Size destinationSize) { // The first layer should be blended with the transparent checkerboard var checker = true; CheckerBoardOperation checker_op = null; for (int i = 0; i < layers.Count; i++) { var layer = layers[i]; // If we're in LivePreview, substitute current layer with the preview layer if (layer == PintaCore.Layers.CurrentLayer && PintaCore.LivePreview.IsEnabled) { layer = CreateLivePreviewLayer(layer); } // If the layer is offset, handle it here if (!layer.Offset.IsEmpty()) { layer = CreateOffsetLayer(layer); } var src = layer.Surface; // Get the blend mode for this layer and opacity var blend_op = UserBlendOps.GetBlendOp(layer.BlendMode, layer.Opacity); if (checker) { checker_op = new CheckerBoardOperation(layer.Opacity); } const int fpShift = 12; const int fpFactor = (1 << fpShift); Gdk.Size sourceSize = src.GetBounds().Size; long fDstLeftLong = ((long)offset.X * fpFactor * (long)sourceSize.Width) / (long)destinationSize.Width; long fDstTopLong = ((long)offset.Y * fpFactor * (long)sourceSize.Height) / (long)destinationSize.Height; long fDstRightLong = ((long)(offset.X + dst.Width) * fpFactor * (long)sourceSize.Width) / (long)destinationSize.Width; long fDstBottomLong = ((long)(offset.Y + dst.Height) * fpFactor * (long)sourceSize.Height) / (long)destinationSize.Height; int fDstLeft = (int)fDstLeftLong; int fDstTop = (int)fDstTopLong; int fDstRight = (int)fDstRightLong; int fDstBottom = (int)fDstBottomLong; int dx = (fDstRight - fDstLeft) / dst.Width; int dy = (fDstBottom - fDstTop) / dst.Height; ColorBgra *src_ptr = (ColorBgra *)src.DataPtr; ColorBgra *dst_ptr = (ColorBgra *)dst.DataPtr; int src_width = src.Width; int dst_width = dst.Width; for (int dstRow = 0, fDstY = fDstTop; dstRow < dst.Height && fDstY < fDstBottom; ++dstRow, fDstY += dy) { int srcY1 = fDstY >> fpShift; // y int srcY2 = (fDstY + (dy >> 2)) >> fpShift; // y + 0.25 int srcY3 = (fDstY + (dy >> 1)) >> fpShift; // y + 0.50 int srcY4 = (fDstY + (dy >> 1) + (dy >> 2)) >> fpShift; // y + 0.75 ColorBgra *src1 = src.GetRowAddressUnchecked(src_ptr, src_width, srcY1); ColorBgra *src2 = src.GetRowAddressUnchecked(src_ptr, src_width, srcY2); ColorBgra *src3 = src.GetRowAddressUnchecked(src_ptr, src_width, srcY3); ColorBgra *src4 = src.GetRowAddressUnchecked(src_ptr, src_width, srcY4); ColorBgra *dstPtr = dst.GetRowAddressUnchecked(dst_ptr, dst_width, dstRow); int checkerY = dstRow + offset.Y; int checkerX = offset.X; int maxCheckerX = checkerX + dst.Width; for (int fDstX = fDstLeft; checkerX < maxCheckerX && fDstX < fDstRight; ++checkerX, fDstX += dx) { int srcX1 = (fDstX + (dx >> 2)) >> fpShift; // x + 0.25 int srcX2 = (fDstX + (dx >> 1) + (dx >> 2)) >> fpShift; // x + 0.75 int srcX3 = fDstX >> fpShift; // x int srcX4 = (fDstX + (dx >> 1)) >> fpShift; // x + 0.50 ColorBgra *p1 = src1 + srcX1; ColorBgra *p2 = src2 + srcX2; ColorBgra *p3 = src3 + srcX3; ColorBgra *p4 = src4 + srcX4; int r = (2 + p1->R + p2->R + p3->R + p4->R) >> 2; int g = (2 + p1->G + p2->G + p3->G + p4->G) >> 2; int b = (2 + p1->B + p2->B + p3->B + p4->B) >> 2; int a = (2 + p1->A + p2->A + p3->A + p4->A) >> 2; // Blend it over the checkerboard background if (checker) { *dstPtr = checker_op.Apply(ColorBgra.FromUInt32((uint)b + ((uint)g << 8) + ((uint)r << 16) + ((uint)a << 24)), checkerX, checkerY); } else { *dstPtr = blend_op.Apply(*dstPtr, ColorBgra.FromUInt32((uint)b + ((uint)g << 8) + ((uint)r << 16) + ((uint)a << 24))); } ++dstPtr; } } // Only checker the first layer checker = false; } }
private unsafe void RenderZoomIn(List <Layer> layers, Cairo.ImageSurface dst, Gdk.Point offset) { // The first layer should be blended with the transparent checkerboard var checker = true; CheckerBoardOperation checker_op = null; for (int i = 0; i < layers.Count; i++) { var layer = layers[i]; // If we're in LivePreview, substitute current layer with the preview layer if (layer == PintaCore.Layers.CurrentLayer && PintaCore.LivePreview.IsEnabled) { layer = CreateLivePreviewLayer(layer); } // If the layer is offset, handle it here if (!layer.Offset.IsEmpty()) { layer = CreateOffsetLayer(layer); } var src = layer.Surface; // Get the blend mode for this layer and opacity var blend_op = UserBlendOps.GetBlendOp(layer.BlendMode, layer.Opacity); if (checker) { checker_op = new CheckerBoardOperation(layer.Opacity); } ColorBgra *src_ptr = (ColorBgra *)src.DataPtr; ColorBgra *dst_ptr = (ColorBgra *)dst.DataPtr; int src_width = src.Width; int dst_width = dst.Width; int dst_height = dst.Height; if (!generated) { d2sLookupX = CreateLookupX(src_width, destination_size.Width, scale_factor); d2sLookupY = CreateLookupY(src.Height, destination_size.Height, scale_factor); s2dLookupX = CreateS2DLookupX(src_width, destination_size.Width, scale_factor); s2dLookupY = CreateS2DLookupY(src.Height, destination_size.Height, scale_factor); generated = true; } for (int dstRow = 0; dstRow < dst_height; ++dstRow) { int nnY = dstRow + offset.Y; int srcY = d2sLookupY[nnY]; ColorBgra *dstPtr = dst.GetRowAddressUnchecked(dst_ptr, dst_width, dstRow); ColorBgra *srcRow = src.GetRowAddressUnchecked(src_ptr, src_width, srcY); for (int dstCol = 0; dstCol < dst_width; ++dstCol) { int nnX = dstCol + offset.X; int srcX = d2sLookupX[nnX]; // Blend it over the checkerboard background if (checker) { *dstPtr = checker_op.Apply(*(srcRow + srcX), dstCol + offset.X, dstRow + offset.Y); } else { *dstPtr = blend_op.Apply(*dstPtr, *(srcRow + srcX)); } ++dstPtr; } } // Only checker the first layer checker = false; } // If we are at least 200% and grid is requested, draw it if (PintaCore.Actions.View.PixelGrid.Active && scale_factor.Ratio <= 0.5d) { RenderPixelGrid(dst, offset); } }
private unsafe void RenderOneToOne(List <Layer> layers, Cairo.ImageSurface dst, Gdk.Point offset) { // The first layer should be blended with the transparent checkerboard var checker = true; CheckerBoardOperation checker_op = null; for (int i = 0; i < layers.Count; i++) { var layer = layers[i]; // If we're in LivePreview, substitute current layer with the preview layer if (layer == PintaCore.Layers.CurrentLayer && PintaCore.LivePreview.IsEnabled) { layer = CreateLivePreviewLayer(layer); } // If the layer is offset, handle it here if (!layer.Offset.IsEmpty()) { layer = CreateOffsetLayer(layer); } var src = layer.Surface; // Get the blend mode for this layer and opacity var blend_op = UserBlendOps.GetBlendOp(layer.BlendMode, layer.Opacity); if (checker) { checker_op = new CheckerBoardOperation(layer.Opacity); } // Figure out where our source and destination intersect var srcRect = new Gdk.Rectangle(offset, dst.GetBounds().Size); srcRect.Intersect(src.GetBounds()); // Get pointers to our surfaces var src_ptr = (ColorBgra *)src.DataPtr; var dst_ptr = (ColorBgra *)dst.DataPtr; // Cache widths int src_width = src.Width; int dst_width = dst.Width; for (int dstRow = 0; dstRow < srcRect.Height; ++dstRow) { ColorBgra *dstRowPtr = dst.GetRowAddressUnchecked(dst_ptr, dst_width, dstRow); ColorBgra *srcRowPtr = src.GetPointAddressUnchecked(src_ptr, src_width, offset.X, dstRow + offset.Y); int dstCol = offset.X; int dstColEnd = offset.X + srcRect.Width; int checkerY = dstRow + offset.Y; while (dstCol < dstColEnd) { // Blend it over the checkerboard background if (checker) { *dstRowPtr = checker_op.Apply(*srcRowPtr, dstCol, checkerY); } else { *dstRowPtr = blend_op.Apply(*dstRowPtr, *srcRowPtr); } ++dstRowPtr; ++srcRowPtr; ++dstCol; } } // Only checker the first layer checker = false; } }