jdk/src/share/classes/sun/java2d/pisces/Renderer.java
author ohair
Tue, 28 Dec 2010 15:53:50 -0800
changeset 7668 d4a77089c587
parent 6997 3642614e2282
child 8131 e2932d8114cb
permissions -rw-r--r--
6962318: Update copyright year Reviewed-by: xdono
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
7668
d4a77089c587 6962318: Update copyright year
ohair
parents: 6997
diff changeset
     2
 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4244
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4244
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4244
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4244
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4244
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.java2d.pisces;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    28
import java.util.Arrays;
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    29
import java.util.Iterator;
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    30
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    31
import sun.awt.geom.PathConsumer2D;
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    32
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    33
public class Renderer implements PathConsumer2D {
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    34
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    35
    private class ScanlineIterator {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    36
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    37
        private int[] crossings;
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    38
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    39
        // crossing bounds. The bounds are not necessarily tight (the scan line
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    40
        // at minY, for example, might have no crossings). The x bounds will
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    41
        // be accumulated as crossings are computed.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    42
        private int minY, maxY;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    43
        private int nextY;
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    44
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    45
        // indices into the segment pointer lists. They indicate the "active"
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    46
        // sublist in the segment lists (the portion of the list that contains
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    47
        // all the segments that cross the next scan line).
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    48
        private int elo, ehi;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    49
        private final int[] edgePtrs;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    50
        private int qlo, qhi;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    51
        private final int[] quadPtrs;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    52
        private int clo, chi;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    53
        private final int[] curvePtrs;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    54
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    55
        private static final int INIT_CROSSINGS_SIZE = 10;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    56
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    57
        private ScanlineIterator() {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    58
            crossings = new int[INIT_CROSSINGS_SIZE];
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    59
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    60
            edgePtrs = new int[numEdges];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    61
            Helpers.fillWithIdxes(edgePtrs, SIZEOF_EDGE);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    62
            qsort(edges, edgePtrs, YMIN, 0, numEdges - 1);
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    63
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    64
            quadPtrs = new int[numQuads];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    65
            Helpers.fillWithIdxes(quadPtrs, SIZEOF_QUAD);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    66
            qsort(quads, quadPtrs, YMIN, 0, numQuads - 1);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    67
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    68
            curvePtrs = new int[numCurves];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    69
            Helpers.fillWithIdxes(curvePtrs, SIZEOF_CURVE);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    70
            qsort(curves, curvePtrs, YMIN, 0, numCurves - 1);
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    71
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    72
            // We don't care if we clip some of the line off with ceil, since
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    73
            // no scan line crossings will be eliminated (in fact, the ceil is
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    74
            // the y of the first scan line crossing).
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    75
            nextY = minY = Math.max(boundsMinY, (int)Math.ceil(edgeMinY));
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    76
            maxY = Math.min(boundsMaxY, (int)Math.ceil(edgeMaxY));
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    77
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    78
            for (elo = 0; elo < numEdges && edges[edgePtrs[elo]+YMAX] <= minY; elo++)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    79
                ;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    80
            // the active list is *edgePtrs[lo] (inclusive) *edgePtrs[hi] (exclusive)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    81
            for (ehi = elo; ehi < numEdges && edges[edgePtrs[ehi]+YMIN] <= minY; ehi++)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    82
                edgeSetCurY(edgePtrs[ehi], minY);// TODO: make minY a float to avoid casts
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    83
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    84
            for (qlo = 0; qlo < numQuads && quads[quadPtrs[qlo]+YMAX] <= minY; qlo++)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    85
                ;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    86
            for (qhi = qlo; qhi < numQuads && quads[quadPtrs[qhi]+YMIN] <= minY; qhi++)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    87
                quadSetCurY(quadPtrs[qhi], minY);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    88
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    89
            for (clo = 0; clo < numCurves && curves[curvePtrs[clo]+YMAX] <= minY; clo++)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    90
                ;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    91
            for (chi = clo; chi < numCurves && curves[curvePtrs[chi]+YMIN] <= minY; chi++)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    92
                curveSetCurY(curvePtrs[chi], minY);
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    93
        }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
    94
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    95
        private int next() {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    96
            // we go through the active lists and remove segments that don't cross
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    97
            // the nextY scanline.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    98
            int crossingIdx = 0;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
    99
            for (int i = elo; i < ehi; i++) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   100
                if (edges[edgePtrs[i]+YMAX] <= nextY) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   101
                    edgePtrs[i] = edgePtrs[elo++];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   102
                }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   103
            }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   104
            for (int i = qlo; i < qhi; i++) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   105
                if (quads[quadPtrs[i]+YMAX] <= nextY) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   106
                    quadPtrs[i] = quadPtrs[qlo++];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   107
                }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   108
            }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   109
            for (int i = clo; i < chi; i++) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   110
                if (curves[curvePtrs[i]+YMAX] <= nextY) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   111
                    curvePtrs[i] = curvePtrs[clo++];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   112
                }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   113
            }
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   114
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   115
            crossings = Helpers.widenArray(crossings, 0, ehi-elo+qhi-qlo+chi-clo);
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   116
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   117
            // Now every edge between lo and hi crosses nextY. Compute it's
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   118
            // crossing and put it in the crossings array.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   119
            for (int i = elo; i < ehi; i++) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   120
                int ptr = edgePtrs[i];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   121
                addCrossing(nextY, (int)edges[ptr+CURX], edges[ptr+OR], crossingIdx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   122
                edgeGoToNextY(ptr);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   123
                crossingIdx++;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   124
            }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   125
            for (int i = qlo; i < qhi; i++) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   126
                int ptr = quadPtrs[i];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   127
                addCrossing(nextY, (int)quads[ptr+CURX], quads[ptr+OR], crossingIdx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   128
                quadGoToNextY(ptr);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   129
                crossingIdx++;
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   130
            }
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   131
            for (int i = clo; i < chi; i++) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   132
                int ptr = curvePtrs[i];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   133
                addCrossing(nextY, (int)curves[ptr+CURX], curves[ptr+OR], crossingIdx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   134
                curveGoToNextY(ptr);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   135
                crossingIdx++;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   136
            }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   137
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   138
            nextY++;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   139
            // Expand active lists to include new edges.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   140
            for (; ehi < numEdges && edges[edgePtrs[ehi]+YMIN] <= nextY; ehi++) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   141
                edgeSetCurY(edgePtrs[ehi], nextY);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   142
            }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   143
            for (; qhi < numQuads && quads[quadPtrs[qhi]+YMIN] <= nextY; qhi++) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   144
                quadSetCurY(quadPtrs[qhi], nextY);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   145
            }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   146
            for (; chi < numCurves && curves[curvePtrs[chi]+YMIN] <= nextY; chi++) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   147
                curveSetCurY(curvePtrs[chi], nextY);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   148
            }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   149
            Arrays.sort(crossings, 0, crossingIdx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   150
            return crossingIdx;
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   151
        }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   152
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   153
        private boolean hasNext() {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   154
            return nextY < maxY;
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   155
        }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   156
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   157
        private int curY() {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   158
            return nextY - 1;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   159
        }
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   160
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   161
        private void addCrossing(int y, int x, float or, int idx) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   162
            x <<= 1;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   163
            crossings[idx] = ((or > 0) ? (x | 0x1) : x);
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   164
        }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   165
    }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   166
    // quicksort implementation for sorting the edge indices ("pointers")
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   167
    // by increasing y0. first, last are indices into the "pointer" array
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   168
    // It sorts the pointer array from first (inclusive) to last (inclusive)
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   169
    private static void qsort(final float[] data, final int[] ptrs,
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   170
                              final int fieldForCmp, int first, int last)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   171
    {
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   172
        if (last > first) {
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   173
            int p = partition(data, ptrs, fieldForCmp, first, last);
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   174
            if (first < p - 1) {
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   175
                qsort(data, ptrs, fieldForCmp, first, p - 1);
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   176
            }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   177
            if (p < last) {
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   178
                qsort(data, ptrs, fieldForCmp, p, last);
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   179
            }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   180
        }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   181
    }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   182
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   183
    // i, j are indices into edgePtrs.
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   184
    private static int partition(final float[] data, final int[] ptrs,
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   185
                                 final int fieldForCmp, int i, int j)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   186
    {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   187
        int pivotValFieldForCmp = ptrs[i]+fieldForCmp;
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   188
        while (i <= j) {
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   189
            // edges[edgePtrs[i]+1] is equivalent to (*(edgePtrs[i])).y0 in C
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   190
            while (data[ptrs[i]+fieldForCmp] < data[pivotValFieldForCmp])
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   191
                i++;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   192
            while (data[ptrs[j]+fieldForCmp] > data[pivotValFieldForCmp])
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   193
                j--;
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   194
            if (i <= j) {
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   195
                int tmp = ptrs[i];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   196
                ptrs[i] = ptrs[j];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   197
                ptrs[j] = tmp;
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   198
                i++;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   199
                j--;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   200
            }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   201
        }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   202
        return i;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   203
    }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   204
