TexturePaintContext(ColorModel cm, AffineTransform xform, int bWidth, int bHeight, int maxw) {
    this.colorModel = getInternedColorModel(cm);
    this.bWidth = bWidth;
    this.bHeight = bHeight;
    this.maxWidth = maxw;

    try {
      xform = xform.createInverse();
    } catch (NoninvertibleTransformException e) {
      xform.setToScale(0, 0);
    }
    this.incXAcross = mod(xform.getScaleX(), bWidth);
    this.incYAcross = mod(xform.getShearY(), bHeight);
    this.incXDown = mod(xform.getShearX(), bWidth);
    this.incYDown = mod(xform.getScaleY(), bHeight);
    this.xOrg = xform.getTranslateX();
    this.yOrg = xform.getTranslateY();
    this.colincx = (int) incXAcross;
    this.colincy = (int) incYAcross;
    this.colincxerr = fractAsInt(incXAcross);
    this.colincyerr = fractAsInt(incYAcross);
    this.rowincx = (int) incXDown;
    this.rowincy = (int) incYDown;
    this.rowincxerr = fractAsInt(incXDown);
    this.rowincyerr = fractAsInt(incYDown);
  }
Ejemplo n.º 2
0
  public AffineRed(CachableRed src, AffineTransform src2me, RenderingHints hints) {
    super(); // We _must_ call init...

    this.src2me = src2me;
    this.hints = hints;

    try {
      me2src = src2me.createInverse();
    } catch (NoninvertibleTransformException nite) {
      me2src = null;
    }

    // Calculate my bounds by applying the affine transform to
    // my input data..codec/
    Rectangle srcBounds = src.getBounds();
    // srcBounds.grow(-1,-1);
    Rectangle myBounds;
    myBounds = src2me.createTransformedShape(srcBounds).getBounds();

    // If the output buffer is not premultiplied in certain cases it
    // fails to properly divide out the Alpha (it always does
    // the affine on premultiplied data), hence you get ugly
    // back aliasing effects...
    ColorModel cm = fixColorModel(src);

    // fix my sample model so it makes sense given my size.
    SampleModel sm = fixSampleModel(src, cm, myBounds);

    Point2D pt = new Point2D.Float(src.getTileGridXOffset(), src.getTileGridYOffset());
    pt = src2me.transform(pt, null);

    // Finish initializing our base class...
    init(src, myBounds, cm, sm, (int) pt.getX(), (int) pt.getY(), null);
  }
Ejemplo n.º 3
0
 /** @see Graphics#getClip() */
 public Shape getClip() {
   try {
     return transform.createInverse().createTransformedShape(clip);
   } catch (NoninvertibleTransformException e) {
     return null;
   }
 }
Ejemplo n.º 4
0
  /**
   * Calculate the affine transforms used to convert between world and pixel coordinates. The
   * calculations here are very basic and assume a cartesian reference system.
   *
   * <p>Tne transform is calculated such that {@code envelope} will be centred in the display
   *
   * @param envelope the current map extent (world coordinates)
   * @param paintArea the current map pane extent (screen units)
   */
  private void setTransforms(final Envelope envelope, final Rectangle paintArea) {
    ReferencedEnvelope refEnv = null;
    if (envelope != null) {
      refEnv = new ReferencedEnvelope(envelope);
    } else {
      refEnv = worldEnvelope();
      // FIXME content.setCoordinateReferenceSystem(DefaultGeographicCRS.WGS84);
    }

    java.awt.Rectangle awtPaintArea = Utils.toAwtRectangle(paintArea);
    double xscale = awtPaintArea.getWidth() / refEnv.getWidth();
    double yscale = awtPaintArea.getHeight() / refEnv.getHeight();

    double scale = Math.min(xscale, yscale);

    double xoff = refEnv.getMedian(0) * scale - awtPaintArea.getCenterX();
    double yoff = refEnv.getMedian(1) * scale + awtPaintArea.getCenterY();

    worldToScreen = new AffineTransform(scale, 0, 0, -scale, -xoff, yoff);
    try {
      screenToWorld = worldToScreen.createInverse();

    } catch (NoninvertibleTransformException ex) {
      ex.printStackTrace();
    }
  }
Ejemplo n.º 5
0
  /**
   * Draw some graphics into an Graphics2D object.
   *
   * @param image the image to draw into
   * @throws NoninvertibleTransformException in transform errors.
   */
  private void draw(Graphics2D gr) throws NoninvertibleTransformException {
    gr.setPaint(Color.WHITE);
    gr.fill(new Rectangle(0, 0, tileWidth, tileHeight));

    // AffineTransform[[0.318755336305853, 0.0, 420.03106689453125],
    //                 [0.0, 0.318755336305853, 245.5029296875]]
    AffineTransform transform =
        new AffineTransform(
            0.318755336305853, 0.0, 0.0, 0.318755336305853, 420.03106689453125, 245.5029296875);
    gr.setTransform(transform);

    Shape s = new Rectangle(0, 0, 96, 83);

    // create an enbedded graphics
    Graphics2D grr = (Graphics2D) gr.create();
    // AffineTransform[[1.0, 0.0, -343.9285583496093],
    //                 [0.0, 1.0, -502.5158386230469]]
    grr.clip(s.getBounds());
    transform = new AffineTransform(1.0, 0.0, 0.0, 1.0, -343.9285583496093, -502.5158386230469);
    grr.transform(transform);

    AffineTransform t = transform.createInverse();
    s = t.createTransformedShape(s);

    assertTrue(s.getBounds().intersects(grr.getClip().getBounds2D()));

    grr.setPaint(Color.BLUE);
    grr.draw(s);

    grr.dispose();
    gr.dispose();
  }
  /**
   * Constructor creates an instance to be used for fill operations.
   *
   * @param shading the shading type to be used
   * @param colorModel the color model to be used
   * @param xform transformation for user to device space
   * @param matrix the pattern matrix concatenated with that of the parent content stream
   * @param deviceBounds the bounds of the area to paint, in device units
   * @throws IOException if there is an error getting the color space or doing color conversion.
   */
  public AxialShadingContext(
      PDShadingType2 shading,
      ColorModel colorModel,
      AffineTransform xform,
      Matrix matrix,
      Rectangle deviceBounds)
      throws IOException {
    super(shading, colorModel, xform, matrix);
    this.axialShadingType = shading;
    coords = shading.getCoords().toFloatArray();

    // domain values
    if (shading.getDomain() != null) {
      domain = shading.getDomain().toFloatArray();
    } else {
      // set default values
      domain = new float[] {0, 1};
    }
    // extend values
    COSArray extendValues = shading.getExtend();
    if (shading.getExtend() != null) {
      extend = new boolean[2];
      extend[0] = ((COSBoolean) extendValues.get(0)).getValue();
      extend[1] = ((COSBoolean) extendValues.get(1)).getValue();
    } else {
      // set default values
      extend = new boolean[] {false, false};
    }
    // calculate some constants to be used in getRaster
    x1x0 = coords[2] - coords[0];
    y1y0 = coords[3] - coords[1];
    d1d0 = domain[1] - domain[0];
    denom = Math.pow(x1x0, 2) + Math.pow(y1y0, 2);

    try {
      // get inverse transform to be independent of current user / device space
      // when handling actual pixels in getRaster()
      rat = matrix.createAffineTransform().createInverse();
      rat.concatenate(xform.createInverse());
    } catch (NoninvertibleTransformException ex) {
      LOG.error(ex, ex);
    }

    // shading space -> device space
    AffineTransform shadingToDevice = (AffineTransform) xform.clone();
    shadingToDevice.concatenate(matrix.createAffineTransform());

    // worst case for the number of steps is opposite diagonal corners, so use that
    double dist =
        Math.sqrt(
            Math.pow(deviceBounds.getMaxX() - deviceBounds.getMinX(), 2)
                + Math.pow(deviceBounds.getMaxY() - deviceBounds.getMinY(), 2));
    factor = (int) Math.ceil(dist);

    // build the color table for the given number of steps
    colorTable = calcColorTable();
  }
 public Frame(Point2D point, Vector2D vec1, Vector2D vec2)
     throws NoninvertibleTransformException {
   toStd_ =
       new AffineTransform(
           vec1.getX(), vec1.getY(), vec2.getX(), vec2.getY(), point.getX(), point.getY());
   fromStd_ = toStd_.createInverse();
   origin_ = (Point2D) point.clone();
   xAxis_ = new Vector2D(vec1);
   yAxis_ = new Vector2D(vec2);
 }
