aboutsummaryrefslogtreecommitdiffstats
path: root/java/org
diff options
context:
space:
mode:
authorPo Lu2024-04-28 16:58:58 +0800
committerPo Lu2024-04-28 17:00:43 +0800
commite658a6938e3b7a8a7c0be8b74fbd885787c26df6 (patch)
tree9da9dec34bfd979ad7d09b4cdd6997ea0480f048 /java/org
parentb329358334712671de38f919c99d1434026aa8f2 (diff)
downloademacs-e658a6938e3b7a8a7c0be8b74fbd885787c26df6.tar.gz
emacs-e658a6938e3b7a8a7c0be8b74fbd885787c26df6.zip
Implement dots and dashes on Android
* java/org/gnu/emacs/EmacsDrawLine.java (EmacsDrawLine) (measureLine, polyDashPattern): New function. (perform): Delegate to polyDashPattern if the line style is not LineSolid. Also simplify now that anti-aliasing need no longer be taken into account. * java/org/gnu/emacs/EmacsDrawRectangle.java (perform): Mention omission in commentary. * java/org/gnu/emacs/EmacsGC.java (EmacsGC): Disable anti-aliasing in default paint object. <line_style, line>: New fields. (markDirty): Apply stroke width. * src/android.c (android_init_emacs_gc_class): Initialize new fields. (android_create_gc, android_free_gc, android_change_gc) (android_set_dashes, android_get_gc_values): * src/androidgui.h (enum android_line_style) (enum android_gc_value_mask, struct android_gc): Introduce line style, width, dash offset and dash GC attributes. * src/androidterm.c (android_draw_dash, android_fill_underline) (android_draw_glyph_string): Port from X. * src/xterm.c (x_draw_dash): Delete redundant code.
Diffstat (limited to 'java/org')
-rw-r--r--java/org/gnu/emacs/EmacsDrawLine.java109
-rw-r--r--java/org/gnu/emacs/EmacsDrawRectangle.java3
-rw-r--r--java/org/gnu/emacs/EmacsGC.java12
3 files changed, 113 insertions, 11 deletions
diff --git a/java/org/gnu/emacs/EmacsDrawLine.java b/java/org/gnu/emacs/EmacsDrawLine.java
index 61b7d54d63c..a49fe96c26e 100644
--- a/java/org/gnu/emacs/EmacsDrawLine.java
+++ b/java/org/gnu/emacs/EmacsDrawLine.java
@@ -25,6 +25,97 @@ import android.graphics.Rect;
25 25
26public final class EmacsDrawLine 26public final class EmacsDrawLine
27{ 27{
28 /* Return the normalized slope and magnitude of a line whose extrema
29 are DX and DY removed, on the X and Y axes respectively, from its
30 origin point. */
31
32 private static float[]
33 measureLine (float dx, float dy)
34 {
35 float hypot;
36
37 if (dx == 0f && dy == 0f)
38 return new float[] { 0f, 0f, 0f, };
39
40 if (dx == 0f)
41 return new float[] { 0f, dy > 0f ? 1f : -1f, Math.abs (dy), };
42 else if (dy == 0f)
43 return new float[] { dx > 0f ? 1f : -1f, 0f, Math.abs (dx), };
44 else
45 {
46 hypot = (float) Math.hypot (dx, dy);
47 return new float[] { dx / hypot, dy / hypot, hypot, };
48 }
49 }
50
51 private static void
52 polyDashPattern (EmacsGC gc, Canvas canvas, Paint paint, float x0,
53 float y0, float x1, float y1)
54 {
55 int patternTotal, i, offset;
56 float dx, dy, mag, dash_mag, rem, lx1, ly1;
57 float[] measured;
58 boolean which;
59
60 /* Compute the total length of this pattern. */
61 patternTotal = 0;
62 for (i = 0; i < gc.dashes.length; ++i)
63 patternTotal += gc.dashes[i];
64 if ((gc.dashes.length & 1) != 0)
65 patternTotal += patternTotal;
66
67 /* Subtract as much of the offset as does not contribute to the
68 phase at the first pixel of the line. */
69 offset = gc.dash_offset % patternTotal;
70
71 /* Set I to the first dash that ought to be drawn and WHICH to its
72 phase. */
73 i = 0;
74 which = true;
75 while (offset >= gc.dashes[i])
76 {
77 offset -= gc.dashes[i++];
78 if (i >= gc.dashes.length)
79 i = 0;
80 which = !which;
81 }
82
83 /* Compute the length of the first visible segment. */
84 dash_mag = gc.dashes[i] - offset;
85
86 /* Compute the slope of the line. */
87 dx = x1 - x0;
88 dy = y1 - y0;
89 measured = measureLine (dx, dy);
90 dx = measured[0];
91 dy = measured[1];
92 rem = mag = measured[2];
93 lx1 = x0;
94 ly1 = y0;
95
96 while (rem > 0f)
97 {
98 dash_mag = Math.min (dash_mag, rem);
99 rem -= dash_mag;
100
101 /* End of this segment. */
102 x1 = (mag - rem) * dx + x0;
103 y1 = (mag - rem) * dy + y0;
104
105 if (which)
106 canvas.drawLine (lx1, ly1, x1, y1, paint);
107 which = !which;
108
109 /* Start of the next segment. */
110 lx1 = x1;
111 ly1 = y1;
112 i++;
113 if (i >= gc.dashes.length)
114 i = 0;
115 dash_mag = gc.dashes[i];
116 }
117 }
118
28 public static void 119 public static void
29 perform (EmacsDrawable drawable, EmacsGC gc, 120 perform (EmacsDrawable drawable, EmacsGC gc,
30 int x, int y, int x2, int y2) 121 int x, int y, int x2, int y2)
@@ -52,22 +143,20 @@ public final class EmacsDrawLine
52 if (canvas == null) 143 if (canvas == null)
53 return; 144 return;
54 145
55 paint.setStyle (Paint.Style.FILL);
56
57 /* Since drawLine has PostScript style behavior, adjust the 146 /* Since drawLine has PostScript style behavior, adjust the
58 coordinates appropriately. 147 coordinates appropriately.
59 148
60 The left most pixel of a straight line is always partially 149 The leftmost pixel of a straight line is always partially filled.
61 filled. Patch it in manually. */ 150 Patch it in manually. */
62 151
63 if (gc.clip_mask == null) 152 if (gc.clip_mask == null)
64 { 153 {
65 canvas.drawLine ((float) x + 0.5f, (float) y + 0.5f, 154 if (gc.line_style != EmacsGC.GC_LINE_ON_OFF_DASH)
66 (float) x2 + 0.5f, (float) y2 + 0.5f, 155 canvas.drawLine ((float) x, (float) y, (float) x2, (float) y2,
67 paint); 156 paint);
68 157 else
69 if (x2 > x) 158 polyDashPattern (gc, canvas, paint, (float) x, (float) y,
70 canvas.drawRect (new Rect (x, y, x + 1, y + 1), paint); 159 (float) x2, (float) y2);
71 } 160 }
72 161
73 /* DrawLine with clip mask not implemented; it is not used by 162 /* DrawLine with clip mask not implemented; it is not used by
diff --git a/java/org/gnu/emacs/EmacsDrawRectangle.java b/java/org/gnu/emacs/EmacsDrawRectangle.java
index a8f68c6530a..e40a7c16068 100644
--- a/java/org/gnu/emacs/EmacsDrawRectangle.java
+++ b/java/org/gnu/emacs/EmacsDrawRectangle.java
@@ -52,6 +52,9 @@ public final class EmacsDrawRectangle
52 paint = gc.gcPaint; 52 paint = gc.gcPaint;
53 paint.setStyle (Paint.Style.STROKE); 53 paint.setStyle (Paint.Style.STROKE);
54 54
55 /* This graphics request, in contrast to X, does not presently
56 respect the GC's line style. */
57
55 if (gc.clip_mask == null) 58 if (gc.clip_mask == null)
56 /* Use canvas.drawRect with a RectF. That seems to reliably 59 /* Use canvas.drawRect with a RectF. That seems to reliably
57 get PostScript behavior. */ 60 get PostScript behavior. */
diff --git a/java/org/gnu/emacs/EmacsGC.java b/java/org/gnu/emacs/EmacsGC.java
index b2474c5bd76..ec2b9c9e475 100644
--- a/java/org/gnu/emacs/EmacsGC.java
+++ b/java/org/gnu/emacs/EmacsGC.java
@@ -46,12 +46,17 @@ public final class EmacsGC extends EmacsHandleObject
46 public static final int GC_FILL_SOLID = 0; 46 public static final int GC_FILL_SOLID = 0;
47 public static final int GC_FILL_OPAQUE_STIPPLED = 1; 47 public static final int GC_FILL_OPAQUE_STIPPLED = 1;
48 48
49 public static final int GC_LINE_SOLID = 0;
50 public static final int GC_LINE_ON_OFF_DASH = 1;
51
49 public static final Xfermode xorAlu, srcInAlu; 52 public static final Xfermode xorAlu, srcInAlu;
50 53
51 public int function, fill_style; 54 public int function, fill_style;
52 public int foreground, background; 55 public int foreground, background;
53 public int clip_x_origin, clip_y_origin; 56 public int clip_x_origin, clip_y_origin;
54 public int ts_origin_x, ts_origin_y; 57 public int ts_origin_x, ts_origin_y;
58 public int line_style, line_width;
59 public int dashes[], dash_offset;
55 public Rect clip_rects[], real_clip_rects[]; 60 public Rect clip_rects[], real_clip_rects[];
56 public EmacsPixmap clip_mask, stipple; 61 public EmacsPixmap clip_mask, stipple;
57 public Paint gcPaint; 62 public Paint gcPaint;
@@ -89,6 +94,10 @@ public final class EmacsGC extends EmacsHandleObject
89 foreground = 0; 94 foreground = 0;
90 background = 0xffffff; 95 background = 0xffffff;
91 gcPaint = new Paint (); 96 gcPaint = new Paint ();
97
98 /* Android S and above enable anti-aliasing unless explicitly told
99 otherwise. */
100 gcPaint.setAntiAlias (false);
92 } 101 }
93 102
94 /* Mark this GC as dirty. Apply parameters to the paint and 103 /* Mark this GC as dirty. Apply parameters to the paint and
@@ -119,7 +128,8 @@ public final class EmacsGC extends EmacsHandleObject
119 clipRectID = ++clip_serial; 128 clipRectID = ++clip_serial;
120 } 129 }
121 130
122 gcPaint.setStrokeWidth (1f); 131 /* A line_width of 0 is equivalent to that of 1. */
132 gcPaint.setStrokeWidth (line_width < 1 ? 1 : line_width);
123 gcPaint.setColor (foreground | 0xff000000); 133 gcPaint.setColor (foreground | 0xff000000);
124 gcPaint.setXfermode (function == GC_XOR 134 gcPaint.setXfermode (function == GC_XOR
125 ? xorAlu : srcInAlu); 135 ? xorAlu : srcInAlu);