Example #1
0
        // For now, we only export in uncompressed ARGB32 format. If someone requests this functionality,
        // we can always add more through an export dialog.
        public void Export(Document document, string fileName)
        {
            ImageSurface surf = document.GetFlattenedImage (); // Assumes the surface is in ARGB32 format
            BinaryWriter writer = new BinaryWriter (new FileStream (fileName, FileMode.Create, FileAccess.Write));

            try {
                TgaHeader header = new TgaHeader();

                header.idLength = (byte) (ImageIdField.Length + 1);
                header.cmapType = 0;
                header.imageType = 2; // uncompressed RGB
                header.cmapIndex = 0;
                header.cmapLength = 0;
                header.cmapEntrySize = 0;
                header.xOrigin = 0;
                header.yOrigin = 0;
                header.imageWidth = (ushort) surf.Width;
                header.imageHeight = (ushort) surf.Height;
                header.pixelDepth = 32;
                header.imageDesc = 8; // 32-bit, lower-left origin, which is weird but hey...
                header.WriteTo (writer);

                writer.Write(ImageIdField);

                byte[] data = surf.Data;

                // It just so happens that the Cairo ARGB32 internal representation matches
                // the TGA format, except vertically-flipped. In little-endian, of course.
                for (int y = surf.Height - 1; y >= 0; y--)
                    writer.Write (data, surf.Stride * y, surf.Stride);
            } finally {
                (surf as IDisposable).Dispose ();
                writer.Close ();
            }
        }
Example #2
0
        public void Import(string filename, Gtk.Window parent)
        {
            FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read);

            pdn.Document loaded = PaintDotNetFileLoader.FromStream((stream));


            // Create a new document and add an initial layer.
            Pinta.Core.Document doc = PintaCore.Workspace.CreateAndActivateDocument(filename, new Gdk.Size(loaded.Width, loaded.Height));
            doc.HasFile = true;
            doc.Workspace.CanvasSize = doc.ImageSize;

            int index = 0;

            foreach (BitmapLayer l in loaded.Layers)
            {
                UserLayer layer = doc.CreateLayer(l.Name, l.Width, l.Height);
                doc.Insert(layer, index++);

                layer.Hidden    = !l.Visible;                          // pdn stores visible, not hidden
                layer.BlendMode = ConvertBlendMode(l.BlendMode);
                layer.Opacity   = Convert.ToDouble(l.Opacity) / 255.0; // pdn stores opacity with 255 as max

                // Copy over the image data to the layer's surface.
                CopyToSurface(l.Surface.Data.Buffer, layer.Surface);
            }
        }
Example #3
0
        public CanvasWindow (Document document) : base (2, 2, false)
        {
            scrolled_window = new ScrolledWindow ();

            var vp = new Viewport () {
                ShadowType = ShadowType.None
            };

            Canvas = new PintaCanvas (this, document) {
                Name = "canvas",
                CanDefault = true,
                CanFocus = true,
                Events = (Gdk.EventMask)16134
            };

            // Rulers
            horizontal_ruler = new HRuler ();
            horizontal_ruler.Metric = MetricType.Pixels;
            Attach (horizontal_ruler, 1, 2, 0, 1, AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Shrink | AttachOptions.Fill, 0, 0);

            vertical_ruler = new VRuler ();
            vertical_ruler.Metric = MetricType.Pixels;
            Attach (vertical_ruler, 0, 1, 1, 2, AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Shrink | AttachOptions.Fill, 0, 0);

            scrolled_window.Hadjustment.ValueChanged += delegate {
                UpdateRulerRange ();
            };

            scrolled_window.Vadjustment.ValueChanged += delegate {
                UpdateRulerRange ();
            };

            document.Workspace.CanvasSizeChanged += delegate {
                UpdateRulerRange ();
            };

            Canvas.MotionNotifyEvent += delegate (object o, MotionNotifyEventArgs args) {
                if (!PintaCore.Workspace.HasOpenDocuments)
                    return;

                var point = PintaCore.Workspace.WindowPointToCanvas (args.Event.X, args.Event.Y);

                horizontal_ruler.Position = point.X;
                vertical_ruler.Position = point.Y;
            };

            Attach (scrolled_window, 1, 2, 1, 2, AttachOptions.Expand | AttachOptions.Fill, AttachOptions.Expand | AttachOptions.Fill, 0, 0);

            scrolled_window.Add (vp);
            vp.Add (Canvas);

            ShowAll ();
            Canvas.Show ();
            vp.Show ();

            horizontal_ruler.Visible = false;
            vertical_ruler.Visible = false;

            Canvas.SizeAllocated += delegate { UpdateRulerRange (); };
        }
Example #4
0
        public RadioAction AddDocument(Document doc)
        {
            RadioAction action = new RadioAction (doc.Guid.ToString (), doc.Filename, string.Empty, null, 0);

            // Tie these all together as a radio group
            if (OpenWindows.Count > 0)
                action.Group = OpenWindows[0].Group;

            action.Active = true;
            action.Activated += (o, e) => { if ((o as Gtk.ToggleAction).Active) PintaCore.Workspace.SetActiveDocumentInternal (doc); };

            OpenWindows.Add (action);
            CheckMenuItem menuitem;

            // We only assign accelerators up to Alt-9
            if (OpenWindows.Count < 10)
                menuitem = action.CreateAcceleratedMenuItem (IntegerToNumKey (OpenWindows.Count), Gdk.ModifierType.Mod1Mask);
            else
                menuitem = (CheckMenuItem)action.CreateMenuItem ();

            action_menu_items.Add (action, menuitem);
            window_menu.Add (menuitem);

            doc.Renamed += (o, e) => { UpdateMenuLabel (action, o as Document); };
            doc.IsDirtyChanged += (o, e) => { UpdateMenuLabel (action, o as Document); };

            return action;
        }
Example #5
0
        public void Export(Document document, string fileName)
        {
            Cairo.ImageSurface surf = document.GetFlattenedImage ();

            Pixbuf pb = surf.ToPixbuf ();
            DoSave(pb, fileName, filetype);

            (pb as IDisposable).Dispose ();
            (surf as IDisposable).Dispose ();
        }
Example #6
0
		public PintaCanvas (CanvasWindow window, Document document)
		{
            CanvasWindow = window;
            this.document = document;

			cr = new CanvasRenderer (true);
			
			// Keep the widget the same size as the canvas
            document.Workspace.CanvasSizeChanged += delegate (object sender, EventArgs e) {
                SetRequisition (document.Workspace.CanvasSize);
			};

			// Update the canvas when the image changes
            document.Workspace.CanvasInvalidated += delegate (object sender, CanvasInvalidatedEventArgs e) {
                // If GTK+ hasn't created the canvas window yet, no need to invalidate it
                if (GdkWindow == null)
                    return;

				if (e.EntireSurface)
					GdkWindow.Invalidate ();
				else
					GdkWindow.InvalidateRect (e.Rectangle, false);
			};

			// Give mouse press events to the current tool
			ButtonPressEvent += delegate (object sender, ButtonPressEventArgs e) {
                // The canvas gets the button press before the tab system, so
                // if this click is on a canvas that isn't currently the ActiveDocument yet, 
                // we need to go ahead and make it the active document for the tools
                // to use it, even though right after this the tab system would have switched it
                if (PintaCore.Workspace.ActiveDocument != document)
                    PintaCore.Workspace.SetActiveDocument (document);

                PintaCore.Tools.CurrentTool.DoMouseDown (this, e, document.Workspace.WindowPointToCanvas (e.Event.X, e.Event.Y));
			};

			// Give mouse release events to the current tool
			ButtonReleaseEvent += delegate (object sender, ButtonReleaseEventArgs e) {
                PintaCore.Tools.CurrentTool.DoMouseUp (this, e, document.Workspace.WindowPointToCanvas (e.Event.X, e.Event.Y));
			};

			// Give mouse move events to the current tool
			MotionNotifyEvent += delegate (object sender, MotionNotifyEventArgs e) {
                var point = document.Workspace.WindowPointToCanvas (e.Event.X, e.Event.Y);

                if (document.Workspace.PointInCanvas (point))
					PintaCore.Chrome.LastCanvasCursorPoint = point.ToGdkPoint ();

				if (PintaCore.Tools.CurrentTool != null)
					PintaCore.Tools.CurrentTool.DoMouseMove ((DrawingArea)sender, e, point);
			};
		}