Ejemplo n.º 8
0
  /**
   * Performs a translation using the "Resample" operation.
   *
   * @param grid the {@link GridCoverage2D} to apply the translation on.
   * @throws NoninvertibleTransformException If a "grid to CRS" transform is not invertible.
   */
  private void doTranslation(GridCoverage2D grid) throws NoninvertibleTransformException {
    final int transX = -253;
    final int transY = -456;
    final double scaleX = 0.04;
    final double scaleY = -0.04;
    final ParameterBlock block =
        new ParameterBlock()
            .addSource(grid.getRenderedImage())
            .add((float) transX)
            .add((float) transY);
    RenderedImage image = JAI.create("Translate", block);
    assertEquals("Incorrect X translation", transX, image.getMinX());
    assertEquals("Incorrect Y translation", transY, image.getMinY());

    /*
     * Create a grid coverage from the translated image but with the same envelope.
     * Consequently, the 'gridToCoordinateSystem' should be translated by the same
     * amount, with the opposite sign.
     */
    AffineTransform expected = getAffineTransform(grid);
    assertNotNull(expected);
    expected = new AffineTransform(expected); // Get a mutable instance.
    final GridCoverageFactory factory = CoverageFactoryFinder.getGridCoverageFactory(null);
    grid =
        factory.create(
            "Translated",
            image,
            grid.getEnvelope(),
            grid.getSampleDimensions(),
            new GridCoverage2D[] {grid},
            grid.getProperties());
    expected.translate(-transX, -transY);
    assertTransformEquals(expected, getAffineTransform(grid));

    /*
     * Apply the "Resample" operation with a specific 'gridToCoordinateSystem' transform.
     * The envelope is left unchanged. The "Resample" operation should compute automatically
     * new image bounds.
     */
    final AffineTransform at = AffineTransform.getScaleInstance(scaleX, scaleY);
    final MathTransform tr = ProjectiveTransform.create(at);
    // account for the half pixel correction between the two spaces since we are talking raster here
    // but the resample will talk model!
    final MathTransform correctedTransform =
        PixelTranslation.translate(tr, PixelInCell.CELL_CORNER, PixelInCell.CELL_CENTER);
    final GridGeometry2D geometry = new GridGeometry2D(null, correctedTransform, null);
    final GridCoverage2D newGrid =
        (GridCoverage2D)
            Operations.DEFAULT.resample(grid, grid.getCoordinateReferenceSystem(), geometry, null);
    assertEquals(correctedTransform, getAffineTransform(newGrid));
    image = newGrid.getRenderedImage();
    expected.preConcatenate(at.createInverse());
    final Point point = new Point(transX, transY);
    assertSame(point, expected.transform(point, point)); // Round toward neareast integer
  }
 public Frame() {
   toStd_ = new AffineTransform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
   try {
     fromStd_ = toStd_.createInverse();
   } catch (NoninvertibleTransformException ntex) {
     throw new IllegalStateException();
   }
   origin_ = new Point2D.Double(0.0, 0.0);
   xAxis_ = new Vector2D(1.0, 0.0);
   yAxis_ = new Vector2D(0.0, 1.0);
 }
Ejemplo n.º 10
0
  /** @throws RuntimeException */
  private void calculateAffineTransform() {
    if (extent == null) {
      return;
    } else if (image == null || getWidth() == 0 || getHeight() == 0) {
      return;
    }

    if (adjustExtent) {
      double escalaX = getWidth() / extent.getWidth();
      double escalaY = getHeight() / extent.getHeight();

      double xCenter = extent.getMinX() + extent.getWidth() / 2.0;
      double yCenter = extent.getMinY() + extent.getHeight() / 2.0;
      adjustedExtent = new Envelope();

      double scale;
      if (escalaX < escalaY) {
        scale = escalaX;
        double newHeight = getHeight() / scale;
        double newX = xCenter - (extent.getWidth() / 2.0);
        double newY = yCenter - (newHeight / 2.0);
        adjustedExtent = new Envelope(newX, newX + extent.getWidth(), newY, newY + newHeight);
      } else {
        scale = escalaY;
        double newWidth = getWidth() / scale;
        double newX = xCenter - (newWidth / 2.0);
        double newY = yCenter - (extent.getHeight() / 2.0);
        adjustedExtent = new Envelope(newX, newX + newWidth, newY, newY + extent.getHeight());
      }

      trans.setToIdentity();
      trans.concatenate(AffineTransform.getScaleInstance(scale, -scale));
      trans.concatenate(
          AffineTransform.getTranslateInstance(
              -adjustedExtent.getMinX(), -adjustedExtent.getMinY() - adjustedExtent.getHeight()));
    } else {
      adjustedExtent = new Envelope(extent);
      trans.setToIdentity();
      double scaleX = getWidth() / extent.getWidth();
      double scaleY = getHeight() / extent.getHeight();

      /** Map Y axis grows downward but CRS grows upward => -1 */
      trans.concatenate(AffineTransform.getScaleInstance(scaleX, -scaleY));
      trans.concatenate(
          AffineTransform.getTranslateInstance(
              -extent.getMinX(), -extent.getMinY() - extent.getHeight()));
    }
    try {
      transInv = trans.createInverse();
    } catch (NoninvertibleTransformException ex) {
      transInv = null;
      throw new RuntimeException(ex);
    }
  }
Ejemplo n.º 11
0
 /**
  * Clears any existing transformation and sets the a new one. The default implementation calls
  * writeTransform using the inverted affine transform to calculate it. s *
  *
  * @param transform to be written
  */
 protected void writeSetTransform(AffineTransform transform) throws IOException {
   try {
     AffineTransform deltaTransform = new AffineTransform(transform);
     deltaTransform.concatenate(oldTransform.createInverse());
     writeTransform(deltaTransform);
   } catch (NoninvertibleTransformException e) {
     // ignored...
     System.err.println(
         "Warning: (ignored) Could not invert matrix: " //$NON-NLS-1$
             + oldTransform);
   }
 }
 public Frame(Point2D origin, Point2D ptX, Point2D ptY) throws NoninvertibleTransformException {
   toStd_ =
       new AffineTransform(
           ptX.getX() - origin.getX(),
           ptX.getY() - origin.getY(),
           ptY.getX() - origin.getX(),
           ptY.getY() - origin.getY(),
           origin.getX(),
           origin.getY());
   fromStd_ = toStd_.createInverse();
   origin_ = (Point2D) origin.clone();
   xAxis_ = new Vector2D(origin, ptX).normalized();
   yAxis_ = new Vector2D(origin, ptY).normalized();
 }
Ejemplo n.º 13
0
  /**
   * Constructs a raster reference with given resolutions, origin and rotations. The origin maps to
   * the pixel location given by location.
   *
   * @param location of the origin on the upper left pixel.
   * @param resolutionX the resolution of one pixel on the x axis in the raster
   * @param resolutionY the resolution of one pixel on the y axis in the raster
   * @param rotationX rotation about x-axis
   * @param rotationY rotation about y-axis
   * @param origin0 ordinate of the origin of the first axis defined in the world crs
   * @param origin1 ordinate of the origin of the second axis defined in the world crs
   * @param crs in which the origin is defined.
   */
  public RasterGeoReference(
      OriginLocation location,
      double resolutionX,
      double resolutionY,
      double rotationX,
      double rotationY,
      double origin0,
      double origin1,
      ICRS crs) {

    this.crs = crs;
    if (crs != null) {
      transformer = new GeometryTransformer(crs);
      try {
        eastingAxis = crs.getEasting();
      } catch (ReferenceResolvingException e) {
        transformer = null;
        LOG.debug("CRS could not be resolved: {}", e.getLocalizedMessage());
      }
    } else {
      transformer = null;
    }
    // define a delta to which calculations will be correct. It is dependent on the highest
    // resolution. (smallest
    // value).
    delta = Math.min(Math.abs(resolutionX), Math.abs(resolutionY)) * 1E-6;

    this.resX = resolutionX;
    this.resY = resolutionY;
    this.rotX = rotationX;
    this.rotY = rotationY;

    transform =
        new AffineTransform(
            cos(rotationX) * resolutionX,
            sin(rotationY),
            -sin(rotationX),
            cos(rotationY) * resolutionY,
            origin0,
            origin1);
    try {
      invTransform = transform.createInverse();
    } catch (NoninvertibleTransformException e) {
      LOG.debug("No inverse transform available, this means the supplies values are not valid.", e);
      throw new IllegalArgumentException(
          "Could not create Raster Geo reference, the given values do not specify an affine transform: "
              + e.getLocalizedMessage());
    }
    this.location = location;
  }
