public void RestoreRegion(PdnRegion region) { if (region != null) { BitmapLayer activeLayer = (BitmapLayer)ActiveLayer; activeLayer.Surface.CopySurface(this.ScratchSurface, region); activeLayer.Invalidate(region); } }
public void RestoreSavedRegion() { if (this.saveRegion != null) { BitmapLayer activeLayer = (BitmapLayer)ActiveLayer; activeLayer.Surface.CopySurface(this.ScratchSurface, this.saveRegion); activeLayer.Invalidate(this.saveRegion); this.saveRegion.Dispose(); this.saveRegion = null; } }
// TODO: add "name" parameter, keep this for legacy and fill it in with "Background" // goal is to put complete burden of loc on the client public static BitmapLayer CreateBackgroundLayer(int width, int height) { // set colors to 0xffffffff // note: we use alpha of 255 here so that "invert colors" works as expected // that is, for just 1 layer we invert the initial white->black // but on subsequent layers we invert transparent white -> transparent black, which shows up as white for the most part BitmapLayer layer = new BitmapLayer(width, height, ColorBgra.White); layer.Name = PdnResources.GetString("Layer.Background.Name"); // tag it as a background layer layer.properties.isBackground = true; return(layer); }
protected BitmapLayer(BitmapLayer copyMe) : base(copyMe) { this.surface = copyMe.Surface.Clone(); this.properties = (BitmapLayerProperties)copyMe.properties.Clone(); }
/// <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; } }
protected void LoadDocumentLayer(Document doc, BytePtr ibuf, int sz, string name) { BitmapLayer layer; Bitmap bmp; PDJPG_LayerInfo linf; byte[] rgba; byte[] norm; byte[] spec; byte[] luma; int xs, ys, ox, oy, ln, fl; // int i, j; rgba = new byte[4096 * 4096 * 4]; norm = new byte[4096 * 4096 * 4]; spec = new byte[4096 * 4096 * 4]; luma = new byte[4096 * 4096 * 4]; PDJPG.PDJPG_DecodeComponent(ibuf, sz, rgba, norm, spec, luma, out xs, out ys, out linf); fl = linf.flags; //PDJPG_DecodeHasComponent() ln = doc.Layers.Count; //doc.Layers.Insert(ln, null); if (true) { //layer = new BitmapLayer(xs, ys); layer = new BitmapLayer(doc.Width, doc.Height); layer.Name = name; layer.Opacity = linf.alpha; layer.Visible = true; if((fl&PDJPG.PDJPG_BCSFL_LAYER_HIDDEN)!=0) layer.Visible = false; if ((fl & PDJPG.PDJPG_BCSFL_ALPHACYAN) != 0) { BlendByteBufferInverseTransparentColor(rgba, xs, ys); } //bmp = BitmapFromByteBuffer(rgba, xs, ys); bmp = BitmapFromByteBuffer(rgba, xs, ys, doc.Width, doc.Height, linf.orgx, linf.orgy); layer.Surface.CopyFromGdipBitmap(bmp, false); doc.Layers.Insert(ln++, layer); } if (PDJPG.PDJPG_DecodeHasComponent(ibuf, sz, "XYZ")) { //layer = new BitmapLayer(xs, ys); layer = new BitmapLayer(doc.Width, doc.Height); layer.Name = name + "::Normal"; layer.Opacity = linf.alpha; layer.Visible = false; //bmp = BitmapFromByteBufferRGB(norm, xs, ys); bmp = BitmapFromByteBufferRGB(norm, xs, ys, doc.Width, doc.Height, linf.orgx, linf.orgy); layer.Surface.CopyFromGdipBitmap(bmp, false); doc.Layers.Insert(ln++, layer); } if (PDJPG.PDJPG_DecodeHasComponent(ibuf, sz, "SpRGB")) { //layer = new BitmapLayer(xs, ys); layer = new BitmapLayer(doc.Width, doc.Height); layer.Name = name + "::Specular"; layer.Opacity = linf.alpha; layer.Visible = false; //bmp = BitmapFromByteBufferRGB(spec, xs, ys); bmp = BitmapFromByteBufferRGB(spec, xs, ys, doc.Width, doc.Height, linf.orgx, linf.orgy); layer.Surface.CopyFromGdipBitmap(bmp, false); doc.Layers.Insert(ln++, layer); } if (PDJPG.PDJPG_DecodeHasComponent(ibuf, sz, "LuRGB")) { //layer = new BitmapLayer(xs, ys); layer = new BitmapLayer(doc.Width, doc.Height); layer.Name = name + "::Luma"; layer.Opacity = linf.alpha; layer.Visible = false; //bmp = BitmapFromByteBufferRGB(luma, xs, ys); bmp = BitmapFromByteBufferRGB(luma, xs, ys, doc.Width, doc.Height, linf.orgx, linf.orgy); layer.Surface.CopyFromGdipBitmap(bmp, false); doc.Layers.Insert(ln++, layer); } }
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(); } }
public static BitmapLayer ResizeLayer(BitmapLayer layer, int width, int height, ResamplingAlgorithm algorithm) { bool pleaseStop = false; return ResizeLayer(layer, width, height, algorithm, 0, null, ref pleaseStop); }
private static BitmapLayer ResizeLayer(BitmapLayer layer, int width, int height, ResamplingAlgorithm algorithm, int tileCount, Procedure progressCallback, ref bool pleaseStopMonitor) { Surface surface = new Surface(width, height); surface.Clear(ColorBgra.FromBgra(255, 255, 255, 0)); PaintDotNet.Threading.ThreadPool threadPool = new PaintDotNet.Threading.ThreadPool(); int rectCount; if (tileCount == 0) { rectCount = Processor.LogicalCpuCount; } else { rectCount = tileCount; } Rectangle[] rects = new Rectangle[rectCount]; Utility.SplitRectangle(surface.Bounds, rects); FitSurfaceContext fsc = new FitSurfaceContext(surface, layer.Surface, rects, algorithm); if (progressCallback != null) { fsc.RenderedRect += progressCallback; } WaitCallback callback = new WaitCallback(fsc.FitSurface); for (int i = 0; i < rects.Length; ++i) { if (pleaseStopMonitor) { break; } else { threadPool.QueueUserWorkItem(callback, BoxedConstants.GetInt32(i)); } } threadPool.Drain(); threadPool.DrainExceptions(); if (pleaseStopMonitor) { surface.Dispose(); surface = null; } BitmapLayer newLayer; if (surface == null) { newLayer = null; } else { newLayer = new BitmapLayer(surface, true); newLayer.LoadProperties(layer.SaveProperties()); } if (progressCallback != null) { fsc.RenderedRect -= progressCallback; } return newLayer; }
// TODO: add "name" parameter, keep this for legacy and fill it in with "Background" // goal is to put complete burden of loc on the client public static BitmapLayer CreateBackgroundLayer(int width, int height) { // set colors to 0xffffffff // note: we use alpha of 255 here so that "invert colors" works as expected // that is, for just 1 layer we invert the initial white->black // but on subsequent layers we invert transparent white -> transparent black, which shows up as white for the most part BitmapLayer layer = new BitmapLayer(width, height, ColorBgra.White); layer.Name = PdnResources.GetString("Layer.Background.Name"); // tag it as a background layer layer.properties.isBackground = true; return layer; }
protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); if (!(ActiveLayer is BitmapLayer)) { return; } Cursor = cursorMouseDown; if (IsMouseLeftDown(e)) { this.rendererDst.Visible = false; if (IsCtrlDown()) { GetStaticData().takeFrom = new Point(e.X, e.Y); this.rendererSrc.BrushLocation = new Point(e.X, e.Y); this.rendererSrc.BrushSize = AppEnvironment.PenInfo.Width / 2.0f; this.rendererSrc.Visible = true; GetStaticData().updateSrcPreview = false; GetStaticData().wr = new WeakReference(((BitmapLayer)ActiveLayer)); takeFromLayer = (BitmapLayer)(GetStaticData().wr.Target); GetStaticData().lastMoved = Point.Empty; ra = new RenderArgs(((BitmapLayer)ActiveLayer).Surface); } else { GetStaticData().updateSrcPreview = true; // Determine if there is something to work if, if there isn't return if (GetStaticData().takeFrom == Point.Empty) { } else if (!GetStaticData().wr.IsAlive || takeFromLayer == null) { GetStaticData().takeFrom = Point.Empty; GetStaticData().lastMoved = Point.Empty; } // Make sure the layer is still there! else if (takeFromLayer != null && !Document.Layers.Contains(takeFromLayer)) { GetStaticData().takeFrom = Point.Empty; GetStaticData().lastMoved = Point.Empty; } else { this.antialiasing = AppEnvironment.AntiAliasing; this.ra = new RenderArgs(((BitmapLayer)ActiveLayer).Surface); this.ra.Graphics.SmoothingMode = SmoothingMode.AntiAlias; OnMouseMove(e); } } } }
protected override void OnActivate() { base.OnActivate(); cursorMouseDown = new Cursor(PdnResources.GetResourceStream("Cursors.GenericToolCursorMouseDown.cur")); cursorMouseDownSetSource = new Cursor(PdnResources.GetResourceStream("Cursors.CloneStampToolCursorSetSource.cur")); cursorMouseUp = new Cursor(PdnResources.GetResourceStream("Cursors.CloneStampToolCursor.cur")); this.Cursor = cursorMouseUp; this.rendererDst = new BrushPreviewRenderer(this.RendererList); this.RendererList.Add(this.rendererDst, false); this.rendererSrc = new BrushPreviewRenderer(this.RendererList); this.rendererSrc.BrushLocation = GetStaticData().takeFrom; this.rendererSrc.BrushSize = AppEnvironment.PenInfo.Width / 2.0f; this.rendererSrc.Visible = (GetStaticData().takeFrom != Point.Empty); this.RendererList.Add(this.rendererSrc, false); if (ActiveLayer != null) { switchedTo = true; historyRects = new Vector<Rectangle>(); if (GetStaticData().wr != null && GetStaticData().wr.IsAlive) { takeFromLayer = (BitmapLayer)GetStaticData().wr.Target; } else { takeFromLayer = null; } } AppEnvironment.PenInfoChanged += new EventHandler(Environment_PenInfoChanged); }