示例#1
0
        public Surface Clone()
        {
            Surface surf = new Surface(width, height);

            surf.CopySurface(this);
            return(surf);
        }
示例#2
0
        public void Draw(Surface dst)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("PlacedSurface");
            }

            dst.CopySurface(what, where);
        }
示例#3
0
        public PlacedSurface(Surface source, Rectangle roi)
        {
            where = roi.Location;

            Surface window = source.CreateWindow(roi);
            what = new Surface(window.Size);
            what.CopySurface(window);
            window.Dispose();
        }
示例#4
0
        public PlacedSurface(Surface source, Rectangle roi)
        {
            where = roi.Location;

            Surface window = source.CreateWindow(roi);

            what = new Surface(window.Size);
            what.CopySurface(window);
            window.Dispose();
        }
示例#5
0
        public void Draw(Surface dst)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("PlacedSurface");
            }

            dst.CopySurface(what, where);
        }
示例#6
0
        /// <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;
            }
        }
示例#7
0
        /// <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();
                }
            }
        }
示例#8
0
 void Render(Surface dst, Surface src, Rectangle rect)
 {
     dst.CopySurface(processedSurface, rect.Location, rect);
 }
示例#9
0
        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);
        }
示例#10
0
        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();
            }
        }
示例#11
0
        /// <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);
                }
            }
        }