aboutsummaryrefslogtreecommitdiffstats
path: root/src/android.c
diff options
context:
space:
mode:
authorPo Lu2023-05-29 17:46:19 +0800
committerPo Lu2023-05-29 17:46:19 +0800
commit7fdde02f3216536aa8977fa4b396bec8fbaf994b (patch)
tree6f38d0cdc45f5cd50343d48f4028febe8b397251 /src/android.c
parent9a3535459333b5a1a32ed5b5ef4c593e585bfe9a (diff)
downloademacs-7fdde02f3216536aa8977fa4b396bec8fbaf994b.tar.gz
emacs-7fdde02f3216536aa8977fa4b396bec8fbaf994b.zip
Work around more problems with Bitmaps
* java/org/gnu/emacs/EmacsNative.java (EmacsNative): New function `blitRect'. * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView): Use it on Android 8.x. * src/android.c (blitRect): Implement new function.
Diffstat (limited to 'src/android.c')
-rw-r--r--src/android.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/android.c b/src/android.c
index 7b9c478f212..4184be3086b 100644
--- a/src/android.c
+++ b/src/android.c
@@ -4754,6 +4754,104 @@ android_copy_area (android_drawable src, android_drawable dest,
4754 4754
4755 4755
4756 4756
4757JNIEXPORT void JNICALL
4758NATIVE_NAME (blitRect) (JNIEnv *env, jobject object,
4759 jobject src, jobject dest,
4760 jint x1, jint y1, jint x2, jint y2)
4761{
4762 AndroidBitmapInfo src_info, dest_info;
4763 unsigned char *src_data_1, *dest_data_1;
4764 void *src_data, *dest_data;
4765
4766 /* N.B. that X2 and Y2 represent the pixel past the edge of the
4767 rectangle; thus, the width is x2 - x1 and the height is y2 -
4768 y1. */
4769
4770 memset (&src_info, 0, sizeof src_info);
4771 memset (&dest_info, 0, sizeof dest_info);
4772 AndroidBitmap_getInfo (env, src, &src_info);
4773 AndroidBitmap_getInfo (env, dest, &dest_info);
4774
4775 /* If the stride is 0 after a call to `getInfo', assume it
4776 failed. */
4777
4778 if (!src_info.stride || !dest_info.stride)
4779 return;
4780
4781 /* If formats differ, abort. */
4782 eassert (src_info.format == dest_info.format
4783 && src_info.format == ANDROID_BITMAP_FORMAT_RGBA_8888);
4784
4785 /* Lock the image data. */
4786 src_data = NULL;
4787 AndroidBitmap_lockPixels (env, src, &src_data);
4788
4789 if (!src_data)
4790 return;
4791
4792 dest_data = NULL;
4793 AndroidBitmap_lockPixels (env, dest, &dest_data);
4794
4795 if (!dest_data)
4796 goto fail1;
4797
4798 /* Now clip the rectangle to the bounds of the source and
4799 destination bitmap. */
4800
4801 x1 = MAX (x1, 0);
4802 y1 = MAX (y1, 0);
4803 x2 = MAX (x2, 0);
4804 y2 = MAX (y2, 0);
4805
4806
4807 if (x1 >= src_info.width
4808 || x1 >= dest_info.width)
4809 x1 = MIN (dest_info.width - 1, src_info.width - 1);
4810
4811 if (x2 > src_info.width
4812 || x2 > dest_info.width)
4813 x2 = MIN (src_info.width, dest_info.width);
4814
4815 if (y1 >= src_info.height
4816 || y1 >= dest_info.height)
4817 y1 = MIN (dest_info.height - 1, src_info.height - 1);
4818
4819 if (y2 > src_info.height
4820 || y2 > dest_info.height)
4821 y2 = MIN (src_info.height, dest_info.height);
4822
4823 if (x1 >= x2 || y1 >= y2)
4824 goto fail2;
4825
4826 /* Determine the address of the first line to copy. */
4827
4828 src_data_1 = src_data;
4829 dest_data_1 = dest_data;
4830 src_data_1 += x1 * 4;
4831 src_data_1 += y1 * src_info.stride;
4832 dest_data_1 += x1 * 4;
4833 dest_data_1 += y1 * dest_info.stride;
4834
4835 /* Start copying each line. */
4836
4837 while (y1 != y2)
4838 {
4839 memcpy (dest_data_1, src_data_1, (x2 - x1) * 4);
4840 src_data_1 += src_info.stride;
4841 dest_data_1 += dest_info.stride;
4842 y1++;
4843 }
4844
4845 /* Complete the copy and unlock the bitmap. */
4846
4847 fail2:
4848 AndroidBitmap_unlockPixels (env, dest);
4849 fail1:
4850 AndroidBitmap_unlockPixels (env, src);
4851}
4852
4853
4854
4757void 4855void
4758android_free_pixmap (android_pixmap pixmap) 4856android_free_pixmap (android_pixmap pixmap)
4759{ 4857{