diff options
Diffstat (limited to 'java/org/gnu/emacs/EmacsFillPolygon.java')
| -rw-r--r-- | java/org/gnu/emacs/EmacsFillPolygon.java | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/java/org/gnu/emacs/EmacsFillPolygon.java b/java/org/gnu/emacs/EmacsFillPolygon.java new file mode 100644 index 00000000000..3198c7f07c4 --- /dev/null +++ b/java/org/gnu/emacs/EmacsFillPolygon.java @@ -0,0 +1,150 @@ +/* Communication module for Android terminals. -*- c-file-style: "GNU" -*- + +Copyright (C) 2023 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ + +package org.gnu.emacs; + +import java.lang.Math; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Point; +import android.graphics.PorterDuff.Mode; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Xfermode; + +public class EmacsFillPolygon implements EmacsPaintReq +{ + private EmacsDrawable drawable; + private EmacsGC immutableGC; + private Path path; + + private static Xfermode xorAlu, srcInAlu; + + static + { + xorAlu = new PorterDuffXfermode (Mode.XOR); + srcInAlu = new PorterDuffXfermode (Mode.SRC_IN); + }; + + public + EmacsFillPolygon (EmacsDrawable drawable, Point points[], + EmacsGC immutableGC) + { + int i; + + this.drawable = drawable; + this.immutableGC = immutableGC; + + /* Build the path from the given array of points. */ + path = new Path (); + + if (points.length >= 1) + { + path.moveTo (points[0].x, points[0].y); + + for (i = 1; i < points.length; ++i) + path.lineTo (points[i].x, points[i].y); + + path.close (); + } + } + + @Override + public Rect + getRect () + { + RectF rect; + + rect = new RectF (0, 0, 0, 0); + path.computeBounds (rect, true); + + return new Rect ((int) Math.floor (rect.left), + (int) Math.floor (rect.top), + (int) Math.ceil (rect.right), + (int) Math.ceil (rect.bottom)); + } + + @Override + public EmacsDrawable + getDrawable () + { + return drawable; + } + + @Override + public EmacsGC + getGC () + { + return immutableGC; + } + + @Override + public void + paintTo (Canvas canvas, Paint paint, EmacsGC immutableGC) + { + int alu; + Paint maskPaint; + Canvas maskCanvas; + Bitmap maskBitmap; + Rect rect; + + /* TODO implement stippling. */ + if (immutableGC.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED) + return; + + alu = immutableGC.function; + rect = getRect (); + + if (alu == EmacsGC.GC_COPY) + paint.setXfermode (null); + else + paint.setXfermode (xorAlu); + + paint.setStyle (Paint.Style.FILL); + + if (immutableGC.clip_mask == null) + { + paint.setColor (immutableGC.foreground | 0xff000000); + canvas.drawPath (path, paint); + } + else + { + maskPaint = new Paint (); + maskBitmap = immutableGC.clip_mask.bitmap; + maskBitmap = maskBitmap.copy (Bitmap.Config.ARGB_8888, + true); + + if (maskBitmap == null) + return; + + maskPaint.setXfermode (srcInAlu); + maskPaint.setColor (immutableGC.foreground | 0xff000000); + maskCanvas = new Canvas (maskBitmap); + path.offset (-rect.left, -rect.top, null); + maskCanvas.drawPath (path, maskPaint); + canvas.drawBitmap (maskBitmap, new Rect (0, 0, rect.width (), + rect.height ()), + rect, paint); + } + } +} |
