/**
  * When the ERASE or SMUDGE tools are used and the mouse jumps from (x1,y1) to (x2,y2), the tool
  * has to be applied to a line of pixel positions between the two points in order to cover the
  * entire line that the mouse moves along. The change is made to the off-screen canvas, and
  * repaint() is called to copy the changes to the screen.
  */
 void applyToolAlongLine(int x1, int y1, int x2, int y2) {
   Graphics g = OSC.getGraphics();
   g.setColor(fillColor); // (for ERASE only)
   int w = OSC.getWidth(); // (for SMUDGE only)
   int h = OSC.getHeight(); // (for SMUDGE only)
   int dist = Math.max(Math.abs(x2 - x1), Math.abs(y2 - y1));
   // dist is the number of points along the line from
   // (x1,y1) to (x2,y2) at which the tool will be applied.
   double dx = (double) (x2 - x1) / dist;
   double dy = (double) (y2 - y1) / dist;
   for (int d = 1; d <= dist; d++) {
     // Apply the tool at one of the points (x,y) along the
     // line from (x1,y1) to (x2,y2).
     int x = (int) Math.round(x1 + dx * d);
     int y = (int) Math.round(y1 + dy * d);
     if (currentTool == Tool.ERASE) {
       // Erase a 10-by-10 block of pixels around (x,y)
       g.fillRect(x - 5, y - 5, 10, 10);
       repaint(x - 5, y - 5, 10, 10);
     } else {
       // For the SMUDGE tool, blend some of the color from
       // the smudgeRed, smudgeGreen, and smudgeBlue arrays
       // into the pixels in a 7-by-7 block around (x,y), and
       // vice versa.  The effect is to smear out the color
       // of pixels that are visited by the tool.
       for (int i = 0; i < 7; i++) {
         for (int j = 0; j < 7; j++) {
           int r = y + j - 3;
           int c = x + i - 3;
           if (!(r < 0 || r >= h || c < 0 || c >= w || smudgeRed[i][j] == -1)) {
             int curCol = OSC.getRGB(c, r);
             int curRed = (curCol >> 16) & 0xFF;
             int curGreen = (curCol >> 8) & 0xFF;
             int curBlue = curCol & 0xFF;
             int newRed = (int) (curRed * 0.7 + smudgeRed[i][j] * 0.3);
             int newGreen = (int) (curGreen * 0.7 + smudgeGreen[i][j] * 0.3);
             int newBlue = (int) (curBlue * 0.7 + smudgeBlue[i][j] * 0.3);
             int newCol = newRed << 16 | newGreen << 8 | newBlue;
             OSC.setRGB(c, r, newCol);
             smudgeRed[i][j] = curRed * 0.3 + smudgeRed[i][j] * 0.7;
             smudgeGreen[i][j] = curGreen * 0.3 + smudgeGreen[i][j] * 0.7;
             smudgeBlue[i][j] = curBlue * 0.3 + smudgeBlue[i][j] * 0.7;
           }
         }
       }
       repaint(x - 3, y - 3, 7, 7);
     }
   }
   g.dispose();
 }