Example #7
0
        public void Export(Document document, string fileName)
        {
            ZipOutputStream stream = new ZipOutputStream (new FileStream (fileName, FileMode.Create));
            ZipEntry mimetype = new ZipEntry ("mimetype");
            mimetype.CompressionMethod = CompressionMethod.Stored;
            stream.PutNextEntry (mimetype);

            byte[] databytes = System.Text.Encoding.ASCII.GetBytes ("image/openraster");
            stream.Write (databytes, 0, databytes.Length);

            for (int i = 0; i < document.UserLayers.Count; i++) {
                Pixbuf pb = document.UserLayers[i].Surface.ToPixbuf ();
                byte[] buf = pb.SaveToBuffer ("png");
                (pb as IDisposable).Dispose ();

                stream.PutNextEntry (new ZipEntry ("data/layer" + i.ToString () + ".png"));
                stream.Write (buf, 0, buf.Length);
            }

            stream.PutNextEntry (new ZipEntry ("stack.xml"));
            databytes = GetLayerXmlData (document.UserLayers);
            stream.Write (databytes, 0, databytes.Length);

            ImageSurface flattened = document.GetFlattenedImage ();
            Pixbuf flattenedPb = flattened.ToPixbuf ();
            Size newSize = GetThumbDimensions (flattenedPb.Width, flattenedPb.Height);
            Pixbuf thumb = flattenedPb.ScaleSimple (newSize.Width, newSize.Height, InterpType.Bilinear);

            stream.PutNextEntry (new ZipEntry ("Thumbnails/thumbnail.png"));
            databytes = thumb.SaveToBuffer ("png");
            stream.Write (databytes, 0, databytes.Length);

            (flattened as IDisposable).Dispose();
            (flattenedPb as IDisposable).Dispose();
            (thumb as IDisposable).Dispose();

            stream.Close ();
        }
Example #8
0
        public void RemoveDocument(Document doc)
        {
            // Remove from our list of actions
            RadioAction act = OpenWindows.Where (p => p.Name == doc.Guid.ToString ()).FirstOrDefault ();
            OpenWindows.Remove (act);

            // Remove all the menu items from the menu
            foreach (var item in action_menu_items.Values) {
                window_menu.Remove (item);
                item.Dispose ();
            }

            action_menu_items.Clear ();

            // Recreate all of our menu items
            // I tried simply changing the accelerators, but could
            // no get it to work.
            CheckMenuItem menuitem;

            for (int i = 0; i < OpenWindows.Count; i++) {
                RadioAction action = OpenWindows[i];

                if (i < 9)
                    menuitem = action.CreateAcceleratedMenuItem (IntegerToNumKey (i + 1), Gdk.ModifierType.Mod1Mask);
                else
                    menuitem = (CheckMenuItem)action.CreateMenuItem ();

                action_menu_items.Add (action, menuitem);
                window_menu.Add (menuitem);
            }
        }
Example #9
0
 public WorkspaceManager()
 {
     ActiveDocument = Document = new Document ();
     CanvasSize = new Gdk.Size (800, 600);
     ImageSize = new Gdk.Size (800, 600);
 }
        private bool SaveFile(Document document, string file, FormatDescriptor format)
        {
            if (string.IsNullOrEmpty (file))
                file = document.PathAndFileName;

            if (format == null)
                format = PintaCore.System.ImageFormats.GetFormatByFile (file);

            if (format == null || format.IsReadOnly ()) {
                MessageDialog md = new MessageDialog (PintaCore.Chrome.MainWindow, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, Catalog.GetString ("Pinta does not support saving images in this file format."), file);
                md.Title = Catalog.GetString ("Error");

                md.Run ();
                md.Destroy ();
                return false;
            }

            // Commit any pending changes
            PintaCore.Tools.Commit ();

            format.Exporter.Export (document, file);

            document.Filename = Path.GetFileName (file);
            document.IsDirty = false;

            return true;
        }
