Commit e4f2061e authored by Alan Third's avatar Alan Third

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.
parent 1cdd0e8c
......@@ -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
......
......@@ -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)
......
......@@ -76,8 +76,9 @@ Updated by Christian Limpach (chris@nice.ch)
{
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 @@ Updated by Christian Limpach (chris@nice.ch)
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 @@ Updated by Christian Limpach (chris@nice.ch)
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 @@ Updated by Christian Limpach (chris@nice.ch)
/* 4) set img->pixmap = emacsimage */
img->pixmap = eImg;
img->lisp_data = [eImg getMetadata];
return 1;
}
......@@ -510,4 +524,102 @@ - (BOOL)setFrame: (unsigned int) index
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
......@@ -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__
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment