aboutsummaryrefslogtreecommitdiffstats
path: root/java/org/gnu/emacs/EmacsCopyArea.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/org/gnu/emacs/EmacsCopyArea.java')
-rw-r--r--java/org/gnu/emacs/EmacsCopyArea.java206
1 files changed, 0 insertions, 206 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}