//============================================================================
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   205
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   206
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   207
//////////////////////////////////////////////////////////////////////////////
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   208
//  EDGE LIST
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   209
//////////////////////////////////////////////////////////////////////////////
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   210
// TODO(maybe): very tempting to use fixed point here. A lot of opportunities
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   211
// for shifts and just removing certain operations altogether.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   212
// TODO: it might be worth it to make an EdgeList class. It would probably
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   213
// clean things up a bit and not impact performance much.
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   214
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   215
    // common to all types of input path segments.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   216
    private static final int YMIN = 0;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   217
    private static final int YMAX = 1;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   218
    private static final int CURX = 2;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   219
    // this and OR are meant to be indeces into "int" fields, but arrays must
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   220
    // be homogenous, so every field is a float. However floats can represent
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   221
    // exactly up to 26 bit ints, so we're ok.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   222
    private static final int CURY = 3;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   223
    private static final int OR   = 4;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   224
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   225
    // for straight lines only:
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   226
    private static final int SLOPE = 5;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   227
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   228
    // for quads and cubics:
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   229
    private static final int X0 = 5;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   230
    private static final int Y0 = 6;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   231
    private static final int XL = 7;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   232
    private static final int COUNT = 8;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   233
    private static final int CURSLOPE = 9;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   234
    private static final int DX = 10;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   235
    private static final int DY = 11;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   236
    private static final int DDX = 12;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   237
    private static final int DDY = 13;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   238
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   239
    // for cubics only
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   240
    private static final int DDDX = 14;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   241
    private static final int DDDY = 15;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   242
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   243
    private float edgeMinY = Float.POSITIVE_INFINITY;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   244
    private float edgeMaxY = Float.NEGATIVE_INFINITY;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   245
    private float edgeMinX = Float.POSITIVE_INFINITY;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   246
    private float edgeMaxX = Float.NEGATIVE_INFINITY;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   247
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   248
    private static final int SIZEOF_EDGE = 6;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   249
    private float[] edges = null;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   250
    private int numEdges;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   251
    // these are static because we need them to be usable from ScanlineIterator
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   252
    private void edgeSetCurY(final int idx, int y) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   253
        edges[idx+CURX] += (y - edges[idx+CURY]) * edges[idx+SLOPE];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   254
        edges[idx+CURY] = y;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   255
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   256
    private void edgeGoToNextY(final int idx) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   257
        edges[idx+CURY] += 1;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   258
        edges[idx+CURX] += edges[idx+SLOPE];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   259
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   260
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   261
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   262
    private static final int SIZEOF_QUAD = 14;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   263
    private float[] quads = null;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   264
    private int numQuads;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   265
    // This function should be called exactly once, to set the first scanline
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   266
    // of the curve. Before it is called, the curve should think its first
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   267
    // scanline is CEIL(YMIN).
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   268
    private void quadSetCurY(final int idx, final int y) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   269
        assert y < quads[idx+YMAX];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   270
        assert (quads[idx+CURY] > y);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   271
        assert (quads[idx+CURY] == Math.ceil(quads[idx+CURY]));
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   272
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   273
        while (quads[idx+CURY] < ((float)y)) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   274
            quadGoToNextY(idx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   275
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   276
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   277
    private void quadGoToNextY(final int idx) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   278
        quads[idx+CURY] += 1;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   279
        // this will get overriden if the while executes.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   280
        quads[idx+CURX] += quads[idx+CURSLOPE];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   281
        int count = (int)quads[idx+COUNT];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   282
        // this loop should never execute more than once because our
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   283
        // curve is monotonic in Y. Still we put it in because you can
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   284
        // never be too sure when dealing with floating point.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   285
        while(quads[idx+CURY] >= quads[idx+Y0] && count > 0) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   286
            float x0 = quads[idx+X0], y0 = quads[idx+Y0];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   287
            count = executeQuadAFDIteration(idx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   288
            float x1 = quads[idx+X0], y1 = quads[idx+Y0];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   289
            // our quads are monotonic, so this shouldn't happen, but
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   290
            // it is conceivable that for very flat quads with different
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   291
            // y values at their endpoints AFD might give us a horizontal
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   292
            // segment.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   293
            if (y1 == y0) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   294
                continue;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   295
            }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   296
            quads[idx+CURSLOPE] = (x1 - x0) / (y1 - y0);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   297
            quads[idx+CURX] = x0 + (quads[idx+CURY] - y0) * quads[idx+CURSLOPE];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   298
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   299
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   300
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   301
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   302
    private static final int SIZEOF_CURVE = 16;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   303
    private float[] curves = null;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   304
    private int numCurves;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   305
    private void curveSetCurY(final int idx, final int y) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   306
        assert y < curves[idx+YMAX];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   307
        assert (curves[idx+CURY] > y);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   308
        assert (curves[idx+CURY] == Math.ceil(curves[idx+CURY]));
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   309
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   310
        while (curves[idx+CURY] < ((float)y)) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   311
            curveGoToNextY(idx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   312
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   313
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   314
    private void curveGoToNextY(final int idx) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   315
        curves[idx+CURY] += 1;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   316
        // this will get overriden if the while executes.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   317
        curves[idx+CURX] += curves[idx+CURSLOPE];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   318
        int count = (int)curves[idx+COUNT];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   319
        // this loop should never execute more than once because our
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   320
        // curve is monotonic in Y. Still we put it in because you can
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   321
        // never be too sure when dealing with floating point.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   322
        while(curves[idx+CURY] >= curves[idx+Y0] && count > 0) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   323
            float x0 = curves[idx+X0], y0 = curves[idx+Y0];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   324
            count = executeCurveAFDIteration(idx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   325
            float x1 = curves[idx+X0], y1 = curves[idx+Y0];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   326
            // our curves are monotonic, so this shouldn't happen, but
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   327
            // it is conceivable that for very flat curves with different
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   328
            // y values at their endpoints AFD might give us a horizontal
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   329
            // segment.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   330
            if (y1 == y0) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   331
                continue;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   332
            }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   333
            curves[idx+CURSLOPE] = (x1 - x0) / (y1 - y0);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   334
            curves[idx+CURX] = x0 + (curves[idx+CURY] - y0) * curves[idx+CURSLOPE];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   335
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   336
    }
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   337
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   338
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   339
    private static final float DEC_BND = 20f;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   340
    private static final float INC_BND = 8f;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   341
    // Flattens using adaptive forward differencing. This only carries out
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   342
    // one iteration of the AFD loop. All it does is update AFD variables (i.e.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   343
    // X0, Y0, D*[X|Y], COUNT; not variables used for computing scanline crossings).
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   344
    private int executeQuadAFDIteration(int idx) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   345
        int count = (int)quads[idx+COUNT];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   346
        float ddx = quads[idx+DDX];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   347
        float ddy = quads[idx+DDY];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   348
        float dx = quads[idx+DX];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   349
        float dy = quads[idx+DY];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   350
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   351
        while (Math.abs(ddx) > DEC_BND || Math.abs(ddy) > DEC_BND) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   352
            ddx = ddx / 4;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   353
            ddy = ddy / 4;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   354
            dx = (dx - ddx) / 2;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   355
            dy = (dy - ddy) / 2;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   356
            count <<= 1;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   357
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   358
        // can only do this on even "count" values, because we must divide count by 2
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   359
        while (count % 2 == 0 && Math.abs(dx) <= INC_BND && Math.abs(dy) <= INC_BND) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   360
            dx = 2 * dx + ddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   361
            dy = 2 * dy + ddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   362
            ddx = 4 * ddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   363
            ddy = 4 * ddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   364
            count >>= 1;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   365
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   366
        count--;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   367
        if (count > 0) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   368
            quads[idx+X0] += dx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   369
            dx += ddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   370
            quads[idx+Y0] += dy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   371
            dy += ddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   372
        } else {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   373
            quads[idx+X0] = quads[idx+XL];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   374
            quads[idx+Y0] = quads[idx+YMAX];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   375
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   376
        quads[idx+COUNT] = count;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   377
        quads[idx+DDX] = ddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   378
        quads[idx+DDY] = ddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   379
        quads[idx+DX] = dx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   380
        quads[idx+DY] = dy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   381
        return count;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   382
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   383
    private int executeCurveAFDIteration(int idx) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   384
        int count = (int)curves[idx+COUNT];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   385
        float ddx = curves[idx+DDX];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   386
        float ddy = curves[idx+DDY];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   387
        float dx = curves[idx+DX];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   388
        float dy = curves[idx+DY];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   389
        float dddx = curves[idx+DDDX];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   390
        float dddy = curves[idx+DDDY];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   391
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   392
        while (Math.abs(ddx) > DEC_BND || Math.abs(ddy) > DEC_BND) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   393
            dddx /= 8;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   394
            dddy /= 8;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   395
            ddx = ddx/4 - dddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   396
            ddy = ddy/4 - dddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   397
            dx = (dx - ddx) / 2;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   398
            dy = (dy - ddy) / 2;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   399
            count <<= 1;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   400
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   401
        // can only do this on even "count" values, because we must divide count by 2
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   402
        while (count % 2 == 0 && Math.abs(dx) <= INC_BND && Math.abs(dy) <= INC_BND) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   403
            dx = 2 * dx + ddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   404
            dy = 2 * dy + ddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   405
            ddx = 4 * (ddx + dddx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   406
            ddy = 4 * (ddy + dddy);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   407
            dddx = 8 * dddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   408
            dddy = 8 * dddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   409
            count >>= 1;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   410
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   411
        count--;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   412
        if (count > 0) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   413
            curves[idx+X0] += dx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   414
            dx += ddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   415
            ddx += dddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   416
            curves[idx+Y0] += dy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   417
            dy += ddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   418
            ddy += dddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   419
        } else {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   420
            curves[idx+X0] = curves[idx+XL];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   421
            curves[idx+Y0] = curves[idx+YMAX];
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   422
        }
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   423
        curves[idx+COUNT] = count;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   424
        curves[idx+DDDX] = dddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   425
        curves[idx+DDDY] = dddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   426
        curves[idx+DDX] = ddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   427
        curves[idx+DDY] = ddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   428
        curves[idx+DX] = dx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   429
        curves[idx+DY] = dy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   430
        return count;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   431
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   432
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   433
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   434
    private void initLine(final int idx, float[] pts, int or) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   435
        edges[idx+SLOPE] = (pts[2] - pts[0]) / (pts[3] - pts[1]);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   436
        edges[idx+CURX] = pts[0] + (edges[idx+CURY] - pts[1]) * edges[idx+SLOPE];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   437
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   438
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   439
    private void initQuad(final int idx, float[] points, int or) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   440
        final int countlg = 3;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   441
        final int count = 1 << countlg;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   442
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   443
        // the dx and dy refer to forward differencing variables, not the last
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   444
        // coefficients of the "points" polynomial
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   445
        final float ddx, ddy, dx, dy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   446
        c.set(points, 6);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   447
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   448
        ddx = c.dbx / (1 << (2 * countlg));
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   449
        ddy = c.dby / (1 << (2 * countlg));
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   450
        dx = c.bx / (1 << (2 * countlg)) + c.cx / (1 << countlg);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   451
        dy = c.by / (1 << (2 * countlg)) + c.cy / (1 << countlg);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   452
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   453
        quads[idx+DDX] = ddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   454
        quads[idx+DDY] = ddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   455
        quads[idx+DX] = dx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   456
        quads[idx+DY] = dy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   457
        quads[idx+COUNT] = count;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   458
        quads[idx+XL] = points[4];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   459
        quads[idx+X0] = points[0];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   460
        quads[idx+Y0] = points[1];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   461
        executeQuadAFDIteration(idx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   462
        float x1 = quads[idx+X0], y1 = quads[idx+Y0];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   463
        quads[idx+CURSLOPE] = (x1 - points[0]) / (y1 - points[1]);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   464
        quads[idx+CURX] = points[0] + (quads[idx+CURY] - points[1])*quads[idx+CURSLOPE];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   465
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   466
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   467
    private void initCurve(final int idx, float[] points, int or) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   468
        final int countlg = 3;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   469
        final int count = 1 << countlg;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   470
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   471
        // the dx and dy refer to forward differencing variables, not the last
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   472
        // coefficients of the "points" polynomial
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   473
        final float dddx, dddy, ddx, ddy, dx, dy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   474
        c.set(points, 8);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   475
        dddx = 2f * c.dax / (1 << (3 * countlg));
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   476
        dddy = 2f * c.day / (1 << (3 * countlg));
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   477
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   478
        ddx = dddx + c.dbx / (1 << (2 * countlg));
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   479
        ddy = dddy + c.dby / (1 << (2 * countlg));
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   480
        dx = c.ax / (1 << (3 * countlg)) + c.bx / (1 << (2 * countlg)) + c.cx / (1 << countlg);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   481
        dy = c.ay / (1 << (3 * countlg)) + c.by / (1 << (2 * countlg)) + c.cy / (1 << countlg);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   482
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   483
        curves[idx+DDDX] = dddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   484
        curves[idx+DDDY] = dddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   485
        curves[idx+DDX] = ddx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   486
        curves[idx+DDY] = ddy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   487
        curves[idx+DX] = dx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   488
        curves[idx+DY] = dy;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   489
        curves[idx+COUNT] = count;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   490
        curves[idx+XL] = points[6];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   491
        curves[idx+X0] = points[0];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   492
        curves[idx+Y0] = points[1];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   493
        executeCurveAFDIteration(idx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   494
        float x1 = curves[idx+X0], y1 = curves[idx+Y0];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   495
        curves[idx+CURSLOPE] = (x1 - points[0]) / (y1 - points[1]);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   496
        curves[idx+CURX] = points[0] + (curves[idx+CURY] - points[1])*curves[idx+CURSLOPE];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   497
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   498
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   499
    private void addPathSegment(float[] pts, final int type, final int or) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   500
        int idx;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   501
        float[] addTo;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   502
        switch (type) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   503
        case 4:
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   504
            idx = numEdges * SIZEOF_EDGE;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   505
            addTo = edges = Helpers.widenArray(edges, numEdges*SIZEOF_EDGE, SIZEOF_EDGE);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   506
            numEdges++;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   507
            break;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   508
        case 6:
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   509
            idx = numQuads * SIZEOF_QUAD;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   510
            addTo = quads = Helpers.widenArray(quads, numQuads*SIZEOF_QUAD, SIZEOF_QUAD);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   511
            numQuads++;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   512
            break;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   513
        case 8:
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   514
            idx = numCurves * SIZEOF_CURVE;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   515
            addTo = curves = Helpers.widenArray(curves, numCurves*SIZEOF_CURVE, SIZEOF_CURVE);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   516
            numCurves++;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   517
            break;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   518
        default:
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   519
            throw new InternalError();
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   520
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   521
        // set the common fields, except CURX, for which we must know the kind
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   522
        // of curve. NOTE: this must be done before the type specific fields
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   523
        // are initialized, because those depend on the common ones.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   524
        addTo[idx+YMIN] = pts[1];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   525
        addTo[idx+YMAX] = pts[type-1];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   526
        addTo[idx+OR] = or;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   527
        addTo[idx+CURY] = (float)Math.ceil(pts[1]);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   528
        switch (type) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   529
        case 4:
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   530
            initLine(idx, pts, or);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   531
            break;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   532
        case 6:
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   533
            initQuad(idx, pts, or);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   534
            break;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   535
        case 8:
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   536
            initCurve(idx, pts, or);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   537
            break;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   538
        default:
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   539
            throw new InternalError();
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   540
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   541
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   542
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   543
    // precondition: the curve in pts must be monotonic and increasing in y.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   544
    private void somethingTo(float[] pts, final int type, final int or) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   545
        // NOTE: it's very important that we check for or >= 0 below (as
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   546
        // opposed to or == 1, or or > 0, or anything else). That's
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   547
        // because if we check for or==1, when the curve being added
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   548
        // is a horizontal line, or will be 0 so or==1 will be false and
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   549
        // x0 and y0 will be updated to pts[0] and pts[1] instead of pts[type-2]
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   550
        // and pts[type-1], which is the correct thing to do.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   551
        this.x0 = or >= 0 ? pts[type - 2] : pts[0];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   552
        this.y0 = or >= 0 ? pts[type - 1] : pts[1];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   553
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   554
        float minY = pts[1], maxY = pts[type - 1];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   555
        if (Math.ceil(minY) >= Math.ceil(maxY) ||
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   556
            Math.ceil(minY) >= boundsMaxY || maxY < boundsMinY)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   557
        {
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   558
            return;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   559
        }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   560
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   561
        if (minY < edgeMinY) { edgeMinY = minY; }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   562
        if (maxY > edgeMaxY) { edgeMaxY = maxY; }
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   563
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   564
        int minXidx = (pts[0] < pts[type-2] ? 0 : type - 2);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   565
        float minX = pts[minXidx];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   566
        float maxX = pts[type - 2 - minXidx];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   567
        if (minX < edgeMinX) { edgeMinX = minX; }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   568
        if (maxX > edgeMaxX) { edgeMaxX = maxX; }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   569
        addPathSegment(pts, type, or);
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   570
    }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   571
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   572
// END EDGE LIST
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   573
//////////////////////////////////////////////////////////////////////////////
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   574
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   575
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
    public static final int WIND_EVEN_ODD = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
    public static final int WIND_NON_ZERO = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
    // Antialiasing
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   580
    final private int SUBPIXEL_LG_POSITIONS_X;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   581
    final private int SUBPIXEL_LG_POSITIONS_Y;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   582
    final private int SUBPIXEL_POSITIONS_X;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   583
    final private int SUBPIXEL_POSITIONS_Y;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   584
    final private int SUBPIXEL_MASK_X;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   585
    final private int SUBPIXEL_MASK_Y;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   586
    final int MAX_AA_ALPHA;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    // Cache to store RLE-encoded coverage mask of the current primitive
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   589
    PiscesCache cache;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   591
    // Bounds of the drawing region, at subpixel precision.
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   592
    private final int boundsMinX, boundsMinY, boundsMaxX, boundsMaxY;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    // Current winding rule
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   595
    private final int windingRule;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    // Current drawing position, i.e., final point of last segment
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   598
    private float x0, y0;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
    // Position of most recent 'moveTo' command
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   601
    private float pix_sx0, pix_sy0;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   603
    public Renderer(int subpixelLgPositionsX, int subpixelLgPositionsY,
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   604
                    int pix_boundsX, int pix_boundsY,
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   605
                    int pix_boundsWidth, int pix_boundsHeight,
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   606
                    int windingRule)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   607
    {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        this.SUBPIXEL_LG_POSITIONS_X = subpixelLgPositionsX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        this.SUBPIXEL_LG_POSITIONS_Y = subpixelLgPositionsY;
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   610
        this.SUBPIXEL_MASK_X = (1 << (SUBPIXEL_LG_POSITIONS_X)) - 1;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   611
        this.SUBPIXEL_MASK_Y = (1 << (SUBPIXEL_LG_POSITIONS_Y)) - 1;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   612
        this.SUBPIXEL_POSITIONS_X = 1 << (SUBPIXEL_LG_POSITIONS_X);
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   613
        this.SUBPIXEL_POSITIONS_Y = 1 << (SUBPIXEL_LG_POSITIONS_Y);
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   614
        this.MAX_AA_ALPHA = (SUBPIXEL_POSITIONS_X * SUBPIXEL_POSITIONS_Y);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   616
        this.windingRule = windingRule;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   618
        this.boundsMinX = pix_boundsX * SUBPIXEL_POSITIONS_X;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   619
        this.boundsMinY = pix_boundsY * SUBPIXEL_POSITIONS_Y;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   620
        this.boundsMaxX = (pix_boundsX + pix_boundsWidth) * SUBPIXEL_POSITIONS_X;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   621
        this.boundsMaxY = (pix_boundsY + pix_boundsHeight) * SUBPIXEL_POSITIONS_Y;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   624
    private float tosubpixx(float pix_x) {
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   625
        return pix_x * SUBPIXEL_POSITIONS_X;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   626
    }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   627
    private float tosubpixy(float pix_y) {
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   628
        return pix_y * SUBPIXEL_POSITIONS_Y;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   631
    public void moveTo(float pix_x0, float pix_y0) {
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   632
        closePath();
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   633
        this.pix_sx0 = pix_x0;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   634
        this.pix_sy0 = pix_y0;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   635
        this.y0 = tosubpixy(pix_y0);
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   636
        this.x0 = tosubpixx(pix_x0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   639
    public void lineJoin() { /* do nothing */ }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   641
    private final float[][] pts = new float[2][8];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   642
    private final float[] ts = new float[4];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   643
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   644
    private static void invertPolyPoints(float[] pts, int off, int type) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   645
        for (int i = off, j = off + type - 2; i < j; i += 2, j -= 2) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   646
            float tmp = pts[i];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   647
            pts[i] = pts[j];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   648
            pts[j] = tmp;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   649
            tmp = pts[i+1];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   650
            pts[i+1] = pts[j+1];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   651
            pts[j+1] = tmp;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   652
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   653
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   655
    // return orientation before making the curve upright.
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   656
    private static int makeMonotonicCurveUpright(float[] pts, int off, int type) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   657
        float y0 = pts[off + 1];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   658
        float y1 = pts[off + type - 1];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   659
        if (y0 > y1) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   660
            invertPolyPoints(pts, off, type);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   661
            return -1;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   662
        } else if (y0 < y1) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   663
            return 1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        }
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   665
        return 0;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   666
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   668
    public void lineTo(float pix_x1, float pix_y1) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   669
        pts[0][0] = x0; pts[0][1] = y0;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   670
        pts[0][2] = tosubpixx(pix_x1); pts[0][3] = tosubpixy(pix_y1);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   671
        int or = makeMonotonicCurveUpright(pts[0], 0, 4);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   672
        somethingTo(pts[0], 4, or);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   675
    Curve c = new Curve();
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   676
    private void curveOrQuadTo(int type) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   677
        c.set(pts[0], type);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   678
        int numTs = c.dxRoots(ts, 0);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   679
        numTs += c.dyRoots(ts, numTs);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   680
        numTs = Helpers.filterOutNotInAB(ts, 0, numTs, 0, 1);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   681
        Helpers.isort(ts, 0, numTs);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   682
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   683
        Iterator<float[]> it = Curve.breakPtsAtTs(pts, type, ts, numTs);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   684
        while(it.hasNext()) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   685
            float[] curCurve = it.next();
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   686
            int or = makeMonotonicCurveUpright(curCurve, 0, type);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   687
            somethingTo(curCurve, type, or);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   688
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   689
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   690
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   691
    @Override public void curveTo(float x1, float y1,
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   692
                                  float x2, float y2,
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   693
                                  float x3, float y3)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   694
    {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   695
        pts[0][0] = x0; pts[0][1] = y0;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   696
        pts[0][2] = tosubpixx(x1); pts[0][3] = tosubpixy(y1);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   697
        pts[0][4] = tosubpixx(x2); pts[0][5] = tosubpixy(y2);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   698
        pts[0][6] = tosubpixx(x3); pts[0][7] = tosubpixy(y3);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   699
        curveOrQuadTo(8);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   700
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   701
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   702
    @Override public void quadTo(float x1, float y1, float x2, float y2) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   703
        pts[0][0] = x0; pts[0][1] = y0;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   704
        pts[0][2] = tosubpixx(x1); pts[0][3] = tosubpixy(y1);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   705
        pts[0][4] = tosubpixx(x2); pts[0][5] = tosubpixy(y2);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   706
        curveOrQuadTo(6);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   707
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   708
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   709
    public void closePath() {
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   710
        // lineTo expects its input in pixel coordinates.
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   711
        lineTo(pix_sx0, pix_sy0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   714
    public void pathDone() {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   715
        closePath();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   718
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   719
    @Override
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   720
    public long getNativeConsumer() {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   721
        throw new InternalError("Renderer does not use a native consumer.");
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   722
    }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   723
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   724
    private void _endRendering(final int pix_bboxx0, final int pix_bboxy0,
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   725
                               final int pix_bboxx1, final int pix_bboxy1)
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   726
    {
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   727
        // Mask to determine the relevant bit of the crossing sum
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   728
        // 0x1 if EVEN_ODD, all bits if NON_ZERO
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   729
        int mask = (windingRule == WIND_EVEN_ODD) ? 0x1 : ~0x0;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   730
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   731
        // add 1 to better deal with the last pixel in a pixel row.
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   732
        int width = pix_bboxx1 - pix_bboxx0 + 1;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   733
        int[] alpha = new int[width+1];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   734
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   735
        int bboxx0 = pix_bboxx0 << SUBPIXEL_LG_POSITIONS_X;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   736
        int bboxx1 = pix_bboxx1 << SUBPIXEL_LG_POSITIONS_X;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   738
        // Now we iterate through the scanlines. We must tell emitRow the coord
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   739
        // of the first non-transparent pixel, so we must keep accumulators for
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   740
        // the first and last pixels of the section of the current pixel row
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   741
        // that we will emit.
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   742
        // We also need to accumulate pix_bbox*, but the iterator does it
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   743
        // for us. We will just get the values from it once this loop is done
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   744
        int pix_maxX = Integer.MIN_VALUE;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   745
        int pix_minX = Integer.MAX_VALUE;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   747
        int y = boundsMinY; // needs to be declared here so we emit the last row properly.
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   748
        ScanlineIterator it = this.new ScanlineIterator();
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   749
        for ( ; it.hasNext(); ) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   750
            int numCrossings = it.next();
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   751
            int[] crossings = it.crossings;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   752
            y = it.curY();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   754
            if (numCrossings > 0) {
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   755
                int lowx = crossings[0] >> 1;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   756
                int highx = crossings[numCrossings - 1] >> 1;
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   757
                int x0 = Math.max(lowx, bboxx0);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   758
                int x1 = Math.min(highx, bboxx1);
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   759
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   760
                pix_minX = Math.min(pix_minX, x0 >> SUBPIXEL_LG_POSITIONS_X);
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   761
                pix_maxX = Math.max(pix_maxX, x1 >> SUBPIXEL_LG_POSITIONS_X);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   764
            int sum = 0;
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   765
            int prev = bboxx0;
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   766
            for (int i = 0; i < numCrossings; i++) {
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   767
                int curxo = crossings[i];
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   768
                int curx = curxo >> 1;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   769
                int crorientation = ((curxo & 0x1) == 0x1) ? 1 : -1;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   770
                if ((sum & mask) != 0) {
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   771
                    int x0 = Math.max(prev, bboxx0);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   772
                    int x1 = Math.min(curx, bboxx1);
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   773
                    if (x0 < x1) {
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   774
                        x0 -= bboxx0; // turn x0, x1 from coords to indeces
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   775
                        x1 -= bboxx0; // in the alpha array.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   777
                        int pix_x = x0 >> SUBPIXEL_LG_POSITIONS_X;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   778
                        int pix_xmaxm1 = (x1 - 1) >> SUBPIXEL_LG_POSITIONS_X;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   780
                        if (pix_x == pix_xmaxm1) {
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   781
                            // Start and end in same pixel
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   782
                            alpha[pix_x] += (x1 - x0);
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   783
                            alpha[pix_x+1] -= (x1 - x0);
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   784
                        } else {
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   785
                            int pix_xmax = x1 >> SUBPIXEL_LG_POSITIONS_X;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   786
                            alpha[pix_x] += SUBPIXEL_POSITIONS_X - (x0 & SUBPIXEL_MASK_X);
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   787
                            alpha[pix_x+1] += (x0 & SUBPIXEL_MASK_X);
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   788
                            alpha[pix_xmax] -= SUBPIXEL_POSITIONS_X - (x1 & SUBPIXEL_MASK_X);
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   789
                            alpha[pix_xmax+1] -= (x1 & SUBPIXEL_MASK_X);
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   790
                        }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   791
                    }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   792
                }
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   793
                sum += crorientation;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   794
                prev = curx;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   795
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   797
            // even if this last row had no crossings, alpha will be zeroed
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   798
            // from the last emitRow call. But this doesn't matter because
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   799
            // maxX < minX, so no row will be emitted to the cache.
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   800
            if ((y & SUBPIXEL_MASK_Y) == SUBPIXEL_MASK_Y) {
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   801
                emitRow(alpha, y >> SUBPIXEL_LG_POSITIONS_Y, pix_minX, pix_maxX);
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   802
                pix_minX = Integer.MAX_VALUE;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   803
                pix_maxX = Integer.MIN_VALUE;
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   804
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   807
        // Emit final row
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   808
        if (pix_maxX >= pix_minX) {
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   809
            emitRow(alpha, y >> SUBPIXEL_LG_POSITIONS_Y, pix_minX, pix_maxX);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
        }
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   811
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
    public void endRendering() {
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   814
        final int bminx = boundsMinX >> SUBPIXEL_LG_POSITIONS_X;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   815
        final int bmaxx = boundsMaxX >> SUBPIXEL_LG_POSITIONS_X;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   816
        final int bminy = boundsMinY >> SUBPIXEL_LG_POSITIONS_Y;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   817
        final int bmaxy = boundsMaxY >> SUBPIXEL_LG_POSITIONS_Y;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   818
        final int eminx = ((int)Math.floor(edgeMinX)) >> SUBPIXEL_LG_POSITIONS_X;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   819
        final int emaxx = ((int)Math.ceil(edgeMaxX)) >> SUBPIXEL_LG_POSITIONS_X;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   820
        final int eminy = ((int)Math.floor(edgeMinY)) >> SUBPIXEL_LG_POSITIONS_Y;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   821
        final int emaxy = ((int)Math.ceil(edgeMaxY)) >> SUBPIXEL_LG_POSITIONS_Y;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   822
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   823
        final int minX = Math.max(bminx, eminx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   824
        final int maxX = Math.min(bmaxx, emaxx);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   825
        final int minY = Math.max(bminy, eminy);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   826
        final int maxY = Math.min(bmaxy, emaxy);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   827
        if (minX > maxX || minY > maxY) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   828
            this.cache = new PiscesCache(bminx, bminy, bmaxx, bmaxy);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   829
            return;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   832
        this.cache = new PiscesCache(minX, minY, maxX, maxY);
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   833
        _endRendering(minX, minY, maxX, maxY);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   836
    public PiscesCache getCache() {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   837
        if (cache == null) {
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   838
            throw new InternalError("cache not yet initialized");
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   839
        }
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   840
        return cache;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   843
    private void emitRow(int[] alphaRow, int pix_y, int pix_from, int pix_to) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
        // Copy rowAA data into the cache if one is present
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        if (cache != null) {
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   846
            if (pix_to >= pix_from) {
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   847
                cache.startRow(pix_y, pix_from);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   849
                // Perform run-length encoding and store results in the cache
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   850
                int from = pix_from - cache.bboxX0;
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   851
                int to = pix_to - cache.bboxX0;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
                int runLen = 1;
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   854
                int startVal = alphaRow[from];
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   855
                for (int i = from + 1; i <= to; i++) {
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   856
                    int nextVal = startVal + alphaRow[i];
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   857
                    if (nextVal == startVal) {
6284
695b3c6241c8 6967436: lines longer than 2^15 can fill window.
dlila
parents: 5506
diff changeset
   858
                        runLen++;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                        cache.addRLERun(startVal, runLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                        runLen = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                        startVal = nextVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
                cache.addRLERun(startVal, runLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
        }
6997
3642614e2282 6967434: Round joins/caps of scaled up lines have poor quality.
dlila
parents: 6284
diff changeset
   868
        java.util.Arrays.fill(alphaRow, 0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
}