Ejemplo n.º 14
0
 public void undo() throws CannotUndoException {
   super.undo();
   JEnvironment env = viewer.getEnvironment();
   AffineTransform inv = null;
   try {
     inv = af.createInverse();
   } catch (NoninvertibleTransformException e) {
     return;
   }
   env.addClip(target.getBounds());
   for (int i = 0; i < segments.size(); i++) {
     segments.get(i).transform(inv);
   }
   target.updatePath();
   env.addClip(target.getBounds());
 }
Ejemplo n.º 15
0
  /** Renders the GVT tree. */
  protected void renderGVTTree() {
    Rectangle visRect = getRenderRect();
    if (gvtRoot == null || visRect.width <= 0 || visRect.height <= 0) {
      return;
    }

    // Renderer setup.
    if (renderer == null || renderer.getTree() != gvtRoot) {
      renderer = createImageRenderer();
      renderer.setTree(gvtRoot);
    }

    // Area of interest computation.
    AffineTransform inv;
    try {
      inv = renderingTransform.createInverse();
    } catch (NoninvertibleTransformException e) {
      throw new IllegalStateException("NoninvertibleTransformEx:" + e.getMessage());
    }
    Shape s = inv.createTransformedShape(visRect);

    // Rendering thread setup.
    gvtTreeRenderer =
        new GVTTreeRenderer(
            renderer,
            renderingTransform,
            doubleBufferedRendering,
            s,
            visRect.width,
            visRect.height);
    gvtTreeRenderer.setPriority(Thread.MIN_PRIORITY);

    Iterator it = gvtTreeRendererListeners.iterator();
    while (it.hasNext()) {
      gvtTreeRenderer.addGVTTreeRendererListener((GVTTreeRendererListener) it.next());
    }

    // Disable the dispatch during the rendering
    // to avoid concurrent access to the GVT tree.
    if (eventDispatcher != null) {
      eventDispatcher.setEventDispatchEnabled(false);
    }

    gvtTreeRenderer.start();
  }
Ejemplo n.º 16
0
 public void vec2FieldMagnitude(Field field, AffineTransform ftoi) {
   AffineTransform itof = null;
   try {
     itof = ftoi.createInverse();
   } catch (NoninvertibleTransformException niv) {
     TDebug.println(0, "NoninvertibleTransformException: " + niv);
   }
   Vector3d v = new Vector3d();
   Point2D.Double p = new Point2D.Double();
   for (int j = 0, k = 0; j < height; ++j)
     for (int i = 0; i < width; ++i, ++k) {
       p.x = i;
       p.y = j;
       itof.transform(p, p);
       v = field.get(p.x, p.y, 0.0);
       f[k] = (float) Math.sqrt(v.x * v.x + v.y * v.y);
     }
 }
Ejemplo n.º 17
0
  /**
   * Función de pintado del canvas. Pintamos un marco a la imagen para saber donde la movemos.
   *
   * <p>Para dibujar el marco alrededor del raster hacemos lo mismo que para pintar el raster
   * rotado. En realidad dibujamos un cuadrado y luego le aplicamos las transformaciones necesarias
   * para que se vea con la misma forma del raster al que representa.
   */
  public void paintComponent(Graphics g) {
    if (isMoveable && lyr != null && ptoFin != null && ptoIni != null) {
      try {
        ViewPort vp = grBehavior.getMapControl().getMapContext().getViewPort();
        AffineTransform at = (AffineTransform) lyr.getAffineTransform().clone();
        at.preConcatenate(vp.getAffineTransform());
        Extent ext = lyr.getFullRasterExtent();

        Point2D pt = new Point2D.Double(ext.getULX(), ext.getULY());
        vp.getAffineTransform().transform(pt, pt);
        at.inverseTransform(pt, pt);

        Point2D size = new Point2D.Double(ext.getLRX(), ext.getLRY());
        vp.getAffineTransform().transform(size, size);
        at.inverseTransform(size, size);

        double distX = ptoFin.getX() - ptoIni.getX();
        double distY = ptoFin.getY() - ptoIni.getY();
        Point2D d = new Point2D.Double(ext.getULX() + distX, ext.getULY() + distY);
        vp.getAffineTransform().transform(d, d);
        at.inverseTransform(d, d);

        // Giramos el graphics se dibuja y se vuelve a dejar como estaba
        ((Graphics2D) g).transform(at);
        g.setColor(rectangleColor);
        AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f);
        ((Graphics2D) g).setComposite(alpha);
        g.fillRect(
            (int) pt.getX() + (int) d.getX(),
            (int) pt.getY() + (int) d.getY(),
            (int) size.getX(),
            (int) size.getY());
        ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
        g.drawRect(
            (int) pt.getX() + (int) d.getX(),
            (int) pt.getY() + (int) d.getY(),
            (int) size.getX(),
            (int) size.getY());
        ((Graphics2D) g).transform(at.createInverse());
      } catch (NoninvertibleTransformException e1) {
        RasterToolsUtil.messageBoxError("error_transformacion1", this, e1);
      }
    }
  }
Ejemplo n.º 18
0
  /**
   * Derives the "magic" transform that can transform source points to destination points.
   *
   * @param srcPoints Three points representing the source parallelogram.
   * @param destPoints Three points representing the destination parallelogram.
   *     <p>Matrix is represent [m00 m01 m02] [m10 m11 m12] [ 0 0 1 ]
   * @return A transform as described above.
   */
  public static AffineTransform deriveTransform(Point2D[] srcPoints, Point2D[] destPoints)
      throws NoninvertibleTransformException {
    if ((srcPoints == null) || (srcPoints.length != 3)) {
      throw new IllegalArgumentException("Source points must contain three points!");
    } else if ((destPoints == null) || (destPoints.length != 3)) {
      throw new IllegalArgumentException("Destination points must contain three points!");
    }
    AffineTransform returnTransform = null;

    // System.out.println(srcPoints[0]+","+srcPoints[1]+","+srcPoints[2]);
    final double m00 = srcPoints[1].getX() - srcPoints[0].getX();
    final double m10 = srcPoints[1].getY() - srcPoints[0].getY();
    final double m01 = srcPoints[2].getX() - srcPoints[0].getX();
    final double m11 = srcPoints[2].getY() - srcPoints[0].getY();
    final double m02 = srcPoints[0].getX();
    final double m12 = srcPoints[0].getY();

    final double n00 = destPoints[1].getX() - destPoints[0].getX();
    final double n10 = destPoints[1].getY() - destPoints[0].getY();
    final double n01 = destPoints[2].getX() - destPoints[0].getX();
    final double n11 = destPoints[2].getY() - destPoints[0].getY();
    final double n02 = destPoints[0].getX();
    final double n12 = destPoints[0].getY();

    // Build the transform based on the source points.
    final AffineTransform srcTransform =
        new AffineTransform(new double[] {m00, m10, m01, m11, m02, m12});
    // System.out.println("src Tran "+srcTransform);

    final AffineTransform destTransform =
        new AffineTransform(new double[] {n00, n10, n01, n11, n02, n12});
    // System.out.println("destTran "+destTransform);

    try {

      returnTransform = srcTransform.createInverse();
      returnTransform.preConcatenate(destTransform);

    } catch (NoninvertibleTransformException e) {
      NaviLogger.logger.severe(e.getMessage());
    }
    // System.out.println("retTran "+returnTransform);
    return returnTransform;
  }
