aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorPo Lu2024-04-23 14:30:38 +0800
committerPo Lu2024-04-23 14:30:38 +0800
commitb9c191d690fd5d1480858469df23cc4509996fae (patch)
tree2e0536607f1442a99e88e39af8d24c51bab45aeb /java
parent63765a74f15ef22109750414ec3025c8a40039f0 (diff)
downloademacs-b9c191d690fd5d1480858469df23cc4509996fae.tar.gz
emacs-b9c191d690fd5d1480858469df23cc4509996fae.zip
Implement face stipples on Android
* .gitignore: * java/Makefile.in: Fix typos. * java/org/gnu/emacs/EmacsFillRectangle.java (perform): Call blitOpaqueStipple if filling an unobscured rectangle with an opaque stipple. * java/org/gnu/emacs/EmacsGC.java (EmacsGC) <tileObject>: New field. (markDirty): Synchronize the current stipple with tileObject. (prepareStipple, blitOpaqueStipple): New functions. * java/org/gnu/emacs/EmacsService.java (EmacsService) <resources>: New static field. (onCreate): Set it. * src/android.c (android_create_bitmap_from_data): Correct order of arguments to android_create_pixmap_from_bitmap_data. (HAS_BUILTIN_TRAP): Delete macro. (emacs_abort): Always induce backtraces by means of a NULL pointer deference. * src/dispextern.h (Emacs_GC, Emacs_Rectangle, GCForeground) (GCBackground, GCFillStyle, GCStipple, FillOpaqueStipple) [HAVE_ANDROID]: Define to their Android counterparts rather than simulating their existence. * src/epaths.in: Set bitmap path to /assets/bitmaps on Android. * src/image.c (image_bitmap_pixmap): Also enable when HAVE_ANDROID. * src/sfntfont-android.c (sfntfont_android_put_glyphs): Assert that this is never called to draw a stippled background. * src/xfaces.c (x_create_gc) [HAVE_ANDROID]: Redefine as wrapper around android_create_gc. (prepare_face_for_display) [HAVE_ANDROID]: Enable stipples.
Diffstat (limited to 'java')
-rw-r--r--java/Makefile.in9
-rw-r--r--java/org/gnu/emacs/EmacsFillRectangle.java15
-rw-r--r--java/org/gnu/emacs/EmacsGC.java94
-rw-r--r--java/org/gnu/emacs/EmacsService.java7
4 files changed, 110 insertions, 15 deletions
diff --git a/java/Makefile.in b/java/Makefile.in
index abddae6b5cf..35d2637837c 100644
--- a/java/Makefile.in
+++ b/java/Makefile.in
@@ -197,10 +197,13 @@ install_temp: $(CROSS_BINS) $(CROSS_LIBS) $(RESOURCE_FILES)
197 $(AM_V_SILENT) mkdir -p install_temp/assets/etc 197 $(AM_V_SILENT) mkdir -p install_temp/assets/etc
198 $(AM_V_SILENT) mkdir -p install_temp/assets/lisp 198 $(AM_V_SILENT) mkdir -p install_temp/assets/lisp
199 $(AM_V_SILENT) mkdir -p install_temp/assets/info 199 $(AM_V_SILENT) mkdir -p install_temp/assets/info
200# Install architecture independents to assets/etc and assets/lisp 200 $(AM_V_SILENT) mkdir -p install_temp/assets/bitmaps
201# Install architecture independents to assets/etc, assets/lisp and
202# assets/bitmaps
201 $(AM_V_SILENT) cp -r $(top_srcdir)/lisp install_temp/assets 203 $(AM_V_SILENT) cp -r $(top_srcdir)/lisp install_temp/assets
202 $(AM_V_SILENT) cp -r $(top_srcdir)/etc install_temp/assets 204 $(AM_V_SILENT) cp -r $(top_srcdir)/etc install_temp/assets
203 $(AM_V_SILENT) cp -r $(top_srcdir)/info install_temp/assets 205 $(AM_V_SILENT) cp -r $(top_srcdir)/info install_temp/assets
206 $(AM_V_SILENT) cp -r $(top_srcdir)/src/bitmaps install_temp/assets
204# Replace etc/DOC generated by compiling Emacs for the build machine 207# Replace etc/DOC generated by compiling Emacs for the build machine
205# with etc/DOC from the cross-compiled Emacs. 208# with etc/DOC from the cross-compiled Emacs.
206 $(AM_V_SILENT) test -f $(top_builddir)/cross/etc/DOC \ 209 $(AM_V_SILENT) test -f $(top_builddir)/cross/etc/DOC \
@@ -354,8 +357,8 @@ public static final String[] EMACS_SHARED_LIBRARIES\
354 357
355# cf-stamp-1 is a phony target invoked in a second `make' instance after 358# cf-stamp-1 is a phony target invoked in a second `make' instance after
356# all shared libraries are compiled, because the computation of 359# all shared libraries are compiled, because the computation of
357# ALL_DEPENDENCIES cannot be postponed until that stage in this instance 360# ALL_DEPENDENCIES in this instance of Make cannot be postponed until
358# of Make. 361# that stage.
359cf-stamp: $(NDK_BUILD_SHARED) $(CROSS_LIBS) 362cf-stamp: $(NDK_BUILD_SHARED) $(CROSS_LIBS)
360 $(AM_V_EMACSCONFIG) $(MAKE) cf-stamp-1 363 $(AM_V_EMACSCONFIG) $(MAKE) cf-stamp-1
361 $(AM_V_at) touch $@ 364 $(AM_V_at) touch $@
diff --git a/java/org/gnu/emacs/EmacsFillRectangle.java b/java/org/gnu/emacs/EmacsFillRectangle.java
index ca87c06c014..f338a54f97b 100644
--- a/java/org/gnu/emacs/EmacsFillRectangle.java
+++ b/java/org/gnu/emacs/EmacsFillRectangle.java
@@ -40,22 +40,23 @@ public final class EmacsFillRectangle
40 Canvas canvas; 40 Canvas canvas;
41 Bitmap clipBitmap; 41 Bitmap clipBitmap;
42 42
43 /* TODO implement stippling. */
44 if (gc.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED)
45 return;
46
47 canvas = drawable.lockCanvas (gc); 43 canvas = drawable.lockCanvas (gc);
48 44
49 if (canvas == null) 45 if (canvas == null)
50 return; 46 return;
51 47
52 paint = gc.gcPaint;
53 rect = new Rect (x, y, x + width, y + height); 48 rect = new Rect (x, y, x + width, y + height);
54 49
50 paint = gc.gcPaint;
55 paint.setStyle (Paint.Style.FILL); 51 paint.setStyle (Paint.Style.FILL);
56 52
57 if (gc.clip_mask == null) 53 if (gc.clip_mask == null)
58 canvas.drawRect (rect, paint); 54 {
55 if (gc.fill_style != EmacsGC.GC_FILL_OPAQUE_STIPPLED)
56 canvas.drawRect (rect, paint);
57 else
58 gc.blitOpaqueStipple (canvas, rect);
59 }
59 else 60 else
60 { 61 {
61 /* Drawing with a clip mask involves calculating the 62 /* Drawing with a clip mask involves calculating the
@@ -113,4 +114,4 @@ public final class EmacsFillRectangle
113 114
114 drawable.damageRect (rect); 115 drawable.damageRect (rect);
115 } 116 }
116} 117};
diff --git a/java/org/gnu/emacs/EmacsGC.java b/java/org/gnu/emacs/EmacsGC.java
index e45f0666fe2..96df0c61ca6 100644
--- a/java/org/gnu/emacs/EmacsGC.java
+++ b/java/org/gnu/emacs/EmacsGC.java
@@ -22,10 +22,19 @@ package org.gnu.emacs;
22import android.graphics.Rect; 22import android.graphics.Rect;
23import android.graphics.Paint; 23import android.graphics.Paint;
24 24
25import android.graphics.Bitmap;
26import android.graphics.Canvas;
27import android.graphics.ColorFilter;
25import android.graphics.PorterDuff.Mode; 28import android.graphics.PorterDuff.Mode;
29import android.graphics.PorterDuffColorFilter;
26import android.graphics.PorterDuffXfermode; 30import android.graphics.PorterDuffXfermode;
31import android.graphics.Shader.TileMode;
27import android.graphics.Xfermode; 32import android.graphics.Xfermode;
28 33
34import android.graphics.drawable.BitmapDrawable;
35
36import android.os.Build;
37
29/* X like graphics context structures. Keep the enums in synch with 38/* X like graphics context structures. Keep the enums in synch with
30 androidgui.h! */ 39 androidgui.h! */
31 40
@@ -47,6 +56,9 @@ public final class EmacsGC extends EmacsHandleObject
47 public EmacsPixmap clip_mask, stipple; 56 public EmacsPixmap clip_mask, stipple;
48 public Paint gcPaint; 57 public Paint gcPaint;
49 58
59 /* Drawable object for rendering the stiple bitmap. */
60 public BitmapDrawable tileObject;
61
50 /* ID incremented every time the clipping rectangles of any GC 62 /* ID incremented every time the clipping rectangles of any GC
51 changes. */ 63 changes. */
52 private static long clip_serial; 64 private static long clip_serial;
@@ -86,6 +98,7 @@ public final class EmacsGC extends EmacsHandleObject
86 markDirty (boolean clipRectsChanged) 98 markDirty (boolean clipRectsChanged)
87 { 99 {
88 int i; 100 int i;
101 Bitmap stippleBitmap;
89 102
90 if (clipRectsChanged) 103 if (clipRectsChanged)
91 { 104 {
@@ -110,12 +123,85 @@ public final class EmacsGC extends EmacsHandleObject
110 gcPaint.setColor (foreground | 0xff000000); 123 gcPaint.setColor (foreground | 0xff000000);
111 gcPaint.setXfermode (function == GC_XOR 124 gcPaint.setXfermode (function == GC_XOR
112 ? xorAlu : srcInAlu); 125 ? xorAlu : srcInAlu);
126
127 /* Update the stipple object with the new stipple bitmap, or delete
128 it if the stipple has been cleared on systems too old to support
129 modifying such objects. */
130
131 if (stipple != null)
132 {
133 stippleBitmap = stipple.getBitmap ();
134
135 /* Allocate a new tile object if none is already present or it
136 cannot be reconfigured. */
137 if ((tileObject == null)
138 || (Build.VERSION.SDK_INT < Build.VERSION_CODES.S))
139 {
140 tileObject = new BitmapDrawable (EmacsService.resources,
141 stippleBitmap);
142 tileObject.setTileModeXY (TileMode.MIRROR, TileMode.MIRROR);
143 }
144 else
145 /* Otherwise, update the existing tile object with the new
146 bitmap. */
147 tileObject.setBitmap (stippleBitmap);
148 }
149 else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
150 && tileObject != null)
151 tileObject.setBitmap (null);
152 else if (tileObject != null)
153 tileObject = null;
113 } 154 }
114 155
115 public void 156 /* Prepare the tile object to draw a stippled image onto a section of
116 resetXfermode () 157 a drawable defined by RECT. It is an error to call this function
158 unless the `stipple' field of the GContext is set. */
159
160 private void
161 prepareStipple (Rect rect)
117 { 162 {
118 gcPaint.setXfermode (function == GC_XOR 163 int sx, sy; /* Stipple origin. */
119 ? xorAlu : srcInAlu); 164 int bw, bh; /* Stipple size. */
165 Bitmap bitmap;
166 Rect boundsRect;
167
168 /* Retrieve the dimensions of the stipple bitmap, which doubles as
169 the unit of advance for this stipple. */
170 bitmap = tileObject.getBitmap ();
171 bw = bitmap.getWidth ();
172 bh = bitmap.getHeight ();
173
174 /* Align the lower left corner of the bounds rectangle to the
175 initial position of the stipple. */
176 sx = (rect.left % bw) * -1 + (-ts_origin_x % bw) * -1;
177 sy = (rect.top % bh) * -1 + (-ts_origin_y % bh) * -1;
178 boundsRect = new Rect (rect.left + sx, rect.top + sy,
179 rect.right, rect.bottom);
180 tileObject.setBounds (boundsRect);
181 }
182
183 /* Fill the rectangle BOUNDS in the provided CANVAS with the stipple
184 pattern defined for this GContext, in the foreground color where
185 the pattern is on, and in the background color where off. */
186
187 protected void
188 blitOpaqueStipple (Canvas canvas, Rect rect)
189 {
190 ColorFilter filter;
191
192 prepareStipple (rect);
193 filter = new PorterDuffColorFilter (foreground | 0xff000000,
194 Mode.SRC_IN);
195 tileObject.setColorFilter (filter);
196
197 canvas.save ();
198 canvas.clipRect (rect);
199
200 tileObject.draw (canvas);
201 filter = new PorterDuffColorFilter (background | 0xff000000,
202 Mode.SRC_OUT);
203 tileObject.setColorFilter (filter);
204 tileObject.draw (canvas);
205 canvas.restore ();
120 } 206 }
121}; 207};
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java
index 2d4079c11b0..8e459ce4cdc 100644
--- a/java/org/gnu/emacs/EmacsService.java
+++ b/java/org/gnu/emacs/EmacsService.java
@@ -64,6 +64,7 @@ import android.content.pm.PackageManager;
64 64
65import android.content.res.AssetManager; 65import android.content.res.AssetManager;
66import android.content.res.Configuration; 66import android.content.res.Configuration;
67import android.content.res.Resources;
67 68
68import android.hardware.input.InputManager; 69import android.hardware.input.InputManager;
69 70
@@ -146,6 +147,9 @@ public final class EmacsService extends Service
146 thread. */ 147 thread. */
147 private Thread mainThread; 148 private Thread mainThread;
148 149
150 /* "Resources" object required by GContext bookkeeping. */
151 public static Resources resources;
152
149 static 153 static
150 { 154 {
151 servicingQuery = new AtomicInteger (); 155 servicingQuery = new AtomicInteger ();
@@ -238,10 +242,11 @@ public final class EmacsService extends Service
238 super.onCreate (); 242 super.onCreate ();
239 243
240 SERVICE = this; 244 SERVICE = this;
245 resources = getResources ();
241 handler = new Handler (Looper.getMainLooper ()); 246 handler = new Handler (Looper.getMainLooper ());
242 manager = getAssets (); 247 manager = getAssets ();
243 app_context = getApplicationContext (); 248 app_context = getApplicationContext ();
244 metrics = getResources ().getDisplayMetrics (); 249 metrics = resources.getDisplayMetrics ();
245 pixelDensityX = metrics.xdpi; 250 pixelDensityX = metrics.xdpi;
246 pixelDensityY = metrics.ydpi; 251 pixelDensityY = metrics.ydpi;
247 tempScaledDensity = ((getScaledDensity (metrics) 252 tempScaledDensity = ((getScaledDensity (metrics)