aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorPo Lu2023-05-29 15:44:14 +0800
committerPo Lu2023-05-29 15:44:14 +0800
commit00671b18438fec8f2e7f774cb3fd4cd6f694fd18 (patch)
treeca4dd77499a73711cced57ddf58c9131bac19706 /java
parent327d2d013130ec745880b44573dcda3a6620faba (diff)
downloademacs-00671b18438fec8f2e7f774cb3fd4cd6f694fd18.tar.gz
emacs-00671b18438fec8f2e7f774cb3fd4cd6f694fd18.zip
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.
Diffstat (limited to 'java')
-rw-r--r--java/org/gnu/emacs/EmacsCopyArea.java206
-rw-r--r--java/org/gnu/emacs/EmacsService.java12
2 files changed, 0 insertions, 218 deletions
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 @@
1/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
2
3Copyright (C) 2023 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or (at
10your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
19
20package org.gnu.emacs;
21
22import android.graphics.Bitmap;
23import android.graphics.Canvas;
24import android.graphics.Paint;
25import android.graphics.PorterDuff.Mode;
26import android.graphics.PorterDuffXfermode;
27import android.graphics.Rect;
28import android.graphics.Xfermode;
29
30public final class EmacsCopyArea
31{
32 private static Xfermode overAlu;
33
34 static
35 {
36 overAlu = new PorterDuffXfermode (Mode.SRC_OVER);
37 };
38
39 private static void
40 insetRectBy (Rect rect, int left, int top, int right,
41 int bottom)
42 {
43 rect.left += left;
44 rect.top += top;
45 rect.right -= right;
46 rect.bottom -= bottom;
47 }
48
49 public static void
50 perform (EmacsDrawable source, EmacsGC gc,
51 EmacsDrawable destination,
52 int src_x, int src_y, int width, int height,
53 int dest_x, int dest_y)
54 {
55 int i;
56 Bitmap bitmap;
57 Paint maskPaint, paint;
58 Canvas maskCanvas, canvas;
59 Bitmap srcBitmap, maskBitmap, clipBitmap;
60 Rect rect, maskRect, srcRect, dstRect, maskDestRect;
61 boolean needFill;
62
63 /* TODO implement stippling. */
64 if (gc.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED)
65 return;
66
67 paint = gc.gcPaint;
68
69 canvas = destination.lockCanvas (gc);
70
71 if (canvas == null)
72 return;
73
74 /* A copy must be created or drawBitmap could end up overwriting
75 itself. */
76 srcBitmap = source.getBitmap ();
77
78 /* If srcBitmap is out of bounds, then adjust the source rectangle
79 to be within bounds. Note that tiling on windows with
80 backgrounds is unimplemented. */
81
82 if (src_x < 0)
83 {
84 width += src_x;
85 dest_x -= src_x;
86 src_x = 0;
87 }
88
89 if (src_y < 0)
90 {
91 height += src_y;
92 dest_y -= src_y;
93 src_y = 0;
94 }
95
96 if (src_x + width > srcBitmap.getWidth ())
97 width = srcBitmap.getWidth () - src_x;
98
99 if (src_y + height > srcBitmap.getHeight ())
100 height = srcBitmap.getHeight () - src_y;
101
102 /* If width and height are empty or negative, then skip the entire
103 CopyArea operation lest createBitmap throw an exception. */
104
105 if (width <= 0 || height <= 0)
106 return;
107
108 rect = new Rect (dest_x, dest_y, dest_x + width,
109 dest_y + height);
110
111 if (gc.clip_mask == null)
112 {
113 if (source == destination)
114 {
115 /* Create a copy of the bitmap, since Android can't handle
116 overlapping copies. */
117 bitmap = Bitmap.createBitmap (srcBitmap,
118 src_x, src_y, width,
119 height);
120 canvas.drawBitmap (bitmap, null, rect, paint);
121 bitmap.recycle ();
122 }
123 else
124 {
125 /* But here the bitmaps are known to not overlap, so avoid
126 that extra consing overhead. */
127
128 srcRect = new Rect (src_x, src_y, src_x + width,
129 src_y + height);
130 canvas.drawBitmap (srcBitmap, srcRect, rect, paint);
131 }
132 }
133 else
134 {
135 /* Drawing with a clip mask involves calculating the
136 intersection of the clip mask with the dst rect, and
137 extrapolating the corresponding part of the src rect. */
138 clipBitmap = gc.clip_mask.bitmap;
139 dstRect = new Rect (dest_x, dest_y,
140 dest_x + width,
141 dest_y + height);
142 maskRect = new Rect (gc.clip_x_origin,
143 gc.clip_y_origin,
144 (gc.clip_x_origin
145 + clipBitmap.getWidth ()),
146 (gc.clip_y_origin
147 + clipBitmap.getHeight ()));
148 clipBitmap = gc.clip_mask.bitmap;
149
150 if (!maskRect.setIntersect (dstRect, maskRect))
151 /* There is no intersection between the clip mask and the
152 dest rect. */
153 return;
154
155 /* Now figure out which part of the source corresponds to
156 maskRect and return it relative to srcBitmap. */
157 srcRect = new Rect (src_x, src_y, src_x + width,
158 src_y + height);
159 insetRectBy (srcRect, maskRect.left - dstRect.left,
160 maskRect.top - dstRect.top,
161 maskRect.right - dstRect.right,
162 maskRect.bottom - dstRect.bottom);
163
164 /* Finally, create a temporary bitmap that is the size of
165 maskRect. */
166
167 maskBitmap
168 = Bitmap.createBitmap (maskRect.width (), maskRect.height (),
169 Bitmap.Config.ARGB_8888);
170
171 /* Draw the mask onto the maskBitmap. */
172 maskCanvas = new Canvas (maskBitmap);
173 maskPaint = new Paint ();
174 maskRect.offset (-gc.clip_x_origin,
175 -gc.clip_y_origin);
176 maskCanvas.drawBitmap (gc.clip_mask.bitmap,
177 maskRect,
178 new Rect (0, 0,
179 maskRect.width (),
180 maskRect.height ()),
181 maskPaint);
182 maskRect.offset (gc.clip_x_origin,
183 gc.clip_y_origin);
184
185 /* Set the transfer mode to SRC_IN to preserve only the parts
186 of the source that overlap with the mask. */
187 maskPaint.setXfermode (EmacsGC.srcInAlu);
188
189 /* Draw the source. */
190 maskDestRect = new Rect (0, 0, srcRect.width (),
191 srcRect.height ());
192 maskCanvas.drawBitmap (srcBitmap, srcRect, maskDestRect,
193 maskPaint);
194
195 /* Finally, draw the mask bitmap to the destination. */
196 paint.setXfermode (overAlu);
197 canvas.drawBitmap (maskBitmap, null, maskRect, paint);
198 gc.resetXfermode ();
199
200 /* Recycle this unused bitmap. */
201 maskBitmap.recycle ();
202 }
203
204 destination.damageRect (rect);
205 }
206}
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
@@ -375,18 +375,6 @@ public final class EmacsService extends Service
375 } 375 }
376 376
377 public void 377 public void
378 copyArea (EmacsDrawable srcDrawable, EmacsDrawable dstDrawable,
379 EmacsGC gc,
380 int srcX, int srcY, int width, int height, int destX,
381 int destY)
382 {
383 checkEmacsThread ();
384 EmacsCopyArea.perform (srcDrawable, gc, dstDrawable,
385 srcX, srcY, width, height, destX,
386 destY);
387 }
388
389 public void
390 clearWindow (EmacsWindow window) 378 clearWindow (EmacsWindow window)
391 { 379 {
392 checkEmacsThread (); 380 checkEmacsThread ();