Ejemplo n.º 19
0
 public void vec2FieldZero(Field field, AffineTransform ftoi) {
   AffineTransform itof = null;
   try {
     itof = ftoi.createInverse();
   } catch (NoninvertibleTransformException niv) {
     TDebug.println(0, "NoninvertibleTransformException: " + niv);
   }
   Vector3d v = new Vector3d();
   Point2D.Double p = new Point2D.Double();
   for (int j = 0, k = 0; j < height; ++j)
     for (int i = 0; i < width; ++i, ++k) {
       p.x = i;
       p.y = j;
       itof.transform(p, p);
       v = field.get(p.x, p.y, 0.0);
       if ((v.x == 0.0) && (v.y == 0.0)) f[k] = 1.0f;
       else f[k] = 0.0f;
     }
 }
Ejemplo n.º 20
0
  public void setRenderingTransform(AffineTransform at, boolean performRedraw) {
    renderingTransform = new AffineTransform(at);
    suspendInteractions = true;
    if (eventDispatcher != null) {
      try {
        eventDispatcher.setBaseTransform(renderingTransform.createInverse());
      } catch (NoninvertibleTransformException e) {
        handleException(e);
      }
    }
    if (jgvtListeners != null) {
      Iterator iter = jgvtListeners.iterator();
      ComponentEvent ce =
          new ComponentEvent(this, JGVTComponentListener.COMPONENT_TRANSFORM_CHANGED);
      while (iter.hasNext()) {
        JGVTComponentListener l = (JGVTComponentListener) iter.next();
        l.componentTransformChanged(ce);
      }
    }

    if (performRedraw) scheduleGVTRendering();
  }
Ejemplo n.º 21
0
  /**
   * Utility method for transforming a geometry ROI into the raster space, using the provided affine
   * transformation.
   *
   * @param roi a {@link Geometry} in model space.
   * @param mt2d an {@link AffineTransform} that maps from raster to model space. This is already
   *     referred to the pixel corner.
   * @return a {@link ROI} suitable for using with JAI.
   * @throws ProcessException in case there are problems with ivnerting the provided {@link
   *     AffineTransform}. Very unlikely to happen.
   */
  public static ROI prepareROI(Geometry roi, AffineTransform mt2d) throws ProcessException {
    // transform the geometry to raster space so that we can use it as a ROI source
    Geometry rasterSpaceGeometry;
    try {
      rasterSpaceGeometry = JTS.transform(roi, new AffineTransform2D(mt2d.createInverse()));
    } catch (MismatchedDimensionException e) {
      throw new ProcessException(e);
    } catch (TransformException e) {
      throw new ProcessException(e);
    } catch (NoninvertibleTransformException e) {
      throw new ProcessException(e);
    }
    // System.out.println(rasterSpaceGeometry);
    // System.out.println(rasterSpaceGeometry.getEnvelopeInternal());

    // simplify the geometry so that it's as precise as the coverage, excess coordinates
    // just make it slower to determine the point in polygon relationship
    Geometry simplifiedGeometry = DouglasPeuckerSimplifier.simplify(rasterSpaceGeometry, 1);

    // build a shape using a fast point in polygon wrapper
    return new ROIGeometry(simplifiedGeometry);
  }
Ejemplo n.º 22
0
  /**
   * Applies the band select operation to a grid coverage.
   *
   * @param cropEnvelope the target envelope; always not null
   * @param cropROI the target ROI shape; nullable
   * @param roiTolerance; as read from op's params
   * @param sourceCoverage is the source {@link GridCoverage2D} that we want to crop.
   * @param hints A set of rendering hints, or {@code null} if none.
   * @param sourceGridToWorldTransform is the 2d grid-to-world transform for the source coverage.
   * @return The result as a grid coverage.
   */
  private static GridCoverage2D buildResult(
      final GeneralEnvelope cropEnvelope,
      final Geometry cropROI,
      final double roiTolerance,
      final boolean forceMosaic,
      final Hints hints,
      final GridCoverage2D sourceCoverage,
      final AffineTransform sourceGridToWorldTransform) {

    //
    // Getting the source coverage and its child geolocation objects
    //
    final RenderedImage sourceImage = sourceCoverage.getRenderedImage();
    final GridGeometry2D sourceGridGeometry = ((GridGeometry2D) sourceCoverage.getGridGeometry());
    final GridEnvelope2D sourceGridRange = sourceGridGeometry.getGridRange2D();

    //
    // Now we try to understand if we have a simple scale and translate or a
    // more elaborated grid-to-world transformation n which case a simple
    // crop could not be enough, but we may need a more elaborated chain of
    // operation in order to do a good job. As an instance if we
    // have a rotation which is not multiple of PI/2 we have to use
    // the mosaic with a ROI
    //
    final boolean isSimpleTransform =
        CoverageUtilities.isSimpleGridToWorldTransform(sourceGridToWorldTransform, EPS);

    // Do we need to explode the Palette to RGB(A)?
    //
    int actionTaken = 0;

    // //
    //
    // Layout
    //
    // //
    final RenderingHints targetHints = new RenderingHints(null);
    if (hints != null) targetHints.add(hints);
    final ImageLayout layout = initLayout(sourceImage, targetHints);
    targetHints.put(JAI.KEY_IMAGE_LAYOUT, layout);

    //
    // prepare the processor to use for this operation
    //
    final JAI processor = OperationJAI.getJAI(targetHints);
    final boolean useProvidedProcessor = !processor.equals(JAI.getDefaultInstance());

    try {

      if (cropROI != null) {
        // replace the cropEnvelope with the envelope of the intersection
        // of the ROI and the cropEnvelope.
        // Remember that envelope(intersection(roi,cropEnvelope)) != intersection(cropEnvelope,
        // envelope(roi))
        final Polygon modelSpaceROI = FeatureUtilities.getPolygon(cropEnvelope, GFACTORY);
        Geometry intersection = IntersectUtils.intersection(cropROI, modelSpaceROI);
        Envelope2D e2d =
            JTS.getEnvelope2D(
                intersection.getEnvelopeInternal(), cropEnvelope.getCoordinateReferenceSystem());
        GeneralEnvelope ge = new GeneralEnvelope((org.opengis.geometry.Envelope) e2d);
        cropEnvelope.setEnvelope(ge);
      }

      // //
      //
      // Build the new range by keeping into
      // account translation of grid geometry constructor for respecting
      // OGC PIXEL-IS-CENTER ImageDatum assumption.
      //
      // //
      final AffineTransform sourceWorldToGridTransform = sourceGridToWorldTransform.createInverse();

      // //
      //
      // finalRasterArea will hold the smallest rectangular integer raster area that contains the
      // floating point raster
      // area which we obtain when applying the world-to-grid transform to the cropEnvelope. Note
      // that we need to intersect
      // such an area with the area covered by the source coverage in order to be sure we do not try
      // to crop outside the
      // bounds of the source raster.
      //
      // //
      final Rectangle2D finalRasterAreaDouble =
          XAffineTransform.transform(
              sourceWorldToGridTransform, cropEnvelope.toRectangle2D(), null);
      final Rectangle finalRasterArea = finalRasterAreaDouble.getBounds();

      // intersection with the original range in order to not try to crop outside the image bounds
      Rectangle.intersect(finalRasterArea, sourceGridRange, finalRasterArea);
      if (finalRasterArea.isEmpty())
        throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP));

      // //
      //
      // It is worth to point out that doing a crop the G2W transform
      // should not change while the envelope might change as
      // a consequence of the rounding of the underlying image datum
      // which uses integer factors or in case the G2W is very
      // complex. Note that we will always strive to
      // conserve the original grid-to-world transform.
      //
      // //

      // we do not have to crop in this case (should not really happen at
      // this time)
      if (finalRasterArea.equals(sourceGridRange) && isSimpleTransform && cropROI == null)
        return sourceCoverage;

      // //
      //
      // if I get here I have something to crop
      // using the world-to-grid transform for going from envelope to the
      // new grid range.
      //
      // //
      final double minX = finalRasterArea.getMinX();
      final double minY = finalRasterArea.getMinY();
      final double width = finalRasterArea.getWidth();
      final double height = finalRasterArea.getHeight();

      // //
      //
      // Check if we need to use mosaic or crop
      //
      // //
      final PlanarImage croppedImage;
      final ParameterBlock pbj = new ParameterBlock();
      pbj.addSource(sourceImage);
      java.awt.Polygon rasterSpaceROI = null;
      String operatioName = null;
      if (!isSimpleTransform || cropROI != null) {
        // /////////////////////////////////////////////////////////////////////
        //
        // We don't have a simple scale and translate transform, JAI
        // crop MAY NOT suffice. Let's decide whether or not we'll use
        // the Mosaic.
        //
        // /////////////////////////////////////////////////////////////////////
        Polygon modelSpaceROI = FeatureUtilities.getPolygon(cropEnvelope, GFACTORY);

        // //
        //
        // Now convert this polygon back into a shape for the source
        // raster space.
        //
        // //
        final List<Point2D> points = new ArrayList<Point2D>(5);
        rasterSpaceROI =
            FeatureUtilities.convertPolygonToPointArray(
                modelSpaceROI, ProjectiveTransform.create(sourceWorldToGridTransform), points);
        if (rasterSpaceROI == null || rasterSpaceROI.getBounds().isEmpty())
          if (finalRasterArea.isEmpty())
            throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP));
        final boolean doMosaic =
            forceMosaic
                ? true
                : decideJAIOperation(roiTolerance, rasterSpaceROI.getBounds2D(), points);
        if (doMosaic || cropROI != null) {
          // prepare the params for the mosaic
          final ROI[] roiarr;
          try {
            if (cropROI != null) {
              final LiteShape2 cropRoiLS2 =
                  new LiteShape2(
                      cropROI, ProjectiveTransform.create(sourceWorldToGridTransform), null, false);
              ROI cropRS = new ROIShape(cropRoiLS2);
              Rectangle2D rt = cropRoiLS2.getBounds2D();
              if (!hasIntegerBounds(rt)) {
                // Approximate Geometry
                Geometry geo = (Geometry) cropRoiLS2.getGeometry().clone();
                transformGeometry(geo);
                cropRS = new ROIShape(new LiteShape2(geo, null, null, false));
              }
              roiarr = new ROI[] {cropRS};
            } else {
              final ROIShape roi = new ROIShape(rasterSpaceROI);
              roiarr = new ROI[] {roi};
            }
          } catch (FactoryException ex) {
            throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP), ex);
          }
          pbj.add(MosaicDescriptor.MOSAIC_TYPE_OVERLAY);
          pbj.add(null);
          pbj.add(roiarr);
          pbj.add(null);
          pbj.add(CoverageUtilities.getBackgroundValues(sourceCoverage));

          // prepare the final layout
          final Rectangle bounds = rasterSpaceROI.getBounds2D().getBounds();
          Rectangle.intersect(bounds, sourceGridRange, bounds);
          if (bounds.isEmpty()) throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP));

          // we do not have to crop in this case (should not really happen at
          // this time)
          if (!doMosaic && bounds.getBounds().equals(sourceGridRange) && isSimpleTransform)
            return sourceCoverage;

          // nice trick, we use the layout to do the actual crop
          final Rectangle boundsInt = bounds.getBounds();
          layout.setMinX(boundsInt.x);
          layout.setWidth(boundsInt.width);
          layout.setMinY(boundsInt.y);
          layout.setHeight(boundsInt.height);
          operatioName = "Mosaic";
        }
      }

      // do we still have to set the operation name? If so that means we have to go for crop.
      if (operatioName == null) {
        // executing the crop
        pbj.add((float) minX);
        pbj.add((float) minY);
        pbj.add((float) width);
        pbj.add((float) height);
        operatioName = "GTCrop";
      }
      // //
      //
      // Apply operation
      //
      // //
      if (!useProvidedProcessor) {
        croppedImage = JAI.create(operatioName, pbj, targetHints);
      } else {
        croppedImage = processor.createNS(operatioName, pbj, targetHints);
      }

      // conserve the input grid to world transformation
      Map sourceProperties = sourceCoverage.getProperties();
      Map properties = null;
      if (sourceProperties != null && !sourceProperties.isEmpty()) {
        properties = new HashMap(sourceProperties);
      }
      if (rasterSpaceROI != null) {
        if (properties != null) {
          properties.put("GC_ROI", rasterSpaceROI);
        } else {
          properties = Collections.singletonMap("GC_ROI", rasterSpaceROI);
        }
      }

      return new GridCoverageFactory(hints)
          .create(
              sourceCoverage.getName(),
              croppedImage,
              new GridGeometry2D(
                  new GridEnvelope2D(croppedImage.getBounds()),
                  sourceGridGeometry.getGridToCRS2D(PixelOrientation.CENTER),
                  sourceCoverage.getCoordinateReferenceSystem()),
              (GridSampleDimension[])
                  (actionTaken == 1 ? null : sourceCoverage.getSampleDimensions().clone()),
              new GridCoverage[] {sourceCoverage},
              properties);

    } catch (TransformException e) {
      throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP), e);
    } catch (NoninvertibleTransformException e) {
      throw new CannotCropException(Errors.format(ErrorKeys.CANT_CROP), e);
    }
  }
