public TrapezoidList tesselateStroke( Shape s, BasicStroke bs, boolean thin, boolean adjust, boolean antialias, AffineTransform at, Region clip) { float lw; if (thin) { if (antialias) { lw = 0.5f; } else { lw = 1.0f; } } else { lw = bs.getLineWidth(); } convertPathData(s, at); double[] dashArray = floatToDoubleArray(bs.getDashArray()); xTrapArray[0] = 0; xTrapArray = tesselateStrokeNative( points.getArray(), ops.getArray(), points.getSize(), ops.getSize(), xTrapArray, xTrapArray.length, lw, bs.getEndCap(), bs.getLineJoin(), bs.getMiterLimit(), dashArray, dashArray.length, bs.getDashPhase(), 1, 0, 0, 0, 1, 0, clip.getLoX(), clip.getLoY(), clip.getHiX(), clip.getHiY()); return new TrapezoidList(xTrapArray); }
public TrapezoidList tesselateFill(Shape s, AffineTransform at, Region clip) { int windingRule = convertPathData(s, at); xTrapArray[0] = 0; xTrapArray = tesselateFillNative( points.getArray(), ops.getArray(), points.getSize(), ops.getSize(), xTrapArray, xTrapArray.length, getCairoWindingRule(windingRule), clip.getLoX(), clip.getLoY(), clip.getHiX(), clip.getHiY()); return new TrapezoidList(xTrapArray); }
private void setClip(Region clip) { // assert rq.lock.isHeldByCurrentThread(); if (clip.isRectangular()) { rq.ensureCapacity(20); buf.putInt(SET_RECT_CLIP); buf.putInt(clip.getLoX()).putInt(clip.getLoY()); buf.putInt(clip.getHiX()).putInt(clip.getHiY()); } else { rq.ensureCapacity(28); // so that we have room for at least a span buf.putInt(BEGIN_SHAPE_CLIP); buf.putInt(SET_SHAPE_CLIP_SPANS); // include a placeholder for the span count int countIndex = buf.position(); buf.putInt(0); int spanCount = 0; int remainingSpans = buf.remaining() / BYTES_PER_SPAN; int span[] = new int[4]; SpanIterator si = clip.getSpanIterator(); while (si.nextSpan(span)) { if (remainingSpans == 0) { buf.putInt(countIndex, spanCount); rq.flushNow(); buf.putInt(SET_SHAPE_CLIP_SPANS); countIndex = buf.position(); buf.putInt(0); spanCount = 0; remainingSpans = buf.remaining() / BYTES_PER_SPAN; } buf.putInt(span[0]); // x1 buf.putInt(span[1]); // y1 buf.putInt(span[2]); // x2 buf.putInt(span[3]); // y2 spanCount++; remainingSpans--; } buf.putInt(countIndex, spanCount); rq.ensureCapacity(4); buf.putInt(END_SHAPE_CLIP); } }
/** * Validates the given parameters against the current state for this context. If this context is * not current, it will be made current for the given source and destination surfaces, and the * viewport will be updated. Then each part of the context state (clip, composite, etc.) is * checked against the previous value. If the value has changed since the last call to validate(), * it will be updated accordingly. * * <p>Note that the SunGraphics2D parameter is only used for the purposes of validating a * (non-null) Paint parameter. In all other cases it is safe to pass a null SunGraphics2D and it * will be ignored. * * <p>Note: must be called while the RenderQueue lock is held. * * @throws InvalidPipeException if either src or dest surface is not valid or lost */ public void validate( AccelSurface srcData, AccelSurface dstData, Region clip, Composite comp, AffineTransform xform, Paint paint, SunGraphics2D sg2d, int flags) { // assert rq.lock.isHeldByCurrentThread(); boolean updateClip = false; boolean updatePaint = false; if (!dstData.isValid() || dstData.isSurfaceLost() || srcData.isSurfaceLost()) { invalidateContext(); throw new InvalidPipeException("bounds changed or surface lost"); } if (paint instanceof Color) { // REMIND: not 30-bit friendly int newRGB = ((Color) paint).getRGB(); if (isValidatedPaintAColor) { if (newRGB != validatedRGB) { validatedRGB = newRGB; updatePaint = true; } } else { validatedRGB = newRGB; updatePaint = true; isValidatedPaintAColor = true; } } else if (validatedPaint != paint) { updatePaint = true; // this should be set when we are switching from paint to color // in which case this condition will be true isValidatedPaintAColor = false; } if ((currentContext != this) || (srcData != validatedSrcData) || (dstData != validatedDstData)) { if (dstData != validatedDstData) { // the clip is dependent on the destination surface, so we // need to update it if we have a new destination surface updateClip = true; } if (paint == null) { // make sure we update the color state (otherwise, it might // not be updated if this is the first time the context // is being validated) updatePaint = true; } // update the current source and destination surfaces setSurfaces(srcData, dstData); currentContext = this; validatedSrcData = srcData; validatedDstData = dstData; } // validate clip if ((clip != validatedClip) || updateClip) { if (clip != null) { if (updateClip || validatedClip == null || !(validatedClip.isRectangular() && clip.isRectangular()) || ((clip.getLoX() != validatedClip.getLoX() || clip.getLoY() != validatedClip.getLoY() || clip.getHiX() != validatedClip.getHiX() || clip.getHiY() != validatedClip.getHiY()))) { setClip(clip); } } else { resetClip(); } validatedClip = clip; } // validate composite (note that a change in the context flags // may require us to update the composite state, even if the // composite has not changed) if ((comp != validatedComp) || (flags != validatedFlags)) { if (comp != null) { setComposite(comp, flags); } else { resetComposite(); } // the paint state is dependent on the composite state, so make // sure we update the color below updatePaint = true; validatedComp = comp; validatedFlags = flags; } // validate transform boolean txChanged = false; if (xform == null) { if (xformInUse) { resetTransform(); xformInUse = false; txChanged = true; } else if (sg2d != null) { if (transX != sg2d.transX || transY != sg2d.transY) { txChanged = true; } } if (sg2d != null) { transX = sg2d.transX; transY = sg2d.transY; } } else { setTransform(xform); xformInUse = true; txChanged = true; } // non-Color paints may require paint revalidation if (!isValidatedPaintAColor && txChanged) { updatePaint = true; } // validate paint if (updatePaint) { if (paint != null) { BufferedPaints.setPaint(rq, sg2d, paint, flags); } else { BufferedPaints.resetPaint(rq); } validatedPaint = paint; } // mark dstData dirty // REMIND: is this really needed now? we do it in SunGraphics2D.. dstData.markDirty(); }