* png images in tool-bar / alpha mask @ 2008-04-01 17:14 David Reitter 2008-04-01 21:41 ` YAMAMOTO Mitsuharu 0 siblings, 1 reply; 16+ messages in thread From: David Reitter @ 2008-04-01 17:14 UTC (permalink / raw) To: emacs- devel I'm trying to use PNG images with alpha information in the tool-bar and find that the mask / alpha is ignored: (find-image (list (list :type 'png :file "undo.png"))) i.e. I'm not setting a ":mask 'heuristic" property here. The background just appears white. This is with the new toolkit toolbars (under Carbon), but I remember having such problems with the non-toolkit toolbar as well. `image-make-p' generally returns nil for PNGs. It seems that "image_load_quartz2d" is used to load the file (in image.c). This already determines some background colors and draws it into a new graphics context, with the background color present. And then it doesn't actually store the original image data, but creates an XCreatePixmap. (A mask is handled separately.) Would the solution be to also store the original image data (CGImageRef) in the "struct image", and then to simply use that when defining the toolbar, if it is present and if the toolkit supports it? As is probably obvious, I'm not familiar with how this is generally handled in Emacs, but if someone could provide a bit of guidance, I could try to make it work. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-01 17:14 png images in tool-bar / alpha mask David Reitter @ 2008-04-01 21:41 ` YAMAMOTO Mitsuharu 2008-04-01 23:10 ` David Reitter 0 siblings, 1 reply; 16+ messages in thread From: YAMAMOTO Mitsuharu @ 2008-04-01 21:41 UTC (permalink / raw) To: David Reitter; +Cc: emacs-devel >>>>> On Tue, 1 Apr 2008 18:14:45 +0100, David Reitter <david.reitter@gmail.com> said: > Would the solution be to also store the original image data > (CGImageRef) in the "struct image", and then to simply use that when > defining the toolbar, if it is present and if the toolkit supports > it? That wouldn't work for the case that some postprocessing is necessary for the loaded image. YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-01 21:41 ` YAMAMOTO Mitsuharu @ 2008-04-01 23:10 ` David Reitter 2008-04-02 12:39 ` YAMAMOTO Mitsuharu 0 siblings, 1 reply; 16+ messages in thread From: David Reitter @ 2008-04-01 23:10 UTC (permalink / raw) To: emacs- devel On 1 Apr 2008, at 22:41, YAMAMOTO Mitsuharu wrote: >> >> Would the solution be to also store the original image data >> (CGImageRef) in the "struct image", and then to simply use that when >> defining the toolbar, if it is present and if the toolkit supports >> it? > > That wouldn't work for the case that some postprocessing is necessary > for the loaded image. I think that would be okay. For high-quality images, such processing is best done manually or with a dedicated tool chain (ImageMagick...). One could remove the reference to the original image as soon as any kind of processing is done in order to maintain compatibility. I'm working on a patch to see if this is doable. I'll get back to you once I've tested it. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-01 23:10 ` David Reitter @ 2008-04-02 12:39 ` YAMAMOTO Mitsuharu 2008-04-03 15:09 ` David Reitter 0 siblings, 1 reply; 16+ messages in thread From: YAMAMOTO Mitsuharu @ 2008-04-02 12:39 UTC (permalink / raw) To: David Reitter; +Cc: emacs-devel >>>>> On Wed, 2 Apr 2008 00:10:09 +0100, David Reitter <david.reitter@gmail.com> said: >>> Would the solution be to also store the original image data >>> (CGImageRef) in the "struct image", and then to simply use that >>> when defining the toolbar, if it is present and if the toolkit >>> supports it? >> >> That wouldn't work for the case that some postprocessing is >> necessary for the loaded image. > I think that would be okay. For high-quality images, such > processing is best done manually or with a dedicated tool chain > (ImageMagick...). One could remove the reference to the original > image as soon as any kind of processing is done in order to maintain > compatibility. Then, that sounds feasible. > I'm working on a patch to see if this is doable. I'll get back to > you once I've tested it. OK, I'll wait a month. YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-02 12:39 ` YAMAMOTO Mitsuharu @ 2008-04-03 15:09 ` David Reitter 2008-04-03 21:15 ` YAMAMOTO Mitsuharu 0 siblings, 1 reply; 16+ messages in thread From: David Reitter @ 2008-04-03 15:09 UTC (permalink / raw) To: YAMAMOTO Mitsuharu; +Cc: emacs-devel On 2 Apr 2008, at 13:39, YAMAMOTO Mitsuharu wrote: > >> I'm working on a patch to see if this is doable. I'll get back to >> you once I've tested it. > > OK, I'll wait a month. OK, how about the patches below? The change to image.c is actually very short. The patch to tool-bar.el is intended to load PNG files where they are available, and to automatically load files named <basename>_dis.<ext> and <basename>_sel.<ext> to automatically find the disabled (greyed out) and selected (darkened) variant where provided. I find that the algorithm that is applied now (by OS X at least) to my PNG graphics works perfectly, so I'm not even providing the _dis and _sel files any longer. However, this was beneficial when the non-tool- kit toolbar was used to avoid the default manipulation of the images, so I'm leaving it in for others. Index: image.c =================================================================== RCS file: /sources/emacs/emacs/src/image.c,v retrieving revision 1.65.2.13 diff -c -r1.65.2.13 image.c *** image.c 28 Mar 2008 14:57:32 -0000 1.65.2.13 --- image.c 3 Apr 2008 15:01:11 -0000 *************** *** 2767,2773 **** } CGContextDrawImage (context, rectangle, image); QDEndCGContext (ximg, &context); ! CGImageRelease (image); /* Maybe fill in the background field while we have ximg handy. */ if (NILP (image_spec_value (img->spec, QCbackground, NULL))) --- 2767,2774 ---- } CGContextDrawImage (context, rectangle, image); QDEndCGContext (ximg, &context); ! ! img->data.ptr_val = image; /* retain original data */ /* Maybe fill in the background field while we have ximg handy. */ if (NILP (image_spec_value (img->spec, QCbackground, NULL))) Index: tool-bar.el =================================================================== RCS file: /sources/emacs/emacs/lisp/tool-bar.el,v retrieving revision 1.7.2.2 diff -c -r1.7.2.2 tool-bar.el *** tool-bar.el 7 Jan 2008 02:44:11 -0000 1.7.2.2 --- tool-bar.el 3 Apr 2008 15:04:53 -0000 *************** *** 90,95 **** --- 90,165 ---- '(menu-item "tool bar" ignore :filter (lambda (ignore) tool-bar-map))) + (defun tool-bar-set-file-extension (image-spec-list extension) + "Set new file extensions for all :file properties + Replace any extensions of :file properties in elements of + IMAGE-SPEC-LIST. An extension may start with a period . or an + underscore. EXTENSION and the original file name extension (starting + with a period) are added to the file name. + + E.g. foo_dis.xpm becomes foo_sel.xpm if EXTENSION is '_sel'." + (mapcar + (lambda (spec) + (let ((f (plist-get spec :file)) + ) + (if (null f) + spec + ;; need to replace previous extensions, including those + ;; starting with _ - + (plist-put spec :file (concat (replace-regexp-in-string "[\.\_].*$" + "" f) + extension + (file-name-extension f t))) + ))) + image-spec-list)) + + (defun tool-bar-get-image-spec (icon) + (let* ((fg (face-attribute 'tool-bar :foreground)) + (bg (face-attribute 'tool-bar :background)) + (colors (nconc (if (eq fg 'unspecified) nil (list :foreground fg)) + (if (eq bg 'unspecified) nil (list :background bg)))) + (xpm-spec (list :type 'xpm :file (concat icon ".xpm"))) + (xpm-lo-spec (if (> (display-color-cells) 256) + nil + (list :type 'xpm :file + (concat "low-color/" icon ".xpm")))) + (png-spec (list :type 'png + :file (concat icon ".png") :background "grey") ) + (pbm-spec (append (list :type 'pbm :file + (concat icon ".pbm")) colors)) + (xbm-spec (append (list :type 'xbm :file + (concat icon ".xbm")) colors)) + (image (find-image + (if (display-color-p) + (list png-spec xpm-lo-spec xpm-spec pbm-spec xbm-spec) + (list pbm-spec xbm-spec xpm-lo-spec xpm-spec)))) + (image-sel (find-image + (if (display-color-p) + (tool-bar-set-file-extension + (list png-spec xpm-lo-spec xpm-spec pbm-spec xbm-spec) + "_sel") + nil))) + (image-dis (find-image + (if (display-color-p) + (tool-bar-set-file-extension + (list png-spec xpm-lo-spec xpm-spec pbm-spec xbm-spec) + "_dis") + nil))) + (images (when image ;; image may be nil if not found. + (unless (image-mask-p image) + (setq image (append image '(:mask heuristic)))) + (if (and image-sel image-dis) + (progn + (unless (image-mask-p image-sel) + (setq image-sel (append image-sel + '(:mask heuristic)))) + (unless (image-mask-p image-dis) + (setq image-dis (append image-dis + '(:mask heuristic)))) + (vector image-sel image image-dis image-dis)) + image)))) + (cons image images))) + ;;;###autoload (defun tool-bar-add-item (icon def key &rest props) "Add an item to the tool bar. *************** *** 119,147 **** function will first try to use low-color/ICON.xpm if display-color- cells is less or equal to 256, then ICON.xpm, then ICON.pbm, and finally ICON.xbm, using `find-image'." ! (let* ((fg (face-attribute 'tool-bar :foreground)) ! (bg (face-attribute 'tool-bar :background)) ! (colors (nconc (if (eq fg 'unspecified) nil (list :foreground fg)) ! (if (eq bg 'unspecified) nil (list :background bg)))) ! (xpm-spec (list :type 'xpm :file (concat icon ".xpm"))) ! (xpm-lo-spec (if (> (display-color-cells) 256) ! nil ! (list :type 'xpm :file ! (concat "low-color/" icon ".xpm")))) ! (pbm-spec (append (list :type 'pbm :file ! (concat icon ".pbm")) colors)) ! (xbm-spec (append (list :type 'xbm :file ! (concat icon ".xbm")) colors)) ! (image (find-image ! (if (display-color-p) ! (list xpm-lo-spec xpm-spec pbm-spec xbm-spec) ! (list pbm-spec xbm-spec xpm-lo-spec xpm-spec))))) ! (when (and (display-images-p) image) - (unless (image-mask-p image) - (setq image (append image '(:mask heuristic)))) (define-key-after map (vector key) ! `(menu-item ,(symbol-name key) ,def :image ,image ,@props))))) ;;;###autoload (defun tool-bar-add-item-from-menu (command icon &optional map &rest props) --- 189,200 ---- function will first try to use low-color/ICON.xpm if display-color- cells is less or equal to 256, then ICON.xpm, then ICON.pbm, and finally ICON.xbm, using `find-image'." ! (let* ((is (tool-bar-get-image-spec icon)) ! (image (car is)) ! (images (cdr is))) (when (and (display-images-p) image) (define-key-after map (vector key) ! `(menu-item ,(symbol-name key) ,def :image ,images ,@props))))) ;;;###autoload (defun tool-bar-add-item-from-menu (command icon &optional map &rest props) *************** *** 174,196 **** (setq from-map global-map)) (let* ((menu-bar-map (lookup-key from-map [menu-bar])) (keys (where-is-internal command menu-bar-map)) ! (fg (face-attribute 'tool-bar :foreground)) ! (bg (face-attribute 'tool-bar :background)) ! (colors (nconc (if (eq fg 'unspecified) nil (list :foreground fg)) ! (if (eq bg 'unspecified) nil (list :background bg)))) ! (xpm-spec (list :type 'xpm :file (concat icon ".xpm"))) ! (xpm-lo-spec (if (> (display-color-cells) 256) ! nil ! (list :type 'xpm :file ! (concat "low-color/" icon ".xpm")))) ! (pbm-spec (append (list :type 'pbm :file ! (concat icon ".pbm")) colors)) ! (xbm-spec (append (list :type 'xbm :file ! (concat icon ".xbm")) colors)) ! (spec (if (display-color-p) ! (list xpm-lo-spec xpm-spec pbm-spec xbm-spec) ! (list pbm-spec xbm-spec xpm-lo-spec xpm-spec))) ! (image (find-image spec)) submap key) (when (and (display-images-p) image) ;; We'll pick up the last valid entry in the list of keys if --- 227,235 ---- (setq from-map global-map)) (let* ((menu-bar-map (lookup-key from-map [menu-bar])) (keys (where-is-internal command menu-bar-map)) ! (is (tool-bar-get-image-spec icon)) ! (image (car is)) ! (images (cdr is)) submap key) (when (and (display-images-p) image) ;; We'll pick up the last valid entry in the list of keys if *************** *** 210,221 **** key kk))))) (when (and (symbolp submap) (boundp submap)) (setq submap (eval submap))) - (unless (image-mask-p image) - (setq image (append image '(:mask heuristic)))) (let ((defn (assq key (cdr submap)))) (if (eq (cadr defn) 'menu-item) (define-key-after in-map (vector key) ! (append (cdr defn) (list :image image) props)) (setq defn (cdr defn)) (define-key-after in-map (vector key) (let ((rest (cdr defn))) --- 249,258 ---- key kk))))) (when (and (symbolp submap) (boundp submap)) (setq submap (eval submap))) (let ((defn (assq key (cdr submap)))) (if (eq (cadr defn) 'menu-item) (define-key-after in-map (vector key) ! (append (cdr defn) (list :image images) props)) (setq defn (cdr defn)) (define-key-after in-map (vector key) (let ((rest (cdr defn))) ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-03 15:09 ` David Reitter @ 2008-04-03 21:15 ` YAMAMOTO Mitsuharu 2008-04-03 21:42 ` David Reitter 0 siblings, 1 reply; 16+ messages in thread From: YAMAMOTO Mitsuharu @ 2008-04-03 21:15 UTC (permalink / raw) To: David Reitter; +Cc: emacs-devel >>>>> On Thu, 3 Apr 2008 16:09:06 +0100, David Reitter <david.reitter@gmail.com> said: >>> I'm working on a patch to see if this is doable. I'll get back to >>> you once I've tested it. >> >> OK, I'll wait a month. > OK, how about the patches below? > The change to image.c is actually very short. It seems to completely ignore postprocessing for PNG images. Didn't you say that "One could remove the reference to the original image as soon as any kind of processing is done in order to maintain compatibility."? YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-03 21:15 ` YAMAMOTO Mitsuharu @ 2008-04-03 21:42 ` David Reitter 2008-04-03 21:55 ` YAMAMOTO Mitsuharu 0 siblings, 1 reply; 16+ messages in thread From: David Reitter @ 2008-04-03 21:42 UTC (permalink / raw) To: YAMAMOTO Mitsuharu; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 798 bytes --] On 3 Apr 2008, at 22:15, YAMAMOTO Mitsuharu wrote: > > It seems to completely ignore postprocessing for PNG images. Didn't > you say that "One could remove the reference to the original image as > soon as any kind of processing is done in order to maintain > compatibility."? prepare_image_for_display sets data.ptr_val in the image structure as well. What happens when the image is manipulated after it's been first drawn? I assumed that data.ptr_val would be invalidated at that point, as is done in x_clear_image_1. Are you concerned about postprocess_image? One would have to invalidate the pointer and free the image when anything is done to the image there (x_build_heuristic_mask is called, or QCconversion is given). Any other places where image manipulation can take place? [-- Attachment #2: smime.p7s --] [-- Type: application/pkcs7-signature, Size: 2193 bytes --] ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-03 21:42 ` David Reitter @ 2008-04-03 21:55 ` YAMAMOTO Mitsuharu 2008-04-03 22:42 ` David Reitter 0 siblings, 1 reply; 16+ messages in thread From: YAMAMOTO Mitsuharu @ 2008-04-03 21:55 UTC (permalink / raw) To: David Reitter; +Cc: emacs-devel >>>>> On Thu, 3 Apr 2008 22:42:47 +0100, David Reitter <david.reitter@gmail.com> said: >> It seems to completely ignore postprocessing for PNG images. >> Didn't you say that "One could remove the reference to the original >> image as soon as any kind of processing is done in order to >> maintain compatibility."? > prepare_image_for_display sets data.ptr_val in the image structure > as well. What happens when the image is manipulated after it's been > first drawn? prepare_image_for_display is never called before all the postprocessing for the image is completed. YAMAMOTO Mitusharu mituharu@math.s.chiba-u.ac.jp ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-03 21:55 ` YAMAMOTO Mitsuharu @ 2008-04-03 22:42 ` David Reitter 2008-04-03 23:12 ` YAMAMOTO Mitsuharu 0 siblings, 1 reply; 16+ messages in thread From: David Reitter @ 2008-04-03 22:42 UTC (permalink / raw) To: YAMAMOTO Mitsuharu; +Cc: emacs-devel On 3 Apr 2008, at 22:55, YAMAMOTO Mitsuharu wrote: > > prepare_image_for_display is never called before all the > postprocessing for the image is completed. OK, so postprocessing seems to be the only processing that can be done to an image. Index: image.c =================================================================== RCS file: /sources/emacs/emacs/src/image.c,v retrieving revision 1.65.2.13 diff -c -r1.65.2.13 image.c *** image.c 28 Mar 2008 14:57:32 -0000 1.65.2.13 --- image.c 3 Apr 2008 22:38:10 -0000 *************** *** 1549,1555 **** } #if defined (MAC_OS) && USE_CG_DRAWING ! if (img->data.ptr_val) { CGImageRelease (img->data.ptr_val); img->data.ptr_val = NULL; --- 1549,1555 ---- } #if defined (MAC_OS) && USE_CG_DRAWING ! if (img->data.ptr_val != NULL) { CGImageRelease (img->data.ptr_val); img->data.ptr_val = NULL; *************** *** 1850,1861 **** mask = image_spec_value (spec, QCheuristic_mask, NULL); if (!NILP (mask)) ! x_build_heuristic_mask (f, img, mask); else { int found_p; mask = image_spec_value (spec, QCmask, &found_p); if (EQ (mask, Qheuristic)) x_build_heuristic_mask (f, img, Qt); --- 1850,1877 ---- mask = image_spec_value (spec, QCheuristic_mask, NULL); if (!NILP (mask)) ! { ! #if defined (MAC_OS) && USE_CG_DRAWING ! if (img->data.ptr_val != NULL) ! { ! CGImageRelease (img->data.ptr_val); ! img->data.ptr_val = NULL; ! } ! #endif ! x_build_heuristic_mask (f, img, mask); ! } else { int found_p; mask = image_spec_value (spec, QCmask, &found_p); + #if defined (MAC_OS) && USE_CG_DRAWING + if (!NILP(mask) && img->data.ptr_val != NULL) + { + CGImageRelease (img->data.ptr_val); + img->data.ptr_val = NULL; + } + #endif if (EQ (mask, Qheuristic)) x_build_heuristic_mask (f, img, Qt); *************** *** 2756,2761 **** --- 2772,2782 ---- UNGCPRO; return 0; } + + #ifdef USE_CG_DRAWING + img->data.ptr_val = image; /* retain original data */ + #endif + rectangle = CGRectMake (0, 0, width, height); QDBeginCGContext (ximg, &context); if (png_p) *************** *** 2767,2773 **** } CGContextDrawImage (context, rectangle, image); QDEndCGContext (ximg, &context); - CGImageRelease (image); /* Maybe fill in the background field while we have ximg handy. */ if (NILP (image_spec_value (img->spec, QCbackground, NULL))) --- 2788,2793 ---- ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-03 22:42 ` David Reitter @ 2008-04-03 23:12 ` YAMAMOTO Mitsuharu 2008-04-04 11:24 ` David Reitter 0 siblings, 1 reply; 16+ messages in thread From: YAMAMOTO Mitsuharu @ 2008-04-03 23:12 UTC (permalink / raw) To: David Reitter; +Cc: emacs-devel >>>>> On Thu, 3 Apr 2008 23:42:46 +0100, David Reitter <david.reitter@gmail.com> said: > mask = image_spec_value (spec, QCmask, &found_p); > + #if defined (MAC_OS) && USE_CG_DRAWING > + if (!NILP(mask) && img->data.ptr_val != NULL) > + { > + CGImageRelease (img->data.ptr_val); > + img->data.ptr_val = NULL; > + } > + #endif `:mask nil' means removing the mask. > + #ifdef USE_CG_DRAWING > + img->data.ptr_val = image; /* retain original data */ > + #endif Should be #if instead of #ifdef. > CGContextDrawImage (context, rectangle, image); > QDEndCGContext (ximg, &context); > - CGImageRelease (image); Need to release it if !USE_CG_DRAWING. YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-03 23:12 ` YAMAMOTO Mitsuharu @ 2008-04-04 11:24 ` David Reitter 2008-04-04 12:20 ` YAMAMOTO Mitsuharu 0 siblings, 1 reply; 16+ messages in thread From: David Reitter @ 2008-04-04 11:24 UTC (permalink / raw) To: YAMAMOTO Mitsuharu, emacs- devel On 4 Apr 2008, at 00:12, YAMAMOTO Mitsuharu wrote: > `:mask nil' means removing the mask. > Should be #if instead of #ifdef. > Need to release it if !USE_CG_DRAWING. All good points. Thanks. Also, image-mask-p needed to be changed to recognize the alpha channel. 2008-04-04 David Reitter <david.reitter@gmail.com> * tool-bar.el (tool-bar-set-file-extension): add function (tool-bar-get-image-spec): load PNG if available and load image files named foo_sel.bar and foo_dis.bar to define selected and disabled state images. (tool-bar-local-item-from-menu): take images and masks from icon, do not create extra mask. 2008-04-04 David Reitter <david.reitter@gmail.com> * image.c (image_load_quartz2d) [USE_CG_DRAWING]: retain platform image data (postprocess_image) [USE_CG_DRAWING]: release data when making modifications to the image (Fimage_mask_p) [USE_CG_DRAWING]: check for mask in data Index: lisp/tool-bar.el =================================================================== RCS file: /sources/emacs/emacs/lisp/tool-bar.el,v retrieving revision 1.7.2.2 diff -c -r1.7.2.2 tool-bar.el *** lisp/tool-bar.el 7 Jan 2008 02:44:11 -0000 1.7.2.2 --- lisp/tool-bar.el 4 Apr 2008 11:22:19 -0000 *************** *** 90,95 **** --- 90,166 ---- '(menu-item "tool bar" ignore :filter (lambda (ignore) tool-bar-map))) + (defun tool-bar-set-file-extension (image-spec-list extension) + "Set new file extensions for all :file properties + Replace any extensions of :file properties in elements of + IMAGE-SPEC-LIST. An extension may start with a period . or an + underscore. EXTENSION and the original file name extension (starting + with a period) are added to the file name. + + E.g. foo_dis.xpm becomes foo_sel.xpm if EXTENSION is '_sel'." + (mapcar + (lambda (spec) + (let ((f (plist-get spec :file)) + ) + (if (null f) + spec + ;; need to replace previous extensions, including those + ;; starting with _ - + (plist-put spec :file (concat (replace-regexp-in-string "[\.\_].*$" + "" f) + extension + (file-name-extension f t))) + ))) + image-spec-list)) + + (defun tool-bar-get-image-spec (icon) + (let* ((fg (face-attribute 'tool-bar :foreground)) + (bg (face-attribute 'tool-bar :background)) + (colors (nconc (if (eq fg 'unspecified) nil (list :foreground fg)) + (if (eq bg 'unspecified) nil (list :background bg)))) + (xpm-spec (list :type 'xpm :file (concat icon ".xpm"))) + (xpm-lo-spec (if (> (display-color-cells) 256) + nil + (list :type 'xpm :file + (concat "low-color/" icon ".xpm")))) + (png-spec (if (image-type-available-p 'png) + (list :type 'png :file (concat icon ".png") + :background "grey"))) + (pbm-spec (append (list :type 'pbm :file + (concat icon ".pbm")) colors)) + (xbm-spec (append (list :type 'xbm :file + (concat icon ".xbm")) colors)) + (image (find-image + (if (display-color-p) + (list png-spec xpm-lo-spec xpm-spec pbm-spec xbm-spec) + (list pbm-spec xbm-spec xpm-lo-spec xpm-spec)))) + (image-sel (find-image + (if (display-color-p) + (tool-bar-set-file-extension + (list png-spec xpm-lo-spec xpm-spec pbm-spec xbm-spec) + "_sel") + nil))) + (image-dis (find-image + (if (display-color-p) + (tool-bar-set-file-extension + (list png-spec xpm-lo-spec xpm-spec pbm-spec xbm-spec) + "_dis") + nil))) + (images (when image ;; image may be nil if not found. + (unless (image-mask-p image) + (setq image (append image '(:mask heuristic)))) + (if (and image-sel image-dis) + (progn + (unless (image-mask-p image-sel) + (setq image-sel (append image-sel + '(:mask heuristic)))) + (unless (image-mask-p image-dis) + (setq image-dis (append image-dis + '(:mask heuristic)))) + (vector image-sel image image-dis image-dis)) + image)))) + (cons image images))) + ;;;###autoload (defun tool-bar-add-item (icon def key &rest props) "Add an item to the tool bar. *************** *** 119,147 **** function will first try to use low-color/ICON.xpm if display-color- cells is less or equal to 256, then ICON.xpm, then ICON.pbm, and finally ICON.xbm, using `find-image'." ! (let* ((fg (face-attribute 'tool-bar :foreground)) ! (bg (face-attribute 'tool-bar :background)) ! (colors (nconc (if (eq fg 'unspecified) nil (list :foreground fg)) ! (if (eq bg 'unspecified) nil (list :background bg)))) ! (xpm-spec (list :type 'xpm :file (concat icon ".xpm"))) ! (xpm-lo-spec (if (> (display-color-cells) 256) ! nil ! (list :type 'xpm :file ! (concat "low-color/" icon ".xpm")))) ! (pbm-spec (append (list :type 'pbm :file ! (concat icon ".pbm")) colors)) ! (xbm-spec (append (list :type 'xbm :file ! (concat icon ".xbm")) colors)) ! (image (find-image ! (if (display-color-p) ! (list xpm-lo-spec xpm-spec pbm-spec xbm-spec) ! (list pbm-spec xbm-spec xpm-lo-spec xpm-spec))))) ! (when (and (display-images-p) image) - (unless (image-mask-p image) - (setq image (append image '(:mask heuristic)))) (define-key-after map (vector key) ! `(menu-item ,(symbol-name key) ,def :image ,image ,@props))))) ;;;###autoload (defun tool-bar-add-item-from-menu (command icon &optional map &rest props) --- 190,201 ---- function will first try to use low-color/ICON.xpm if display-color- cells is less or equal to 256, then ICON.xpm, then ICON.pbm, and finally ICON.xbm, using `find-image'." ! (let* ((is (tool-bar-get-image-spec icon)) ! (image (car is)) ! (images (cdr is))) (when (and (display-images-p) image) (define-key-after map (vector key) ! `(menu-item ,(symbol-name key) ,def :image ,images ,@props))))) ;;;###autoload (defun tool-bar-add-item-from-menu (command icon &optional map &rest props) *************** *** 174,196 **** (setq from-map global-map)) (let* ((menu-bar-map (lookup-key from-map [menu-bar])) (keys (where-is-internal command menu-bar-map)) ! (fg (face-attribute 'tool-bar :foreground)) ! (bg (face-attribute 'tool-bar :background)) ! (colors (nconc (if (eq fg 'unspecified) nil (list :foreground fg)) ! (if (eq bg 'unspecified) nil (list :background bg)))) ! (xpm-spec (list :type 'xpm :file (concat icon ".xpm"))) ! (xpm-lo-spec (if (> (display-color-cells) 256) ! nil ! (list :type 'xpm :file ! (concat "low-color/" icon ".xpm")))) ! (pbm-spec (append (list :type 'pbm :file ! (concat icon ".pbm")) colors)) ! (xbm-spec (append (list :type 'xbm :file ! (concat icon ".xbm")) colors)) ! (spec (if (display-color-p) ! (list xpm-lo-spec xpm-spec pbm-spec xbm-spec) ! (list pbm-spec xbm-spec xpm-lo-spec xpm-spec))) ! (image (find-image spec)) submap key) (when (and (display-images-p) image) ;; We'll pick up the last valid entry in the list of keys if --- 228,236 ---- (setq from-map global-map)) (let* ((menu-bar-map (lookup-key from-map [menu-bar])) (keys (where-is-internal command menu-bar-map)) ! (is (tool-bar-get-image-spec icon)) ! (image (car is)) ! (images (cdr is)) submap key) (when (and (display-images-p) image) ;; We'll pick up the last valid entry in the list of keys if *************** *** 210,221 **** key kk))))) (when (and (symbolp submap) (boundp submap)) (setq submap (eval submap))) - (unless (image-mask-p image) - (setq image (append image '(:mask heuristic)))) (let ((defn (assq key (cdr submap)))) (if (eq (cadr defn) 'menu-item) (define-key-after in-map (vector key) ! (append (cdr defn) (list :image image) props)) (setq defn (cdr defn)) (define-key-after in-map (vector key) (let ((rest (cdr defn))) --- 250,259 ---- key kk))))) (when (and (symbolp submap) (boundp submap)) (setq submap (eval submap))) (let ((defn (assq key (cdr submap)))) (if (eq (cadr defn) 'menu-item) (define-key-after in-map (vector key) ! (append (cdr defn) (list :image images) props)) (setq defn (cdr defn)) (define-key-after in-map (vector key) (let ((rest (cdr defn))) Index: src/image.c =================================================================== RCS file: /sources/emacs/emacs/src/image.c,v retrieving revision 1.65.2.13 diff -c -r1.65.2.13 image.c *** src/image.c 28 Mar 2008 14:57:32 -0000 1.65.2.13 --- src/image.c 4 Apr 2008 11:14:01 -0000 *************** *** 1135,1140 **** --- 1135,1146 ---- struct image *img = IMAGE_FROM_ID (f, id); if (img->mask) mask = Qt; + #if USE_CG_DRAWING + /* Mask may be in an Alpha channel in the image data */ + if (img->data.ptr_val != NULL && + CGImageGetAlphaInfo(img->data.ptr_val) != kCGImageAlphaNone) + mask = Qt; + #endif } else error ("Invalid image specification"); *************** *** 1549,1555 **** } #if defined (MAC_OS) && USE_CG_DRAWING ! if (img->data.ptr_val) { CGImageRelease (img->data.ptr_val); img->data.ptr_val = NULL; --- 1555,1561 ---- } #if defined (MAC_OS) && USE_CG_DRAWING ! if (img->data.ptr_val != NULL) { CGImageRelease (img->data.ptr_val); img->data.ptr_val = NULL; *************** *** 1850,1861 **** mask = image_spec_value (spec, QCheuristic_mask, NULL); if (!NILP (mask)) ! x_build_heuristic_mask (f, img, mask); else { int found_p; mask = image_spec_value (spec, QCmask, &found_p); if (EQ (mask, Qheuristic)) x_build_heuristic_mask (f, img, Qt); --- 1856,1883 ---- mask = image_spec_value (spec, QCheuristic_mask, NULL); if (!NILP (mask)) ! { ! #if defined (MAC_OS) && USE_CG_DRAWING ! if (img->data.ptr_val != NULL) ! { ! CGImageRelease (img->data.ptr_val); ! img->data.ptr_val = NULL; ! } ! #endif ! x_build_heuristic_mask (f, img, mask); ! } else { int found_p; mask = image_spec_value (spec, QCmask, &found_p); + #if defined (MAC_OS) && USE_CG_DRAWING + if (found_p && img->data.ptr_val != NULL) + { + CGImageRelease (img->data.ptr_val); + img->data.ptr_val = NULL; + } + #endif if (EQ (mask, Qheuristic)) x_build_heuristic_mask (f, img, Qt); *************** *** 2767,2773 **** --- 2789,2800 ---- } CGContextDrawImage (context, rectangle, image); QDEndCGContext (ximg, &context); + + #if USE_CG_DRAWING + img->data.ptr_val = image; /* retain original data */ + #else CGImageRelease (image); + #endif /* Maybe fill in the background field while we have ximg handy. */ if (NILP (image_spec_value (img->spec, QCbackground, NULL))) ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-04 11:24 ` David Reitter @ 2008-04-04 12:20 ` YAMAMOTO Mitsuharu 2008-04-05 10:58 ` David Reitter 0 siblings, 1 reply; 16+ messages in thread From: YAMAMOTO Mitsuharu @ 2008-04-04 12:20 UTC (permalink / raw) To: David Reitter; +Cc: emacs- devel >>>>> On Fri, 4 Apr 2008 12:24:58 +0100, David Reitter <david.reitter@gmail.com> said: > Also, image-mask-p needed to be changed to recognize the alpha > channel. And the invalidation only takes care of the `mask' spec, but not for `conversion'. YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-04 12:20 ` YAMAMOTO Mitsuharu @ 2008-04-05 10:58 ` David Reitter 2008-04-06 2:52 ` YAMAMOTO Mitsuharu 0 siblings, 1 reply; 16+ messages in thread From: David Reitter @ 2008-04-05 10:58 UTC (permalink / raw) To: emacs- devel On 4 Apr 2008, at 13:20, YAMAMOTO Mitsuharu wrote: > > And the invalidation only takes care of the `mask' spec, but not for > `conversion'. Index: image.c =================================================================== RCS file: /sources/emacs/emacs/src/image.c,v retrieving revision 1.65.2.13 diff -c -r1.65.2.13 image.c *** image.c 28 Mar 2008 14:57:32 -0000 1.65.2.13 --- image.c 4 Apr 2008 15:05:11 -0000 *************** *** 1135,1140 **** --- 1135,1146 ---- struct image *img = IMAGE_FROM_ID (f, id); if (img->mask) mask = Qt; + #if USE_CG_DRAWING + /* Mask may be in an Alpha channel in the image data */ + if (img->data.ptr_val != NULL && + CGImageGetAlphaInfo(img->data.ptr_val) != kCGImageAlphaNone) + mask = Qt; + #endif } else error ("Invalid image specification"); *************** *** 1549,1555 **** } #if defined (MAC_OS) && USE_CG_DRAWING ! if (img->data.ptr_val) { CGImageRelease (img->data.ptr_val); img->data.ptr_val = NULL; --- 1555,1561 ---- } #if defined (MAC_OS) && USE_CG_DRAWING ! if (img->data.ptr_val != NULL) { CGImageRelease (img->data.ptr_val); img->data.ptr_val = NULL; *************** *** 1835,1840 **** --- 1841,1848 ---- { Lisp_Object conversion, spec; Lisp_Object mask; + int release = 0; + int found_p = 0; spec = img->spec; *************** *** 1850,1862 **** mask = image_spec_value (spec, QCheuristic_mask, NULL); if (!NILP (mask)) ! x_build_heuristic_mask (f, img, mask); else { - int found_p; - mask = image_spec_value (spec, QCmask, &found_p); ! if (EQ (mask, Qheuristic)) x_build_heuristic_mask (f, img, Qt); else if (CONSP (mask) --- 1858,1872 ---- mask = image_spec_value (spec, QCheuristic_mask, NULL); if (!NILP (mask)) ! { ! release = 1; ! x_build_heuristic_mask (f, img, mask); ! } else { mask = image_spec_value (spec, QCmask, &found_p); ! if (found_p) ! release = 1; if (EQ (mask, Qheuristic)) x_build_heuristic_mask (f, img, Qt); else if (CONSP (mask) *************** *** 1876,1882 **** /* Should we apply an image transformation algorithm? */ ! conversion = image_spec_value (spec, QCconversion, NULL); if (EQ (conversion, Qdisabled)) x_disable_image (f, img); else if (EQ (conversion, Qlaplace)) --- 1886,1895 ---- /* Should we apply an image transformation algorithm? */ ! found_p = 0; ! conversion = image_spec_value (spec, QCconversion, &found_p); ! if (found_p) ! release = 1; if (EQ (conversion, Qdisabled)) x_disable_image (f, img); else if (EQ (conversion, Qlaplace)) *************** *** 1893,1898 **** --- 1906,1918 ---- Fplist_get (tem, QCmatrix), Fplist_get (tem, QCcolor_adjustment)); } + #if defined (MAC_OS) && USE_CG_DRAWING + if (release && img->data.ptr_val != NULL) + { + CGImageRelease (img->data.ptr_val); + img->data.ptr_val = NULL; + } + #endif } } *************** *** 2767,2773 **** --- 2787,2798 ---- } CGContextDrawImage (context, rectangle, image); QDEndCGContext (ximg, &context); + + #if USE_CG_DRAWING + img->data.ptr_val = image; /* retain original data */ + #else CGImageRelease (image); + #endif /* Maybe fill in the background field while we have ximg handy. */ if (NILP (image_spec_value (img->spec, QCbackground, NULL))) ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-05 10:58 ` David Reitter @ 2008-04-06 2:52 ` YAMAMOTO Mitsuharu 2008-04-06 13:42 ` David Reitter 0 siblings, 1 reply; 16+ messages in thread From: YAMAMOTO Mitsuharu @ 2008-04-06 2:52 UTC (permalink / raw) To: David Reitter; +Cc: emacs-devel >>>>> On Sat, 5 Apr 2008 11:58:15 +0100, David Reitter <david.reitter@gmail.com> said: > On 4 Apr 2008, at 13:20, YAMAMOTO Mitsuharu wrote: >> >> And the invalidation only takes care of the `mask' spec, but not for >> `conversion'. > Index: image.c > =================================================================== > RCS file: /sources/emacs/emacs/src/image.c,v > retrieving revision 1.65.2.13 > diff -c -r1.65.2.13 image.c > *** image.c 28 Mar 2008 14:57:32 -0000 1.65.2.13 > --- image.c 4 Apr 2008 15:05:11 -0000 > *************** > *** 1135,1140 **** > --- 1135,1146 ---- > struct image *img = IMAGE_FROM_ID (f, id); > if (img->mask) > mask = Qt; > + #if USE_CG_DRAWING > + /* Mask may be in an Alpha channel in the image data */ > + if (img->data.ptr_val != NULL && > + CGImageGetAlphaInfo(img->data.ptr_val) != kCGImageAlphaNone) > + mask = Qt; > + #endif > } > else > error ("Invalid image specification"); This is not the only place where NULL-check of img->mask is used for determining the existence of the image mask. At least, xdisp.c and macterm.c also assume that. And add BLOCK_INPUT around CGImageGetAlphaInfo just in case. > *************** > *** 1835,1840 **** > --- 1841,1848 ---- > { > Lisp_Object conversion, spec; > Lisp_Object mask; > + int release = 0; > + int found_p = 0; > spec = img->spec; > *************** > *** 1850,1862 **** > mask = image_spec_value (spec, QCheuristic_mask, NULL); > if (!NILP (mask)) > ! x_build_heuristic_mask (f, img, mask); > else > { > - int found_p; > - > mask = image_spec_value (spec, QCmask, &found_p); > ! > if (EQ (mask, Qheuristic)) > x_build_heuristic_mask (f, img, Qt); > else if (CONSP (mask) > --- 1858,1872 ---- > mask = image_spec_value (spec, QCheuristic_mask, NULL); > if (!NILP (mask)) > ! { > ! release = 1; > ! x_build_heuristic_mask (f, img, mask); > ! } > else > { > mask = image_spec_value (spec, QCmask, &found_p); > ! if (found_p) > ! release = 1; > if (EQ (mask, Qheuristic)) > x_build_heuristic_mask (f, img, Qt); > else if (CONSP (mask) > *************** > *** 1876,1882 **** > /* Should we apply an image transformation algorithm? */ > ! conversion = image_spec_value (spec, QCconversion, NULL); > if (EQ (conversion, Qdisabled)) > x_disable_image (f, img); > else if (EQ (conversion, Qlaplace)) > --- 1886,1895 ---- > /* Should we apply an image transformation algorithm? */ > ! found_p = 0; > ! conversion = image_spec_value (spec, QCconversion, &found_p); > ! if (found_p) > ! release = 1; > if (EQ (conversion, Qdisabled)) > x_disable_image (f, img); > else if (EQ (conversion, Qlaplace)) > *************** > *** 1893,1898 **** > --- 1906,1918 ---- > Fplist_get (tem, QCmatrix), > Fplist_get (tem, QCcolor_adjustment)); > } > + #if defined (MAC_OS) && USE_CG_DRAWING > + if (release && img->data.ptr_val != NULL) > + { > + CGImageRelease (img->data.ptr_val); > + img->data.ptr_val = NULL; > + } > + #endif > } > } I would add an assignment to some variable around each call to x_build_heuristic_mask etc. so as not to be confused with bogus mask/conversion specs. YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-06 2:52 ` YAMAMOTO Mitsuharu @ 2008-04-06 13:42 ` David Reitter 2008-04-06 14:09 ` YAMAMOTO Mitsuharu 0 siblings, 1 reply; 16+ messages in thread From: David Reitter @ 2008-04-06 13:42 UTC (permalink / raw) To: emacs- devel [-- Attachment #1: Type: text/plain, Size: 1207 bytes --] On 6 Apr 2008, at 03:52, YAMAMOTO Mitsuharu wrote: > This is not the only place where NULL-check of img->mask is used for > determining the existence of the image mask. At least, xdisp.c and > macterm.c also assume that. Yes, but doesn't that happen in order to check whether there is a bitmap mask that will be used for something? x_draw_image_foreground actually uses that mask to draw the image, and my understanding is that we want to use the original (platform specific) image data for that, including its alpha channel. As we can't do that (yet) on X or W32, we don't set the platform specific image data in the first place there. In macterm.c, we want to call mac_copy_area rather than mac_copy_area_with_mask, right? In x_draw_image_foreground (macterm.c), it is always safe to draw a rectangle around given that we don't know what the alpha channel specifies, but one could go through Fimage_mask_pp to get the same semantics. As for image.c: I don't understand all of the code. In general, it appears safe to assume we don't have a mask on the C level. The alternative would be to acquire a bitmap mask from the PNG when loading it. Maybe that would be cleaner. [-- Attachment #2: smime.p7s --] [-- Type: application/pkcs7-signature, Size: 2193 bytes --] ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: png images in tool-bar / alpha mask 2008-04-06 13:42 ` David Reitter @ 2008-04-06 14:09 ` YAMAMOTO Mitsuharu 0 siblings, 0 replies; 16+ messages in thread From: YAMAMOTO Mitsuharu @ 2008-04-06 14:09 UTC (permalink / raw) To: David Reitter; +Cc: emacs-devel >>>>> On Sun, 6 Apr 2008 14:42:08 +0100, David Reitter <david.reitter@gmail.com> said: >> This is not the only place where NULL-check of img->mask is used >> for determining the existence of the image mask. At least, xdisp.c >> and macterm.c also assume that. > Yes, but doesn't that happen in order to check whether there is a > bitmap mask that will be used for something? Did you seriously test your own patch? You'll see the previous contents unerased under the alpha channel part because filling with the background color is done only when the image is considered to have a mask. YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2008-04-06 14:09 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-04-01 17:14 png images in tool-bar / alpha mask David Reitter 2008-04-01 21:41 ` YAMAMOTO Mitsuharu 2008-04-01 23:10 ` David Reitter 2008-04-02 12:39 ` YAMAMOTO Mitsuharu 2008-04-03 15:09 ` David Reitter 2008-04-03 21:15 ` YAMAMOTO Mitsuharu 2008-04-03 21:42 ` David Reitter 2008-04-03 21:55 ` YAMAMOTO Mitsuharu 2008-04-03 22:42 ` David Reitter 2008-04-03 23:12 ` YAMAMOTO Mitsuharu 2008-04-04 11:24 ` David Reitter 2008-04-04 12:20 ` YAMAMOTO Mitsuharu 2008-04-05 10:58 ` David Reitter 2008-04-06 2:52 ` YAMAMOTO Mitsuharu 2008-04-06 13:42 ` David Reitter 2008-04-06 14:09 ` YAMAMOTO Mitsuharu
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.