[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master e4f2061: Add image resizing and rotation to NS port
From: |
Alan Third |
Subject: |
[Emacs-diffs] master e4f2061: Add image resizing and rotation to NS port |
Date: |
Sun, 3 Dec 2017 17:44:42 -0500 (EST) |
branch: master
commit e4f2061ebc61168f23c0d9440221cbc99864deae
Author: Alan Third <address@hidden>
Commit: Alan Third <address@hidden>
Add image resizing and rotation to NS port
* lisp/image.el (image--get-imagemagick-and-warn): Bypass imagemagick
check when using NS.
* src/nsimage.m (ns_load_image): Add rotation and resizing
functionality. Move the getMetaData call to before the resize/rotation
so it returns correct metadata.
(EmacsImage::setSizeFromSpec, EmacsImage::rotate): New functions.
* src/nsterm.h (EmacsImage): Add new function prototypes.
(NSCompositingOperationCopy): Add define to older equivalent for
GNUstep and pre-10.12 macOS.
* configure.ac: Don't use libjpeg on Cocoa.
---
configure.ac | 6 ++-
lisp/image.el | 5 ++-
src/nsimage.m | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/nsterm.h | 3 ++
4 files changed, 124 insertions(+), 6 deletions(-)
diff --git a/configure.ac b/configure.ac
index b773e3b..61455a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3424,7 +3424,9 @@ AC_SUBST(LIBXPM)
### Use -ljpeg if available, unless '--with-jpeg=no'.
HAVE_JPEG=no
LIBJPEG=
-if test "${with_jpeg}" != "no"; then
+if test "${NS_IMPL_COCOA}" = yes; then
+ : # Cocoa provides its own jpeg support, so do nothing.
+elif test "${with_jpeg}" != "no"; then
AC_CACHE_CHECK([for jpeglib 6b or later],
[emacs_cv_jpeglib],
[OLD_LIBS=$LIBS
@@ -3559,7 +3561,7 @@ HAVE_PNG=no
LIBPNG=
PNG_CFLAGS=
if test "${NS_IMPL_COCOA}" = yes; then
- : # Nothing to do
+ : # Cocoa provides its own png support, so do nothing.
elif test "${with_png}" != no; then
# mingw32 loads the library dynamically.
if test "$opsys" = mingw32; then
diff --git a/lisp/image.el b/lisp/image.el
index 32df508..ed32307 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -976,11 +976,12 @@ default is 20%."
image))
(defun image--get-imagemagick-and-warn ()
- (unless (fboundp 'imagemagick-types)
+ (unless (or (fboundp 'imagemagick-types) (featurep 'ns))
(error "Can't rescale images without ImageMagick support"))
(let ((image (image--get-image)))
(image-flush image)
- (plist-put (cdr image) :type 'imagemagick)
+ (when (fboundp 'imagemagick-types)
+ (plist-put (cdr image) :type 'imagemagick))
image))
(defun image--change-size (factor)
diff --git a/src/nsimage.m b/src/nsimage.m
index 9d45b06..52e3bae 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -76,8 +76,9 @@ ns_load_image (struct frame *f, struct image *img,
{
EmacsImage *eImg = nil;
NSSize size;
- Lisp_Object lisp_index;
+ Lisp_Object lisp_index, lisp_rotation;
unsigned int index;
+ double rotation;
NSTRACE ("ns_load_image");
@@ -86,6 +87,9 @@ ns_load_image (struct frame *f, struct image *img,
lisp_index = Fplist_get (XCDR (img->spec), QCindex);
index = INTEGERP (lisp_index) ? XFASTINT (lisp_index) : 0;
+ lisp_rotation = Fplist_get (XCDR (img->spec), QCrotation);
+ rotation = NUMBERP (lisp_rotation) ? XFLOATINT (lisp_rotation) : 0;
+
if (STRINGP (spec_file))
{
eImg = [EmacsImage allocInitFromFile: spec_file];
@@ -113,6 +117,17 @@ ns_load_image (struct frame *f, struct image *img,
return 0;
}
+ img->lisp_data = [eImg getMetadata];
+
+ if (rotation != 0)
+ {
+ EmacsImage *temp = [eImg rotate:rotation];
+ [eImg release];
+ eImg = temp;
+ }
+
+ [eImg setSizeFromSpec:XCDR (img->spec)];
+
size = [eImg size];
img->width = size.width;
img->height = size.height;
@@ -120,7 +135,6 @@ ns_load_image (struct frame *f, struct image *img,
/* 4) set img->pixmap = emacsimage */
img->pixmap = eImg;
- img->lisp_data = [eImg getMetadata];
return 1;
}
@@ -510,4 +524,102 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
return YES;
}
+- (void)setSizeFromSpec: (Lisp_Object) spec
+{
+ NSSize size = [self size];
+ Lisp_Object value;
+ double scale = 1, aspect = size.width / size.height;
+ double width = -1, height = -1, max_width = -1, max_height = -1;
+
+ value = Fplist_get (spec, QCscale);
+ if (NUMBERP (value))
+ scale = XFLOATINT (value) ;
+
+ value = Fplist_get (spec, QCmax_width);
+ if (NUMBERP (value))
+ max_width = XFLOATINT (value);
+
+ value = Fplist_get (spec, QCmax_height);
+ if (NUMBERP (value))
+ max_height = XFLOATINT (value);
+
+ value = Fplist_get (spec, QCwidth);
+ if (NUMBERP (value))
+ {
+ width = XFLOATINT (value) * scale;
+ /* :width overrides :max-width. */
+ max_width = -1;
+ }
+
+ value = Fplist_get (spec, QCheight);
+ if (NUMBERP (value))
+ {
+ height = XFLOATINT (value) * scale;
+ /* :height overrides :max-height. */
+ max_height = -1;
+ }
+
+ if (width <= 0 && height <= 0)
+ {
+ width = size.width * scale;
+ height = size.height * scale;
+ }
+ else if (width > 0 && height <= 0)
+ height = width / aspect;
+ else if (height > 0 && width <= 0)
+ width = height * aspect;
+
+ if (max_width > 0 && width > max_width)
+ {
+ width = max_width;
+ height = max_width / aspect;
+ }
+
+ if (max_height > 0 && height > max_height)
+ {
+ height = max_height;
+ width = max_height * aspect;
+ }
+
+ [self setSize:NSMakeSize(width, height)];
+}
+
+- (instancetype)rotate: (double)rotation
+{
+ EmacsImage *new_image;
+ NSPoint new_origin;
+ NSSize new_size, size = [self size];
+ NSRect rect = { NSZeroPoint, [self size] };
+
+ /* Create a bezier path of the outline of the image and do the
+ * rotation on it. */
+ NSBezierPath *bounds_path = [NSBezierPath bezierPathWithRect:rect];
+ NSAffineTransform *transform = [NSAffineTransform transform];
+ [transform rotateByDegrees: rotation * -1];
+ [bounds_path transformUsingAffineTransform:transform];
+
+ /* Now we can find out how large the rotated image needs to be. */
+ new_size = [bounds_path bounds].size;
+ new_image = [[EmacsImage alloc] initWithSize:new_size];
+
+ new_origin = NSMakePoint((new_size.width - size.width)/2,
+ (new_size.height - size.height)/2);
+
+ [new_image lockFocus];
+
+ /* Create the final transform. */
+ transform = [NSAffineTransform transform];
+ [transform translateXBy:new_size.width/2 yBy:new_size.height/2];
+ [transform rotateByDegrees: rotation * -1];
+ [transform translateXBy:-new_size.width/2 yBy:-new_size.height/2];
+
+ [transform concat];
+ [self drawAtPoint:new_origin fromRect:NSZeroRect
+ operation:NSCompositingOperationCopy fraction:1];
+
+ [new_image unlockFocus];
+
+ return new_image;
+}
+
@end
diff --git a/src/nsterm.h b/src/nsterm.h
index de96e0d..c81bf5f 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -646,6 +646,8 @@ typedef id instancetype;
- (NSColor *)stippleMask;
- (Lisp_Object)getMetadata;
- (BOOL)setFrame: (unsigned int) index;
+- (void)setSizeFromSpec: (Lisp_Object) spec;
+- (instancetype)rotate: (double)rotation;
@end
@@ -1306,6 +1308,7 @@ extern char gnustep_base_version[]; /* version tracking
*/
#define NSWindowStyleMaskUtilityWindow NSUtilityWindowMask
#define NSAlertStyleCritical NSCriticalAlertStyle
#define NSControlSizeRegular NSRegularControlSize
+#define NSCompositingOperationCopy NSCompositeCopy
/* And adds NSWindowStyleMask. */
#ifdef __OBJC__
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master e4f2061: Add image resizing and rotation to NS port,
Alan Third <=