Ejemplo n.º 23
0
 private void setPaint(boolean invert, double xoffset, double yoffset, boolean fill) {
   if (paint instanceof Color) {
     Color color = (Color) paint;
     int alpha = color.getAlpha();
     if (fill) {
       if (alpha != currentFillGState) {
         currentFillGState = alpha;
         PdfGState gs = fillGState[alpha];
         if (gs == null) {
           gs = new PdfGState();
           gs.setFillOpacity(alpha / 255f);
           fillGState[alpha] = gs;
         }
         cb.setGState(gs);
       }
       cb.setColorFill(color);
     } else {
       if (alpha != currentStrokeGState) {
         currentStrokeGState = alpha;
         PdfGState gs = strokeGState[alpha];
         if (gs == null) {
           gs = new PdfGState();
           gs.setStrokeOpacity(alpha / 255f);
           strokeGState[alpha] = gs;
         }
         cb.setGState(gs);
       }
       cb.setColorStroke(color);
     }
   } else if (paint instanceof GradientPaint) {
     GradientPaint gp = (GradientPaint) paint;
     Point2D p1 = gp.getPoint1();
     transform.transform(p1, p1);
     Point2D p2 = gp.getPoint2();
     transform.transform(p2, p2);
     Color c1 = gp.getColor1();
     Color c2 = gp.getColor2();
     PdfShading shading =
         PdfShading.simpleAxial(
             cb.getPdfWriter(),
             (float) p1.getX(),
             normalizeY((float) p1.getY()),
             (float) p2.getX(),
             normalizeY((float) p2.getY()),
             c1,
             c2);
     PdfShadingPattern pat = new PdfShadingPattern(shading);
     if (fill) cb.setShadingFill(pat);
     else cb.setShadingStroke(pat);
   } else if (paint instanceof TexturePaint) {
     try {
       TexturePaint tp = (TexturePaint) paint;
       BufferedImage img = tp.getImage();
       Rectangle2D rect = tp.getAnchorRect();
       com.lowagie.text.Image image = com.lowagie.text.Image.getInstance(img, null);
       PdfPatternPainter pattern = cb.createPattern(image.getWidth(), image.getHeight());
       AffineTransform inverse = this.normalizeMatrix();
       inverse.translate(rect.getX(), rect.getY());
       inverse.scale(rect.getWidth() / image.getWidth(), -rect.getHeight() / image.getHeight());
       double[] mx = new double[6];
       inverse.getMatrix(mx);
       pattern.setPatternMatrix(
           (float) mx[0],
           (float) mx[1],
           (float) mx[2],
           (float) mx[3],
           (float) mx[4],
           (float) mx[5]);
       image.setAbsolutePosition(0, 0);
       pattern.addImage(image);
       if (fill) cb.setPatternFill(pattern);
       else cb.setPatternStroke(pattern);
     } catch (Exception ex) {
       if (fill) cb.setColorFill(Color.gray);
       else cb.setColorStroke(Color.gray);
     }
   } else {
     try {
       BufferedImage img = null;
       int type = BufferedImage.TYPE_4BYTE_ABGR;
       if (paint.getTransparency() == Transparency.OPAQUE) {
         type = BufferedImage.TYPE_3BYTE_BGR;
       }
       img = new BufferedImage((int) width, (int) height, type);
       Graphics2D g = (Graphics2D) img.getGraphics();
       g.transform(transform);
       AffineTransform inv = transform.createInverse();
       Shape fillRect = new Rectangle2D.Double(0, 0, img.getWidth(), img.getHeight());
       fillRect = inv.createTransformedShape(fillRect);
       g.setPaint(paint);
       g.fill(fillRect);
       if (invert) {
         AffineTransform tx = new AffineTransform();
         tx.scale(1, -1);
         tx.translate(-xoffset, -yoffset);
         g.drawImage(img, tx, null);
       }
       g.dispose();
       g = null;
       com.lowagie.text.Image image = com.lowagie.text.Image.getInstance(img, null);
       PdfPatternPainter pattern = cb.createPattern(width, height);
       image.setAbsolutePosition(0, 0);
       pattern.addImage(image);
       if (fill) cb.setPatternFill(pattern);
       else cb.setPatternStroke(pattern);
     } catch (Exception ex) {
       if (fill) cb.setColorFill(Color.gray);
       else cb.setColorStroke(Color.gray);
     }
   }
 }
  /**
   * Slow filter.
   *
   * @param src the src.
   * @param dst the dst.
   * @return the int.
   */
  private int slowFilter(Raster src, WritableRaster dst) {
    // TODO: make correct interpolation
    // TODO: what if there are different data types?

    Rectangle srcBounds = src.getBounds();
    Rectangle dstBounds = dst.getBounds();
    Rectangle normDstBounds = new Rectangle(0, 0, dstBounds.width, dstBounds.height);
    Rectangle bounds = getBounds2D(src).getBounds().intersection(normDstBounds);

    AffineTransform inv = null;
    try {
      inv = at.createInverse();
    } catch (NoninvertibleTransformException e) {
      return -1;
    }

    double[] m = new double[6];
    inv.getMatrix(m);

    int minSrcX = srcBounds.x;
    int minSrcY = srcBounds.y;
    int maxSrcX = srcBounds.x + srcBounds.width;
    int maxSrcY = srcBounds.y + srcBounds.height;

    int minX = bounds.x + dstBounds.x;
    int minY = bounds.y + dstBounds.y;
    int maxX = minX + bounds.width;
    int maxY = minY + bounds.height;

    int hx = (int) (m[0] * 256);
    int hy = (int) (m[1] * 256);
    int vx = (int) (m[2] * 256);
    int vy = (int) (m[3] * 256);
    int sx = (int) (m[4] * 256) + hx * bounds.x + vx * bounds.y + (srcBounds.x) * 256;
    int sy = (int) (m[5] * 256) + hy * bounds.x + vy * bounds.y + (srcBounds.y) * 256;

    vx -= hx * bounds.width;
    vy -= hy * bounds.width;

    if (src.getTransferType() == dst.getTransferType()) {
      for (int y = minY; y < maxY; y++) {
        for (int x = minX; x < maxX; x++) {
          int px = sx >> 8;
          int py = sy >> 8;
          if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
            Object val = src.getDataElements(px, py, null);
            dst.setDataElements(x, y, val);
          }
          sx += hx;
          sy += hy;
        }
        sx += vx;
        sy += vy;
      }
    } else {
      float pixel[] = null;
      for (int y = minY; y < maxY; y++) {
        for (int x = minX; x < maxX; x++) {
          int px = sx >> 8;
          int py = sy >> 8;
          if (px >= minSrcX && py >= minSrcY && px < maxSrcX && py < maxSrcY) {
            pixel = src.getPixel(px, py, pixel);
            dst.setPixel(x, y, pixel);
          }
          sx += hx;
          sy += hy;
        }
        sx += vx;
        sy += vy;
      }
    }

    return 0;
  }
