root/java/org/gnu/emacs/EmacsDrawRectangle.java

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. perform

     1 /* Communication module for Android terminals.  -*- c-file-style: "GNU" -*-
     2 
     3 Copyright (C) 2023 Free Software Foundation, Inc.
     4 
     5 This file is part of GNU Emacs.
     6 
     7 GNU Emacs is free software: you can redistribute it and/or modify
     8 it under the terms of the GNU General Public License as published by
     9 the Free Software Foundation, either version 3 of the License, or (at
    10 your option) any later version.
    11 
    12 GNU Emacs is distributed in the hope that it will be useful,
    13 but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 GNU General Public License for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    19 
    20 package org.gnu.emacs;
    21 
    22 import android.graphics.Bitmap;
    23 import android.graphics.Canvas;
    24 import android.graphics.Paint;
    25 import android.graphics.Rect;
    26 import android.graphics.RectF;
    27 
    28 import android.util.Log;
    29 
    30 public final class EmacsDrawRectangle
    31 {
    32   public static void
    33   perform (EmacsDrawable drawable, EmacsGC gc,
    34            int x, int y, int width, int height)
    35   {
    36     Paint maskPaint, paint;
    37     Canvas maskCanvas;
    38     Bitmap maskBitmap;
    39     Rect maskRect, dstRect;
    40     Canvas canvas;
    41     Bitmap clipBitmap;
    42 
    43     /* TODO implement stippling.  */
    44     if (gc.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED)
    45       return;
    46 
    47     canvas = drawable.lockCanvas (gc);
    48 
    49     if (canvas == null)
    50       return;
    51 
    52     paint = gc.gcPaint;
    53     paint.setStyle (Paint.Style.STROKE);
    54 
    55     if (gc.clip_mask == null)
    56       /* Use canvas.drawRect with a RectF.  That seems to reliably
    57          get PostScript behavior.  */
    58       canvas.drawRect (new RectF (x + 0.5f, y + 0.5f,
    59                                   x + width + 0.5f,
    60                                   y + height + 0.5f),
    61                        paint);
    62     else
    63       {
    64         /* Drawing with a clip mask involves calculating the
    65            intersection of the clip mask with the dst rect, and
    66            extrapolating the corresponding part of the src rect.  */
    67         clipBitmap = gc.clip_mask.bitmap;
    68         dstRect = new Rect (x, y, x + width, y + height);
    69         maskRect = new Rect (gc.clip_x_origin,
    70                              gc.clip_y_origin,
    71                              (gc.clip_x_origin
    72                               + clipBitmap.getWidth ()),
    73                              (gc.clip_y_origin
    74                               + clipBitmap.getHeight ()));
    75 
    76         if (!maskRect.setIntersect (dstRect, maskRect))
    77           /* There is no intersection between the clip mask and the
    78              dest rect.  */
    79           return;
    80 
    81         /* Finally, create a temporary bitmap that is the size of
    82            maskRect.  */
    83 
    84         maskBitmap
    85           = Bitmap.createBitmap (maskRect.width (), maskRect.height (),
    86                                  Bitmap.Config.ARGB_8888);
    87 
    88         /* Draw the mask onto the maskBitmap.  */
    89         maskCanvas = new Canvas (maskBitmap);
    90         maskRect.offset (-gc.clip_x_origin,
    91                          -gc.clip_y_origin);
    92         maskCanvas.drawBitmap (gc.clip_mask.bitmap,
    93                                maskRect, new Rect (0, 0,
    94                                                    maskRect.width (),
    95                                                    maskRect.height ()),
    96                                paint);
    97         maskRect.offset (gc.clip_x_origin,
    98                          gc.clip_y_origin);
    99 
   100         /* Set the transfer mode to SRC_IN to preserve only the parts
   101            of the source that overlap with the mask.  */
   102         maskPaint = new Paint ();
   103         maskPaint.setXfermode (EmacsGC.srcInAlu);
   104         maskPaint.setStyle (Paint.Style.STROKE);
   105 
   106         /* Draw the source.  */
   107         maskCanvas.drawRect (maskRect, maskPaint);
   108 
   109         /* Finally, draw the mask bitmap to the destination.  */
   110         paint.setXfermode (null);
   111         canvas.drawBitmap (maskBitmap, null, maskRect, paint);
   112 
   113         /* Recycle this unused bitmap.  */
   114         maskBitmap.recycle ();
   115       }
   116 
   117     drawable.damageRect (new Rect (x, y, x + width + 1,
   118                                    y + height + 1));
   119   }
   120 }

/* [<][>][^][v][top][bottom][index][help] */