예제 #1
0
  /**
   * This implementation calls <code>super.hitTest</code> and returns the result if non-null (this
   * should be a HitInfo.Point), then returns a HitInfo.Interior if the mouse-click occured inside
   * the text bound (as defined by text layout)
   *
   * @return a HitInfo corresponding to the given mouse-event
   */
  public HitInfo hitTest(PEMouseEvent e) {

    // from Bitmap:
    if (image != null) {
      if (getBounds().contains(e.getPicPoint())) {
        return new HitInfo.Interior((PicText) element, e);
      }
      return null;
    }

    // from TextLayout:
    if (!getBounds().contains(e.getPicPoint())) return null;

    PicText te = (PicText) element;
    // recompute textlayout b-box, but store it in a temporary field !
    Rectangle2D tb = textLayout.getBounds();
    Shape text_bounds = text2ModelTr.createTransformedShape(tb);
    if (text_bounds.contains(e.getPicPoint())) {
      // [SR:pending] for the hitInfo to be reliable, getPicPoint() should first be transformed by
      //              inverse text2ModelTr ! (especially when rotationAngle != 0)
      TextHitInfo thi =
          textLayout.hitTestChar(
              (float) (e.getPicPoint().x - strx),
              (float) (e.getPicPoint().y - stry)); // guaranteed to return a non-null thi
      return new HitInfo.Text((PicText) element, thi, e);
    }
    // test hit on textlayout's bounding rectangle :
    // else if (bounds.contains(e.getPicPoint())) return new HitInfo.Interior(element,e);
    return null;
  }
 /**
  * Rebuilds the template from an input image. The input image dimensions must match the original.
  * The input and original are overlaid onto the existing template, if any. Pixels that fall
  * outside the mask are ignored in the final template.
  *
  * @param image the input image
  * @param alphaInput the opacity with which the input image is overlaid
  * @param alphaOriginal the opacity with which the original image is overlaid
  */
 public void rebuildTemplate(BufferedImage image, int alphaInput, int alphaOriginal) {
   int w = image.getWidth();
   int h = image.getHeight();
   // return if image dimensions do not match original image
   if (original.getWidth() != w || original.getHeight() != h) return;
   // return if both alphas are zero
   if (alphaInput == 0 && alphaOriginal == 0) return;
   // draw image onto argb input
   BufferedImage input = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
   input.createGraphics().drawImage(image, 0, 0, null);
   // create working image if needed
   if (working == null) {
     working = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
   }
   // reset template dimensions and create new template if needed
   if (template == null || w != wTemplate || h != hTemplate) {
     wTemplate = w;
     hTemplate = h;
     int len = w * h;
     template = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
     pixels = new int[len];
     templateR = new int[len];
     templateG = new int[len];
     templateB = new int[len];
     isPixelTransparent = new boolean[len];
   }
   // set alpha of input and draw onto working
   Graphics2D gWorking = working.createGraphics();
   alphaInput = Math.max(0, Math.min(255, alphaInput));
   if (alphaInput > 0) { // overlay only if not transparent
     gWorking.setComposite(getComposite(alphaInput));
     input.getRaster().getDataElements(0, 0, w, h, pixels);
     gWorking.drawImage(input, 0, 0, null);
   }
   // set alpha of original and draw onto working
   alphaOriginal = Math.max(0, Math.min(255, alphaOriginal));
   if (alphaOriginal > 0) { // overlay only if not transparent
     gWorking.setComposite(getComposite(alphaOriginal));
     original.getRaster().getDataElements(0, 0, w, h, pixels);
     gWorking.drawImage(original, 0, 0, null);
   }
   // read pixels from working raster
   working.getRaster().getDataElements(0, 0, wTemplate, hTemplate, pixels);
   if (mask != null) {
     // set pixels outside mask to transparent
     for (int i = 0; i < pixels.length; i++) {
       boolean inside = true;
       // pixel is inside only if all corners are inside
       int x = i % wTemplate, y = i / wTemplate;
       for (int j = 0; j < 2; j++) {
         for (int k = 0; k < 2; k++) {
           p.setLocation(x + j, y + k);
           inside = inside && mask.contains(p);
         }
       }
       if (!inside) pixels[i] = pixels[i] & (0 << 24); // set alpha to zero (transparent)
     }
   }
   // write pixels to template raster
   template.getRaster().setDataElements(0, 0, wTemplate, hTemplate, pixels);
   // trim transparent edges from template
   int trimRight = 0, trimBottom = 0;
   trimLeft = trimTop = 0;
   // left edge
   boolean transparentEdge = true;
   while (transparentEdge && trimLeft < wTemplate) {
     for (int line = 0; line < hTemplate; line++) {
       int i = line * wTemplate + trimLeft;
       transparentEdge = transparentEdge && getAlpha(pixels[i]) == 0;
     }
     if (transparentEdge) trimLeft++;
   }
   // right edge
   transparentEdge = true;
   while (transparentEdge && (trimLeft + trimRight) < wTemplate) {
     for (int line = 0; line < hTemplate; line++) {
       int i = (line + 1) * wTemplate - 1 - trimRight;
       transparentEdge = transparentEdge && getAlpha(pixels[i]) == 0;
     }
     if (transparentEdge) trimRight++;
   }
   // top edge
   transparentEdge = true;
   while (transparentEdge && trimTop < hTemplate) {
     for (int col = 0; col < wTemplate; col++) {
       int i = trimTop * wTemplate + col;
       transparentEdge = transparentEdge && getAlpha(pixels[i]) == 0;
     }
     if (transparentEdge) trimTop++;
   }
   // bottom edge
   transparentEdge = true;
   while (transparentEdge && (trimTop + trimBottom) < hTemplate) {
     for (int col = 0; col < wTemplate; col++) {
       int i = (hTemplate - 1 - trimBottom) * wTemplate + col;
       transparentEdge = transparentEdge && getAlpha(pixels[i]) == 0;
     }
     if (transparentEdge) trimBottom++;
   }
   // reduce size of template if needed
   if (trimLeft + trimRight + trimTop + trimBottom > 0) {
     wTemplate -= (trimLeft + trimRight);
     hTemplate -= (trimTop + trimBottom);
     pixels = new int[wTemplate * hTemplate];
     templateR = new int[wTemplate * hTemplate];
     templateG = new int[wTemplate * hTemplate];
     templateB = new int[wTemplate * hTemplate];
     isPixelTransparent = new boolean[wTemplate * hTemplate];
     BufferedImage bi = new BufferedImage(wTemplate, hTemplate, BufferedImage.TYPE_INT_ARGB);
     bi.createGraphics().drawImage(template, -trimLeft, -trimTop, null);
     template = bi;
     template.getRaster().getDataElements(0, 0, wTemplate, hTemplate, pixels);
   }
   // set up rgb and transparency arrays for faster matching
   for (int i = 0; i < pixels.length; i++) {
     int val = pixels[i];
     templateR[i] = getRed(val); // red
     templateG[i] = getGreen(val); // green
     templateB[i] = getBlue(val); // blue
     isPixelTransparent[i] = getAlpha(val) == 0; // alpha
   }
 }