220 ctx.setLineJoin(linejoin);
221 ctx.setMiterLimit(miterlimit);
222 GrowableDataBuffer buf = ctx.getBuffer();
223 while (ctx.curState.numClipPaths > numClipPaths) {
224 ctx.curState.numClipPaths--;
225 ctx.clipStack.removeLast();
226 buf.putByte(NGCanvas.POP_CLIP);
227 }
228 ctx.setFillRule(fillRule);
229 ctx.setFont(font);
230 ctx.setTextAlign(textalign);
231 ctx.setTextBaseline(textbaseline);
232 ctx.setEffect(effect);
233 }
234 }
235
236 private GrowableDataBuffer getBuffer() {
237 return theCanvas.getBuffer();
238 }
239
240 private static float coords[] = new float[6];
241 private static final byte pgtype[] = {
242 NGCanvas.MOVETO,
243 NGCanvas.LINETO,
244 NGCanvas.QUADTO,
245 NGCanvas.CUBICTO,
246 NGCanvas.CLOSEPATH,
247 };
248 private static final int numsegs[] = { 2, 2, 4, 6, 0, };
249
250 private void markPathDirty() {
251 pathDirty = true;
252 }
253
254 private void writePath(byte command) {
255 updateTransform();
256 GrowableDataBuffer buf = getBuffer();
257 if (pathDirty) {
258 buf.putByte(NGCanvas.PATHSTART);
259 PathIterator pi = path.getPathIterator(null);
260 while (!pi.isDone()) {
568
569 /**
570 * Scales the current transform by x, y.
571 * @param x value to scale in the x axis.
572 * @param y value to scale in the y axis.
573 */
574 public void scale(double x, double y) {
575 curState.transform.scale(x, y);
576 txdirty = true;
577 }
578
579 /**
580 * Rotates the current transform in degrees.
581 * @param degrees value in degrees to rotate the current transform.
582 */
583 public void rotate(double degrees) {
584 curState.transform.rotate(Math.toRadians(degrees));
585 txdirty = true;
586 }
587
588 private static Affine2D scratchTX = new Affine2D();
589 /**
590 * Concatenates the input with the current transform.
591 *
592 * @param mxx - the X coordinate scaling element of the 3x4 matrix
593 * @param myx - the Y coordinate shearing element of the 3x4 matrix
594 * @param mxy - the X coordinate shearing element of the 3x4 matrix
595 * @param myy - the Y coordinate scaling element of the 3x4 matrix
596 * @param mxt - the X coordinate translation element of the 3x4 matrix
597 * @param myt - the Y coordinate translation element of the 3x4 matrix
598 */
599 public void transform(double mxx, double myx,
600 double mxy, double myy,
601 double mxt, double myt)
602 {
603 scratchTX.setTransform(mxx, myx,
604 mxy, myy,
605 mxt, myt);
606 curState.transform.concatenate(scratchTX);
607 txdirty = true;
608 }
609
610 /**
611 * Concatenates the input with the current transform. Only 2D transforms are
612 * supported. The only values used are the X and Y scaling, translation, and
613 * shearing components of a transform. A {@code null} value is treated as identity.
614 *
615 * @param xform The affine to be concatenated with the current transform or null.
616 */
617 public void transform(Affine xform) {
618 if (xform == null) return;
619 scratchTX.setTransform(xform.getMxx(), xform.getMyx(),
620 xform.getMxy(), xform.getMyy(),
621 xform.getTx(), xform.getTy());
622 curState.transform.concatenate(scratchTX);
623 txdirty = true;
624 }
625
626 /**
627 * Sets the current transform.
628 * @param mxx - the X coordinate scaling element of the 3x4 matrix
629 * @param myx - the Y coordinate shearing element of the 3x4 matrix
630 * @param mxy - the X coordinate shearing element of the 3x4 matrix
631 * @param myy - the Y coordinate scaling element of the 3x4 matrix
632 * @param mxt - the X coordinate translation element of the 3x4 matrix
633 * @param myt - the Y coordinate translation element of the 3x4 matrix
634 */
635 public void setTransform(double mxx, double myx,
636 double mxy, double myy,
637 double mxt, double myt)
638 {
639 curState.transform.setTransform(mxx, myx,
640 mxy, myy,
641 mxt, myt);
642 txdirty = true;
703 * @param alpha value in the range {@code 0.0-1.0}. The value is clamped if it is
704 * out of range.
705 */
706 public void setGlobalAlpha(double alpha) {
707 if (curState.globalAlpha != alpha) {
708 curState.globalAlpha = alpha;
709 alpha = (alpha > 1.0) ? 1.0 : (alpha < 0.0) ? 0.0 : alpha;
710 writeParam(alpha, NGCanvas.GLOBAL_ALPHA);
711 }
712 }
713
714 /**
715 * Gets the current global alpha.
716 *
717 * @return the current global alpha.
718 */
719 public double getGlobalAlpha() {
720 return curState.globalAlpha;
721 }
722
723 private static Blend TMP_BLEND = new Blend(BlendMode.SRC_OVER);
724 /**
725 * Sets the global blend mode.
726 * A {@code null} value will be ignored and the current value will remain unchanged.
727 *
728 * @param op the {@code BlendMode} that will be set or null.
729 */
730 public void setGlobalBlendMode(BlendMode op) {
731 if (op != null && op != curState.blendop) {
732 GrowableDataBuffer buf = getBuffer();
733 curState.blendop = op;
734 TMP_BLEND.setMode(op);
735 TMP_BLEND.impl_sync();
736 buf.putByte(NGCanvas.COMP_MODE);
737 buf.putObject(((com.sun.scenario.effect.Blend)TMP_BLEND.impl_getImpl()).getMode());
738 }
739 }
740
741 /**
742 * Gets the global blend mode.
743 *
744 * @return the global {@code BlendMode} of the current state.
745 */
746 public BlendMode getGlobalBlendMode() {
747 return curState.blendop;
748 }
749
750 /**
751 * Sets the current fill attribute. This method affects the paint used for any
752 * method with "fill" in it. For Example, fillRect(...), fillOval(...).
753 * A {@code null} value will be ignored and the current value will remain unchanged.
754 *
755 * @param p The {@code Paint} to be used as the fill {@code Paint} or null.
756 */
757 public void setFill(Paint p) {
1324 double cosqtrarc = Math.sqrt((1.0 + coshalfarc) / 2.0);
1325 double cv = 4.0 / 3.0 * sinqtrarc / (1.0 + cosqtrarc);
1326 if (ccw) cv = -cv;
1327 double midratio = radius / Math.sqrt(lenratioden);
1328 double midarcx = cx + (x1 - mx) * midratio;
1329 double midarcy = cy + (y1 - my) * midratio;
1330 double cpx0 = tx0 - cv * (ty0 - cy);
1331 double cpy0 = ty0 + cv * (tx0 - cx);
1332 double cpx1 = midarcx + cv * (midarcy - cy);
1333 double cpy1 = midarcy - cv * (midarcx - cx);
1334 bezierCurveTo(cpx0, cpy0, cpx1, cpy1, midarcx, midarcy);
1335 cpx0 = midarcx - cv * (midarcy - cy);
1336 cpy0 = midarcy + cv * (midarcx - cx);
1337 cpx1 = tx1 + cv * (ty1 - cy);
1338 cpy1 = ty1 - cv * (tx1 - cx);
1339 bezierCurveTo(cpx0, cpy0, cpx1, cpy1, tx1, ty1);
1340 }
1341 return true;
1342 }
1343
1344 private static final Arc2D TEMP_ARC = new Arc2D();
1345 /**
1346 * Adds path elements to the current path to make an arc that uses Euclidean
1347 * degrees. This Euclidean orientation sweeps from East to North, then West,
1348 * then South, then back to East.
1349 *
1350 * @param centerX the center x position of the arc.
1351 * @param centerY the center y position of the arc.
1352 * @param radiusX the x radius of the arc.
1353 * @param radiusY the y radius of the arc.
1354 * @param startAngle the starting angle of the arc in the range {@code 0-360.0}
1355 * @param length the length of the baseline of the arc.
1356 */
1357 public void arc(double centerX, double centerY,
1358 double radiusX, double radiusY,
1359 double startAngle, double length)
1360 {
1361 TEMP_ARC.setArc((float)(centerX - radiusX), // x
1362 (float)(centerY - radiusY), // y
1363 (float)(radiusX * 2.0), // w
1364 (float)(radiusY * 2.0), // h
1365 (float)startAngle,
1366 (float)length,
1367 Arc2D.OPEN);
1368 path.append(TEMP_ARC.getPathIterator(curState.transform), true);
1369 markPathDirty();
1370 }
1371
1372 /**
1373 * Adds path elements to the current path to make a rectangle.
1374 *
1375 * @param x x position of the upper left corner of the rectangle.
1376 * @param y y position of the upper left corner of the rectangle.
1377 * @param w width of the rectangle.
1378 * @param h height of the rectangle.
1379 */
1380 public void rect(double x, double y, double w, double h) {
1381 coords[0] = (float) x;
1382 coords[1] = (float) y;
1383 coords[2] = (float) w;
1384 coords[3] = (float) 0;
1385 coords[4] = (float) 0;
1386 coords[5] = (float) h;
1387 curState.transform.deltaTransform(coords, 0, coords, 0, 3);
1388 float x0 = coords[0] + (float) curState.transform.getMxt();
|
220 ctx.setLineJoin(linejoin);
221 ctx.setMiterLimit(miterlimit);
222 GrowableDataBuffer buf = ctx.getBuffer();
223 while (ctx.curState.numClipPaths > numClipPaths) {
224 ctx.curState.numClipPaths--;
225 ctx.clipStack.removeLast();
226 buf.putByte(NGCanvas.POP_CLIP);
227 }
228 ctx.setFillRule(fillRule);
229 ctx.setFont(font);
230 ctx.setTextAlign(textalign);
231 ctx.setTextBaseline(textbaseline);
232 ctx.setEffect(effect);
233 }
234 }
235
236 private GrowableDataBuffer getBuffer() {
237 return theCanvas.getBuffer();
238 }
239
240 private float coords[] = new float[6];
241 private static final byte pgtype[] = {
242 NGCanvas.MOVETO,
243 NGCanvas.LINETO,
244 NGCanvas.QUADTO,
245 NGCanvas.CUBICTO,
246 NGCanvas.CLOSEPATH,
247 };
248 private static final int numsegs[] = { 2, 2, 4, 6, 0, };
249
250 private void markPathDirty() {
251 pathDirty = true;
252 }
253
254 private void writePath(byte command) {
255 updateTransform();
256 GrowableDataBuffer buf = getBuffer();
257 if (pathDirty) {
258 buf.putByte(NGCanvas.PATHSTART);
259 PathIterator pi = path.getPathIterator(null);
260 while (!pi.isDone()) {
568
569 /**
570 * Scales the current transform by x, y.
571 * @param x value to scale in the x axis.
572 * @param y value to scale in the y axis.
573 */
574 public void scale(double x, double y) {
575 curState.transform.scale(x, y);
576 txdirty = true;
577 }
578
579 /**
580 * Rotates the current transform in degrees.
581 * @param degrees value in degrees to rotate the current transform.
582 */
583 public void rotate(double degrees) {
584 curState.transform.rotate(Math.toRadians(degrees));
585 txdirty = true;
586 }
587
588 /**
589 * Concatenates the input with the current transform.
590 *
591 * @param mxx - the X coordinate scaling element of the 3x4 matrix
592 * @param myx - the Y coordinate shearing element of the 3x4 matrix
593 * @param mxy - the X coordinate shearing element of the 3x4 matrix
594 * @param myy - the Y coordinate scaling element of the 3x4 matrix
595 * @param mxt - the X coordinate translation element of the 3x4 matrix
596 * @param myt - the Y coordinate translation element of the 3x4 matrix
597 */
598 public void transform(double mxx, double myx,
599 double mxy, double myy,
600 double mxt, double myt)
601 {
602 curState.transform.concatenate(mxx, mxy, mxt,
603 myx, myy, myt);
604 txdirty = true;
605 }
606
607 /**
608 * Concatenates the input with the current transform. Only 2D transforms are
609 * supported. The only values used are the X and Y scaling, translation, and
610 * shearing components of a transform. A {@code null} value is treated as identity.
611 *
612 * @param xform The affine to be concatenated with the current transform or null.
613 */
614 public void transform(Affine xform) {
615 if (xform == null) return;
616 curState.transform.concatenate(xform.getMxx(), xform.getMxy(), xform.getTx(),
617 xform.getMyx(), xform.getMyy(), xform.getTy());
618 txdirty = true;
619 }
620
621 /**
622 * Sets the current transform.
623 * @param mxx - the X coordinate scaling element of the 3x4 matrix
624 * @param myx - the Y coordinate shearing element of the 3x4 matrix
625 * @param mxy - the X coordinate shearing element of the 3x4 matrix
626 * @param myy - the Y coordinate scaling element of the 3x4 matrix
627 * @param mxt - the X coordinate translation element of the 3x4 matrix
628 * @param myt - the Y coordinate translation element of the 3x4 matrix
629 */
630 public void setTransform(double mxx, double myx,
631 double mxy, double myy,
632 double mxt, double myt)
633 {
634 curState.transform.setTransform(mxx, myx,
635 mxy, myy,
636 mxt, myt);
637 txdirty = true;
698 * @param alpha value in the range {@code 0.0-1.0}. The value is clamped if it is
699 * out of range.
700 */
701 public void setGlobalAlpha(double alpha) {
702 if (curState.globalAlpha != alpha) {
703 curState.globalAlpha = alpha;
704 alpha = (alpha > 1.0) ? 1.0 : (alpha < 0.0) ? 0.0 : alpha;
705 writeParam(alpha, NGCanvas.GLOBAL_ALPHA);
706 }
707 }
708
709 /**
710 * Gets the current global alpha.
711 *
712 * @return the current global alpha.
713 */
714 public double getGlobalAlpha() {
715 return curState.globalAlpha;
716 }
717
718 /**
719 * Sets the global blend mode.
720 * A {@code null} value will be ignored and the current value will remain unchanged.
721 *
722 * @param op the {@code BlendMode} that will be set or null.
723 */
724 public void setGlobalBlendMode(BlendMode op) {
725 if (op != null && op != curState.blendop) {
726 GrowableDataBuffer buf = getBuffer();
727 curState.blendop = op;
728 buf.putByte(NGCanvas.COMP_MODE);
729 buf.putObject(Blend.impl_getToolkitMode(op));
730 }
731 }
732
733 /**
734 * Gets the global blend mode.
735 *
736 * @return the global {@code BlendMode} of the current state.
737 */
738 public BlendMode getGlobalBlendMode() {
739 return curState.blendop;
740 }
741
742 /**
743 * Sets the current fill attribute. This method affects the paint used for any
744 * method with "fill" in it. For Example, fillRect(...), fillOval(...).
745 * A {@code null} value will be ignored and the current value will remain unchanged.
746 *
747 * @param p The {@code Paint} to be used as the fill {@code Paint} or null.
748 */
749 public void setFill(Paint p) {
1316 double cosqtrarc = Math.sqrt((1.0 + coshalfarc) / 2.0);
1317 double cv = 4.0 / 3.0 * sinqtrarc / (1.0 + cosqtrarc);
1318 if (ccw) cv = -cv;
1319 double midratio = radius / Math.sqrt(lenratioden);
1320 double midarcx = cx + (x1 - mx) * midratio;
1321 double midarcy = cy + (y1 - my) * midratio;
1322 double cpx0 = tx0 - cv * (ty0 - cy);
1323 double cpy0 = ty0 + cv * (tx0 - cx);
1324 double cpx1 = midarcx + cv * (midarcy - cy);
1325 double cpy1 = midarcy - cv * (midarcx - cx);
1326 bezierCurveTo(cpx0, cpy0, cpx1, cpy1, midarcx, midarcy);
1327 cpx0 = midarcx - cv * (midarcy - cy);
1328 cpy0 = midarcy + cv * (midarcx - cx);
1329 cpx1 = tx1 + cv * (ty1 - cy);
1330 cpy1 = ty1 - cv * (tx1 - cx);
1331 bezierCurveTo(cpx0, cpy0, cpx1, cpy1, tx1, ty1);
1332 }
1333 return true;
1334 }
1335
1336 /**
1337 * Adds path elements to the current path to make an arc that uses Euclidean
1338 * degrees. This Euclidean orientation sweeps from East to North, then West,
1339 * then South, then back to East.
1340 *
1341 * @param centerX the center x position of the arc.
1342 * @param centerY the center y position of the arc.
1343 * @param radiusX the x radius of the arc.
1344 * @param radiusY the y radius of the arc.
1345 * @param startAngle the starting angle of the arc in the range {@code 0-360.0}
1346 * @param length the length of the baseline of the arc.
1347 */
1348 public void arc(double centerX, double centerY,
1349 double radiusX, double radiusY,
1350 double startAngle, double length)
1351 {
1352 Arc2D arc = new Arc2D((float) (centerX - radiusX), // x
1353 (float) (centerY - radiusY), // y
1354 (float) (radiusX * 2.0), // w
1355 (float) (radiusY * 2.0), // h
1356 (float) startAngle,
1357 (float) length,
1358 Arc2D.OPEN);
1359 path.append(arc.getPathIterator(curState.transform), true);
1360 markPathDirty();
1361 }
1362
1363 /**
1364 * Adds path elements to the current path to make a rectangle.
1365 *
1366 * @param x x position of the upper left corner of the rectangle.
1367 * @param y y position of the upper left corner of the rectangle.
1368 * @param w width of the rectangle.
1369 * @param h height of the rectangle.
1370 */
1371 public void rect(double x, double y, double w, double h) {
1372 coords[0] = (float) x;
1373 coords[1] = (float) y;
1374 coords[2] = (float) w;
1375 coords[3] = (float) 0;
1376 coords[4] = (float) 0;
1377 coords[5] = (float) h;
1378 curState.transform.deltaTransform(coords, 0, coords, 0, 3);
1379 float x0 = coords[0] + (float) curState.transform.getMxt();
|