Example #11
0
        internal bool RaiseSaveDocument(Document document)
        {
            DocumentCancelEventArgs e = new DocumentCancelEventArgs (document);

            if (SaveDocument == null)
                throw new InvalidOperationException ("GUI is not handling PintaCore.Workspace.SaveDocument");
            else
                SaveDocument (this, e);

            return !e.Cancel;
        }
		// This is actually both for "Save As" and saving a file that never
		// been saved before.  Either way, we need to prompt for a filename.
		private bool SaveFileAs (Document document)
		{
			var fcd = new FileChooserDialog (Mono.Unix.Catalog.GetString ("Save Image File"),
									       PintaCore.Chrome.MainWindow,
									       FileChooserAction.Save,
									       Gtk.Stock.Cancel,
									       Gtk.ResponseType.Cancel,
									       Gtk.Stock.Save, Gtk.ResponseType.Ok);

			fcd.DoOverwriteConfirmation = true;
            fcd.SetCurrentFolder (PintaCore.System.GetDialogDirectory ());
			fcd.AlternativeButtonOrder = new int[] { (int)ResponseType.Ok, (int)ResponseType.Cancel };

			bool hasFile = document.HasFile;

			if (hasFile)
				fcd.SetFilename (document.PathAndFileName);

			Dictionary<FileFilter, FormatDescriptor> filetypes = new Dictionary<FileFilter, FormatDescriptor> ();

			// Add all the formats we support to the save dialog
			foreach (var format in PintaCore.System.ImageFormats.Formats) {
				if (!format.IsReadOnly ()) {
					fcd.AddFilter (format.Filter);
					filetypes.Add (format.Filter, format);

					// Set the filter to anything we found
					// We want to ensure that *something* is selected in the filetype
					fcd.Filter = format.Filter;
				}
			}

			// If we already have a format, set it to the default.
			// If not, default to jpeg
			FormatDescriptor format_desc = null;

			if (hasFile)
				format_desc = PintaCore.System.ImageFormats.GetFormatByFile (document.Filename);

			if (format_desc == null) {
				format_desc = PintaCore.System.ImageFormats.GetDefaultSaveFormat ();

				// Gtk doesn't like it if we set the file name to an extension that we don't have
				// a filter for, so we change the extension to our default extension.
				if (hasFile)
					fcd.SetFilename (Path.ChangeExtension (document.PathAndFileName, format_desc.Extensions[0]));
			}

			fcd.Filter = format_desc.Filter;

            fcd.AddNotification("filter", this.OnFilterChanged);

			// Replace GTK's ConfirmOverwrite with our own, for UI consistency
			fcd.ConfirmOverwrite += (eventSender, eventArgs) => {
				if (this.ConfirmOverwrite (fcd, fcd.Filename))
					eventArgs.RetVal = FileChooserConfirmation.AcceptFilename;
				else
					eventArgs.RetVal = FileChooserConfirmation.SelectAgain;
			};

			while (fcd.Run () == (int)Gtk.ResponseType.Ok) {
				FormatDescriptor format = filetypes[fcd.Filter];
				string file = fcd.Filename;

				if (string.IsNullOrEmpty (Path.GetExtension (file))) {
					// No extension; add one from the format descriptor.
					file = string.Format ("{0}.{1}", file, format.Extensions[0]);
					fcd.CurrentName = Path.GetFileName (file);

					// We also need to display an overwrite confirmation message manually,
					// because MessageDialog won't do this for us in this case.
					if (File.Exists (file) && !ConfirmOverwrite (fcd, file))
						continue;
				}

				// Always follow the extension rather than the file type drop down
				// ie: if the user chooses to save a "jpeg" as "foo.png", we are going
				// to assume they just didn't update the dropdown and really want png
				var format_type = PintaCore.System.ImageFormats.GetFormatByFile (file);

				if (format_type != null)
					format = format_type;

				PintaCore.System.LastDialogDirectory = fcd.CurrentFolder;

				// If saving the file failed or was cancelled, let the user select
				// a different file type.
				if (!SaveFile (document, file, format, fcd))
					continue;

				//The user is saving the Document to a new file, so technically it
				//hasn't been saved to its associated file in this session.
				document.HasBeenSavedInSession = false;

				RecentManager.Default.AddFull (fcd.Uri, PintaCore.System.RecentData);
				PintaCore.System.ImageFormats.SetDefaultFormat (Path.GetExtension (file));

				document.HasFile = true;
				document.PathAndFileName = file;

				fcd.Destroy ();
				return true;
			}

			fcd.Destroy ();
			return false;
		}
