diff options
| author | Po Lu | 2024-05-02 11:31:37 +0800 |
|---|---|---|
| committer | Po Lu | 2024-05-02 11:31:37 +0800 |
| commit | b84fa71f8985284560bacda7d407e3559583844f (patch) | |
| tree | d7ed4518760fe51795dce384bc9dfa0b4ed32faf /src/android.c | |
| parent | d3e95fcae9078a0ea8fcb15a4aee417e6e546ee5 (diff) | |
| download | emacs-b84fa71f8985284560bacda7d407e3559583844f.tar.gz emacs-b84fa71f8985284560bacda7d407e3559583844f.zip | |
Port visible bell to Android
* java/org/gnu/emacs/EmacsDrawRectangle.java (perform): Ignore
GC_INVERT.
* java/org/gnu/emacs/EmacsFillRectangle.java
(EmacsFillRectangle) <invertFilter>: New variable.
(perform): If the transfer mode is invert, copy the source
to itself with invertFilter as the color filter.
* java/org/gnu/emacs/EmacsGC.java (EmacsGC) <xorAlu, srcInAlu>:
Delete now-redundant ALUs.
(markDirty): Cease updating the paint's transfermode.
* java/org/gnu/emacs/EmacsSafThread.java (openDocument1): Fix
typo in documentation.
* src/android.c (android_blit_xor): Delete unused function.
(android_copy_area): Remove calls to unused blit functions.
* src/androidgui.h (enum android_gc_function): Rename XOR to
INVERT.
* src/androidterm.c (android_flash): Replace with GXinvert.
Diffstat (limited to 'src/android.c')
| -rw-r--r-- | src/android.c | 288 |
1 files changed, 4 insertions, 284 deletions
diff --git a/src/android.c b/src/android.c index 2777add5059..c76afdb9bf2 100644 --- a/src/android.c +++ b/src/android.c | |||
| @@ -4381,286 +4381,6 @@ android_blit_copy (int src_x, int src_y, int width, int height, | |||
| 4381 | } | 4381 | } |
| 4382 | 4382 | ||
| 4383 | 4383 | ||
| 4384 | /* Xor a rectangle SRC_X, SRC_Y, WIDTH and HEIGHT from SRC, described | ||
| 4385 | by SRC_INFO, to DST_X and DST_Y in DST, as described by DST_INFO. | ||
| 4386 | |||
| 4387 | Ignore the alpha channel when computing the exclusive-or of the | ||
| 4388 | destination pixel. | ||
| 4389 | |||
| 4390 | If MASK is set, mask the source data using MASK_INFO, translating | ||
| 4391 | it by GC->clip_x_origin and GC->clip_y_origin. MASK must be a | ||
| 4392 | pixmap of depth 1. | ||
| 4393 | |||
| 4394 | N.B. that currently only copies between bitmaps of depth 24 are | ||
| 4395 | implemented. */ | ||
| 4396 | |||
| 4397 | static void | ||
| 4398 | android_blit_xor (int src_x, int src_y, int width, int height, | ||
| 4399 | int dst_x, int dst_y, struct android_gc *gc, | ||
| 4400 | unsigned char *src, AndroidBitmapInfo *src_info, | ||
| 4401 | unsigned char *dst, AndroidBitmapInfo *dst_info, | ||
| 4402 | unsigned char *mask, AndroidBitmapInfo *mask_info) | ||
| 4403 | { | ||
| 4404 | #if 0 | ||
| 4405 | uintptr_t start, end; | ||
| 4406 | int mask_offset; | ||
| 4407 | size_t pixel, offset, offset1; | ||
| 4408 | unsigned char *src_current, *dst_current; | ||
| 4409 | unsigned char *mask_current; | ||
| 4410 | int overflow, temp, i; | ||
| 4411 | bool backwards; | ||
| 4412 | unsigned int *long_src, *long_dst; | ||
| 4413 | #endif /* 0 */ | ||
| 4414 | |||
| 4415 | /* Note that this alu hasn't been tested -- it probably does not | ||
| 4416 | work! */ | ||
| 4417 | emacs_abort (); | ||
| 4418 | |||
| 4419 | #if 0 | ||
| 4420 | /* Assert that the specified coordinates are within bounds. */ | ||
| 4421 | eassert (src_x >= 0 && src_y >= 0 | ||
| 4422 | && dst_x >= 0 && dst_y >= 0); | ||
| 4423 | eassert (src_x + width <= src_info->width); | ||
| 4424 | eassert (src_y + height <= src_info->height); | ||
| 4425 | eassert (dst_x + width <= dst_info->width); | ||
| 4426 | eassert (dst_y + height <= dst_info->height); | ||
| 4427 | |||
| 4428 | /* Now check that each bitmap has the correct format. */ | ||
| 4429 | eassert (src_info->format == dst_info->format | ||
| 4430 | && src_info->format == ANDROID_BITMAP_FORMAT_RGBA_8888); | ||
| 4431 | pixel = sizeof (unsigned int); | ||
| 4432 | |||
| 4433 | /* Android doesn't have A1 bitmaps, so A8 is used to represent | ||
| 4434 | packed bitmaps of depth 1. */ | ||
| 4435 | eassert (!mask || mask_info->format == ANDROID_BITMAP_FORMAT_A_8); | ||
| 4436 | |||
| 4437 | /* Calculate the address of the first pixel of the first row to be | ||
| 4438 | copied in both src and dst. Compare them to determine the | ||
| 4439 | direction in which the copy is to take place. */ | ||
| 4440 | |||
| 4441 | overflow = ckd_mul (&start, src_y, src_info->stride); | ||
| 4442 | overflow |= ckd_mul (&end, src_x, pixel); | ||
| 4443 | overflow |= ckd_add (&start, (uintptr_t) src, start); | ||
| 4444 | |||
| 4445 | if (overflow) | ||
| 4446 | return; | ||
| 4447 | |||
| 4448 | src_current = (unsigned char *) start; | ||
| 4449 | |||
| 4450 | overflow = ckd_mul (&start, dst_y, src_info->stride); | ||
| 4451 | overflow |= ckd_mul (&end, dst_x, pixel); | ||
| 4452 | overflow |= ckd_add (&start, (uintptr_t) dst, start); | ||
| 4453 | |||
| 4454 | if (overflow) | ||
| 4455 | return; | ||
| 4456 | |||
| 4457 | dst_current = (unsigned char *) start; | ||
| 4458 | backwards = false; | ||
| 4459 | |||
| 4460 | /* Now see if copying should proceed from the bottom up. */ | ||
| 4461 | |||
| 4462 | if (src == dst && dst_current >= src_current) | ||
| 4463 | { | ||
| 4464 | backwards = true; | ||
| 4465 | |||
| 4466 | /* Walk src and dst from bottom to top, in order to avoid | ||
| 4467 | overlap. Calculate the coordinate of the last pixel of the | ||
| 4468 | last row in both src and dst. */ | ||
| 4469 | |||
| 4470 | overflow = ckd_mul (&start, src_y + height - 1, | ||
| 4471 | src_info->stride); | ||
| 4472 | if (mask) /* If a mask is set, put the pointers before the end | ||
| 4473 | of the row. */ | ||
| 4474 | overflow |= ckd_mul (&end, src_x + width - 1, pixel); | ||
| 4475 | else | ||
| 4476 | overflow |= ckd_mul (&end, src_x, pixel); | ||
| 4477 | overflow |= ckd_add (&start, start, end); | ||
| 4478 | overflow |= ckd_add (&start, (uintptr_t) src, start); | ||
| 4479 | |||
| 4480 | if (overflow) | ||
| 4481 | return; | ||
| 4482 | |||
| 4483 | src_current = (unsigned char *) start; | ||
| 4484 | |||
| 4485 | overflow = ckd_mul (&start, dst_y + height - 1, | ||
| 4486 | dst_info->stride); | ||
| 4487 | if (mask) /* If a mask is set, put the pointers before the end | ||
| 4488 | of the row. */ | ||
| 4489 | overflow |= ckd_mul (&end, dst_x + width - 1, pixel); | ||
| 4490 | else | ||
| 4491 | overflow |= ckd_mul (&end, dst_x, pixel); | ||
| 4492 | overflow |= ckd_add (&start, start, end); | ||
| 4493 | overflow |= ckd_add (&start, (uintptr_t) dst, start); | ||
| 4494 | |||
| 4495 | if (overflow) | ||
| 4496 | return; | ||
| 4497 | |||
| 4498 | dst_current = (unsigned char *) start; | ||
| 4499 | } | ||
| 4500 | |||
| 4501 | if (!mask) | ||
| 4502 | { | ||
| 4503 | /* Change the direction of the copy depending on how SRC and DST | ||
| 4504 | overlap. */ | ||
| 4505 | |||
| 4506 | for (i = 0; i < height; ++i) | ||
| 4507 | { | ||
| 4508 | if (backwards) | ||
| 4509 | { | ||
| 4510 | for (i = width - 1; i <= 0; --i) | ||
| 4511 | (((unsigned int *) dst_current)[i]) | ||
| 4512 | /* Keep the alpha channel intact. */ | ||
| 4513 | ^= (((unsigned int *) src_current)[i]) & 0xffffff; | ||
| 4514 | |||
| 4515 | /* Proceed to the last row. */ | ||
| 4516 | src_current -= src_info->stride; | ||
| 4517 | dst_current -= dst_info->stride; | ||
| 4518 | } | ||
| 4519 | else | ||
| 4520 | { | ||
| 4521 | for (i = 0; i < width; ++i) | ||
| 4522 | (((unsigned int *) dst_current)[i]) | ||
| 4523 | /* Keep the alpha channel intact. */ | ||
| 4524 | ^= (((unsigned int *) src_current)[i]) & 0xffffff; | ||
| 4525 | |||
| 4526 | /* Proceed to the next row. */ | ||
| 4527 | src_current += src_info->stride; | ||
| 4528 | dst_current += dst_info->stride; | ||
| 4529 | } | ||
| 4530 | } | ||
| 4531 | } | ||
| 4532 | else | ||
| 4533 | { | ||
| 4534 | /* Adjust the source and destination Y. The start is MAX | ||
| 4535 | (dst_y, gc->clip_y_origin); the difference between that value | ||
| 4536 | and dst_y is the offset to apply to src_y. */ | ||
| 4537 | |||
| 4538 | temp = dst_y; | ||
| 4539 | dst_y = MAX (dst_y, gc->clip_y_origin); | ||
| 4540 | src_y += dst_y - temp; | ||
| 4541 | height -= dst_y - temp; | ||
| 4542 | |||
| 4543 | /* Verify that the bounds are correct. */ | ||
| 4544 | eassert (dst_y + height | ||
| 4545 | <= gc->clip_y_origin + mask_info->height); | ||
| 4546 | eassert (dst_y >= gc->clip_y_origin); | ||
| 4547 | |||
| 4548 | /* There is a mask. For each scan line... */ | ||
| 4549 | |||
| 4550 | if (backwards) | ||
| 4551 | { | ||
| 4552 | /* Calculate the number of pixels at the end of the | ||
| 4553 | mask. */ | ||
| 4554 | |||
| 4555 | mask_offset = dst_x + width; | ||
| 4556 | mask_offset -= mask_info->width + gc->clip_x_origin; | ||
| 4557 | |||
| 4558 | if (mask_info < 0) | ||
| 4559 | mask_info = 0; | ||
| 4560 | |||
| 4561 | /* Calculate the last column of the mask that will be | ||
| 4562 | consulted. */ | ||
| 4563 | |||
| 4564 | temp = dst_x - gc->clip_x_origin; | ||
| 4565 | temp += MIN (mask_info->width - temp, | ||
| 4566 | width - mask_offset); | ||
| 4567 | |||
| 4568 | if (temp < 0) | ||
| 4569 | return; | ||
| 4570 | |||
| 4571 | /* Now calculate the last row of the mask that will be | ||
| 4572 | consulted. */ | ||
| 4573 | i = dst_y - gc->clip_y_origin + height; | ||
| 4574 | |||
| 4575 | /* Turn both into offsets. */ | ||
| 4576 | |||
| 4577 | if (ckd_mul (&offset, temp, pixel) | ||
| 4578 | || ckd_mul (&offset1, i, mask_info->stride) | ||
| 4579 | || ckd_add (&offset, offset, offset1) | ||
| 4580 | || ckd_add (&start, (uintptr_t) mask, offset)) | ||
| 4581 | return; | ||
| 4582 | |||
| 4583 | mask = mask_current = (unsigned char *) start; | ||
| 4584 | |||
| 4585 | for (i = 0; i < height; ++i) | ||
| 4586 | { | ||
| 4587 | /* Skip backwards past the end of the mask. */ | ||
| 4588 | |||
| 4589 | long_src = (unsigned int *) (src_current - mask_offset * pixel); | ||
| 4590 | long_dst = (unsigned int *) (dst_current - mask_offset * pixel); | ||
| 4591 | mask = mask_current; | ||
| 4592 | |||
| 4593 | /* For each pixel covered by the mask... */ | ||
| 4594 | temp = MIN (mask_info->width - temp, width - mask_offset); | ||
| 4595 | while (temp--) | ||
| 4596 | /* XOR the source to the destination, masked by the | ||
| 4597 | mask. */ | ||
| 4598 | *long_dst-- ^= ((*(long_src--) & (0u - (*(mask--) & 1))) | ||
| 4599 | & 0xffffff); | ||
| 4600 | |||
| 4601 | /* Return to the last row. */ | ||
| 4602 | src_current -= src_info->stride; | ||
| 4603 | dst_current -= dst_info->stride; | ||
| 4604 | mask_current -= mask_info->stride; | ||
| 4605 | } | ||
| 4606 | } | ||
| 4607 | else | ||
| 4608 | { | ||
| 4609 | /* Calculate the first column of the mask that will be | ||
| 4610 | consulted. */ | ||
| 4611 | |||
| 4612 | mask_offset = dst_x - gc->clip_x_origin; | ||
| 4613 | |||
| 4614 | /* Adjust the mask by that much. */ | ||
| 4615 | |||
| 4616 | if (mask_offset > 0) | ||
| 4617 | mask += mask_offset; | ||
| 4618 | else | ||
| 4619 | { | ||
| 4620 | /* Offset src and dst by the mask offset. */ | ||
| 4621 | src_current += -mask_offset * pixel; | ||
| 4622 | dst_current += -mask_offset * pixel; | ||
| 4623 | width -= mask_offset; | ||
| 4624 | } | ||
| 4625 | |||
| 4626 | /* Now move mask to the position of the first row. */ | ||
| 4627 | |||
| 4628 | mask += gc->clip_y_origin * mask_info->stride; | ||
| 4629 | |||
| 4630 | for (i = 0; i < height; ++i) | ||
| 4631 | { | ||
| 4632 | long_src = (unsigned int *) src_current; | ||
| 4633 | long_dst = (unsigned int *) dst_current; | ||
| 4634 | mask_current = mask; | ||
| 4635 | |||
| 4636 | if (mask_offset > 0) | ||
| 4637 | { | ||
| 4638 | /* Copy bytes according to the mask. */ | ||
| 4639 | temp = MIN (mask_info->width - mask_offset, width); | ||
| 4640 | while (temp--) | ||
| 4641 | *long_dst++ ^= ((*(long_src++) | ||
| 4642 | & (0u - (*(mask_current++) & 1))) | ||
| 4643 | & 0xffffff); | ||
| 4644 | } | ||
| 4645 | else | ||
| 4646 | { | ||
| 4647 | /* Copy bytes according to the mask. */ | ||
| 4648 | temp = MIN (mask_info->width, width); | ||
| 4649 | while (temp--) | ||
| 4650 | *long_dst++ = ((*(long_src++) | ||
| 4651 | & (0u - (*(mask_current++) & 1))) | ||
| 4652 | & 0xffffff); | ||
| 4653 | } | ||
| 4654 | |||
| 4655 | src_current += src_info->stride; | ||
| 4656 | dst_current += dst_info->stride; | ||
| 4657 | mask += mask_info->stride; | ||
| 4658 | } | ||
| 4659 | } | ||
| 4660 | } | ||
| 4661 | #endif /* 0 */ | ||
| 4662 | } | ||
| 4663 | |||
| 4664 | void | 4384 | void |
| 4665 | android_copy_area (android_drawable src, android_drawable dest, | 4385 | android_copy_area (android_drawable src, android_drawable dest, |
| 4666 | struct android_gc *gc, int src_x, int src_y, | 4386 | struct android_gc *gc, int src_x, int src_y, |
| @@ -4763,10 +4483,10 @@ android_copy_area (android_drawable src, android_drawable dest, | |||
| 4763 | do_blit = android_blit_copy; | 4483 | do_blit = android_blit_copy; |
| 4764 | break; | 4484 | break; |
| 4765 | 4485 | ||
| 4766 | case ANDROID_GC_XOR: | 4486 | /* case ANDROID_GC_INVERT: */ |
| 4767 | do_blit = android_blit_xor; | 4487 | /* do_blit = android_blit_invert; */ |
| 4768 | break; | 4488 | /* A GC with its operation set to ANDROID_GC_INVERT is never given |
| 4769 | 4489 | to CopyArea. */ | |
| 4770 | default: | 4490 | default: |
| 4771 | emacs_abort (); | 4491 | emacs_abort (); |
| 4772 | } | 4492 | } |