public Surface Clone() { Surface surf = new Surface(width, height); surf.CopySurface(this); return(surf); }
public void Draw(Surface dst) { if (disposed) { throw new ObjectDisposedException("PlacedSurface"); } dst.CopySurface(what, where); }
public PlacedSurface(Surface source, Rectangle roi) { where = roi.Location; Surface window = source.CreateWindow(roi); what = new Surface(window.Size); what.CopySurface(window); window.Dispose(); }
/// <summary> /// Does the dirty work for a File->Save operation. If any of the "Save Options" in the /// DocumentWorkspace are null, this will call DoSaveAs(). If the image has more than 1 /// layer but the file type they want to save with does not support layers, then it will /// ask the user about flattening the image. /// </summary> /// <param name="tryToFlatten"> /// If true, will ask the user about flattening if the workspace's saveFileType does not /// support layers and the image has more than 1 layer. /// If false, then DoSaveAs will be called and the fileType will be prepopulated with /// the .PDN type. /// </param> /// <returns><b>true</b> if the file was saved, <b>false</b> if the user cancelled</returns> protected bool DoSave(bool tryToFlatten) { using (new PushNullToolMode(this)) { string newFileName; FileType newFileType; SaveConfigToken newSaveConfigToken; GetDocumentSaveOptions(out newFileName, out newFileType, out newSaveConfigToken); // if they haven't specified a filename, then revert to "Save As" behavior if (newFileName == null) { return DoSaveAs(); } // if we have a filename but no file type, try to infer the file type if (newFileType == null) { FileTypeCollection fileTypes = FileTypes.GetFileTypes(); string ext = Path.GetExtension(newFileName); int index = fileTypes.IndexOfExtension(ext); FileType inferredFileType = fileTypes[index]; newFileType = inferredFileType; } // if the image has more than 1 layer but is saving with a file type that // does not support layers, then we must ask them if we may flatten the // image first if (Document.Layers.Count > 1 && !newFileType.SupportsLayers) { if (!tryToFlatten) { return DoSaveAs(); } else { DialogResult dr = WarnAboutFlattening(); if (dr == DialogResult.Yes) { ExecuteFunction(new FlattenFunction()); } else { return false; } } } // get the configuration! if (newSaveConfigToken == null) { Surface scratch = BorrowScratchSurface(this.GetType().Name + ".DoSave() calling GetSaveConfigToken()"); bool result; try { result = GetSaveConfigToken(newFileType, newSaveConfigToken, out newSaveConfigToken, scratch); } finally { ReturnScratchSurface(scratch); } if (!result) { return false; } } // At this point fileName, fileType, and saveConfigToken must all be non-null // if the document supports custom headers, embed a thumbnail in there if (newFileType.SupportsCustomHeaders) { using (new WaitCursorChanger(this)) { Utility.GCFullCollect(); const int maxDim = 256; Surface thumb; Surface flattened = BorrowScratchSurface(this.GetType().Name + ".DoSave() preparing embedded thumbnail"); try { Document.Flatten(flattened); if (Document.Width > maxDim || Document.Height > maxDim) { int width; int height; if (Document.Width > Document.Height) { width = maxDim; height = (Document.Height * maxDim) / Document.Width; } else { height = maxDim; width = (Document.Width * maxDim) / Document.Height; } int thumbWidth = Math.Max(1, width); int thumbHeight = Math.Max(1, height); thumb = new Surface(thumbWidth, thumbHeight); thumb.SuperSamplingFitSurface(flattened); } else { thumb = new Surface(flattened.Size); thumb.CopySurface(flattened); } } finally { ReturnScratchSurface(flattened); } Document thumbDoc = new Document(thumb.Width, thumb.Height); BitmapLayer thumbLayer = new BitmapLayer(thumb); BitmapLayer backLayer = new BitmapLayer(thumb.Width, thumb.Height); backLayer.Surface.Clear(ColorBgra.Transparent); thumb.Dispose(); thumbDoc.Layers.Add(backLayer); thumbDoc.Layers.Add(thumbLayer); MemoryStream thumbPng = new MemoryStream(); PropertyBasedSaveConfigToken pngToken = PdnFileTypes.Png.CreateDefaultSaveConfigToken(); PdnFileTypes.Png.Save(thumbDoc, thumbPng, pngToken, null, null, false); byte[] thumbBytes = thumbPng.ToArray(); string thumbString = Convert.ToBase64String(thumbBytes, Base64FormattingOptions.None); thumbDoc.Dispose(); string thumbXml = "<thumb png=\"" + thumbString + "\" />"; Document.CustomHeaders = thumbXml; } } // save! bool success = false; Stream stream = null; try { stream = (Stream)new FileStream(newFileName, FileMode.Create, FileAccess.Write); using (new WaitCursorChanger(this)) { Utility.GCFullCollect(); SaveProgressDialog sd = new SaveProgressDialog(this); Surface scratch = BorrowScratchSurface(this.GetType().Name + ".DoSave() handing off scratch surface to SaveProgressDialog.Save()"); try { sd.Save(stream, Document, newFileType, newSaveConfigToken, scratch); } finally { ReturnScratchSurface(scratch); } success = true; this.lastSaveTime = DateTime.Now; stream.Close(); stream = null; } } catch (UnauthorizedAccessException) { Utility.ErrorBox(this, PdnResources.GetString("SaveImage.Error.UnauthorizedAccessException")); } catch (SecurityException) { Utility.ErrorBox(this, PdnResources.GetString("SaveImage.Error.SecurityException")); } catch (DirectoryNotFoundException) { Utility.ErrorBox(this, PdnResources.GetString("SaveImage.Error.DirectoryNotFoundException")); } catch (IOException) { Utility.ErrorBox(this, PdnResources.GetString("SaveImage.Error.IOException")); } catch (OutOfMemoryException) { Utility.ErrorBox(this, PdnResources.GetString("SaveImage.Error.OutOfMemoryException")); } #if !DEBUG catch (Exception) { Utility.ErrorBox(this, PdnResources.GetString("SaveImage.Error.Exception")); } #endif finally { if (stream != null) { stream.Close(); stream = null; } } if (success) { Shell.AddToRecentDocumentsList(newFileName); } else { return false; } // reset the dirty bit so they won't be asked to save on quitting Document.Dirty = false; // some misc. book keeping ... AddToMruList(); // and finally, shout happiness by way of ... return true; } }
/// <summary> /// Takes the current Document from this DocumentWorkspace instance and adds it to the MRU list. /// </summary> /// <param name="fileName"></param> public void AddToMruList() { using (new PushNullToolMode(this)) { string fullFileName = Path.GetFullPath(this.FilePath); int edgeLength = AppWorkspace.MostRecentFiles.IconSize; Surface thumb1 = RenderThumbnail(edgeLength, true, true); // Put it inside a square bitmap Surface thumb = new Surface(4 + edgeLength, 4 + edgeLength); thumb.Clear(ColorBgra.Transparent); Rectangle dstRect = new Rectangle((thumb.Width - thumb1.Width) / 2, (thumb.Height - thumb1.Height) / 2, thumb1.Width, thumb1.Height); thumb.CopySurface(thumb1, dstRect.Location); using (RenderArgs ra = new RenderArgs(thumb)) { // Draw black border Rectangle borderRect = new Rectangle(dstRect.Left - 1, dstRect.Top - 1, dstRect.Width + 2, dstRect.Height + 2); --borderRect.Width; --borderRect.Height; ra.Graphics.DrawRectangle(Pens.Black, borderRect); Rectangle shadowRect = Rectangle.Inflate(borderRect, 1, 1); ++shadowRect.Width; ++shadowRect.Height; Utility.DrawDropShadow1px(ra.Graphics, shadowRect); thumb1.Dispose(); thumb1 = null; MostRecentFile mrf = new MostRecentFile(fullFileName, Utility.FullCloneBitmap(ra.Bitmap)); if (AppWorkspace.MostRecentFiles.Contains(fullFileName)) { AppWorkspace.MostRecentFiles.Remove(fullFileName); } AppWorkspace.MostRecentFiles.Add(mrf); AppWorkspace.MostRecentFiles.SaveMruList(); } } }
void Render(Surface dst, Surface src, Rectangle rect) { dst.CopySurface(processedSurface, rect.Location, rect); }
protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs) { Rectangle selection = EnvironmentParameters.GetSelection(srcArgs.Surface.Bounds).GetBoundsInt(); Surface selectionSurface = new Surface(selection.Width, selection.Height); selectionSurface.CopySurface(srcArgs.Surface, selection); Surface stretchedSurface = new Surface(selection.Width * 2, selection.Height); stretchedSurface.FitSurface(ResamplingAlgorithm.Bicubic, selectionSurface); processedSurface = new Surface(srcArgs.Surface.Size); ColorBgra t; for (int y = 0; y < stretchedSurface.Height; y++) { if (IsCancelRequested) return; int v = selection.Left; for (int x = 0; x < stretchedSurface.Width; x += 2) { if (x % 2 == 0) { t.R = stretchedSurface[x, y].R; t.G = stretchedSurface[x + 1, y].G; if (x != stretchedSurface.Width - 2) { t.B = stretchedSurface[x + 2, y].B; } else { t.B = (byte)((stretchedSurface[stretchedSurface.Width - 1, y].B + stretchedSurface[stretchedSurface.Width - 2, y].B) >> 1); } processedSurface[v, y + selection.Top] = ColorBgra.FromBgr(t.B, t.G, t.R); v++; } } } base.OnSetRenderInfo(newToken, dstArgs, srcArgs); }
public void SaveRegion(PdnRegion saveMeRegion, Rectangle saveMeBounds) { BitmapLayer activeLayer = (BitmapLayer)ActiveLayer; if (savedTiles == null) { savedTiles = new BitVector2D( (activeLayer.Width + saveTileGranularity - 1) / saveTileGranularity, (activeLayer.Height + saveTileGranularity - 1) / saveTileGranularity); savedTiles.Clear(false); } Rectangle regionBounds; if (saveMeRegion == null) { regionBounds = saveMeBounds; } else { regionBounds = saveMeRegion.GetBoundsInt(); } Rectangle bounds = Rectangle.Union(regionBounds, saveMeBounds); bounds.Intersect(activeLayer.Bounds); int leftTile = bounds.Left / saveTileGranularity; int topTile = bounds.Top / saveTileGranularity; int rightTile = (bounds.Right - 1) / saveTileGranularity; int bottomTile = (bounds.Bottom - 1) / saveTileGranularity; for (int tileY = topTile; tileY <= bottomTile; ++tileY) { Rectangle rowAccumBounds = Rectangle.Empty; for (int tileX = leftTile; tileX <= rightTile; ++tileX) { if (!savedTiles.Get(tileX, tileY)) { Rectangle tileBounds = new Rectangle(tileX * saveTileGranularity, tileY * saveTileGranularity, saveTileGranularity, saveTileGranularity); tileBounds.Intersect(activeLayer.Bounds); if (rowAccumBounds == Rectangle.Empty) { rowAccumBounds = tileBounds; } else { rowAccumBounds = Rectangle.Union(rowAccumBounds, tileBounds); } savedTiles.Set(tileX, tileY, true); } else { if (rowAccumBounds != Rectangle.Empty) { using (Surface dst = ScratchSurface.CreateWindow(rowAccumBounds), src = activeLayer.Surface.CreateWindow(rowAccumBounds)) { dst.CopySurface(src); } rowAccumBounds = Rectangle.Empty; } } } if (rowAccumBounds != Rectangle.Empty) { using (Surface dst = ScratchSurface.CreateWindow(rowAccumBounds), src = activeLayer.Surface.CreateWindow(rowAccumBounds)) { dst.CopySurface(src); } rowAccumBounds = Rectangle.Empty; } } if (this.saveRegion != null) { this.saveRegion.Dispose(); this.saveRegion = null; } if (saveMeRegion != null) { this.saveRegion = saveMeRegion.Clone(); } }
/// <summary> /// Creates a new surface with the same dimensions and pixel values as this one. /// </summary> /// <returns>A new surface that is a clone of the current one.</returns> public Surface Clone() { if (disposed) { throw new ObjectDisposedException("Surface"); } Surface ret = new Surface(this.Size); ret.CopySurface(this); return ret; }
protected override void OnSetRenderInfo(PropertyBasedEffectConfigToken newToken, RenderArgs dstArgs, RenderArgs srcArgs) { Amount1 = newToken.GetProperty<Int32Property>(PropertyNames.Amount1).Value; if (selectionSurface == null) { selectionSurface = new Surface(srcArgs.Surface.Size); PdnRegion selectionRegion = EnvironmentParameters.GetSelection(srcArgs.Bounds); selectionSurface.CopySurface(srcArgs.Surface, selectionRegion); // Increase absolute Transparency within selection to 1 to ensure clamping happens at selection edge ColorBgra alphaTest; foreach (Rectangle r in selectionRegion.GetRegionScansInt()) { for (int y = r.Top; y < r.Bottom; y++) { if (IsCancelRequested) return; for (int x = r.Left; x < r.Right; x++) { alphaTest = selectionSurface[x, y]; if (alphaTest.A == 0) alphaTest.A = 1; selectionSurface[x, y] = alphaTest; } } } } Rectangle selection = EnvironmentParameters.GetSelection(srcArgs.Surface.Bounds).GetBoundsInt(); int left = Math.Max(0, selection.Left - 200); int right = Math.Min(srcArgs.Surface.Width, selection.Right + 200); int top = Math.Max(0, selection.Top - 200); int bottom = Math.Min(srcArgs.Surface.Height, selection.Bottom + 200); if (nearestPixels == null) { nearestPixels = new NearestPixelTransform(left, top, right - left, bottom - top); nearestPixels.Include((x, y) => selectionSurface[x, y].A >= 1); nearestPixels.Transform(); } if (clampedSurface == null) clampedSurface = new Surface(srcArgs.Surface.Size); ColorBgra cp; for (int y = top; y < bottom; y++) { if (IsCancelRequested) return; for (int x = left; x < right; x++) { cp = selectionSurface[x, y]; if (cp.A > 1) { clampedSurface[x, y] = cp; } else { Point p = nearestPixels[x, y]; cp = selectionSurface[p]; clampedSurface[x, y] = cp; } } } base.OnSetRenderInfo(newToken, dstArgs, srcArgs); }
void Render(Surface dst, Surface src, Rectangle rect) { if (Amount3 != 0) { // Setup for calling the Gaussian Blur effect GaussianBlurEffect blurEffect = new GaussianBlurEffect(); PropertyCollection blurProps = blurEffect.CreatePropertyCollection(); PropertyBasedEffectConfigToken BlurParameters = new PropertyBasedEffectConfigToken(blurProps); BlurParameters.SetPropertyValue(GaussianBlurEffect.PropertyNames.Radius, Amount3); blurEffect.SetRenderInfo(BlurParameters, new RenderArgs(dst), new RenderArgs(shadowSurface)); // Call the Gaussian Blur function blurEffect.Render(new Rectangle[1] { rect }, 0, 1); } else { dst.CopySurface(shadowSurface, rect.Location, rect); } Rectangle selection = EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt(); ColorBgra sourcePixel, shadowPixel; for (int y = rect.Top; y < rect.Bottom; y++) { if (IsCancelRequested) return; for (int x = rect.Left; x < rect.Right; x++) { sourcePixel = src[x, y]; shadowPixel = dst[x, y]; if (x < selection.Left + Amount1 + Amount6 || x > selection.Right - Amount1 - 1 + Amount6|| y < selection.Top + Amount1 + Amount7|| y > selection.Bottom - Amount1 - 1 + Amount7) { // Erase the margins shadowPixel.A = 0; } else { shadowPixel.A = Int32Util.ClampToByte(shadowPixel.A * Amount5 / 255); } dst[x, y] = normalOp.Apply(sourcePixel, shadowPixel); } } }