Example #13
0
        public void CloseDocument(Document document)
        {
            int index = OpenDocuments.IndexOf (document);
            OpenDocuments.Remove (document);

            if (index == active_document_index) {
                // If there's other documents open, switch to one of them
                if (HasOpenDocuments) {
                    if (index > 0)
                        SetActiveDocument (index - 1);
                    else
                        SetActiveDocument (index);
                } else {
                    active_document_index = -1;
                    OnActiveDocumentChanged (EventArgs.Empty);
                }
            }

            document.Close ();

            OnDocumentClosed (new DocumentEventArgs (document));
        }
 internal DocumentWorkspaceHistory(Document document, DocumentWorkspace workspace)
 {
     this.document = document;
     this.workspace = workspace;
     ListStore = new ListStore (typeof (BaseHistoryItem));
 }
Example #15
0
        internal void SetActiveDocumentInternal(Document document)
        {
            PintaCore.Tools.Commit ();

            int index = OpenDocuments.IndexOf (document);
            active_document_index = index;

            OnActiveDocumentChanged (EventArgs.Empty);
        }
Example #16
0
 private void UpdateMenuLabel(RadioAction action, Document doc)
 {
     action.Label = string.Format ("{0}{1}", doc.Filename, doc.IsDirty ? "*" : string.Empty);
 }
Example #17
0
 /// <summary>
 /// Creates a thumbnail image preview of a document.
 /// </summary>
 private Cairo.ImageSurface CreateImagePreview(Document doc)
 {
     var surface = new Cairo.ImageSurface (Cairo.Format.Argb32, PreviewWidth, PreviewHeight);
     canvas_renderer.Initialize (doc.ImageSize, new Gdk.Size (PreviewWidth, PreviewHeight));
     canvas_renderer.Render (doc.GetLayersToPaint (), surface, Gdk.Point.Zero);
     return surface;
 }
Example #18
0
		private bool is_lifted;		// Track state of undo/redo lift

		public MovePixelsHistoryItem (string icon, string text, Document document) : base (icon, text)
		{
			doc = document;
		}
Example #19
0
		public DocumentCancelEventArgs (Document document, bool saveAs)
		{
			Document = document;
			SaveAs = saveAs;
		}
Example #20
0
 private void UpdateMenuLabel(RadioAction action, Document doc)
 {
     action.Label = string.Format ("{0}{1}", doc.Filename, doc.IsDirty ? "*" : string.Empty);
     PintaCore.Workspace.ResetTitle ();
 }
Example #21
0
 internal DocumentWorkspace(Document document)
 {
     this.document = document;
     History = new DocumentWorkspaceHistory (document);
 }
Example #22
0
        public Document CreateAndActivateDocument(string filename, Gdk.Size size)
        {
            Document doc = new Document (size);

            if (string.IsNullOrEmpty (filename))
                doc.Filename = string.Format ("Untitled{0}", new_file_name++);
            else
                doc.Filename = filename;

            OpenDocuments.Add (doc);
            active_document_index = OpenDocuments.Count - 1;

            OnDocumentCreated (new DocumentEventArgs (doc));
            OnActiveDocumentChanged (EventArgs.Empty);

            return doc;
        }