Ejemplo n.º 25
0
  /**
   * Stop the generation of any previous page, and draw the new one.
   *
   * @param page the PDFPage to draw.
   */
  public void showPage(PDFPage page) {
    // stop drawing the previous page
    if (currentPage != null && prevSize != null) {
      currentPage.stop(prevSize.width, prevSize.height, prevClip);
    }

    // set up the new page
    currentPage = page;

    if (page == null) {
      // no page
      currentImage = null;
      clip = null;
      currentXform = null;
      canvas.repaint();
    } else {
      // Reset highlight
      highlight = null;
      boolean resize = false;

      int newW = Math.round(zoomFactor * page.getWidth());
      int newH = Math.round(zoomFactor * page.getHeight());
      // setSize(Math.round(zoomFactor*page.getWidth()), Math.round(zoomFactor*page.getHeight()));

      Point sz = getSize();

      if (sz.x != newW || sz.y != newH) {
        sz.x = newW;
        sz.y = newH;
        resize = true;
      }

      if (sz.x + sz.y == 0) {
        // no image to draw.
        return;
      }

      // calculate the clipping rectangle in page space from the
      // desired clip in screen space.
      Rectangle2D useClip = clip;
      if (clip != null && currentXform != null) {
        useClip = currentXform.createTransformedShape(clip).getBounds2D();
      }

      Dimension pageSize = page.getUnstretchedSize(sz.x, sz.y, useClip);

      ImageInfo info = new ImageInfo(pageSize.width, pageSize.height, useClip, null);

      currentImage = new RefImage(pageSize.width, pageSize.height, BufferedImage.TYPE_INT_ARGB);

      Rectangle rect = new Rectangle(0, 0, pageSize.width, pageSize.height);
      PDFRenderer r =
          new PDFRenderer(
              page, ((BufferedImage) currentImage).createGraphics(), rect, useClip, Color.WHITE);
      page.renderers.put(info, new WeakReference<PDFRenderer>(r));
      // get the new image
      /*currentImage = page.getImage(pageSize.width, pageSize.height,
      useClip, this, true, false);*/

      // calculate the transform from screen to page space
      currentXform = page.getInitialTransform(pageSize.width, pageSize.height, useClip);
      try {
        currentXform = currentXform.createInverse();
      } catch (NoninvertibleTransformException nte) {
        System.out.println("Error inverting page transform!");
        nte.printStackTrace();
      }

      prevClip = useClip;
      prevSize = pageSize;

      r.go(true);
      if (r.getStatus() != Watchable.COMPLETED) return;

      if (resize)
        // Resize triggers repaint
        setSize(
            Math.round(zoomFactor * page.getWidth()), Math.round(zoomFactor * page.getHeight()));
      else {
        EventQueue.invokeLater(
            new Runnable() {

              @Override
              public void run() {
                // canvas.repaint();
              }
            });
      }
    }
  }
  public void draw(java.awt.Graphics2D g, java.awt.geom.AffineTransform normal2Device) {
    if ((project == null) || !posWasCalc) return;

    // use world coordinates for position, but draw in screen coordinates
    // so that the symbols stay the same size
    AffineTransform world2Device = g.getTransform();
    g.setTransform(normal2Device); //  identity transform for screen coords

    // transform World to Normal coords:
    //    world2Normal = pixelAT-1 * world2Device
    // cache for pick closest
    AffineTransform world2Normal;
    try {
      world2Normal = normal2Device.createInverse();
      world2Normal.concatenate(world2Device);
    } catch (java.awt.geom.NoninvertibleTransformException e) {
      System.out.println(" RendSurfObs: NoninvertibleTransformException on " + normal2Device);
      return;
    }

    // we want aliasing; but save previous state to restore at end
    Object saveHint = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
    // g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    //    RenderingHints.VALUE_ANTIALIAS_ON);
    g.setStroke(new java.awt.BasicStroke(1.0f));

    /* set up the grid
    Rectangle2D bbox = (Rectangle2D) g.getClip(); // clipping area in normal coords
    // clear the grid = "no stations are drawn"
    stationGrid.clear();
    // set the grid size based on typical bounding box
    stationGrid.setGrid(bbox, typicalBB.getWidth(), typicalBB.getHeight());


    // always draw selected
    if (selected != null) {
      selected.calcPos( world2Normal);
      stationGrid.markIfClear( selected.getBB(), selected);
      selected.draw(g);
    } */

    g.setFont(textFont.getFont());
    g.setColor(color);

    int count = 0;
    int npts = obsUIlist.size();
    GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD, npts);
    for (int i = 0; i < npts; i++) {
      ObservationUI s = (ObservationUI) obsUIlist.get(i);
      s.calcPos(world2Normal);
      s.draw(g);

      if (Double.isNaN(s.screenPos.getX())) {
        System.out.println("screenPos=" + s.screenPos + " world = " + s.worldPos);
        continue;
      }

      if (count == 0) path.moveTo((float) s.screenPos.getX(), (float) s.screenPos.getY());
      else path.lineTo((float) s.screenPos.getX(), (float) s.screenPos.getY());
      count++;
    }

    g.setColor(color);
    g.draw(path);

    // draw selected
    if (selected != null) selected.draw(g);

    // restore
    g.setTransform(world2Device);
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, saveHint);
  }
  /**
   * Constructor for superclass. Does some initialization, but leaves most of the heavy-duty math
   * for calculateGradient(), so the subclass may do some other manipulation beforehand if
   * necessary. This is not possible if this computation is done in the superclass constructor which
   * always gets called first.
   */
  public MultipleGradientPaintContext(
      ColorModel cm,
      Rectangle deviceBounds,
      Rectangle2D userBounds,
      AffineTransform t,
      RenderingHints hints,
      float[] fractions,
      Color[] colors,
      MultipleGradientPaint.CycleMethodEnum cycleMethod,
      MultipleGradientPaint.ColorSpaceEnum colorSpace)
      throws NoninvertibleTransformException {
    // We have to deal with the cases where the 1st gradient stop is not
    // equal to 0 and/or the last gradient stop is not equal to 1.
    // In both cases, create a new point and replicate the previous
    // extreme point's color.

    boolean fixFirst = false;
    boolean fixLast = false;
    int len = fractions.length;

    // if the first gradient stop is not equal to zero, fix this condition
    if (fractions[0] != 0f) {
      fixFirst = true;
      len++;
    }

    // if the last gradient stop is not equal to one, fix this condition
    if (fractions[fractions.length - 1] != 1f) {
      fixLast = true;
      len++;
    }

    for (int i = 0; i < fractions.length - 1; i++) if (fractions[i] == fractions[i + 1]) len--;

    this.fractions = new float[len];
    Color[] loColors = new Color[len - 1];
    Color[] hiColors = new Color[len - 1];
    normalizedIntervals = new float[len - 1];

    gradientUnderflow = colors[0].getRGB();
    gradientOverflow = colors[colors.length - 1].getRGB();

    int idx = 0;
    if (fixFirst) {
      this.fractions[0] = 0;
      loColors[0] = colors[0];
      hiColors[0] = colors[0];
      normalizedIntervals[0] = fractions[0];
      idx++;
    }

    for (int i = 0; i < fractions.length - 1; i++) {
      if (fractions[i] == fractions[i + 1]) {
        // System.out.println("EQ Fracts");
        if (!colors[i].equals(colors[i + 1])) {
          hasDiscontinuity = true;
        }
        continue;
      }
      this.fractions[idx] = fractions[i];
      loColors[idx] = colors[i];
      hiColors[idx] = colors[i + 1];
      normalizedIntervals[idx] = fractions[i + 1] - fractions[i];
      idx++;
    }

    this.fractions[idx] = fractions[fractions.length - 1];

    if (fixLast) {
      loColors[idx] = hiColors[idx] = colors[colors.length - 1];
      normalizedIntervals[idx] = 1 - fractions[fractions.length - 1];
      idx++;
      this.fractions[idx] = 1;
    }

    // The inverse transform is needed to from device to user space.
    // Get all the components of the inverse transform matrix.
    AffineTransform tInv = t.createInverse();

    double m[] = new double[6];
    tInv.getMatrix(m);
    a00 = (float) m[0];
    a10 = (float) m[1];
    a01 = (float) m[2];
    a11 = (float) m[3];
    a02 = (float) m[4];
    a12 = (float) m[5];

    // copy some flags
    this.cycleMethod = cycleMethod;
    this.colorSpace = colorSpace;

    // PATCH Werner Randelshofer: ColorModel can be null!

    // Setup an example Model, we may refine it later.
    if (cm != null && cm.getColorSpace() == lrgbmodel_A.getColorSpace()) dataModel = lrgbmodel_A;
    else if (cm == null || cm.getColorSpace() == srgbmodel_A.getColorSpace())
      dataModel = srgbmodel_A;
    else throw new IllegalArgumentException("Unsupported ColorSpace for interpolation");

    calculateGradientFractions(loColors, hiColors);

    model = GraphicsUtil.coerceColorModel(dataModel, cm != null && cm.isAlphaPremultiplied());
  }
