jdk/src/java.desktop/share/classes/sun/java2d/marlin/Dasher.java
author lbourges
Mon, 23 Nov 2015 15:02:19 -0800
changeset 34419 14108cfd0823
parent 34417 57a3863abbb4
child 39519 21bfc4452441
permissions -rw-r--r--
8143849: Integrate Marlin renderer per JEP 265 Reviewed-by: flar, prr
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
34417
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
     1
/*
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
     2
 * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
     4
 *
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    10
 *
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    15
 * accompanied this code).
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    16
 *
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    20
 *
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    23
 * questions.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    24
 */
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    25
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    26
package sun.java2d.marlin;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    27
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    28
import java.util.Arrays;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    29
import sun.awt.geom.PathConsumer2D;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    30
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    31
/**
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    32
 * The <code>Dasher</code> class takes a series of linear commands
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    33
 * (<code>moveTo</code>, <code>lineTo</code>, <code>close</code> and
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    34
 * <code>end</code>) and breaks them into smaller segments according to a
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    35
 * dash pattern array and a starting dash phase.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    36
 *
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    37
 * <p> Issues: in J2Se, a zero length dash segment as drawn as a very
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    38
 * short dash, whereas Pisces does not draw anything.  The PostScript
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    39
 * semantics are unclear.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    40
 *
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    41
 */
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    42
final class Dasher implements sun.awt.geom.PathConsumer2D, MarlinConst {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    43
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    44
    static final int recLimit = 4;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    45
    static final float ERR = 0.01f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    46
    static final float minTincrement = 1f / (1 << recLimit);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    47
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    48
    private PathConsumer2D out;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    49
    private float[] dash;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    50
    private int dashLen;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    51
    private float startPhase;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    52
    private boolean startDashOn;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    53
    private int startIdx;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    54
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    55
    private boolean starting;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    56
    private boolean needsMoveTo;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    57
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    58
    private int idx;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    59
    private boolean dashOn;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    60
    private float phase;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    61
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    62
    private float sx, sy;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    63
    private float x0, y0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    64
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    65
    // temporary storage for the current curve
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    66
    private final float[] curCurvepts;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    67
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    68
    // per-thread renderer context
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    69
    final RendererContext rdrCtx;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    70
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    71
    // dashes array (dirty)
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    72
    final float[] dashes_initial = new float[INITIAL_ARRAY];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    73
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    74
    // flag to recycle dash array copy
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    75
    boolean recycleDashes;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    76
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    77
    // per-thread initial arrays (large enough to satisfy most usages
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    78
    // +1 to avoid recycling in Helpers.widenArray()
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    79
    private final float[] firstSegmentsBuffer_initial = new float[INITIAL_ARRAY + 1];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    80
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    81
    /**
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    82
     * Constructs a <code>Dasher</code>.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    83
     * @param rdrCtx per-thread renderer context
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    84
     */
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    85
    Dasher(final RendererContext rdrCtx) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    86
        this.rdrCtx = rdrCtx;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    87
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    88
        firstSegmentsBuffer = firstSegmentsBuffer_initial;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    89
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    90
        // we need curCurvepts to be able to contain 2 curves because when
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    91
        // dashing curves, we need to subdivide it
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    92
        curCurvepts = new float[8 * 2];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    93
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    94
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    95
    /**
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    96
     * Initialize the <code>Dasher</code>.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    97
     *
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    98
     * @param out an output <code>PathConsumer2D</code>.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
    99
     * @param dash an array of <code>float</code>s containing the dash pattern
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   100
     * @param dashLen length of the given dash array
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   101
     * @param phase a <code>float</code> containing the dash phase
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   102
     * @param recycleDashes true to indicate to recycle the given dash array
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   103
     * @return this instance
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   104
     */
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   105
    Dasher init(final PathConsumer2D out, float[] dash, int dashLen,
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   106
                float phase, boolean recycleDashes)
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   107
    {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   108
        if (phase < 0f) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   109
            throw new IllegalArgumentException("phase < 0 !");
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   110
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   111
        this.out = out;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   112
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   113
        // Normalize so 0 <= phase < dash[0]
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   114
        int idx = 0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   115
        dashOn = true;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   116
        float d;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   117
        while (phase >= (d = dash[idx])) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   118
            phase -= d;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   119
            idx = (idx + 1) % dashLen;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   120
            dashOn = !dashOn;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   121
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   122
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   123
        this.dash = dash;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   124
        this.dashLen = dashLen;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   125
        this.startPhase = this.phase = phase;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   126
        this.startDashOn = dashOn;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   127
        this.startIdx = idx;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   128
        this.starting = true;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   129
        needsMoveTo = false;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   130
        firstSegidx = 0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   131
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   132
        this.recycleDashes = recycleDashes;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   133
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   134
        return this; // fluent API
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   135
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   136
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   137
    /**
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   138
     * Disposes this dasher:
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   139
     * clean up before reusing this instance
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   140
     */
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   141
    void dispose() {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   142
        if (doCleanDirty) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   143
            // Force zero-fill dirty arrays:
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   144
            Arrays.fill(curCurvepts, 0f);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   145
            Arrays.fill(firstSegmentsBuffer, 0f);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   146
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   147
        // Return arrays:
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   148
        if (recycleDashes && dash != dashes_initial) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   149
            rdrCtx.putDirtyFloatArray(dash);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   150
            dash = null;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   151
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   152
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   153
        if (firstSegmentsBuffer != firstSegmentsBuffer_initial) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   154
            rdrCtx.putDirtyFloatArray(firstSegmentsBuffer);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   155
            firstSegmentsBuffer = firstSegmentsBuffer_initial;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   156
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   157
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   158
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   159
    @Override
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   160
    public void moveTo(float x0, float y0) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   161
        if (firstSegidx > 0) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   162
            out.moveTo(sx, sy);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   163
            emitFirstSegments();
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   164
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   165
        needsMoveTo = true;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   166
        this.idx = startIdx;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   167
        this.dashOn = this.startDashOn;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   168
        this.phase = this.startPhase;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   169
        this.sx = this.x0 = x0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   170
        this.sy = this.y0 = y0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   171
        this.starting = true;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   172
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   173
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   174
    private void emitSeg(float[] buf, int off, int type) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   175
        switch (type) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   176
        case 8:
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   177
            out.curveTo(buf[off+0], buf[off+1],
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   178
                        buf[off+2], buf[off+3],
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   179
                        buf[off+4], buf[off+5]);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   180
            return;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   181
        case 6:
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   182
            out.quadTo(buf[off+0], buf[off+1],
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   183
                       buf[off+2], buf[off+3]);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   184
            return;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   185
        case 4:
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   186
            out.lineTo(buf[off], buf[off+1]);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   187
            return;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   188
        default:
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   189
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   190
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   191
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   192
    private void emitFirstSegments() {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   193
        final float[] fSegBuf = firstSegmentsBuffer;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   194
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   195
        for (int i = 0; i < firstSegidx; ) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   196
            int type = (int)fSegBuf[i];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   197
            emitSeg(fSegBuf, i + 1, type);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   198
            i += (type - 1);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   199
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   200
        firstSegidx = 0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   201
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   202
    // We don't emit the first dash right away. If we did, caps would be
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   203
    // drawn on it, but we need joins to be drawn if there's a closePath()
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   204
    // So, we store the path elements that make up the first dash in the
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   205
    // buffer below.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   206
    private float[] firstSegmentsBuffer; // dynamic array
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   207
    private int firstSegidx;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   208
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   209
    // precondition: pts must be in relative coordinates (relative to x0,y0)
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   210
    // fullCurve is true iff the curve in pts has not been split.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   211
    private void goTo(float[] pts, int off, final int type) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   212
        float x = pts[off + type - 4];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   213
        float y = pts[off + type - 3];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   214
        if (dashOn) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   215
            if (starting) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   216
                int len = type - 2 + 1;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   217
                int segIdx = firstSegidx;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   218
                float[] buf = firstSegmentsBuffer;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   219
                if (segIdx + len  > buf.length) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   220
                    if (doStats) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   221
                        RendererContext.stats.stat_array_dasher_firstSegmentsBuffer
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   222
                            .add(segIdx + len);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   223
                    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   224
                    firstSegmentsBuffer = buf
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   225
                        = rdrCtx.widenDirtyFloatArray(buf, segIdx, segIdx + len);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   226
                }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   227
                buf[segIdx++] = type;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   228
                len--;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   229
                // small arraycopy (2, 4 or 6) but with offset:
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   230
                System.arraycopy(pts, off, buf, segIdx, len);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   231
                segIdx += len;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   232
                firstSegidx = segIdx;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   233
            } else {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   234
                if (needsMoveTo) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   235
                    out.moveTo(x0, y0);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   236
                    needsMoveTo = false;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   237
                }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   238
                emitSeg(pts, off, type);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   239
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   240
        } else {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   241
            starting = false;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   242
            needsMoveTo = true;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   243
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   244
        this.x0 = x;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   245
        this.y0 = y;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   246
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   247
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   248
    @Override
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   249
    public void lineTo(float x1, float y1) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   250
        float dx = x1 - x0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   251
        float dy = y1 - y0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   252
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   253
        float len = dx*dx + dy*dy;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   254
        if (len == 0f) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   255
            return;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   256
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   257
        len = (float) Math.sqrt(len);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   258
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   259
        // The scaling factors needed to get the dx and dy of the
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   260
        // transformed dash segments.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   261
        final float cx = dx / len;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   262
        final float cy = dy / len;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   263
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   264
        final float[] _curCurvepts = curCurvepts;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   265
        final float[] _dash = dash;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   266
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   267
        float leftInThisDashSegment;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   268
        float dashdx, dashdy, p;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   269
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   270
        while (true) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   271
            leftInThisDashSegment = _dash[idx] - phase;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   272
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   273
            if (len <= leftInThisDashSegment) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   274
                _curCurvepts[0] = x1;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   275
                _curCurvepts[1] = y1;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   276
                goTo(_curCurvepts, 0, 4);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   277
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   278
                // Advance phase within current dash segment
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   279
                phase += len;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   280
                // TODO: compare float values using epsilon:
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   281
                if (len == leftInThisDashSegment) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   282
                    phase = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   283
                    idx = (idx + 1) % dashLen;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   284
                    dashOn = !dashOn;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   285
                }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   286
                return;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   287
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   288
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   289
            dashdx = _dash[idx] * cx;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   290
            dashdy = _dash[idx] * cy;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   291
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   292
            if (phase == 0f) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   293
                _curCurvepts[0] = x0 + dashdx;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   294
                _curCurvepts[1] = y0 + dashdy;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   295
            } else {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   296
                p = leftInThisDashSegment / _dash[idx];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   297
                _curCurvepts[0] = x0 + p * dashdx;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   298
                _curCurvepts[1] = y0 + p * dashdy;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   299
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   300
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   301
            goTo(_curCurvepts, 0, 4);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   302
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   303
            len -= leftInThisDashSegment;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   304
            // Advance to next dash segment
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   305
            idx = (idx + 1) % dashLen;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   306
            dashOn = !dashOn;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   307
            phase = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   308
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   309
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   310
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   311
    // shared instance in Dasher
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   312
    private final LengthIterator li = new LengthIterator();
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   313
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   314
    // preconditions: curCurvepts must be an array of length at least 2 * type,
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   315
    // that contains the curve we want to dash in the first type elements
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   316
    private void somethingTo(int type) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   317
        if (pointCurve(curCurvepts, type)) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   318
            return;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   319
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   320
        li.initializeIterationOnCurve(curCurvepts, type);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   321
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   322
        // initially the current curve is at curCurvepts[0...type]
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   323
        int curCurveoff = 0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   324
        float lastSplitT = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   325
        float t;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   326
        float leftInThisDashSegment = dash[idx] - phase;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   327
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   328
        while ((t = li.next(leftInThisDashSegment)) < 1f) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   329
            if (t != 0f) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   330
                Helpers.subdivideAt((t - lastSplitT) / (1f - lastSplitT),
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   331
                                    curCurvepts, curCurveoff,
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   332
                                    curCurvepts, 0,
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   333
                                    curCurvepts, type, type);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   334
                lastSplitT = t;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   335
                goTo(curCurvepts, 2, type);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   336
                curCurveoff = type;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   337
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   338
            // Advance to next dash segment
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   339
            idx = (idx + 1) % dashLen;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   340
            dashOn = !dashOn;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   341
            phase = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   342
            leftInThisDashSegment = dash[idx];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   343
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   344
        goTo(curCurvepts, curCurveoff+2, type);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   345
        phase += li.lastSegLen();
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   346
        if (phase >= dash[idx]) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   347
            phase = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   348
            idx = (idx + 1) % dashLen;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   349
            dashOn = !dashOn;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   350
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   351
        // reset LengthIterator:
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   352
        li.reset();
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   353
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   354
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   355
    private static boolean pointCurve(float[] curve, int type) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   356
        for (int i = 2; i < type; i++) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   357
            if (curve[i] != curve[i-2]) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   358
                return false;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   359
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   360
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   361
        return true;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   362
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   363
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   364
    // Objects of this class are used to iterate through curves. They return
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   365
    // t values where the left side of the curve has a specified length.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   366
    // It does this by subdividing the input curve until a certain error
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   367
    // condition has been met. A recursive subdivision procedure would
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   368
    // return as many as 1<<limit curves, but this is an iterator and we
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   369
    // don't need all the curves all at once, so what we carry out a
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   370
    // lazy inorder traversal of the recursion tree (meaning we only move
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   371
    // through the tree when we need the next subdivided curve). This saves
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   372
    // us a lot of memory because at any one time we only need to store
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   373
    // limit+1 curves - one for each level of the tree + 1.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   374
    // NOTE: the way we do things here is not enough to traverse a general
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   375
    // tree; however, the trees we are interested in have the property that
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   376
    // every non leaf node has exactly 2 children
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   377
    static final class LengthIterator {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   378
        private enum Side {LEFT, RIGHT};
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   379
        // Holds the curves at various levels of the recursion. The root
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   380
        // (i.e. the original curve) is at recCurveStack[0] (but then it
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   381
        // gets subdivided, the left half is put at 1, so most of the time
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   382
        // only the right half of the original curve is at 0)
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   383
        private final float[][] recCurveStack; // dirty
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   384
        // sides[i] indicates whether the node at level i+1 in the path from
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   385
        // the root to the current leaf is a left or right child of its parent.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   386
        private final Side[] sides; // dirty
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   387
        private int curveType;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   388
        // lastT and nextT delimit the current leaf.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   389
        private float nextT;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   390
        private float lenAtNextT;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   391
        private float lastT;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   392
        private float lenAtLastT;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   393
        private float lenAtLastSplit;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   394
        private float lastSegLen;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   395
        // the current level in the recursion tree. 0 is the root. limit
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   396
        // is the deepest possible leaf.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   397
        private int recLevel;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   398
        private boolean done;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   399
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   400
        // the lengths of the lines of the control polygon. Only its first
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   401
        // curveType/2 - 1 elements are valid. This is an optimization. See
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   402
        // next(float) for more detail.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   403
        private final float[] curLeafCtrlPolyLengths = new float[3];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   404
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   405
        LengthIterator() {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   406
            this.recCurveStack = new float[recLimit + 1][8];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   407
            this.sides = new Side[recLimit];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   408
            // if any methods are called without first initializing this object
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   409
            // on a curve, we want it to fail ASAP.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   410
            this.nextT = Float.MAX_VALUE;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   411
            this.lenAtNextT = Float.MAX_VALUE;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   412
            this.lenAtLastSplit = Float.MIN_VALUE;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   413
            this.recLevel = Integer.MIN_VALUE;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   414
            this.lastSegLen = Float.MAX_VALUE;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   415
            this.done = true;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   416
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   417
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   418
        /**
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   419
         * Reset this LengthIterator.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   420
         */
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   421
        void reset() {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   422
            // keep data dirty
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   423
            // as it appears not useful to reset data:
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   424
            if (doCleanDirty) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   425
                final int recLimit = recCurveStack.length - 1;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   426
                for (int i = recLimit; i >= 0; i--) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   427
                    Arrays.fill(recCurveStack[i], 0f);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   428
                }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   429
                Arrays.fill(sides, Side.LEFT);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   430
                Arrays.fill(curLeafCtrlPolyLengths, 0f);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   431
                Arrays.fill(nextRoots, 0f);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   432
                Arrays.fill(flatLeafCoefCache, 0f);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   433
                flatLeafCoefCache[2] = -1f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   434
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   435
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   436
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   437
        void initializeIterationOnCurve(float[] pts, int type) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   438
            // optimize arraycopy (8 values faster than 6 = type):
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   439
            System.arraycopy(pts, 0, recCurveStack[0], 0, 8);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   440
            this.curveType = type;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   441
            this.recLevel = 0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   442
            this.lastT = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   443
            this.lenAtLastT = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   444
            this.nextT = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   445
            this.lenAtNextT = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   446
            goLeft(); // initializes nextT and lenAtNextT properly
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   447
            this.lenAtLastSplit = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   448
            if (recLevel > 0) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   449
                this.sides[0] = Side.LEFT;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   450
                this.done = false;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   451
            } else {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   452
                // the root of the tree is a leaf so we're done.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   453
                this.sides[0] = Side.RIGHT;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   454
                this.done = true;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   455
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   456
            this.lastSegLen = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   457
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   458
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   459
        // 0 == false, 1 == true, -1 == invalid cached value.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   460
        private int cachedHaveLowAcceleration = -1;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   461
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   462
        private boolean haveLowAcceleration(float err) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   463
            if (cachedHaveLowAcceleration == -1) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   464
                final float len1 = curLeafCtrlPolyLengths[0];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   465
                final float len2 = curLeafCtrlPolyLengths[1];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   466
                // the test below is equivalent to !within(len1/len2, 1, err).
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   467
                // It is using a multiplication instead of a division, so it
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   468
                // should be a bit faster.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   469
                if (!Helpers.within(len1, len2, err*len2)) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   470
                    cachedHaveLowAcceleration = 0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   471
                    return false;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   472
                }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   473
                if (curveType == 8) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   474
                    final float len3 = curLeafCtrlPolyLengths[2];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   475
                    // if len1 is close to 2 and 2 is close to 3, that probably
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   476
                    // means 1 is close to 3 so the second part of this test might
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   477
                    // not be needed, but it doesn't hurt to include it.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   478
                    final float errLen3 = err * len3;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   479
                    if (!(Helpers.within(len2, len3, errLen3) &&
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   480
                          Helpers.within(len1, len3, errLen3))) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   481
                        cachedHaveLowAcceleration = 0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   482
                        return false;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   483
                    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   484
                }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   485
                cachedHaveLowAcceleration = 1;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   486
                return true;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   487
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   488
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   489
            return (cachedHaveLowAcceleration == 1);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   490
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   491
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   492
        // we want to avoid allocations/gc so we keep this array so we
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   493
        // can put roots in it,
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   494
        private final float[] nextRoots = new float[4];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   495
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   496
        // caches the coefficients of the current leaf in its flattened
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   497
        // form (see inside next() for what that means). The cache is
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   498
        // invalid when it's third element is negative, since in any
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   499
        // valid flattened curve, this would be >= 0.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   500
        private final float[] flatLeafCoefCache = new float[]{0f, 0f, -1f, 0f};
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   501
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   502
        // returns the t value where the remaining curve should be split in
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   503
        // order for the left subdivided curve to have length len. If len
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   504
        // is >= than the length of the uniterated curve, it returns 1.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   505
        float next(final float len) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   506
            final float targetLength = lenAtLastSplit + len;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   507
            while (lenAtNextT < targetLength) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   508
                if (done) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   509
                    lastSegLen = lenAtNextT - lenAtLastSplit;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   510
                    return 1f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   511
                }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   512
                goToNextLeaf();
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   513
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   514
            lenAtLastSplit = targetLength;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   515
            final float leaflen = lenAtNextT - lenAtLastT;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   516
            float t = (targetLength - lenAtLastT) / leaflen;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   517
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   518
            // cubicRootsInAB is a fairly expensive call, so we just don't do it
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   519
            // if the acceleration in this section of the curve is small enough.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   520
            if (!haveLowAcceleration(0.05f)) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   521
                // We flatten the current leaf along the x axis, so that we're
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   522
                // left with a, b, c which define a 1D Bezier curve. We then
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   523
                // solve this to get the parameter of the original leaf that
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   524
                // gives us the desired length.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   525
                final float[] _flatLeafCoefCache = flatLeafCoefCache;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   526
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   527
                if (_flatLeafCoefCache[2] < 0) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   528
                    float x = 0f + curLeafCtrlPolyLengths[0],
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   529
                          y = x  + curLeafCtrlPolyLengths[1];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   530
                    if (curveType == 8) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   531
                        float z = y + curLeafCtrlPolyLengths[2];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   532
                        _flatLeafCoefCache[0] = 3f * (x - y) + z;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   533
                        _flatLeafCoefCache[1] = 3f * (y - 2f * x);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   534
                        _flatLeafCoefCache[2] = 3f * x;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   535
                        _flatLeafCoefCache[3] = -z;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   536
                    } else if (curveType == 6) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   537
                        _flatLeafCoefCache[0] = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   538
                        _flatLeafCoefCache[1] = y - 2f * x;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   539
                        _flatLeafCoefCache[2] = 2f * x;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   540
                        _flatLeafCoefCache[3] = -y;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   541
                    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   542
                }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   543
                float a = _flatLeafCoefCache[0];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   544
                float b = _flatLeafCoefCache[1];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   545
                float c = _flatLeafCoefCache[2];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   546
                float d = t * _flatLeafCoefCache[3];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   547
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   548
                // we use cubicRootsInAB here, because we want only roots in 0, 1,
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   549
                // and our quadratic root finder doesn't filter, so it's just a
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   550
                // matter of convenience.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   551
                int n = Helpers.cubicRootsInAB(a, b, c, d, nextRoots, 0, 0, 1);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   552
                if (n == 1 && !Float.isNaN(nextRoots[0])) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   553
                    t = nextRoots[0];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   554
                }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   555
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   556
            // t is relative to the current leaf, so we must make it a valid parameter
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   557
            // of the original curve.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   558
            t = t * (nextT - lastT) + lastT;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   559
            if (t >= 1f) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   560
                t = 1f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   561
                done = true;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   562
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   563
            // even if done = true, if we're here, that means targetLength
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   564
            // is equal to, or very, very close to the total length of the
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   565
            // curve, so lastSegLen won't be too high. In cases where len
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   566
            // overshoots the curve, this method will exit in the while
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   567
            // loop, and lastSegLen will still be set to the right value.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   568
            lastSegLen = len;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   569
            return t;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   570
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   571
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   572
        float lastSegLen() {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   573
            return lastSegLen;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   574
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   575
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   576
        // go to the next leaf (in an inorder traversal) in the recursion tree
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   577
        // preconditions: must be on a leaf, and that leaf must not be the root.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   578
        private void goToNextLeaf() {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   579
            // We must go to the first ancestor node that has an unvisited
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   580
            // right child.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   581
            int _recLevel = recLevel;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   582
            final Side[] _sides = sides;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   583
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   584
            _recLevel--;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   585
            while(_sides[_recLevel] == Side.RIGHT) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   586
                if (_recLevel == 0) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   587
                    recLevel = 0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   588
                    done = true;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   589
                    return;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   590
                }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   591
                _recLevel--;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   592
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   593
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   594
            _sides[_recLevel] = Side.RIGHT;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   595
            // optimize arraycopy (8 values faster than 6 = type):
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   596
            System.arraycopy(recCurveStack[_recLevel], 0,
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   597
                             recCurveStack[_recLevel+1], 0, 8);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   598
            _recLevel++;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   599
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   600
            recLevel = _recLevel;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   601
            goLeft();
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   602
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   603
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   604
        // go to the leftmost node from the current node. Return its length.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   605
        private void goLeft() {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   606
            float len = onLeaf();
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   607
            if (len >= 0f) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   608
                lastT = nextT;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   609
                lenAtLastT = lenAtNextT;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   610
                nextT += (1 << (recLimit - recLevel)) * minTincrement;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   611
                lenAtNextT += len;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   612
                // invalidate caches
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   613
                flatLeafCoefCache[2] = -1f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   614
                cachedHaveLowAcceleration = -1;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   615
            } else {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   616
                Helpers.subdivide(recCurveStack[recLevel], 0,
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   617
                                  recCurveStack[recLevel+1], 0,
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   618
                                  recCurveStack[recLevel], 0, curveType);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   619
                sides[recLevel] = Side.LEFT;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   620
                recLevel++;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   621
                goLeft();
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   622
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   623
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   624
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   625
        // this is a bit of a hack. It returns -1 if we're not on a leaf, and
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   626
        // the length of the leaf if we are on a leaf.
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   627
        private float onLeaf() {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   628
            float[] curve = recCurveStack[recLevel];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   629
            float polyLen = 0f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   630
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   631
            float x0 = curve[0], y0 = curve[1];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   632
            for (int i = 2; i < curveType; i += 2) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   633
                final float x1 = curve[i], y1 = curve[i+1];
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   634
                final float len = Helpers.linelen(x0, y0, x1, y1);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   635
                polyLen += len;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   636
                curLeafCtrlPolyLengths[i/2 - 1] = len;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   637
                x0 = x1;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   638
                y0 = y1;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   639
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   640
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   641
            final float lineLen = Helpers.linelen(curve[0], curve[1],
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   642
                                                  curve[curveType-2],
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   643
                                                  curve[curveType-1]);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   644
            if ((polyLen - lineLen) < ERR || recLevel == recLimit) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   645
                return (polyLen + lineLen) / 2f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   646
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   647
            return -1f;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   648
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   649
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   650
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   651
    @Override
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   652
    public void curveTo(float x1, float y1,
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   653
                        float x2, float y2,
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   654
                        float x3, float y3)
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   655
    {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   656
        final float[] _curCurvepts = curCurvepts;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   657
        _curCurvepts[0] = x0;        _curCurvepts[1] = y0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   658
        _curCurvepts[2] = x1;        _curCurvepts[3] = y1;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   659
        _curCurvepts[4] = x2;        _curCurvepts[5] = y2;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   660
        _curCurvepts[6] = x3;        _curCurvepts[7] = y3;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   661
        somethingTo(8);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   662
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   663
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   664
    @Override
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   665
    public void quadTo(float x1, float y1, float x2, float y2) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   666
        final float[] _curCurvepts = curCurvepts;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   667
        _curCurvepts[0] = x0;        _curCurvepts[1] = y0;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   668
        _curCurvepts[2] = x1;        _curCurvepts[3] = y1;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   669
        _curCurvepts[4] = x2;        _curCurvepts[5] = y2;
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   670
        somethingTo(6);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   671
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   672
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   673
    @Override
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   674
    public void closePath() {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   675
        lineTo(sx, sy);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   676
        if (firstSegidx > 0) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   677
            if (!dashOn || needsMoveTo) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   678
                out.moveTo(sx, sy);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   679
            }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   680
            emitFirstSegments();
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   681
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   682
        moveTo(sx, sy);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   683
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   684
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   685
    @Override
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   686
    public void pathDone() {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   687
        if (firstSegidx > 0) {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   688
            out.moveTo(sx, sy);
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   689
            emitFirstSegments();
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   690
        }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   691
        out.pathDone();
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   692
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   693
        // Dispose this instance:
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   694
        dispose();
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   695
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   696
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   697
    @Override
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   698
    public long getNativeConsumer() {
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   699
        throw new InternalError("Dasher does not use a native consumer");
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   700
    }
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   701
}
57a3863abbb4 8076529: Marlin antialiasing renderer integration
flar
parents:
diff changeset
   702