From b84fa71f8985284560bacda7d407e3559583844f Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 2 May 2024 11:31:37 +0800 Subject: Port visible bell to Android * java/org/gnu/emacs/EmacsDrawRectangle.java (perform): Ignore GC_INVERT. * java/org/gnu/emacs/EmacsFillRectangle.java (EmacsFillRectangle) : 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) : 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. --- java/org/gnu/emacs/EmacsDrawRectangle.java | 18 +++++- java/org/gnu/emacs/EmacsFillRectangle.java | 96 +++++++++++------------------- java/org/gnu/emacs/EmacsGC.java | 16 +---- java/org/gnu/emacs/EmacsSafThread.java | 8 +-- 4 files changed, 56 insertions(+), 82 deletions(-) (limited to 'java') diff --git a/java/org/gnu/emacs/EmacsDrawRectangle.java b/java/org/gnu/emacs/EmacsDrawRectangle.java index e40a7c16068..ea0f1c28106 100644 --- a/java/org/gnu/emacs/EmacsDrawRectangle.java +++ b/java/org/gnu/emacs/EmacsDrawRectangle.java @@ -22,13 +22,23 @@ 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.RectF; +import android.graphics.Xfermode; import android.util.Log; public final class EmacsDrawRectangle { + private static final Xfermode srcInAlu; + + static + { + srcInAlu = new PorterDuffXfermode (Mode.SRC_IN); + }; + public static void perform (EmacsDrawable drawable, EmacsGC gc, int x, int y, int width, int height) @@ -40,8 +50,10 @@ public final class EmacsDrawRectangle Canvas canvas; Bitmap clipBitmap; - /* TODO implement stippling. */ - if (gc.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED) + /* TODO implement stippling for this request. */ + if (gc.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED + /* And GC_INVERT also. */ + || gc.fill_style == EmacsGC.GC_INVERT) return; canvas = drawable.lockCanvas (gc); @@ -103,7 +115,7 @@ public final class EmacsDrawRectangle /* Set the transfer mode to SRC_IN to preserve only the parts of the source that overlap with the mask. */ maskPaint = new Paint (); - maskPaint.setXfermode (EmacsGC.srcInAlu); + maskPaint.setXfermode (srcInAlu); maskPaint.setStyle (Paint.Style.STROKE); /* Draw the source. */ diff --git a/java/org/gnu/emacs/EmacsFillRectangle.java b/java/org/gnu/emacs/EmacsFillRectangle.java index f338a54f97b..7642deed7c3 100644 --- a/java/org/gnu/emacs/EmacsFillRectangle.java +++ b/java/org/gnu/emacs/EmacsFillRectangle.java @@ -21,6 +21,8 @@ package org.gnu.emacs; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.ColorMatrixColorFilter; import android.graphics.Paint; import android.graphics.Rect; @@ -28,30 +30,42 @@ import android.util.Log; public final class EmacsFillRectangle { + /* Color filter that inverts colors from the source. */ + private static final ColorFilter invertFilter; + + static + { + invertFilter = new ColorMatrixColorFilter (new float[] { + -1f, 0f, 0f, 0f, 255f, + 0f, -1f, 0f, 0f, 255f, + 0f, 0f, -1f, 0f, 255f, + 0f, 0f, 0f, 1f, 0f, + }); + }; + public static void perform (EmacsDrawable drawable, EmacsGC gc, int x, int y, int width, int height) { - Paint maskPaint, paint; - Canvas maskCanvas; - Bitmap maskBitmap; + Paint paint; Rect rect; - Rect maskRect, dstRect; Canvas canvas; - Bitmap clipBitmap; + Bitmap invertBitmap; canvas = drawable.lockCanvas (gc); - if (canvas == null) + /* Clip masks are not respected or implemented when specified with + this request. */ + if (canvas == null || gc.clip_mask != null) return; rect = new Rect (x, y, x + width, y + height); - paint = gc.gcPaint; - paint.setStyle (Paint.Style.FILL); - - if (gc.clip_mask == null) + if (gc.function != EmacsGC.GC_INVERT) { + paint = gc.gcPaint; + paint.setStyle (Paint.Style.FILL); + if (gc.fill_style != EmacsGC.GC_FILL_OPAQUE_STIPPLED) canvas.drawRect (rect, paint); else @@ -59,57 +73,17 @@ public final class EmacsFillRectangle } 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 (x, y, x + width, 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 ())); - - if (!maskRect.setIntersect (dstRect, maskRect)) - /* There is no intersection between the clip mask and the - dest rect. */ - return; - - /* 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); - 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 ()), - paint); - 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 = new Paint (); - maskPaint.setXfermode (EmacsGC.srcInAlu); - - /* Draw the source. */ - maskCanvas.drawRect (maskRect, maskPaint); - - /* Finally, draw the mask bitmap to the destination. */ - paint.setXfermode (null); - canvas.drawBitmap (maskBitmap, null, maskRect, paint); - - /* Recycle this unused bitmap. */ - maskBitmap.recycle (); + paint = new Paint (); + + /* Simply invert the destination, which is only implemented for + this request. As Android doesn't permit copying a bitmap to + itself, a copy of the source must be procured beforehand. */ + invertBitmap = Bitmap.createBitmap (drawable.getBitmap (), + x, y, width, height); + paint.setColorFilter (invertFilter); + canvas.drawBitmap (invertBitmap, null, rect, paint); + paint.setColorFilter (null); + invertBitmap.recycle (); } drawable.damageRect (rect); diff --git a/java/org/gnu/emacs/EmacsGC.java b/java/org/gnu/emacs/EmacsGC.java index ec2b9c9e475..bb11f76c800 100644 --- a/java/org/gnu/emacs/EmacsGC.java +++ b/java/org/gnu/emacs/EmacsGC.java @@ -27,9 +27,7 @@ import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffColorFilter; -import android.graphics.PorterDuffXfermode; import android.graphics.Shader.TileMode; -import android.graphics.Xfermode; import android.graphics.drawable.BitmapDrawable; @@ -40,8 +38,8 @@ import android.os.Build; public final class EmacsGC extends EmacsHandleObject { - public static final int GC_COPY = 0; - public static final int GC_XOR = 1; + public static final int GC_COPY = 0; + public static final int GC_INVERT = 1; public static final int GC_FILL_SOLID = 0; public static final int GC_FILL_OPAQUE_STIPPLED = 1; @@ -49,8 +47,6 @@ public final class EmacsGC extends EmacsHandleObject public static final int GC_LINE_SOLID = 0; public static final int GC_LINE_ON_OFF_DASH = 1; - public static final Xfermode xorAlu, srcInAlu; - public int function, fill_style; public int foreground, background; public int clip_x_origin, clip_y_origin; @@ -72,12 +68,6 @@ public final class EmacsGC extends EmacsHandleObject rectangles changed. 0 if there are no clip rectangles. */ public long clipRectID; - static - { - xorAlu = new PorterDuffXfermode (Mode.XOR); - srcInAlu = new PorterDuffXfermode (Mode.SRC_IN); - } - /* The following fields are only set on immutable GCs. */ public @@ -131,8 +121,6 @@ public final class EmacsGC extends EmacsHandleObject /* A line_width of 0 is equivalent to that of 1. */ gcPaint.setStrokeWidth (line_width < 1 ? 1 : line_width); gcPaint.setColor (foreground | 0xff000000); - gcPaint.setXfermode (function == GC_XOR - ? xorAlu : srcInAlu); /* Update the stipple object with the new stipple bitmap, or delete it if the stipple has been cleared on systems too old to support diff --git a/java/org/gnu/emacs/EmacsSafThread.java b/java/org/gnu/emacs/EmacsSafThread.java index 14c3f222833..ee8c2e7e0c3 100644 --- a/java/org/gnu/emacs/EmacsSafThread.java +++ b/java/org/gnu/emacs/EmacsSafThread.java @@ -1623,10 +1623,10 @@ public final class EmacsSafThread extends HandlerThread mode is merely w. This may be ascribed to a mix-up in Android's documentation - regardin DocumentsProvider: the `openDocument' function is only - documented to accept r or rw, whereas the default - implementation of the `openFile' function (which documents rwt) - delegates to `openDocument'. */ + regarding DocumentsProvider: the `openDocument' function is only + documented to accept r or rw, whereas the default implementation + of the `openFile' function (which documents rwt) delegates to + `openDocument'. */ if (read && write && truncate && fileDescriptor != null && !EmacsNative.ftruncate (fileDescriptor.getFd ())) -- cgit v1.2.1