1 /*
2 * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
2011 }
2012
2013 public boolean intersects(double x, double y, double w, double h) {
2014 return false; // Not called
2015 }
2016
2017 public boolean contains(double x, double y, double w, double h) {
2018 return false; // Not called
2019 }
2020
2021 public PathIterator getPathIterator(AffineTransform at) {
2022 return new RoundishRectIterator(this, at);
2023 }
2024
2025
2026 static class RoundishRectIterator implements PathIterator {
2027 double x, y, w, h, aw, ah;
2028 AffineTransform affine;
2029 int index;
2030
2031 double ctrlpts[][];
2032 int types[];
2033
2034 private static final double angle = Math.PI / 4.0;
2035 private static final double a = 1.0 - Math.cos(angle);
2036 private static final double b = Math.tan(angle);
2037 private static final double c = Math.sqrt(1.0 + b * b) - 1 + a;
2038 private static final double cv = 4.0 / 3.0 * a * b / c;
2039 private static final double acv = (1.0 - cv) / 2.0;
2040
2041 // For each array:
2042 // 4 values for each point {v0, v1, v2, v3}:
2043 // point = (x + v0 * w + v1 * arcWidth,
2044 // y + v2 * h + v3 * arcHeight);
2045 private static final double CtrlPtTemplate[][] = {
2046 { 0.0, 0.0, 1.0, 0.0 }, /* BOTTOM LEFT corner */
2047 { 0.0, 0.0, 1.0, -0.5 }, /* BOTTOM LEFT arc start */
2048 { 0.0, 0.0, 1.0, -acv, /* BOTTOM LEFT arc curve */
2049 0.0, acv, 1.0, 0.0,
2050 0.0, 0.5, 1.0, 0.0 },
2051 { 1.0, 0.0, 1.0, 0.0 }, /* BOTTOM RIGHT corner */
2052 { 1.0, -0.5, 1.0, 0.0 }, /* BOTTOM RIGHT arc start */
2053 { 1.0, -acv, 1.0, 0.0, /* BOTTOM RIGHT arc curve */
2054 1.0, 0.0, 1.0, -acv,
2055 1.0, 0.0, 1.0, -0.5 },
2056 { 1.0, 0.0, 0.0, 0.0 }, /* TOP RIGHT corner */
2057 { 1.0, 0.0, 0.0, 0.5 }, /* TOP RIGHT arc start */
2058 { 1.0, 0.0, 0.0, acv, /* TOP RIGHT arc curve */
2059 1.0, -acv, 0.0, 0.0,
2060 1.0, -0.5, 0.0, 0.0 },
2061 { 0.0, 0.0, 0.0, 0.0 }, /* TOP LEFT corner */
2062 { 0.0, 0.5, 0.0, 0.0 }, /* TOP LEFT arc start */
2063 { 0.0, acv, 0.0, 0.0, /* TOP LEFT arc curve */
2064 0.0, 0.0, 0.0, acv,
2065 0.0, 0.0, 0.0, 0.5 },
2066 {}, /* Closing path element */
2067 };
2068 private static final int CornerFlags[] = {
2069 RoundRectClipShape.BOTTOM_LEFT,
2070 RoundRectClipShape.BOTTOM_RIGHT,
2071 RoundRectClipShape.TOP_RIGHT,
2072 RoundRectClipShape.TOP_LEFT,
2073 };
2074
2075 RoundishRectIterator(RoundRectClipShape rr, AffineTransform at) {
2076 this.x = rr.getX();
2077 this.y = rr.getY();
2078 this.w = rr.getWidth();
2079 this.h = rr.getHeight();
2080 this.aw = Math.min(w, Math.abs(rr.getArcWidth()));
2081 this.ah = Math.min(h, Math.abs(rr.getArcHeight()));
2082 this.affine = at;
2083 if (w < 0 || h < 0) {
2084 // Don't draw anything...
2085 ctrlpts = new double[0][];
2086 types = new int[0];
2087 } else {
2088 int corners = rr.getCornerFlags();
2109 types[0] = SEG_MOVETO;
2110 }
2111 }
2112
2113 public int getWindingRule() {
2114 return WIND_NON_ZERO;
2115 }
2116
2117 public boolean isDone() {
2118 return index >= ctrlpts.length;
2119 }
2120
2121 public void next() {
2122 index++;
2123 }
2124
2125 public int currentSegment(float[] coords) {
2126 if (isDone()) {
2127 throw new NoSuchElementException("roundrect iterator out of bounds");
2128 }
2129 double ctrls[] = ctrlpts[index];
2130 int nc = 0;
2131 for (int i = 0; i < ctrls.length; i += 4) {
2132 coords[nc++] = (float) (x + ctrls[i + 0] * w + ctrls[i + 1] * aw);
2133 coords[nc++] = (float) (y + ctrls[i + 2] * h + ctrls[i + 3] * ah);
2134 }
2135 if (affine != null) {
2136 affine.transform(coords, 0, coords, 0, nc / 2);
2137 }
2138 return types[index];
2139 }
2140
2141 public int currentSegment(double[] coords) {
2142 if (isDone()) {
2143 throw new NoSuchElementException("roundrect iterator out of bounds");
2144 }
2145 double ctrls[] = ctrlpts[index];
2146 int nc = 0;
2147 for (int i = 0; i < ctrls.length; i += 4) {
2148 coords[nc++] = x + ctrls[i + 0] * w + ctrls[i + 1] * aw;
2149 coords[nc++] = y + ctrls[i + 2] * h + ctrls[i + 3] * ah;
2150 }
2151 if (affine != null) {
2152 affine.transform(coords, 0, coords, 0, nc / 2);
2153 }
2154 return types[index];
2155 }
2156 }
2157 }
2158 }
|
1 /*
2 * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
2011 }
2012
2013 public boolean intersects(double x, double y, double w, double h) {
2014 return false; // Not called
2015 }
2016
2017 public boolean contains(double x, double y, double w, double h) {
2018 return false; // Not called
2019 }
2020
2021 public PathIterator getPathIterator(AffineTransform at) {
2022 return new RoundishRectIterator(this, at);
2023 }
2024
2025
2026 static class RoundishRectIterator implements PathIterator {
2027 double x, y, w, h, aw, ah;
2028 AffineTransform affine;
2029 int index;
2030
2031 double[][] ctrlpts;
2032 int[] types;
2033
2034 private static final double angle = Math.PI / 4.0;
2035 private static final double a = 1.0 - Math.cos(angle);
2036 private static final double b = Math.tan(angle);
2037 private static final double c = Math.sqrt(1.0 + b * b) - 1 + a;
2038 private static final double cv = 4.0 / 3.0 * a * b / c;
2039 private static final double acv = (1.0 - cv) / 2.0;
2040
2041 // For each array:
2042 // 4 values for each point {v0, v1, v2, v3}:
2043 // point = (x + v0 * w + v1 * arcWidth,
2044 // y + v2 * h + v3 * arcHeight);
2045 private static final double[][] CtrlPtTemplate = {
2046 { 0.0, 0.0, 1.0, 0.0 }, /* BOTTOM LEFT corner */
2047 { 0.0, 0.0, 1.0, -0.5 }, /* BOTTOM LEFT arc start */
2048 { 0.0, 0.0, 1.0, -acv, /* BOTTOM LEFT arc curve */
2049 0.0, acv, 1.0, 0.0,
2050 0.0, 0.5, 1.0, 0.0 },
2051 { 1.0, 0.0, 1.0, 0.0 }, /* BOTTOM RIGHT corner */
2052 { 1.0, -0.5, 1.0, 0.0 }, /* BOTTOM RIGHT arc start */
2053 { 1.0, -acv, 1.0, 0.0, /* BOTTOM RIGHT arc curve */
2054 1.0, 0.0, 1.0, -acv,
2055 1.0, 0.0, 1.0, -0.5 },
2056 { 1.0, 0.0, 0.0, 0.0 }, /* TOP RIGHT corner */
2057 { 1.0, 0.0, 0.0, 0.5 }, /* TOP RIGHT arc start */
2058 { 1.0, 0.0, 0.0, acv, /* TOP RIGHT arc curve */
2059 1.0, -acv, 0.0, 0.0,
2060 1.0, -0.5, 0.0, 0.0 },
2061 { 0.0, 0.0, 0.0, 0.0 }, /* TOP LEFT corner */
2062 { 0.0, 0.5, 0.0, 0.0 }, /* TOP LEFT arc start */
2063 { 0.0, acv, 0.0, 0.0, /* TOP LEFT arc curve */
2064 0.0, 0.0, 0.0, acv,
2065 0.0, 0.0, 0.0, 0.5 },
2066 {}, /* Closing path element */
2067 };
2068 private static final int[] CornerFlags = {
2069 RoundRectClipShape.BOTTOM_LEFT,
2070 RoundRectClipShape.BOTTOM_RIGHT,
2071 RoundRectClipShape.TOP_RIGHT,
2072 RoundRectClipShape.TOP_LEFT,
2073 };
2074
2075 RoundishRectIterator(RoundRectClipShape rr, AffineTransform at) {
2076 this.x = rr.getX();
2077 this.y = rr.getY();
2078 this.w = rr.getWidth();
2079 this.h = rr.getHeight();
2080 this.aw = Math.min(w, Math.abs(rr.getArcWidth()));
2081 this.ah = Math.min(h, Math.abs(rr.getArcHeight()));
2082 this.affine = at;
2083 if (w < 0 || h < 0) {
2084 // Don't draw anything...
2085 ctrlpts = new double[0][];
2086 types = new int[0];
2087 } else {
2088 int corners = rr.getCornerFlags();
2109 types[0] = SEG_MOVETO;
2110 }
2111 }
2112
2113 public int getWindingRule() {
2114 return WIND_NON_ZERO;
2115 }
2116
2117 public boolean isDone() {
2118 return index >= ctrlpts.length;
2119 }
2120
2121 public void next() {
2122 index++;
2123 }
2124
2125 public int currentSegment(float[] coords) {
2126 if (isDone()) {
2127 throw new NoSuchElementException("roundrect iterator out of bounds");
2128 }
2129 double[] ctrls = ctrlpts[index];
2130 int nc = 0;
2131 for (int i = 0; i < ctrls.length; i += 4) {
2132 coords[nc++] = (float) (x + ctrls[i + 0] * w + ctrls[i + 1] * aw);
2133 coords[nc++] = (float) (y + ctrls[i + 2] * h + ctrls[i + 3] * ah);
2134 }
2135 if (affine != null) {
2136 affine.transform(coords, 0, coords, 0, nc / 2);
2137 }
2138 return types[index];
2139 }
2140
2141 public int currentSegment(double[] coords) {
2142 if (isDone()) {
2143 throw new NoSuchElementException("roundrect iterator out of bounds");
2144 }
2145 double[] ctrls = ctrlpts[index];
2146 int nc = 0;
2147 for (int i = 0; i < ctrls.length; i += 4) {
2148 coords[nc++] = x + ctrls[i + 0] * w + ctrls[i + 1] * aw;
2149 coords[nc++] = y + ctrls[i + 2] * h + ctrls[i + 3] * ah;
2150 }
2151 if (affine != null) {
2152 affine.transform(coords, 0, coords, 0, nc / 2);
2153 }
2154 return types[index];
2155 }
2156 }
2157 }
2158 }
|