diff options
Diffstat (limited to 'src/android.c')
| -rw-r--r-- | src/android.c | 98 |
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 | ||
| 4757 | JNIEXPORT void JNICALL | ||
| 4758 | NATIVE_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 | |||
| 4757 | void | 4855 | void |
| 4758 | android_free_pixmap (android_pixmap pixmap) | 4856 | android_free_pixmap (android_pixmap pixmap) |
| 4759 | { | 4857 | { |