values rotate clockwise, negative values counter-clockwise. Rotation
is performed after scaling and cropping.
+@item :flip @var{flip}
+If this is @code{t}, the image will be horizontally flipped.
+Currently it has no effect if the image type is @code{imagemagick}.
+Vertical flipping can be achieved by rotating the image 180 degrees
+and toggling this value.
+
@item :transform-smoothing @var{smooth}
If this is @code{t}, any image transform will have smoothing applied;
if @code{nil}, no smoothing will be applied. The exact algorithm used
"+" #'image-increase-size
"r" #'image-rotate
"o" #'image-save
+ "h" #'image-flip-horizontally
+ "v" #'image-flip-vertically
"C-<wheel-down>" #'image-mouse-decrease-size
"C-<mouse-5>" #'image-mouse-decrease-size
"C-<wheel-up>" #'image-mouse-increase-size
(write-region (point-min) (point-max)
(read-file-name "Write image to file: ")))))
+(defun image-flip-horizontally ()
+ "Horizontally flip the image under point."
+ (interactive)
+ (let ((image (image--get-image)))
+ (image-flush image)
+ (setf (image-property image :flip)
+ (not (image-property image :flip)))))
+
+(defun image-flip-vertically ()
+ "Vertically flip the image under point."
+ (interactive)
+ (let ((image (image--get-image)))
+ (image-rotate 180)
+ (setf (image-property image :flip)
+ (not (image-property image :flip)))))
+
(provide 'image)
;;; image.el ends here
double rotation = 0.0;
compute_image_rotation (img, &rotation);
+ /* Determine flipping. */
+ bool flip;
+ Lisp_Object m = image_spec_value (img->spec, QCflip, NULL);
+ flip = !NILP (m);
+
#ifndef HAVE_HAIKU
# if defined USE_CAIRO || defined HAVE_XRENDER || defined HAVE_NS
/* We want scale up operations to use a nearest neighbor filter to
/* Perform rotation transformation. */
int rotate_flag = -1;
- if (rotation == 0)
+ if (rotation == 0 && !flip)
rotate_flag = 0;
else
{
# if (defined USE_CAIRO || defined HAVE_XRENDER \
|| defined HAVE_NTGUI || defined HAVE_NS)
int cos_r, sin_r;
- if (rotation == 90)
+ if (rotation == 0)
+ {
+ /* FLIP is always true here. As this will rotate by 0
+ degrees, it has no visible effect. Applying only
+ translation matrix to the image would be sufficient for
+ horizontal flipping, but writing special handling for
+ this case would increase code complexity somewhat. */
+ cos_r = 1;
+ sin_r = 0;
+ rotate_flag = 1;
+ }
+ else if (rotation == 90)
{
width = img->height;
height = img->width;
matrix3x3 v;
matrix3x3_mult (rot, u, v);
- /* 3. Translate back. */
+ /* 3. Translate back. Flip horizontally if requested. */
t[2][0] = width * -.5;
t[2][1] = height * -.5;
+ if (flip)
+ {
+ t[0][0] = -t[0][0];
+ t[2][0] = -t[2][0];
+ }
matrix3x3_mult (t, v, matrix);
# else
/* 1. Translate so (0, 0) is in the center of the image. */
matrix3x3 v;
matrix3x3_mult (u, rot, v);
- /* 3. Translate back. */
+ /* 3. Translate back. Flip horizontally if requested. */
t[2][0] = width * .5;
t[2][1] = height * .5;
+ if (flip) t[0][0] = -t[0][0];
matrix3x3_mult (v, t, matrix);
# endif
img->width = width;
DEFSYM (QCtransform_smoothing, ":transform-smoothing");
DEFSYM (QCcolor_adjustment, ":color-adjustment");
DEFSYM (QCmask, ":mask");
+ DEFSYM (QCflip, ":flip");
/* Other symbols. */
DEFSYM (Qlaplace, "laplace");