Example #23
0
        public void SetActiveDocument(Document document)
        {
            int index = OpenDocuments.IndexOf (document);

            SetActiveDocument (index);
        }
        private bool SaveFile(Document document, string file, FormatDescriptor format)
        {
            if (string.IsNullOrEmpty (file))
                file = document.PathAndFileName;

            if (format == null)
                format = PintaCore.System.ImageFormats.GetFormatByFile (file);

            if (format == null || format.IsReadOnly ()) {
                MessageDialog md = new MessageDialog (PintaCore.Chrome.MainWindow, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, Catalog.GetString ("Pinta does not support saving images in this file format."), file);
                md.Title = Catalog.GetString ("Error");

                md.Run ();
                md.Destroy ();
                return false;
            }

            // If the user tries to save over a read only file, give a more informative error message than "Unhandled Exception"
            FileInfo file_info = new FileInfo (file);
            if (file_info.Exists && file_info.IsReadOnly) {
                MessageDialog md = new MessageDialog (PintaCore.Chrome.MainWindow, DialogFlags.Modal, MessageType.Error,
                    ButtonsType.Ok, Catalog.GetString ("Cannot save read only file."));
                md.Title = Catalog.GetString ("Error");

                md.Run ();
                md.Destroy ();
                return false;
            }

            // Commit any pending changes
            PintaCore.Tools.Commit ();

            format.Exporter.Export (document, file);

            document.Filename = Path.GetFileName (file);
            document.IsDirty = false;

            return true;
        }
Example #25
0
        internal void SetActiveDocumentInternal(Document document)
        {
            // Work around a case where we closed a document but haven't updated
            // the active_document_index yet and it points to the closed document
            if (HasOpenDocuments && active_document_index != -1 && OpenDocuments.Count > active_document_index)
                PintaCore.Tools.Commit ();

            int index = OpenDocuments.IndexOf (document);
            active_document_index = index;

            OnActiveDocumentChanged (EventArgs.Empty);
        }
		private bool SaveFile (Document document, string file, FormatDescriptor format, Window parent)
		{
			if (string.IsNullOrEmpty (file))
				file = document.PathAndFileName;

			if (format == null)
				format = PintaCore.System.ImageFormats.GetFormatByFile (file);

			if (format == null || format.IsReadOnly ()) {
				MessageDialog md = new MessageDialog (parent, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, Catalog.GetString ("Pinta does not support saving images in this file format."), file);
				md.Title = Catalog.GetString ("Error");

				md.Run ();
				md.Destroy ();
				return false;
			}

			// If the user tries to save over a read only file, give a more informative error message than "Unhandled Exception"
			FileInfo file_info = new FileInfo (file);
			if (file_info.Exists && file_info.IsReadOnly) {
				MessageDialog md = new MessageDialog (parent, DialogFlags.Modal, MessageType.Error,
					ButtonsType.Ok, Catalog.GetString ("Cannot save read only file."));
				md.Title = Catalog.GetString ("Error");

				md.Run ();
				md.Destroy ();
				return false;
			}

			// Commit any pending changes
			PintaCore.Tools.Commit ();

			try {
				format.Exporter.Export (document, file, parent);
			} catch (GLib.GException e) { // Errors from GDK
				if (e.Message == "Image too large to be saved as ICO") {
					string primary = Catalog.GetString ("Image too large");
					string secondary = Catalog.GetString ("ICO files can not be larger than 255 x 255 pixels.");
					string message = string.Format (markup, primary, secondary);

					MessageDialog md = new MessageDialog (parent, DialogFlags.Modal, MessageType.Error,
					ButtonsType.Ok, message);

					md.Run ();
					md.Destroy ();
					return false;
				} else {
					throw e; // Only catch exceptions we know the reason for
				}
			} catch (OperationCanceledException) {
				return false;
			}

			document.Filename = Path.GetFileName (file);
			document.IsDirty = false;

			PintaCore.Tools.CurrentTool.DoAfterSave();

			//Now the Document has been saved to the file it's associated with in this session.
			document.HasBeenSavedInSession = true;

			return true;
		}
        public unsafe void Export(Document document, string fileName, Window parent)
        {
            int w = 64, h = 64; //Default value to configure, pixels per block
            string chars = DefaultCharacters.AsciiChars; //Get the selection from config

            ASCIIOptionsDialog dialog = new ASCIIOptionsDialog (w, h);
            try {
                dialog.WindowPosition = Gtk.WindowPosition.CenterOnParent;

                int response = dialog.Run ();

                if (response == (int)Gtk.ResponseType.Ok) {
                    w = dialog.ExportImageWidth;
                    h = dialog.ExportImageHeight;
                    chars = dialog.ExportImageChars;
                } else {
                    return;
                }

            } finally {
                dialog.Destroy ();
            }

            Cairo.ImageSurface surface = document.GetFlattenedImage ();
            int W = surface.Width, H = surface.Height;

            // Special case where 1 cell corresponds directly to 1 pixel
            // Written separately for performance
            if (h == 1 && w == 1) {
                StreamWriter writer = new StreamWriter(fileName);
                for (int y = 0; y < H; y++) {
                    ColorBgra* current = surface.GetRowAddressUnchecked(y);
                    for (int x = 0; x < W; x++) {
                        int pos = (int)((1 - current->GetIntensity()) * chars.Length);
                        char c = chars[pos == chars.Length ? pos - 1 : pos];
                        writer.Write(c);
                        current++;
                    }
                    if (y != H - 1) {
                        writer.WriteLine();
                    }
                }
                writer.Flush();
            } else {
                double[,] totals = new double[W / w, H / h];
                for (int y = 0; y < H / h * h; y++) {
                    ColorBgra* current = surface.GetRowAddressUnchecked(y);
                    for (int x = 0; x < W / w * w; x++) {
                        totals[x / w, y / h] += 1 - current->GetIntensity();
                        current++;
                    }
                }

                int ppc = w * h;
                StreamWriter writer = new StreamWriter(fileName);
                for (int y = 0; y < H / h; y++) {
                    for (int x = 0; x < W / w; x++) {
                        int pos = (int)(totals[x, y] / ppc * chars.Length);
                        char c = chars[pos == chars.Length ? pos - 1 : pos];
                        writer.Write(c);
                    }
                    if (y != H / h - 1) {
                        writer.WriteLine();
                    }
                }
                writer.Flush();
            }
        }
Example #28
0
        public Document CreateAndActivateDocument(string filename, Gdk.Size size)
        {
            Document doc = new Document (size);

            if (string.IsNullOrEmpty (filename))
                doc.Filename = string.Format (Catalog.GetString ("Unsaved Image {0}"), new_file_name++);
            else
                doc.PathAndFileName = filename;

            OpenDocuments.Add (doc);
            OnDocumentCreated (new DocumentEventArgs (doc));

            SetActiveDocument (doc);

            return doc;
        }
