aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Third2017-12-03 17:39:03 +0000
committerAlan Third2017-12-03 22:41:05 +0000
commite4f2061ebc61168f23c0d9440221cbc99864deae (patch)
treec9831522b68c63c5810b0164ec67fb3714c771fd
parent1cdd0e8cd801aa1d6f04ab4d8e6097a46af8c951 (diff)
downloademacs-e4f2061ebc61168f23c0d9440221cbc99864deae.tar.gz
emacs-e4f2061ebc61168f23c0d9440221cbc99864deae.zip
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.
-rw-r--r--configure.ac6
-rw-r--r--lisp/image.el5
-rw-r--r--src/nsimage.m116
-rw-r--r--src/nsterm.h3
4 files changed, 124 insertions, 6 deletions
diff --git a/configure.ac b/configure.ac
index b773e3b7f0c..61455a4b0fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3424,7 +3424,9 @@ AC_SUBST(LIBXPM)
3424### Use -ljpeg if available, unless '--with-jpeg=no'. 3424### Use -ljpeg if available, unless '--with-jpeg=no'.
3425HAVE_JPEG=no 3425HAVE_JPEG=no
3426LIBJPEG= 3426LIBJPEG=
3427if test "${with_jpeg}" != "no"; then 3427if test "${NS_IMPL_COCOA}" = yes; then
3428 : # Cocoa provides its own jpeg support, so do nothing.
3429elif test "${with_jpeg}" != "no"; then
3428 AC_CACHE_CHECK([for jpeglib 6b or later], 3430 AC_CACHE_CHECK([for jpeglib 6b or later],
3429 [emacs_cv_jpeglib], 3431 [emacs_cv_jpeglib],
3430 [OLD_LIBS=$LIBS 3432 [OLD_LIBS=$LIBS
@@ -3559,7 +3561,7 @@ HAVE_PNG=no
3559LIBPNG= 3561LIBPNG=
3560PNG_CFLAGS= 3562PNG_CFLAGS=
3561if test "${NS_IMPL_COCOA}" = yes; then 3563if test "${NS_IMPL_COCOA}" = yes; then
3562 : # Nothing to do 3564 : # Cocoa provides its own png support, so do nothing.
3563elif test "${with_png}" != no; then 3565elif test "${with_png}" != no; then
3564 # mingw32 loads the library dynamically. 3566 # mingw32 loads the library dynamically.
3565 if test "$opsys" = mingw32; then 3567 if test "$opsys" = mingw32; then
diff --git a/lisp/image.el b/lisp/image.el
index 32df508bc8d..ed32307ae24 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -976,11 +976,12 @@ default is 20%."
976 image)) 976 image))
977 977
978(defun image--get-imagemagick-and-warn () 978(defun image--get-imagemagick-and-warn ()
979 (unless (fboundp 'imagemagick-types) 979 (unless (or (fboundp 'imagemagick-types) (featurep 'ns))
980 (error "Can't rescale images without ImageMagick support")) 980 (error "Can't rescale images without ImageMagick support"))
981 (let ((image (image--get-image))) 981 (let ((image (image--get-image)))
982 (image-flush image) 982 (image-flush image)
983 (plist-put (cdr image) :type 'imagemagick) 983 (when (fboundp 'imagemagick-types)
984 (plist-put (cdr image) :type 'imagemagick))
984 image)) 985 image))
985 986
986(defun image--change-size (factor) 987(defun image--change-size (factor)
diff --git a/src/nsimage.m b/src/nsimage.m
index 9d45b063af1..52e3bae05f1 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -76,8 +76,9 @@ ns_load_image (struct frame *f, struct image *img,
76{ 76{
77 EmacsImage *eImg = nil; 77 EmacsImage *eImg = nil;
78 NSSize size; 78 NSSize size;
79 Lisp_Object lisp_index; 79 Lisp_Object lisp_index, lisp_rotation;
80 unsigned int index; 80 unsigned int index;
81 double rotation;
81 82
82 NSTRACE ("ns_load_image"); 83 NSTRACE ("ns_load_image");
83 84
@@ -86,6 +87,9 @@ ns_load_image (struct frame *f, struct image *img,
86 lisp_index = Fplist_get (XCDR (img->spec), QCindex); 87 lisp_index = Fplist_get (XCDR (img->spec), QCindex);
87 index = INTEGERP (lisp_index) ? XFASTINT (lisp_index) : 0; 88 index = INTEGERP (lisp_index) ? XFASTINT (lisp_index) : 0;
88 89
90 lisp_rotation = Fplist_get (XCDR (img->spec), QCrotation);
91 rotation = NUMBERP (lisp_rotation) ? XFLOATINT (lisp_rotation) : 0;
92
89 if (STRINGP (spec_file)) 93 if (STRINGP (spec_file))
90 { 94 {
91 eImg = [EmacsImage allocInitFromFile: spec_file]; 95 eImg = [EmacsImage allocInitFromFile: spec_file];
@@ -113,6 +117,17 @@ ns_load_image (struct frame *f, struct image *img,
113 return 0; 117 return 0;
114 } 118 }
115 119
120 img->lisp_data = [eImg getMetadata];
121
122 if (rotation != 0)
123 {
124 EmacsImage *temp = [eImg rotate:rotation];
125 [eImg release];
126 eImg = temp;
127 }
128
129 [eImg setSizeFromSpec:XCDR (img->spec)];
130
116 size = [eImg size]; 131 size = [eImg size];
117 img->width = size.width; 132 img->width = size.width;
118 img->height = size.height; 133 img->height = size.height;
@@ -120,7 +135,6 @@ ns_load_image (struct frame *f, struct image *img,
120 /* 4) set img->pixmap = emacsimage */ 135 /* 4) set img->pixmap = emacsimage */
121 img->pixmap = eImg; 136 img->pixmap = eImg;
122 137
123 img->lisp_data = [eImg getMetadata];
124 return 1; 138 return 1;
125} 139}
126 140
@@ -510,4 +524,102 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
510 return YES; 524 return YES;
511} 525}
512 526
527- (void)setSizeFromSpec: (Lisp_Object) spec
528{
529 NSSize size = [self size];
530 Lisp_Object value;
531 double scale = 1, aspect = size.width / size.height;
532 double width = -1, height = -1, max_width = -1, max_height = -1;
533
534 value = Fplist_get (spec, QCscale);
535 if (NUMBERP (value))
536 scale = XFLOATINT (value) ;
537
538 value = Fplist_get (spec, QCmax_width);
539 if (NUMBERP (value))
540 max_width = XFLOATINT (value);
541
542 value = Fplist_get (spec, QCmax_height);
543 if (NUMBERP (value))
544 max_height = XFLOATINT (value);
545
546 value = Fplist_get (spec, QCwidth);
547 if (NUMBERP (value))
548 {
549 width = XFLOATINT (value) * scale;
550 /* :width overrides :max-width. */
551 max_width = -1;
552 }
553
554 value = Fplist_get (spec, QCheight);
555 if (NUMBERP (value))
556 {
557 height = XFLOATINT (value) * scale;
558 /* :height overrides :max-height. */
559 max_height = -1;
560 }
561
562 if (width <= 0 && height <= 0)
563 {
564 width = size.width * scale;
565 height = size.height * scale;
566 }
567 else if (width > 0 && height <= 0)
568 height = width / aspect;
569 else if (height > 0 && width <= 0)
570 width = height * aspect;
571
572 if (max_width > 0 && width > max_width)
573 {
574 width = max_width;
575 height = max_width / aspect;
576 }
577
578 if (max_height > 0 && height > max_height)
579 {
580 height = max_height;
581 width = max_height * aspect;
582 }
583
584 [self setSize:NSMakeSize(width, height)];
585}
586
587- (instancetype)rotate: (double)rotation
588{
589 EmacsImage *new_image;
590 NSPoint new_origin;
591 NSSize new_size, size = [self size];
592 NSRect rect = { NSZeroPoint, [self size] };
593
594 /* Create a bezier path of the outline of the image and do the
595 * rotation on it. */
596 NSBezierPath *bounds_path = [NSBezierPath bezierPathWithRect:rect];
597 NSAffineTransform *transform = [NSAffineTransform transform];
598 [transform rotateByDegrees: rotation * -1];
599 [bounds_path transformUsingAffineTransform:transform];
600
601 /* Now we can find out how large the rotated image needs to be. */
602 new_size = [bounds_path bounds].size;
603 new_image = [[EmacsImage alloc] initWithSize:new_size];
604
605 new_origin = NSMakePoint((new_size.width - size.width)/2,
606 (new_size.height - size.height)/2);
607
608 [new_image lockFocus];
609
610 /* Create the final transform. */
611 transform = [NSAffineTransform transform];
612 [transform translateXBy:new_size.width/2 yBy:new_size.height/2];
613 [transform rotateByDegrees: rotation * -1];
614 [transform translateXBy:-new_size.width/2 yBy:-new_size.height/2];
615
616 [transform concat];
617 [self drawAtPoint:new_origin fromRect:NSZeroRect
618 operation:NSCompositingOperationCopy fraction:1];
619
620 [new_image unlockFocus];
621
622 return new_image;
623}
624
513@end 625@end
diff --git a/src/nsterm.h b/src/nsterm.h
index de96e0dbcbf..c81bf5fb63d 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -646,6 +646,8 @@ typedef id instancetype;
646- (NSColor *)stippleMask; 646- (NSColor *)stippleMask;
647- (Lisp_Object)getMetadata; 647- (Lisp_Object)getMetadata;
648- (BOOL)setFrame: (unsigned int) index; 648- (BOOL)setFrame: (unsigned int) index;
649- (void)setSizeFromSpec: (Lisp_Object) spec;
650- (instancetype)rotate: (double)rotation;
649@end 651@end
650 652
651 653
@@ -1306,6 +1308,7 @@ extern char gnustep_base_version[]; /* version tracking */
1306#define NSWindowStyleMaskUtilityWindow NSUtilityWindowMask 1308#define NSWindowStyleMaskUtilityWindow NSUtilityWindowMask
1307#define NSAlertStyleCritical NSCriticalAlertStyle 1309#define NSAlertStyleCritical NSCriticalAlertStyle
1308#define NSControlSizeRegular NSRegularControlSize 1310#define NSControlSizeRegular NSRegularControlSize
1311#define NSCompositingOperationCopy NSCompositeCopy
1309 1312
1310/* And adds NSWindowStyleMask. */ 1313/* And adds NSWindowStyleMask. */
1311#ifdef __OBJC__ 1314#ifdef __OBJC__