1 /*
2 * Copyright (c) 2005, 2014, 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
843 * simple
844 */
845 hnd.dhnd.xMinf >= xMin ||
846 hnd.dhnd.xMaxf <= xMax ||
847 hnd.dhnd.yMinf >= yMin ||
848 hnd.dhnd.yMaxf <= yMax,
849 pixelInfo);
850 }
851 }
852
853 /*
854 * Split quadratic curve into monotonic in X and Y parts. Calling
855 * ProcessMonotonicQuad for each monotonic piece of the curve.
856 * Note: coords array could be changed
857 */
858 private static void ProcessQuad(ProcessHandler hnd, float[] coords,
859 int[] pixelInfo) {
860 /* Temporary array for holding parameters corresponding to the extreme
861 * in X and Y points
862 */
863 double params[] = new double[2];
864 int cnt = 0;
865 double param;
866
867 /* Simple check for monotonicity in X before searching for the extreme
868 * points of the X(t) function. We first check if the curve is
869 * monotonic in X by seeing if all of the X coordinates are strongly
870 * ordered.
871 */
872 if ((coords[0] > coords[2] || coords[2] > coords[4]) &&
873 (coords[0] < coords[2] || coords[2] < coords[4]))
874 {
875 /* Searching for extreme points of the X(t) function by solving
876 * dX(t)
877 * ---- = 0 equation
878 * dt
879 */
880 double ax = coords[0] - 2*coords[2] + coords[4];
881 if (ax != 0) {
882 /* Calculating root of the following equation
883 * ax*t + bx = 0
1211 hnd.dhnd.xMinf > xMin ||
1212 hnd.dhnd.xMaxf < xMax ||
1213 hnd.dhnd.yMinf > yMin ||
1214 hnd.dhnd.yMaxf < yMax,
1215 pixelInfo);
1216 }
1217 }
1218
1219 /*
1220 * Split cubic curve into monotonic in X and Y parts. Calling
1221 * ProcessMonotonicCubic for each monotonic piece of the curve.
1222 *
1223 * Note: coords array could be changed
1224 */
1225 private static void ProcessCubic(ProcessHandler hnd,
1226 float[] coords,
1227 int[] pixelInfo) {
1228 /* Temporary array for holding parameters corresponding to the extreme
1229 * in X and Y points
1230 */
1231 double params[] = new double[4];
1232 double eqn[] = new double[3];
1233 double res[] = new double[2];
1234 int cnt = 0;
1235
1236 /* Simple check for monotonicity in X before searching for the extreme
1237 * points of the X(t) function. We first check if the curve is
1238 * monotonic in X by seeing if all of the X coordinates are strongly
1239 * ordered.
1240 */
1241 if ((coords[0] > coords[2] || coords[2] > coords[4] ||
1242 coords[4] > coords[6]) &&
1243 (coords[0] < coords[2] || coords[2] < coords[4] ||
1244 coords[4] < coords[6]))
1245 {
1246 /* Searching for extreme points of the X(t) function by solving
1247 * dX(t)
1248 * ---- = 0 equation
1249 * dt
1250 */
1251 eqn[2] = -coords[0] + 3*coords[2] - 3*coords[4] + coords[6];
1252 eqn[1] = 2*(coords[0] - 2*coords[2] + coords[4]);
1253 eqn[0] = -coords[0] + coords[2];
1345 coords[5] = coords[5] + t*(coords[7] - coords[5]);
1346 coords[2] = tx + t*(coords[4] - tx);
1347 coords[3] = ty + t*(coords[5] - ty);
1348 coords[0]=coords1[6]=coords1[4] + t*(coords[2] - coords1[4]);
1349 coords[1]=coords1[7]=coords1[5] + t*(coords[3] - coords1[5]);
1350
1351 ProcessMonotonicCubic(hnd, coords1, pixelInfo);
1352 }
1353
1354 /* Note:
1355 * For more easy reading of the code below each java version of the macros
1356 * from the ProcessPath.c preceded by the commented origin call
1357 * containing verbose names of the parameters
1358 */
1359 private static void ProcessLine(ProcessHandler hnd, float x1, float y1,
1360 float x2, float y2, int[] pixelInfo) {
1361 float xMin, yMin, xMax, yMax;
1362 int X1, Y1, X2, Y2, X3, Y3, res;
1363 boolean clipped = false;
1364 float x3,y3;
1365 float c[] = new float[]{x1, y1, x2, y2, 0, 0};
1366
1367 boolean lastClipped;
1368
1369 xMin = hnd.dhnd.xMinf;
1370 yMin = hnd.dhnd.yMinf;
1371 xMax = hnd.dhnd.xMaxf;
1372 yMax = hnd.dhnd.yMaxf;
1373
1374 //
1375 // TESTANDCLIP(yMin, yMax, y1, x1, y2, x2, res);
1376 //
1377 res = TESTANDCLIP(yMin, yMax, c, 1, 0, 3, 2);
1378 if (res == CRES_INVISIBLE) return;
1379 clipped = IS_CLIPPED(res);
1380 //
1381 // TESTANDCLIP(yMin, yMax, y2, x2, y1, x1, res);
1382 //
1383 res = TESTANDCLIP(yMin, yMax, c, 3, 2, 1, 0);
1384 if (res == CRES_INVISIBLE) return;
1385 lastClipped = IS_CLIPPED(res);
1449 lastClipped = lastClipped || (res == CRES_MAX_CLIPPED);
1450
1451 X2 = (int)(c[2]*MDP_MULT);
1452 Y2 = (int)(c[3]*MDP_MULT);
1453 hnd.processFixedLine(X1, Y1, X2, Y2, pixelInfo,
1454 false, lastClipped);
1455
1456 /* Clamping only by left boundary */
1457 if (res == CRES_MIN_CLIPPED) {
1458 X3 = (int)(c[4]*MDP_MULT);
1459 Y3 = (int)(c[5]*MDP_MULT);
1460 hnd.processFixedLine(X2, Y2, X3, Y3, pixelInfo,
1461 false, lastClipped);
1462 }
1463 }
1464 }
1465
1466 private static boolean doProcessPath(ProcessHandler hnd,
1467 Path2D.Float p2df,
1468 float transXf, float transYf) {
1469 float coords[] = new float[8];
1470 float tCoords[] = new float[8];
1471 float closeCoord[] = new float[] {0.0f, 0.0f};
1472 float firstCoord[] = new float[2];
1473 int pixelInfo[] = new int[5];
1474 boolean subpathStarted = false;
1475 boolean skip = false;
1476 float lastX, lastY;
1477 pixelInfo[0] = 0;
1478
1479 /* Adjusting boundaries to the capabilities of the
1480 * ProcessPath code
1481 */
1482 hnd.dhnd.adjustBounds(LOWER_OUT_BND, LOWER_OUT_BND,
1483 UPPER_OUT_BND, UPPER_OUT_BND);
1484
1485 /* Adding support of the KEY_STROKE_CONTROL rendering hint.
1486 * Now we are supporting two modes: "pixels at centers" and
1487 * "pixels at corners".
1488 * First one is disabled by default but could be enabled by setting
1489 * VALUE_STROKE_PURE to the rendering hint. It means that pixel at the
1490 * screen (x,y) has (x + 0.5, y + 0.5) float coordinates.
1491 *
1492 * Second one is enabled by default and means straightforward mapping
1493 * (x,y) --> (x,y)
2026 */
2027 public void processFixedLine(int x1, int y1, int x2, int y2,
2028 int[] pixelInfo, boolean checkBounds,
2029 boolean endSubPath)
2030 {
2031 int outXMin, outXMax, outYMin, outYMax;
2032 int res;
2033
2034 /* There is no need to round line coordinates to the forward
2035 * differencing precision anymore. Such a rounding was used for
2036 * preventing the curve go out the endpoint (this sometimes does
2037 * not help). The problem was fixed in the forward differencing
2038 * loops.
2039 */
2040 if (checkBounds) {
2041 boolean lastClipped;
2042
2043 /* This function is used only for filling shapes, so there is no
2044 * check for the type of clipping
2045 */
2046 int c[] = new int[]{x1, y1, x2, y2, 0, 0};
2047 outXMin = (int)(dhnd.xMinf * MDP_MULT);
2048 outXMax = (int)(dhnd.xMaxf * MDP_MULT);
2049 outYMin = (int)(dhnd.yMinf * MDP_MULT);
2050 outYMax = (int)(dhnd.yMaxf * MDP_MULT);
2051
2052 /*
2053 * TESTANDCLIP(outYMin, outYMax, y1, x1, y2, x2, res);
2054 */
2055 res = TESTANDCLIP(outYMin, outYMax, c, 1, 0, 3, 2);
2056 if (res == CRES_INVISIBLE) return;
2057
2058 /*
2059 * TESTANDCLIP(outYMin, outYMax, y2, x2, y1, x1, res);
2060 */
2061 res = TESTANDCLIP(outYMin, outYMax, c, 3, 2, 1, 0);
2062 if (res == CRES_INVISIBLE) return;
2063 lastClipped = IS_CLIPPED(res);
2064
2065 /* Clamping starting from first vertex of the processed
2066 * segment
|
1 /*
2 * Copyright (c) 2005, 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
843 * simple
844 */
845 hnd.dhnd.xMinf >= xMin ||
846 hnd.dhnd.xMaxf <= xMax ||
847 hnd.dhnd.yMinf >= yMin ||
848 hnd.dhnd.yMaxf <= yMax,
849 pixelInfo);
850 }
851 }
852
853 /*
854 * Split quadratic curve into monotonic in X and Y parts. Calling
855 * ProcessMonotonicQuad for each monotonic piece of the curve.
856 * Note: coords array could be changed
857 */
858 private static void ProcessQuad(ProcessHandler hnd, float[] coords,
859 int[] pixelInfo) {
860 /* Temporary array for holding parameters corresponding to the extreme
861 * in X and Y points
862 */
863 double[] params = new double[2];
864 int cnt = 0;
865 double param;
866
867 /* Simple check for monotonicity in X before searching for the extreme
868 * points of the X(t) function. We first check if the curve is
869 * monotonic in X by seeing if all of the X coordinates are strongly
870 * ordered.
871 */
872 if ((coords[0] > coords[2] || coords[2] > coords[4]) &&
873 (coords[0] < coords[2] || coords[2] < coords[4]))
874 {
875 /* Searching for extreme points of the X(t) function by solving
876 * dX(t)
877 * ---- = 0 equation
878 * dt
879 */
880 double ax = coords[0] - 2*coords[2] + coords[4];
881 if (ax != 0) {
882 /* Calculating root of the following equation
883 * ax*t + bx = 0
1211 hnd.dhnd.xMinf > xMin ||
1212 hnd.dhnd.xMaxf < xMax ||
1213 hnd.dhnd.yMinf > yMin ||
1214 hnd.dhnd.yMaxf < yMax,
1215 pixelInfo);
1216 }
1217 }
1218
1219 /*
1220 * Split cubic curve into monotonic in X and Y parts. Calling
1221 * ProcessMonotonicCubic for each monotonic piece of the curve.
1222 *
1223 * Note: coords array could be changed
1224 */
1225 private static void ProcessCubic(ProcessHandler hnd,
1226 float[] coords,
1227 int[] pixelInfo) {
1228 /* Temporary array for holding parameters corresponding to the extreme
1229 * in X and Y points
1230 */
1231 double[] params = new double[4];
1232 double[] eqn = new double[3];
1233 double[] res = new double[2];
1234 int cnt = 0;
1235
1236 /* Simple check for monotonicity in X before searching for the extreme
1237 * points of the X(t) function. We first check if the curve is
1238 * monotonic in X by seeing if all of the X coordinates are strongly
1239 * ordered.
1240 */
1241 if ((coords[0] > coords[2] || coords[2] > coords[4] ||
1242 coords[4] > coords[6]) &&
1243 (coords[0] < coords[2] || coords[2] < coords[4] ||
1244 coords[4] < coords[6]))
1245 {
1246 /* Searching for extreme points of the X(t) function by solving
1247 * dX(t)
1248 * ---- = 0 equation
1249 * dt
1250 */
1251 eqn[2] = -coords[0] + 3*coords[2] - 3*coords[4] + coords[6];
1252 eqn[1] = 2*(coords[0] - 2*coords[2] + coords[4]);
1253 eqn[0] = -coords[0] + coords[2];
1345 coords[5] = coords[5] + t*(coords[7] - coords[5]);
1346 coords[2] = tx + t*(coords[4] - tx);
1347 coords[3] = ty + t*(coords[5] - ty);
1348 coords[0]=coords1[6]=coords1[4] + t*(coords[2] - coords1[4]);
1349 coords[1]=coords1[7]=coords1[5] + t*(coords[3] - coords1[5]);
1350
1351 ProcessMonotonicCubic(hnd, coords1, pixelInfo);
1352 }
1353
1354 /* Note:
1355 * For more easy reading of the code below each java version of the macros
1356 * from the ProcessPath.c preceded by the commented origin call
1357 * containing verbose names of the parameters
1358 */
1359 private static void ProcessLine(ProcessHandler hnd, float x1, float y1,
1360 float x2, float y2, int[] pixelInfo) {
1361 float xMin, yMin, xMax, yMax;
1362 int X1, Y1, X2, Y2, X3, Y3, res;
1363 boolean clipped = false;
1364 float x3,y3;
1365 float[] c = new float[]{x1, y1, x2, y2, 0, 0};
1366
1367 boolean lastClipped;
1368
1369 xMin = hnd.dhnd.xMinf;
1370 yMin = hnd.dhnd.yMinf;
1371 xMax = hnd.dhnd.xMaxf;
1372 yMax = hnd.dhnd.yMaxf;
1373
1374 //
1375 // TESTANDCLIP(yMin, yMax, y1, x1, y2, x2, res);
1376 //
1377 res = TESTANDCLIP(yMin, yMax, c, 1, 0, 3, 2);
1378 if (res == CRES_INVISIBLE) return;
1379 clipped = IS_CLIPPED(res);
1380 //
1381 // TESTANDCLIP(yMin, yMax, y2, x2, y1, x1, res);
1382 //
1383 res = TESTANDCLIP(yMin, yMax, c, 3, 2, 1, 0);
1384 if (res == CRES_INVISIBLE) return;
1385 lastClipped = IS_CLIPPED(res);
1449 lastClipped = lastClipped || (res == CRES_MAX_CLIPPED);
1450
1451 X2 = (int)(c[2]*MDP_MULT);
1452 Y2 = (int)(c[3]*MDP_MULT);
1453 hnd.processFixedLine(X1, Y1, X2, Y2, pixelInfo,
1454 false, lastClipped);
1455
1456 /* Clamping only by left boundary */
1457 if (res == CRES_MIN_CLIPPED) {
1458 X3 = (int)(c[4]*MDP_MULT);
1459 Y3 = (int)(c[5]*MDP_MULT);
1460 hnd.processFixedLine(X2, Y2, X3, Y3, pixelInfo,
1461 false, lastClipped);
1462 }
1463 }
1464 }
1465
1466 private static boolean doProcessPath(ProcessHandler hnd,
1467 Path2D.Float p2df,
1468 float transXf, float transYf) {
1469 float[] coords = new float[8];
1470 float[] tCoords = new float[8];
1471 float[] closeCoord = new float[] {0.0f, 0.0f};
1472 float[] firstCoord = new float[2];
1473 int[] pixelInfo = new int[5];
1474 boolean subpathStarted = false;
1475 boolean skip = false;
1476 float lastX, lastY;
1477 pixelInfo[0] = 0;
1478
1479 /* Adjusting boundaries to the capabilities of the
1480 * ProcessPath code
1481 */
1482 hnd.dhnd.adjustBounds(LOWER_OUT_BND, LOWER_OUT_BND,
1483 UPPER_OUT_BND, UPPER_OUT_BND);
1484
1485 /* Adding support of the KEY_STROKE_CONTROL rendering hint.
1486 * Now we are supporting two modes: "pixels at centers" and
1487 * "pixels at corners".
1488 * First one is disabled by default but could be enabled by setting
1489 * VALUE_STROKE_PURE to the rendering hint. It means that pixel at the
1490 * screen (x,y) has (x + 0.5, y + 0.5) float coordinates.
1491 *
1492 * Second one is enabled by default and means straightforward mapping
1493 * (x,y) --> (x,y)
2026 */
2027 public void processFixedLine(int x1, int y1, int x2, int y2,
2028 int[] pixelInfo, boolean checkBounds,
2029 boolean endSubPath)
2030 {
2031 int outXMin, outXMax, outYMin, outYMax;
2032 int res;
2033
2034 /* There is no need to round line coordinates to the forward
2035 * differencing precision anymore. Such a rounding was used for
2036 * preventing the curve go out the endpoint (this sometimes does
2037 * not help). The problem was fixed in the forward differencing
2038 * loops.
2039 */
2040 if (checkBounds) {
2041 boolean lastClipped;
2042
2043 /* This function is used only for filling shapes, so there is no
2044 * check for the type of clipping
2045 */
2046 int[] c = new int[]{x1, y1, x2, y2, 0, 0};
2047 outXMin = (int)(dhnd.xMinf * MDP_MULT);
2048 outXMax = (int)(dhnd.xMaxf * MDP_MULT);
2049 outYMin = (int)(dhnd.yMinf * MDP_MULT);
2050 outYMax = (int)(dhnd.yMaxf * MDP_MULT);
2051
2052 /*
2053 * TESTANDCLIP(outYMin, outYMax, y1, x1, y2, x2, res);
2054 */
2055 res = TESTANDCLIP(outYMin, outYMax, c, 1, 0, 3, 2);
2056 if (res == CRES_INVISIBLE) return;
2057
2058 /*
2059 * TESTANDCLIP(outYMin, outYMax, y2, x2, y1, x1, res);
2060 */
2061 res = TESTANDCLIP(outYMin, outYMax, c, 3, 2, 1, 0);
2062 if (res == CRES_INVISIBLE) return;
2063 lastClipped = IS_CLIPPED(res);
2064
2065 /* Clamping starting from first vertex of the processed
2066 * segment
|