Example #29
0
        // This is actually both for "Save As" and saving a file that never
        // been saved before.  Either way, we need to prompt for a filename.
        private bool SaveFileAs(Document document)
        {
            var fcd = new FileChooserDialog (Mono.Unix.Catalog.GetString ("Save Image File"),
                                           PintaCore.Chrome.MainWindow,
                                           FileChooserAction.Save,
                                           Gtk.Stock.Cancel,
                                           Gtk.ResponseType.Cancel,
                                           Gtk.Stock.Save, Gtk.ResponseType.Ok);

            fcd.DoOverwriteConfirmation = true;
            fcd.SetCurrentFolder (lastDialogDir);
            fcd.AlternativeButtonOrder = new int[] { (int)ResponseType.Ok, (int)ResponseType.Cancel };

            bool hasFile = document.HasFile;

            if (hasFile)
                fcd.SetFilename (document.PathAndFileName);

            Dictionary<FileFilter, FormatDescriptor> filetypes = new Dictionary<FileFilter, FormatDescriptor> ();

            // Add all the formats we support to the save dialog
            foreach (var format in PintaCore.System.ImageFormats.Formats) {
                if (!format.IsReadOnly ()) {
                    fcd.AddFilter (format.Filter);
                    filetypes.Add (format.Filter, format);
                }
            }

            // If we already have a format, set it to the default.
            // If not, default to jpeg
            if (hasFile)
                fcd.Filter = PintaCore.System.ImageFormats.GetFormatByFile (document.Filename).Filter;
            else
                fcd.Filter = PintaCore.System.ImageFormats.GetDefaultFormat ().Filter;

            // Replace GTK's ConfirmOverwrite with our own, for UI consistency
            fcd.ConfirmOverwrite += (eventSender, eventArgs) => {
                if (this.ConfirmOverwrite (fcd, fcd.Filename))
                    eventArgs.RetVal = FileChooserConfirmation.AcceptFilename;
                else
                    eventArgs.RetVal = FileChooserConfirmation.SelectAgain;
            };

            while (fcd.Run () == (int)Gtk.ResponseType.Ok) {
                FormatDescriptor format = filetypes[fcd.Filter];
                string file = fcd.Filename;

                if (string.IsNullOrEmpty (Path.GetExtension (file))) {
                    // No extension; add one from the format descriptor.
                    file = string.Format ("{0}.{1}", file, format.Extensions[0]);
                    fcd.CurrentName = Path.GetFileName (file);

                    // We also need to display an overwrite confirmation message manually,
                    // because MessageDialog won't do this for us in this case.
                    if (File.Exists (file) && !ConfirmOverwrite (fcd, file))
                        continue;
                }

                // Always follow the extension rather than the file type drop down
                // ie: if the user chooses to save a "jpeg" as "foo.png", we are going
                // to assume they just didn't update the dropdown and really want png
                var format_type = PintaCore.System.ImageFormats.GetFormatByFile (file);

                if (format_type != null)
                    format = format_type;

                lastDialogDir = fcd.CurrentFolder;
                SaveFile (document, file, format);
                RecentManager.Default.AddFull (fcd.Uri, recentData);
                PintaCore.System.ImageFormats.SetDefaultFormat (Path.GetExtension (file));

                document.HasFile = true;
                document.PathAndFileName = file;

                fcd.Destroy ();
                return true;
            }

            fcd.Destroy ();
            return false;
        }
Example #30
0
        static void CropImageToRectangle(Document doc, Gdk.Rectangle rect)
        {
            ResizeHistoryItem hist = new ResizeHistoryItem (doc.ImageSize);

            hist.Icon = "Menu.Image.Crop.png";
            hist.Text = Catalog.GetString ("Crop to Selection");
            hist.StartSnapshotOfImage ();
            hist.RestoreSelection = doc.Selection.Clone();

            PintaCore.Chrome.Canvas.GdkWindow.FreezeUpdates ();

            double original_scale = doc.Workspace.Scale;
            doc.ImageSize = rect.Size;
            doc.Workspace.CanvasSize = rect.Size;
            doc.Workspace.Scale = original_scale;

            PintaCore.Actions.View.UpdateCanvasScale ();

            PintaCore.Chrome.Canvas.GdkWindow.ThawUpdates ();

            foreach (var layer in doc.UserLayers)
                layer.Crop (rect, doc.Selection.SelectionPath);

            hist.FinishSnapshotOfImage ();

            doc.History.PushNewItem (hist);
            doc.ResetSelectionPath ();

            doc.Workspace.Invalidate ();
        }
Example #31
0
        public void SetActiveDocument(Document document)
        {
            RadioAction action = PintaCore.Actions.Window.OpenWindows.Where (p => p.Name == document.Guid.ToString ()).FirstOrDefault ();

            if (action == null)
                throw new ArgumentOutOfRangeException ("Tried to WorkspaceManager.SetActiveDocument.  Could not find document.");

            action.Activate ();
        }