From 00671b18438fec8f2e7f774cb3fd4cd6f694fd18 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 29 May 2023 15:44:14 +0800 Subject: Implement android_copy_area in C * java/org/gnu/emacs/EmacsCopyArea.java: Remove file. * java/org/gnu/emacs/EmacsService.java (EmacsService, copyArea): Delete function. * src/android.c (struct android_emacs_service) (android_init_emacs_service): Remove `copy_area'. (android_create_gc, android_change_gc, android_get_gc_values): Record new GC values. (android_neon_mask_line): New function. (android_blit_copy, android_blit_xor): New functions. (android_copy_area): Implement in C. (android_lock_bitmap): Accept drawables instead of windows. * src/android.h: Adjust prototype for `android_lock_bitmap'. * src/androidgui.h (struct android_gc): Record last known GC values. --- java/org/gnu/emacs/EmacsCopyArea.java | 206 ---------------------------------- java/org/gnu/emacs/EmacsService.java | 12 -- 2 files changed, 218 deletions(-) delete mode 100644 java/org/gnu/emacs/EmacsCopyArea.java (limited to 'java') diff --git a/java/org/gnu/emacs/EmacsCopyArea.java b/java/org/gnu/emacs/EmacsCopyArea.java deleted file mode 100644 index f69b0cde866..00000000000 --- a/java/org/gnu/emacs/EmacsCopyArea.java +++ /dev/null @@ -1,206 +0,0 @@ -/* Communication module for Android terminals. -*- c-file-style: "GNU" -*- - -Copyright (C) 2023 Free Software Foundation, Inc. - -This file is part of GNU Emacs. - -GNU Emacs is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or (at -your option) any later version. - -GNU Emacs is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Emacs. If not, see . */ - -package org.gnu.emacs; - -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.PorterDuff.Mode; -import android.graphics.PorterDuffXfermode; -import android.graphics.Rect; -import android.graphics.Xfermode; - -public final class EmacsCopyArea -{ - private static Xfermode overAlu; - - static - { - overAlu = new PorterDuffXfermode (Mode.SRC_OVER); - }; - - private static void - insetRectBy (Rect rect, int left, int top, int right, - int bottom) - { - rect.left += left; - rect.top += top; - rect.right -= right; - rect.bottom -= bottom; - } - - public static void - perform (EmacsDrawable source, EmacsGC gc, - EmacsDrawable destination, - int src_x, int src_y, int width, int height, - int dest_x, int dest_y) - { - int i; - Bitmap bitmap; - Paint maskPaint, paint; - Canvas maskCanvas, canvas; - Bitmap srcBitmap, maskBitmap, clipBitmap; - Rect rect, maskRect, srcRect, dstRect, maskDestRect; - boolean needFill; - - /* TODO implement stippling. */ - if (gc.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED) - return; - - paint = gc.gcPaint; - - canvas = destination.lockCanvas (gc); - - if (canvas == null) - return; - - /* A copy must be created or drawBitmap could end up overwriting - itself. */ - srcBitmap = source.getBitmap (); - - /* If srcBitmap is out of bounds, then adjust the source rectangle - to be within bounds. Note that tiling on windows with - backgrounds is unimplemented. */ - - if (src_x < 0) - { - width += src_x; - dest_x -= src_x; - src_x = 0; - } - - if (src_y < 0) - { - height += src_y; - dest_y -= src_y; - src_y = 0; - } - - if (src_x + width > srcBitmap.getWidth ()) - width = srcBitmap.getWidth () - src_x; - - if (src_y + height > srcBitmap.getHeight ()) - height = srcBitmap.getHeight () - src_y; - - /* If width and height are empty or negative, then skip the entire - CopyArea operation lest createBitmap throw an exception. */ - - if (width <= 0 || height <= 0) - return; - - rect = new Rect (dest_x, dest_y, dest_x + width, - dest_y + height); - - if (gc.clip_mask == null) - { - if (source == destination) - { - /* Create a copy of the bitmap, since Android can't handle - overlapping copies. */ - bitmap = Bitmap.createBitmap (srcBitmap, - src_x, src_y, width, - height); - canvas.drawBitmap (bitmap, null, rect, paint); - bitmap.recycle (); - } - else - { - /* But here the bitmaps are known to not overlap, so avoid - that extra consing overhead. */ - - srcRect = new Rect (src_x, src_y, src_x + width, - src_y + height); - canvas.drawBitmap (srcBitmap, srcRect, rect, paint); - } - } - else - { - /* Drawing with a clip mask involves calculating the - intersection of the clip mask with the dst rect, and - extrapolating the corresponding part of the src rect. */ - clipBitmap = gc.clip_mask.bitmap; - dstRect = new Rect (dest_x, dest_y, - dest_x + width, - dest_y + height); - maskRect = new Rect (gc.clip_x_origin, - gc.clip_y_origin, - (gc.clip_x_origin - + clipBitmap.getWidth ()), - (gc.clip_y_origin - + clipBitmap.getHeight ())); - clipBitmap = gc.clip_mask.bitmap; - - if (!maskRect.setIntersect (dstRect, maskRect)) - /* There is no intersection between the clip mask and the - dest rect. */ - return; - - /* Now figure out which part of the source corresponds to - maskRect and return it relative to srcBitmap. */ - srcRect = new Rect (src_x, src_y, src_x + width, - src_y + height); - insetRectBy (srcRect, maskRect.left - dstRect.left, - maskRect.top - dstRect.top, - maskRect.right - dstRect.right, - maskRect.bottom - dstRect.bottom); - - /* Finally, create a temporary bitmap that is the size of - maskRect. */ - - maskBitmap - = Bitmap.createBitmap (maskRect.width (), maskRect.height (), - Bitmap.Config.ARGB_8888); - - /* Draw the mask onto the maskBitmap. */ - maskCanvas = new Canvas (maskBitmap); - maskPaint = new Paint (); - maskRect.offset (-gc.clip_x_origin, - -gc.clip_y_origin); - maskCanvas.drawBitmap (gc.clip_mask.bitmap, - maskRect, - new Rect (0, 0, - maskRect.width (), - maskRect.height ()), - maskPaint); - maskRect.offset (gc.clip_x_origin, - gc.clip_y_origin); - - /* Set the transfer mode to SRC_IN to preserve only the parts - of the source that overlap with the mask. */ - maskPaint.setXfermode (EmacsGC.srcInAlu); - - /* Draw the source. */ - maskDestRect = new Rect (0, 0, srcRect.width (), - srcRect.height ()); - maskCanvas.drawBitmap (srcBitmap, srcRect, maskDestRect, - maskPaint); - - /* Finally, draw the mask bitmap to the destination. */ - paint.setXfermode (overAlu); - canvas.drawBitmap (maskBitmap, null, maskRect, paint); - gc.resetXfermode (); - - /* Recycle this unused bitmap. */ - maskBitmap.recycle (); - } - - destination.damageRect (rect); - } -} diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index d2e52ed5e62..546d22627c5 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java @@ -374,18 +374,6 @@ public final class EmacsService extends Service EmacsDrawPoint.perform (drawable, gc, x, y); } - public void - copyArea (EmacsDrawable srcDrawable, EmacsDrawable dstDrawable, - EmacsGC gc, - int srcX, int srcY, int width, int height, int destX, - int destY) - { - checkEmacsThread (); - EmacsCopyArea.perform (srcDrawable, gc, dstDrawable, - srcX, srcY, width, height, destX, - destY); - } - public void clearWindow (EmacsWindow window) { -- cgit v1.2.1