< prev index next >

src/java.desktop/share/classes/sun/java2d/loops/ProcessPath.java

Print this page


   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


< prev index next >