Ejemplo n.º 28
0
 private Point getWorldPoint(Point point) throws NoninvertibleTransformException {
   AffineTransform invVTM;
   invVTM = currentAT.createInverse();
   Point2D temp = invVTM.transform(point, null);
   return new java.awt.Point((int) temp.getX(), (int) temp.getY());
 }
Ejemplo n.º 29
0
  protected void renderImageXform(
      SunGraphics2D sg,
      Image img,
      AffineTransform tx,
      int interpType,
      int sx1,
      int sy1,
      int sx2,
      int sy2,
      Color bgColor) {
    Region clip = sg.getCompClip();
    SurfaceData dstData = sg.surfaceData;
    SurfaceData srcData =
        dstData.getSourceSurfaceData(img, sg.TRANSFORM_GENERIC, sg.imageComp, bgColor);

    if (srcData == null) {
      img = getBufferedImage(img);
      srcData = dstData.getSourceSurfaceData(img, sg.TRANSFORM_GENERIC, sg.imageComp, bgColor);
      if (srcData == null) {
        // REMIND: Is this correct?  Can this happen?
        return;
      }
    }

    if (isBgOperation(srcData, bgColor)) {
      // We cannot perform bg operations during transform so make
      // an opaque temp image with the appropriate background
      // and work from there.
      img = makeBufferedImage(img, bgColor, BufferedImage.TYPE_INT_RGB, sx1, sy1, sx2, sy2);
      // Temp image has appropriate subimage at 0,0 now.
      sx2 -= sx1;
      sy2 -= sy1;
      sx1 = sy1 = 0;

      srcData = dstData.getSourceSurfaceData(img, sg.TRANSFORM_GENERIC, sg.imageComp, bgColor);
    }

    SurfaceType srcType = srcData.getSurfaceType();
    TransformHelper helper = TransformHelper.getFromCache(srcType);

    if (helper == null) {
      /* We have no helper for this source image type.
       * But we know that we do have helpers for both RGB and ARGB,
       * so convert to one of those types depending on transparency.
       * ARGB_PRE might be a better choice if the source image has
       * alpha, but it may cause some recursion here since we only
       * tend to have converters that convert to ARGB.
       */
      int type =
          ((srcData.getTransparency() == Transparency.OPAQUE)
              ? BufferedImage.TYPE_INT_RGB
              : BufferedImage.TYPE_INT_ARGB);
      img = makeBufferedImage(img, null, type, sx1, sy1, sx2, sy2);
      // Temp image has appropriate subimage at 0,0 now.
      sx2 -= sx1;
      sy2 -= sy1;
      sx1 = sy1 = 0;

      srcData = dstData.getSourceSurfaceData(img, sg.TRANSFORM_GENERIC, sg.imageComp, null);
      srcType = srcData.getSurfaceType();
      helper = TransformHelper.getFromCache(srcType);
      // assert(helper != null);
    }

    AffineTransform itx;
    try {
      itx = tx.createInverse();
    } catch (NoninvertibleTransformException e) {
      // Non-invertible transform means no output
      return;
    }

    /*
     * Find the maximum bounds on the destination that will be
     * affected by the transformed source.  First, transform all
     * four corners of the source and then min and max the resulting
     * destination coordinates of the transformed corners.
     * Note that tx already has the offset to sx1,sy1 accounted
     * for so we use the box (0, 0, sx2-sx1, sy2-sy1) as the
     * source coordinates.
     */
    double coords[] = new double[8];
    /* corner:  UL      UR      LL      LR   */
    /* index:  0  1    2  3    4  5    6  7  */
    /* coord: (0, 0), (w, 0), (0, h), (w, h) */
    coords[2] = coords[6] = sx2 - sx1;
    coords[5] = coords[7] = sy2 - sy1;
    tx.transform(coords, 0, coords, 0, 4);
    double ddx1, ddy1, ddx2, ddy2;
    ddx1 = ddx2 = coords[0];
    ddy1 = ddy2 = coords[1];
    for (int i = 2; i < coords.length; i += 2) {
      double d = coords[i];
      if (ddx1 > d) ddx1 = d;
      else if (ddx2 < d) ddx2 = d;
      d = coords[i + 1];
      if (ddy1 > d) ddy1 = d;
      else if (ddy2 < d) ddy2 = d;
    }
    int dx1 = (int) Math.floor(ddx1);
    int dy1 = (int) Math.floor(ddy1);
    int dx2 = (int) Math.ceil(ddx2);
    int dy2 = (int) Math.ceil(ddy2);

    SurfaceType dstType = dstData.getSurfaceType();
    MaskBlit maskblit;
    Blit blit;
    if (sg.compositeState <= sg.COMP_ALPHA) {
      /* NOTE: We either have, or we can make,
       * a MaskBlit for any alpha composite type
       */
      maskblit = MaskBlit.getFromCache(SurfaceType.IntArgbPre, sg.imageComp, dstType);

      /* NOTE: We can only use the native TransformHelper
       * func to go directly to the dest if both the helper
       * and the MaskBlit are native.
       * All helpers are native at this point, but some MaskBlit
       * objects are implemented in Java, so we need to check.
       */
      if (maskblit.getNativePrim() != 0) {
        // We can render directly.
        helper.Transform(
            maskblit,
            srcData,
            dstData,
            sg.composite,
            clip,
            itx,
            interpType,
            sx1,
            sy1,
            sx2,
            sy2,
            dx1,
            dy1,
            dx2,
            dy2,
            null,
            0,
            0);
        return;
      }
      blit = null;
    } else {
      /* NOTE: We either have, or we can make,
       * a Blit for any composite type, even Custom
       */
      maskblit = null;
      blit = Blit.getFromCache(SurfaceType.IntArgbPre, sg.imageComp, dstType);
    }

    // We need to transform to a temp image and then copy
    // just the pieces that are valid data to the dest.
    BufferedImage tmpimg = new BufferedImage(dx2 - dx1, dy2 - dy1, BufferedImage.TYPE_INT_ARGB);
    SurfaceData tmpData = SurfaceData.getPrimarySurfaceData(tmpimg);
    SurfaceType tmpType = tmpData.getSurfaceType();
    MaskBlit tmpmaskblit =
        MaskBlit.getFromCache(SurfaceType.IntArgbPre, CompositeType.SrcNoEa, tmpType);
    /*
     * The helper function fills a temporary edges buffer
     * for us with the bounding coordinates of each scanline
     * in the following format:
     *
     * edges[0, 1] = [top y, bottom y)
     * edges[2, 3] = [left x, right x) of top row
     * ...
     * edges[h*2, h*2+1] = [left x, right x) of bottom row
     *
     * all coordinates in the edges array will be relative to dx1, dy1
     *
     * edges thus has to be h*2+2 in length
     */
    int edges[] = new int[(dy2 - dy1) * 2 + 2];
    // It is important that edges[0]=edges[1]=0 when we call
    // Transform in case it must return early and we would
    // not want to render anything on an error condition.
    helper.Transform(
        tmpmaskblit,
        srcData,
        tmpData,
        AlphaComposite.Src,
        null,
        itx,
        interpType,
        sx1,
        sy1,
        sx2,
        sy2,
        0,
        0,
        dx2 - dx1,
        dy2 - dy1,
        edges,
        dx1,
        dy1);

    /*
     * Now copy the results, scanline by scanline, into the dest.
     * The edges array helps us minimize the work.
     */
    int index = 2;
    for (int y = edges[0]; y < edges[1]; y++) {
      int relx1 = edges[index++];
      int relx2 = edges[index++];
      if (relx1 >= relx2) {
        continue;
      }
      if (maskblit != null) {
        maskblit.MaskBlit(
            tmpData,
            dstData,
            sg.composite,
            clip,
            relx1,
            y,
            dx1 + relx1,
            dy1 + y,
            relx2 - relx1,
            1,
            null,
            0,
            0);
      } else {
        blit.Blit(
            tmpData, dstData, sg.composite, clip, relx1, y, dx1 + relx1, dy1 + y, relx2 - relx1, 1);
      }
    }
  }
 /*     */ protected MultipleGradientPaintContext(
     MultipleGradientPaint paramMultipleGradientPaint,
     ColorModel paramColorModel,
     Rectangle paramRectangle,
     Rectangle2D paramRectangle2D,
     AffineTransform paramAffineTransform,
     RenderingHints paramRenderingHints,
     float[] paramArrayOfFloat,
     Color[] paramArrayOfColor,
     MultipleGradientPaint.CycleMethod paramCycleMethod,
     MultipleGradientPaint.ColorSpaceType paramColorSpaceType)
       /*     */ {
   /* 159 */ if (paramRectangle == null) {
     /* 160 */ throw new NullPointerException("Device bounds cannot be null");
     /*     */ }
   /*     */
   /* 163 */ if (paramRectangle2D == null) {
     /* 164 */ throw new NullPointerException("User bounds cannot be null");
     /*     */ }
   /*     */
   /* 167 */ if (paramAffineTransform == null) {
     /* 168 */ throw new NullPointerException("Transform cannot be null");
     /*     */ }
   /*     */
   /*     */ AffineTransform localAffineTransform;
   /*     */ try
   /*     */ {
     /* 177 */ localAffineTransform = paramAffineTransform.createInverse();
     /*     */ }
   /*     */ catch (NoninvertibleTransformException localNoninvertibleTransformException)
   /*     */ {
     /* 181 */ localAffineTransform = new AffineTransform();
     /*     */ }
   /* 183 */ double[] arrayOfDouble = new double[6];
   /* 184 */ localAffineTransform.getMatrix(arrayOfDouble);
   /* 185 */ this.a00 = ((float) arrayOfDouble[0]);
   /* 186 */ this.a10 = ((float) arrayOfDouble[1]);
   /* 187 */ this.a01 = ((float) arrayOfDouble[2]);
   /* 188 */ this.a11 = ((float) arrayOfDouble[3]);
   /* 189 */ this.a02 = ((float) arrayOfDouble[4]);
   /* 190 */ this.a12 = ((float) arrayOfDouble[5]);
   /*     */
   /* 193 */ this.cycleMethod = paramCycleMethod;
   /* 194 */ this.colorSpace = paramColorSpaceType;
   /*     */
   /* 197 */ this.fractions = paramArrayOfFloat;
   /*     */
   /* 202 */ this.gradient =
       (paramMultipleGradientPaint.gradient != null
           ? (int[]) paramMultipleGradientPaint.gradient.get()
           : null);
   /*     */
   /* 204 */ this.gradients =
       (paramMultipleGradientPaint.gradients != null
           ? (int[][]) paramMultipleGradientPaint.gradients.get()
           : (int[][]) null);
   /*     */
   /* 207 */ if ((this.gradient == null) && (this.gradients == null))
   /*     */ {
     /* 209 */ calculateLookupData(paramArrayOfColor);
     /*     */
     /* 213 */ paramMultipleGradientPaint.model = this.model;
     /* 214 */ paramMultipleGradientPaint.normalizedIntervals = this.normalizedIntervals;
     /* 215 */ paramMultipleGradientPaint.isSimpleLookup = this.isSimpleLookup;
     /* 216 */ if (this.isSimpleLookup)
     /*     */ {
       /* 218 */ paramMultipleGradientPaint.fastGradientArraySize = this.fastGradientArraySize;
       /* 219 */ paramMultipleGradientPaint.gradient = new SoftReference(this.gradient);
       /*     */ }
     /*     */ else {
       /* 222 */ paramMultipleGradientPaint.gradients = new SoftReference(this.gradients);
       /*     */ }
     /*     */ }
   /*     */ else {
     /* 226 */ this.model = paramMultipleGradientPaint.model;
     /* 227 */ this.normalizedIntervals = paramMultipleGradientPaint.normalizedIntervals;
     /* 228 */ this.isSimpleLookup = paramMultipleGradientPaint.isSimpleLookup;
     /* 229 */ this.fastGradientArraySize = paramMultipleGradientPaint.fastGradientArraySize;
     /*     */ }
   /*     */ }