jdk/src/share/native/sun/java2d/loops/ProcessPath.c
author ohair
Tue, 28 Dec 2010 15:53:50 -0800
changeset 7668 d4a77089c587
parent 6998 2a7e17242300
child 8746 3eef91f87691
permissions -rw-r--r--
6962318: Update copyright year Reviewed-by: xdono
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
7668
d4a77089c587 6962318: Update copyright year
ohair
parents: 6998
diff changeset
     2
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
#include <math.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
#include <assert.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
#include <stdlib.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
#include <string.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
#include "j2d_md.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
#include "java_awt_geom_PathIterator.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
#include "ProcessPath.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * This framework performs filling and drawing of paths with sub-pixel
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * precision. Also, it performs clipping by the specified view area.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * Drawing of the shapes is performed not pixel by pixel but segment by segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * except several pixels near endpoints of the drawn line. This approach saves
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * lot's of cpu cycles especially in case of large primitives (like ovals with
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * sizes more than 50) and helps in achieving appropriate visual quality. Also,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * such method of drawing is useful for the accelerated pipelines where
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * overhead of the per-pixel drawing could eliminate all benefits of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * hardware acceleration.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * Filling of the path was  taken from
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * [Graphics Gems, edited by Andrew S Glassner. Academic Press 1990,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * ISBN 0-12-286165-5 (Concave polygon scan conversion), 87-91]
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * and modified to work with sub-pixel precision and non-continuous paths.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * It's also speeded up by using hash table by rows of the filled objects.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * Here is high level scheme showing the rendering process:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 *                   doDrawPath   doFillPath
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 *                         \         /
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 *                         ProcessPath
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 *                              |
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 *                      CheckPathSegment
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 *                              |
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 *                      --------+------
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 *                      |             |
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *                      |             |
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 *                      |             |
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 *                  _->ProcessCurve   |
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 *                 /    / |           |
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 *                 \___/  |           |
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 *                        |           |
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 *                    DrawCurve     ProcessLine
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 *                         \         /
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 *                          \       /
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 *                           \     /
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 *                            \   /
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 *                        ------+------
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 *             (filling) /             \ (drawing)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 *                      /               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 *               Clipping and        Clipping
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 *                clamping                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 *                   |                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 *           StoreFixedLine          ProcessFixedLine
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 *                   |                     /    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
 *                   |                    /      \
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
 *             FillPolygon       PROCESS_LINE   PROCESS_POINT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
 *  CheckPathSegment  - rough checking and skipping path's segments  in case of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
 *                      invalid or huge coordinates of the control points to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
 *                      avoid calculation problems with NaNs and values close
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 *                      to the FLT_MAX
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 * ProcessCurve - (ProcessQuad, ProcessCubic) Splitting the curve into
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 *                monotonic parts having appropriate size (calculated as
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
 *                boundary box of the control points)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
 * DrawMonotonicCurve - (DrawMonotonicQuad, DrawMonotonicCubic) flattening
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
 *                      monotonic curve using adaptive forward differencing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
 * StoreFixedLine - storing segment from the flattened path to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
 *                  FillData structure. Performing clipping and clamping if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
 *                  necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
 * PROCESS_LINE, PROCESS_POINT - Helpers for calling appropriate primitive from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
 *                               DrawHandler structure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
 * ProcessFixedLine - Drawing line segment with subpixel precision.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
#define PROCESS_LINE(hnd, fX0, fY0, fX1, fY1, checkBounds, pixelInfo)       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    do {                                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        jint X0 = (fX0) >> MDP_PREC;                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        jint Y0 = (fY0) >> MDP_PREC;                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
        jint X1 = (fX1) >> MDP_PREC;                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        jint Y1 = (fY1) >> MDP_PREC;                                        \
6998
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   119
        jint res;                                                           \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   120
                                                                            \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   121
        /* Checking bounds and clipping if necessary */                     \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   122
        if (checkBounds) {                                                  \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   123
            TESTANDCLIP(hnd->dhnd->yMin, hnd->dhnd->yMax, Y0, X0, Y1, X1,   \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   124
                        jint, res);                                         \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   125
            if (res == CRES_INVISIBLE) break;                               \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   126
            TESTANDCLIP(hnd->dhnd->yMin, hnd->dhnd->yMax, Y1, X1, Y0, X0,   \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   127
                        jint, res);                                         \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   128
            if (res == CRES_INVISIBLE) break;                               \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   129
            TESTANDCLIP(hnd->dhnd->xMin, hnd->dhnd->xMax, X0, Y0, X1, Y1,   \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   130
                        jint, res);                                         \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   131
            if (res == CRES_INVISIBLE) break;                               \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   132
            TESTANDCLIP(hnd->dhnd->xMin, hnd->dhnd->xMax, X1, Y1, X0, Y0,   \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   133
                        jint, res);                                         \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   134
            if (res == CRES_INVISIBLE) break;                               \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   135
        }                                                                   \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   136
                                                                            \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   137
        /* Handling lines having just one pixel      */                     \
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        if (((X0^X1) | (Y0^Y1)) == 0) {                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
            if (pixelInfo[0] == 0) {                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                pixelInfo[0] = 1;                                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
                pixelInfo[1] = X0;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                pixelInfo[2] = Y0;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
                pixelInfo[3] = X0;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
                pixelInfo[4] = Y0;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
                hnd->dhnd->pDrawPixel(hnd->dhnd, X0, Y0);                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            } else if ((X0 != pixelInfo[3] || Y0 != pixelInfo[4]) &&        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
                       (X0 != pixelInfo[1] || Y0 != pixelInfo[2])) {        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
                hnd->dhnd->pDrawPixel(hnd->dhnd, X0, Y0);                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                pixelInfo[3] = X0;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                pixelInfo[4] = Y0;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            }                                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
            break;                                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        }                                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                                                                            \
6998
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   155
        if (pixelInfo[0] &&                                                 \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   156
            ((pixelInfo[1] == X0 && pixelInfo[2] == Y0) ||                  \
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   157
            (pixelInfo[3] == X0 && pixelInfo[4] == Y0)))                    \
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        {                                                                   \
6998
2a7e17242300 6670881: Phantom lines appear when rendering polygons & ellipses with antialiasing OFF
bae
parents: 5506
diff changeset
   159
            hnd->dhnd->pDrawPixel(hnd->dhnd, X0, Y0);                       \
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        }                                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                                                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        hnd->dhnd->pDrawLine(hnd->dhnd, X0, Y0, X1, Y1);                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                                                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        if (pixelInfo[0] == 0) {                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            pixelInfo[0] = 1;                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            pixelInfo[1] = X0;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            pixelInfo[2] = Y0;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            pixelInfo[3] = X0;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
            pixelInfo[4] = Y0;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        }                                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                                                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        /* Switch on last pixel of the line if it was already               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
         * drawn during rendering of the previous segments                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
         */                                                                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        if ((pixelInfo[1] == X1 && pixelInfo[2] == Y1) ||                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            (pixelInfo[3] == X1 && pixelInfo[4] == Y1))                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        {                                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            hnd->dhnd->pDrawPixel(hnd->dhnd, X1, Y1);                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        }                                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        pixelInfo[3] = X1;                                                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        pixelInfo[4] = Y1;                                                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    } while(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
#define PROCESS_POINT(hnd, fX, fY, checkBounds, pixelInfo)                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    do {                                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        jint _X = (fX)>> MDP_PREC;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        jint _Y = (fY)>> MDP_PREC;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        if (checkBounds &&                                                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            (hnd->dhnd->yMin > _Y  ||                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
             hnd->dhnd->yMax <= _Y ||                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
             hnd->dhnd->xMin > _X  ||                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
             hnd->dhnd->xMax <= _X)) break;                                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
/*                                                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
 *       (_X,_Y) should be inside boundaries                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
 *                                                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
 *       assert(hnd->dhnd->yMin <= _Y &&                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
 *              hnd->dhnd->yMax >  _Y &&                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
 *              hnd->dhnd->xMin <= _X &&                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
 *              hnd->dhnd->xMax >  _X);                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
 *                                                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
 */                                                                         \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        if (pixelInfo[0] == 0) {                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            pixelInfo[0] = 1;                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            pixelInfo[1] = _X;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            pixelInfo[2] = _Y;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            pixelInfo[3] = _X;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            pixelInfo[4] = _Y;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            hnd->dhnd->pDrawPixel(hnd->dhnd, _X, _Y);                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        } else if ((_X != pixelInfo[3] || _Y != pixelInfo[4]) &&            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                   (_X != pixelInfo[1] || _Y != pixelInfo[2])) {            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            hnd->dhnd->pDrawPixel(hnd->dhnd, _X, _Y);                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            pixelInfo[3] = _X;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            pixelInfo[4] = _Y;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        }                                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    } while(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
 *                  Constants for the forward differencing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
 *                      of the cubic and quad curves
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
/* Maximum size of the cubic curve (calculated as the size of the bounding box
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
 * of the control points) which could be rendered without splitting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
#define MAX_CUB_SIZE    256
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
/* Maximum size of the quad curve (calculated as the size of the bounding box
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
 * of the control points) which could be rendered without splitting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
#define MAX_QUAD_SIZE   1024
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
/* Default power of 2 steps used in the forward differencing. Here DF prefix
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
 * stands for DeFault. Constants below are used as initial values for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
 * adaptive forward differencing algorithm.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
#define DF_CUB_STEPS    3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
#define DF_QUAD_STEPS   2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
/* Shift of the current point of the curve for preparing to the midpoint
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
 * rounding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
#define DF_CUB_SHIFT    (FWD_PREC + DF_CUB_STEPS*3 - MDP_PREC)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
#define DF_QUAD_SHIFT    (FWD_PREC + DF_QUAD_STEPS*2 - MDP_PREC)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
/* Default amount of steps of the forward differencing */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
#define DF_CUB_COUNT    (1<<DF_CUB_STEPS)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
#define DF_QUAD_COUNT    (1<<DF_QUAD_STEPS)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
/* Default boundary constants used to check the necessity of the restepping */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
#define DF_CUB_DEC_BND     (1<<(DF_CUB_STEPS*3 + FWD_PREC + 2))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
#define DF_CUB_INC_BND     (1<<(DF_CUB_STEPS*3 + FWD_PREC - 1))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
#define DF_QUAD_DEC_BND     (1<<(DF_QUAD_STEPS*2 + FWD_PREC + 2))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
/* Multiplyers for the coefficients of the polynomial form of the cubic and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
 * quad curves representation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
#define CUB_A_SHIFT   FWD_PREC
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
#define CUB_B_SHIFT   (DF_CUB_STEPS + FWD_PREC + 1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
#define CUB_C_SHIFT   (DF_CUB_STEPS*2 + FWD_PREC)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
#define CUB_A_MDP_MULT    (1<<CUB_A_SHIFT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
#define CUB_B_MDP_MULT    (1<<CUB_B_SHIFT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
#define CUB_C_MDP_MULT    (1<<CUB_C_SHIFT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
#define QUAD_A_SHIFT   FWD_PREC
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
#define QUAD_B_SHIFT   (DF_QUAD_STEPS + FWD_PREC)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
#define QUAD_A_MDP_MULT    (1<<QUAD_A_SHIFT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
#define QUAD_B_MDP_MULT    (1<<QUAD_B_SHIFT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
#define CALC_MAX(MAX, X) ((MAX)=((X)>(MAX))?(X):(MAX))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
#define CALC_MIN(MIN, X) ((MIN)=((X)<(MIN))?(X):(MIN))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
#define MAX(MAX, X) (((X)>(MAX))?(X):(MAX))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
#define MIN(MIN, X) (((X)<(MIN))?(X):(MIN))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
#define ABS32(X) (((X)^((X)>>31))-((X)>>31))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
#define SIGN32(X) ((X) >> 31) | ((juint)(-(X)) >> 31)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
/* Boundaries used for clipping large path segments (those are inside
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
 * [UPPER/LOWER]_BND boundaries)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
#define UPPER_OUT_BND (1 << (30 - MDP_PREC))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
#define LOWER_OUT_BND (-UPPER_OUT_BND)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
#define ADJUST(X, LBND, UBND)                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    do {                                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        if ((X) < (LBND)) {                                                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            (X) = (LBND);                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        } else if ((X) > UBND) {                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            (X) = (UBND);                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        }                                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
    } while(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
/* Following constants are used for providing open boundaries of the intervals
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
#define EPSFX 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
#define EPSF (((jfloat)EPSFX)/MDP_MULT)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
/* Calculation boundary. It is used for switching to the more slow but allowing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
 * larger input values method of calculation of the initial values of the scan
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
 * converted line segments inside the FillPolygon.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
#define CALC_BND (1 << (30 - MDP_PREC))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
/* Clipping macros for drawing and filling algorithms */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
#define CLIP(a1, b1, a2, b2, t) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    (b1 + ((jdouble)(t - a1)*(b2 - b1)) / (a2 - a1))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
enum {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    CRES_MIN_CLIPPED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    CRES_MAX_CLIPPED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    CRES_NOT_CLIPPED,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    CRES_INVISIBLE
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
#define IS_CLIPPED(res) (res == CRES_MIN_CLIPPED || res == CRES_MAX_CLIPPED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
#define TESTANDCLIP(LINE_MIN, LINE_MAX, a1, b1, a2, b2, TYPE, res)  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
   do {                                                             \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        jdouble t;                                                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        res = CRES_NOT_CLIPPED;                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        if (a1 < (LINE_MIN) || a1 > (LINE_MAX)) {                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            if (a1 < (LINE_MIN)) {                                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                if (a2 < (LINE_MIN)) {                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                    res = CRES_INVISIBLE;                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                    break;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                };                                                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                res = CRES_MIN_CLIPPED;                             \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                t = (LINE_MIN);                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
            } else {                                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                if (a2 > (LINE_MAX)) {                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                    res = CRES_INVISIBLE;                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                    break;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                };                                                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                res = CRES_MAX_CLIPPED;                             \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                t = (LINE_MAX);                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            }                                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            b1 = (TYPE)CLIP(a1, b1, a2, b2, t);                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            a1 = (TYPE)t;                                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        }                                                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
   } while (0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
/* Following macro is used for clipping and clumping filled shapes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
 * An example of this process is shown on the picture below:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
 *                      ----+          ----+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
 *                    |/    |        |/    |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
 *                    +     |        +     |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
 *                   /|     |        I     |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
 *                  / |     |        I     |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
 *                  | |     |  ===>  I     |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
 *                  \ |     |        I     |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
 *                   \|     |        I     |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
 *                    +     |        +     |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
 *                    |\    |        |\    |
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
 *                    | ----+        | ----+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
 *                 boundary       boundary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
 * We can only perform clipping in case of right side of the output area
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
 * because all segments passed out the right boundary don't influence on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
 * result of scan conversion algorithm (it correctly handles half open
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
 * contours).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
#define CLIPCLAMP(LINE_MIN, LINE_MAX, a1, b1, a2, b2, a3, b3, TYPE, res)  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
    do {                                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        a3 = a1;                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        b3 = b1;                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        TESTANDCLIP(LINE_MIN, LINE_MAX, a1, b1, a2, b2, TYPE, res); \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        if (res == CRES_MIN_CLIPPED) {                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
            a3 = a1;                                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        } else if (res == CRES_MAX_CLIPPED) {                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
            a3 = a1;                                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            res = CRES_MAX_CLIPPED;                                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        } else if (res == CRES_INVISIBLE) {                         \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
            if (a1 > LINE_MAX) {                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                res =  CRES_INVISIBLE;                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            } else {                                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                a1 = (TYPE)LINE_MIN;                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                a2 = (TYPE)LINE_MIN;                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                res = CRES_NOT_CLIPPED;                             \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            }                                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        }                                                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    } while (0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
/* Following macro is used for solving quadratic equations:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
 * A*t^2 + B*t + C = 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
 * in (0,1) range. That means we put to the RES the only roots which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
 * belongs to the (0,1) range. Note: 0 and 1 are not included.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
 * See solveQuadratic method in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
 *  src/share/classes/java/awt/geom/QuadCurve2D.java
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
 * for more info about calculations
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
#define SOLVEQUADINRANGE(A,B,C,RES,RCNT)                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    do {                                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        double param;                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        if ((A) != 0) {                                             \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            /* Calculating roots of the following equation          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
             * A*t^2 + B*t + C = 0                                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
             */                                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            double d = (B)*(B) - 4*(A)*(C);                         \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            double q;                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            if (d < 0) {                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                break;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
            }                                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
            d = sqrt(d);                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
            /* For accuracy, calculate one root using:              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
             *     (-B +/- d) / 2*A                                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
             * and the other using:                                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
             *     2*C / (-B +/- d)                                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
             * Choose the sign of the +/- so that B+D gets larger   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
             * in magnitude                                         \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
             */                                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
            if ((B) < 0) {                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                d = -d;                                             \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
            }                                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
            q = ((B) + d) / -2.0;                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            param = q/(A);                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            if (param < 1.0 && param > 0.0) {                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                (RES)[(RCNT)++] = param;                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
            }                                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            if (d == 0 || q == 0) {                                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                break;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            }                                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            param = (C)/q;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
            if (param < 1.0 && param > 0.0) {                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                (RES)[(RCNT)++] = param;                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
            }                                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        } else {                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
            /* Calculating root of the following equation           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
             * B*t + C = 0                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
             */                                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            if ((B) == 0) {                                         \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                break;                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            }                                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            param = -(C)/(B);                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            if (param < 1.0 && param > 0.0) {                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                (RES)[(RCNT)++] = param;                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
            }                                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        }                                                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
    } while(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
/*                  Drawing line with subpixel endpoints
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
 * (x1, y1), (x2, y2) -  fixed point coordinates of the endpoints
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
 *                       with MDP_PREC bits for the fractional part
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
 * pixelInfo          -  structure which keeps drawing info for avoiding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
 *                       multiple drawing at the same position on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
 *                       screen (required for the XOR mode of drawing)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
 *                          pixelInfo[0]   - state of the drawing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
 *                                           0 - no pixel drawn between
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
 *                                           moveTo/close of the path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
 *                                           1 - there are drawn pixels
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
 *                          pixelInfo[1,2] - first pixel of the path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
 *                                           between moveTo/close of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
 *                                           path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
 *                          pixelInfo[3,4] - last drawn pixel between
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
 *                                           moveTo/close of the path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
 * checkBounds        - flag showing necessity of checking the clip
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
void  ProcessFixedLine(ProcessHandler* hnd,jint x1,jint y1,jint x2,jint y2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                       jint* pixelInfo,jboolean checkBounds,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                       jboolean endSubPath)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
    /* Checking if line is inside a (X,Y),(X+MDP_MULT,Y+MDP_MULT) box */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    jint c = ((x1 ^ x2) | (y1 ^ y2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
    jint rx1, ry1, rx2, ry2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    if ((c & MDP_W_MASK) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        /* Checking for the segments with integer coordinates having
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
         * the same start and end points
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        if (c == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            PROCESS_POINT(hnd, x1 + MDP_HALF_MULT, y1 + MDP_HALF_MULT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                          checkBounds, pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
    if (x1 == x2 || y1 == y2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        rx1 = x1 + MDP_HALF_MULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        rx2 = x2 + MDP_HALF_MULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
        ry1 = y1 + MDP_HALF_MULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        ry2 = y2 + MDP_HALF_MULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        /* Neither dx nor dy can be zero because of the check above */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        jint dx = x2 - x1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        jint dy = y2 - y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        /* Floor of x1, y1, x2, y2 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        jint fx1 = x1 & MDP_W_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        jint fy1 = y1 & MDP_W_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        jint fx2 = x2 & MDP_W_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        jint fy2 = y2 & MDP_W_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        /* Processing first endpoint */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
        if (fx1 == x1 || fy1 == y1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
            /* Adding MDP_HALF_MULT to the [xy]1 if f[xy]1 == [xy]1 will not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
             * affect the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
            rx1 = x1 + MDP_HALF_MULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
            ry1 = y1 + MDP_HALF_MULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
            /* Boundary at the direction from (x1,y1) to (x2,y2) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
            jint bx1 = (x1 < x2) ? fx1 + MDP_MULT : fx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
            jint by1 = (y1 < y2) ? fy1 + MDP_MULT : fy1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            /* intersection with column bx1 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
            jint cross = y1 + ((bx1 - x1)*dy)/dx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            if (cross >= fy1 && cross <= fy1 + MDP_MULT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                rx1 = bx1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                ry1 = cross + MDP_HALF_MULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                /* intersection with row by1 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
                cross = x1 + ((by1 - y1)*dx)/dy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                rx1 = cross + MDP_HALF_MULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                ry1 = by1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        /* Processing second endpoint */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        if (fx2 == x2 || fy2 == y2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            /* Adding MDP_HALF_MULT to the [xy]2 if f[xy]2 == [xy]2 will not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
             * affect the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            rx2 = x2 + MDP_HALF_MULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            ry2 = y2 + MDP_HALF_MULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
            /* Boundary at the direction from (x2,y2) to (x1,y1) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
            jint bx2 = (x1 > x2) ? fx2 + MDP_MULT : fx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
            jint by2 = (y1 > y2) ? fy2 + MDP_MULT : fy2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            /* intersection with column bx2 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
            jint cross = y2 + ((bx2 - x2)*dy)/dx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            if (cross >= fy2 && cross <= fy2 + MDP_MULT) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                rx2 = bx2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                ry2 = cross + MDP_HALF_MULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                /* intersection with row by2 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                cross = x2 + ((by2 - y2)*dx)/dy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                rx2 = cross + MDP_HALF_MULT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                ry2 = by2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
    PROCESS_LINE(hnd, rx1, ry1, rx2, ry2, checkBounds, pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
/* Performing drawing of the monotonic in X and Y quadratic curves with sizes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
 * less than MAX_QUAD_SIZE by using forward differencing method of calculation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
 * See comments to the DrawMonotonicCubic.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
static void DrawMonotonicQuad(ProcessHandler* hnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                              jfloat *coords,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                              jboolean checkBounds,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                              jint* pixelInfo)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
    jint x0 = (jint)(coords[0]*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    jint y0 = (jint)(coords[1]*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
    jint xe = (jint)(coords[4]*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    jint ye = (jint)(coords[5]*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
    /* Extracting fractional part of coordinates of first control point */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    jint px = (x0 & (~MDP_W_MASK)) << DF_QUAD_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
    jint py = (y0 & (~MDP_W_MASK)) << DF_QUAD_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
    /* Setting default amount of steps */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    jint count = DF_QUAD_COUNT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
    /* Setting default shift for preparing to the midpoint rounding */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
    jint shift =  DF_QUAD_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
    jint ax = (jint)((coords[0] - 2*coords[2] +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                      coords[4])*QUAD_A_MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
    jint ay = (jint)((coords[1] - 2*coords[3] +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
                      coords[5])*QUAD_A_MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
    jint bx = (jint)((-2*coords[0] + 2*coords[2])*QUAD_B_MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
    jint by = (jint)((-2*coords[1] + 2*coords[3])*QUAD_B_MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    jint ddpx = 2*ax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
    jint ddpy = 2*ay;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    jint dpx = ax + bx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    jint dpy = ay + by;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    jint x1, y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    jint x2 = x0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    jint y2 = y0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    jint maxDD = MAX(ABS32(ddpx),ABS32(ddpy));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
    jint x0w = x0 & MDP_W_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
    jint y0w = y0 & MDP_W_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
    jint dx = xe - x0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    jint dy = ye - y0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    /* Perform decreasing step in 2 times if slope of the second forward
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
     * difference changes too quickly (more than a pixel per step in X or Y
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
     * direction). We can perform adjusting of the step size before the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
     * rendering loop because the curvature of the quad curve remains the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
     * along all the curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
    while (maxDD > DF_QUAD_DEC_BND) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        dpx = (dpx<<1) - ax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        dpy = (dpy<<1) - ay;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
        count <<= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
        maxDD >>= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        px <<=2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
        py <<=2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
        shift += 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    while(count-- > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        px += dpx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        py += dpy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        dpx += ddpx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
        dpy += ddpy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        x1 = x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        y1 = y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        x2 = x0w + (px >> shift);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        y2 = y0w + (py >> shift);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
        /* Checking that we are not running out of the endpoint and bounding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
         * violating coordinate.  The check is pretty simple because the curve
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
         * passed to the DrawMonotonicQuad already splitted into the monotonic
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
         * in X and Y pieces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        /* Bounding x2 by xe */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
        if (((xe-x2)^dx) < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
            x2 = xe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        /* Bounding y2 by ye */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
        if (((ye-y2)^dy) < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
            y2 = ye;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
        hnd->pProcessFixedLine(hnd, x1, y1, x2, y2, pixelInfo, checkBounds,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
                               JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    /* We are performing one step less than necessary and use actual (xe,ye)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
     * curve's endpoint instead of calculated. This prevent us from accumulated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
     * errors at the last point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    hnd->pProcessFixedLine(hnd, x2, y2, xe, ye, pixelInfo, checkBounds,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
                           JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
 * Checking size of the quad curves and split them if necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
 * Calling DrawMonotonicQuad for the curves of the appropriate size.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
 * Note: coords array could be changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
static void ProcessMonotonicQuad(ProcessHandler* hnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
                                 jfloat *coords,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
                                 jint* pixelInfo) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
    jfloat coords1[6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    jfloat xMin, xMax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
    jfloat yMin, yMax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
    xMin = xMax = coords[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
    yMin = yMax = coords[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
    CALC_MIN(xMin, coords[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
    CALC_MAX(xMax, coords[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
    CALC_MIN(yMin, coords[3]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
    CALC_MAX(yMax, coords[3]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
    CALC_MIN(xMin, coords[4]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
    CALC_MAX(xMax, coords[4]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
    CALC_MIN(yMin, coords[5]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    CALC_MAX(yMax, coords[5]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
    if (hnd->clipMode == PH_MODE_DRAW_CLIP) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        /* In case of drawing we could just skip curves which are completely
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
         * out of bounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
        if (hnd->dhnd->xMaxf < xMin || hnd->dhnd->xMinf > xMax ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
            hnd->dhnd->yMaxf < yMin || hnd->dhnd->yMinf > yMax) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        /* In case of filling we could skip curves which are above,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
         * below and behind the right boundary of the visible area
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
         if (hnd->dhnd->yMaxf < yMin || hnd->dhnd->yMinf > yMax ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
             hnd->dhnd->xMaxf < xMin)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
         {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
             return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        /* We could clamp x coordinates to the corresponding boundary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
         * if the curve is completely behind the left one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
        if (hnd->dhnd->xMinf > xMax) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
            coords[0] = coords[2] = coords[4] = hnd->dhnd->xMinf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
    if (xMax - xMin > MAX_QUAD_SIZE || yMax - yMin > MAX_QUAD_SIZE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        coords1[4] = coords[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        coords1[5] = coords[5];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        coords1[2] = (coords[2] + coords[4])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        coords1[3] = (coords[3] + coords[5])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
        coords[2] = (coords[0] + coords[2])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        coords[3] = (coords[1] + coords[3])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
        coords[4] = coords1[0] = (coords[2] + coords1[2])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
        coords[5] = coords1[1] = (coords[3] + coords1[3])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        ProcessMonotonicQuad(hnd, coords, pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
        ProcessMonotonicQuad(hnd, coords1, pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
        DrawMonotonicQuad(hnd, coords,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                         /* Set checkBounds parameter if curve intersects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                          * boundary of the visible area. We know that the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
                          * curve is visible, so the check is pretty simple
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
                          */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
                         hnd->dhnd->xMinf >= xMin || hnd->dhnd->xMaxf <= xMax ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
                         hnd->dhnd->yMinf >= yMin || hnd->dhnd->yMaxf <= yMax,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
                         pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
 * Bite the piece of the quadratic curve from start point till the point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
 * corresponding to the specified parameter then call ProcessQuad for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
 * bitten part.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
 * Note: coords array will be changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
static void ProcessFirstMonotonicPartOfQuad(ProcessHandler* hnd, jfloat* coords,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
                                            jint* pixelInfo, jfloat t)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    jfloat coords1[6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
    coords1[0] = coords[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
    coords1[1] = coords[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
    coords1[2] = coords[0] + t*(coords[2] - coords[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
    coords1[3] = coords[1] + t*(coords[3] - coords[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
    coords[2] = coords[2] + t*(coords[4] - coords[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
    coords[3] = coords[3] + t*(coords[5] - coords[3]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
    coords[0] = coords1[4] = coords1[2] + t*(coords[2] - coords1[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
    coords[1] = coords1[5] = coords1[3] + t*(coords[3] - coords1[3]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
    ProcessMonotonicQuad(hnd, coords1, pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
 * Split quadratic curve into monotonic in X and Y parts. Calling
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
 * ProcessMonotonicQuad for each monotonic piece of the curve.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
 * Note: coords array could be changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
static void ProcessQuad(ProcessHandler* hnd, jfloat* coords, jint* pixelInfo) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
    /* Temporary array for holding parameters corresponding to the extreme in X
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
     * and Y points. The values are inside the (0,1) range (0 and 1 excluded)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
     * and in ascending order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    double params[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
    jint cnt = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
    double param;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
    /* Simple check for monotonicity in X before searching for the extreme
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
     * points of the X(t) function. We first check if the curve is monotonic
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
     * in X by seeing if all of the X coordinates are strongly ordered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
    if ((coords[0] > coords[2] || coords[2] > coords[4]) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
        (coords[0] < coords[2] || coords[2] < coords[4]))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
        /* Searching for extreme points of the X(t) function  by solving
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
         * dX(t)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
         * ----  = 0 equation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
         *  dt
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
        double ax = coords[0] - 2*coords[2] + coords[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
        if (ax != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
            /* Calculating root of the following equation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
             * ax*t + bx = 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
            double bx = coords[0] - coords[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
            param = bx/ax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
            if (param < 1.0 && param > 0.0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
                params[cnt++] = param;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
    /* Simple check for monotonicity in Y before searching for the extreme
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
     * points of the Y(t) function. We first check if the curve is monotonic
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
     * in Y by seeing if all of the Y coordinates are strongly ordered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
    if ((coords[1] > coords[3] || coords[3] > coords[5]) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
        (coords[1] < coords[3] || coords[3] < coords[5]))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
        /* Searching for extreme points of the Y(t) function by solving
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
         * dY(t)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
         * ----- = 0 equation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
         *  dt
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
        double ay = coords[1] - 2*coords[3] + coords[5];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
        if (ay != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
            /* Calculating root of the following equation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
             * ay*t + by = 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
            double by = coords[1] - coords[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
            param = by/ay;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
            if (param < 1.0 && param > 0.0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
                if (cnt > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
                    /* Inserting parameter only if it differs from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
                     * already stored
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
                    if (params[0] >  param) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
                        params[cnt++] = params[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
                        params[0] = param;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
                    } else if (params[0] <  param) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                        params[cnt++] = param;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
                    params[cnt++] = param;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
    /* Processing obtained monotonic parts */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
    switch(cnt) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
        case 0:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
        case 1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
            ProcessFirstMonotonicPartOfQuad(hnd, coords, pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
                                            (jfloat)params[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
        case 2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
            ProcessFirstMonotonicPartOfQuad(hnd, coords, pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                                            (jfloat)params[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
            param = params[1] - params[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
            if (param > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                ProcessFirstMonotonicPartOfQuad(hnd, coords, pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                    /* Scale parameter to match with rest of the curve */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
                    (jfloat)(param/(1.0 - params[0])));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
    ProcessMonotonicQuad(hnd,coords,pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
 * Performing drawing of the monotonic in X and Y cubic curves with sizes less
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
 * than MAX_CUB_SIZE by using forward differencing method of calculation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
 * Here is some math used in the code below.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
 * If we express the parametric equation for the coordinates as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
 * simple polynomial:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
 *  V(t) = a * t^3 + b * t^2 + c * t + d
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
 * The equations for how we derive these polynomial coefficients
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
 * from the Bezier control points can be found in the method comments
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
 * for the CubicCurve.fillEqn Java method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
 * From this polynomial, we can derive the forward differences to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
 * allow us to calculate V(t+K) from V(t) as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
 * 1) V1(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
 *        = V(K)-V(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
 *        = aK^3 + bK^2 + cK + d - d
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
 *        = aK^3 + bK^2 + cK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
 * 2) V1(K)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
 *        = V(2K)-V(K)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
 *        = 8aK^3 + 4bK^2 + 2cK + d - aK^3 - bK^2 - cK - d
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
 *        = 7aK^3 + 3bK^2 + cK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
 * 3) V1(2K)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
 *        = V(3K)-V(2K)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
 *        = 27aK^3 + 9bK^2 + 3cK + d - 8aK^3 - 4bK^2 - 2cK - d
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
 *        = 19aK^3 + 5bK^2 + cK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
 * 4) V2(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
 *        = V1(K) - V1(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
 *        = 7aK^3 + 3bK^2 + cK - aK^3 - bK^2 - cK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
 *        = 6aK^3 + 2bK^2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
 * 5) V2(K)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
 *        = V1(2K) - V1(K)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
 *        = 19aK^3 + 5bK^2 + cK - 7aK^3 - 3bK^2 - cK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
 *        = 12aK^3 + 2bK^2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
 * 6) V3(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
 *        = V2(K) - V2(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
 *        = 12aK^3 + 2bK^2 - 6aK^3 - 2bK^2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
 *        = 6aK^3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
 * Note that if we continue on to calculate V1(3K), V2(2K) and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
 * V3(K) we will see that V3(K) == V3(0) so we need at most
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
 * 3 cascading forward differences to step through the cubic
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
 * curve.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
 * Note, b coefficient calculating in the DrawCubic is actually twice the b
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
 * coefficient seen above.  It's been done for the better accuracy.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
 * In our case, initialy K is chosen as 1/(2^DF_CUB_STEPS) this value is taken
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
 * with FWD_PREC bits precision. This means that we should do 2^DF_CUB_STEPS
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
 * steps to pass through all the curve.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
 * On each step we examine how far we are stepping by examining our first(V1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
 * and second (V2) order derivatives and verifying that they are met following
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
 * conditions:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
 * abs(V2) <= DF_CUB_DEC_BND
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
 * abs(V1) > DF_CUB_INC_BND
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
 * So, ensures that we step through the curve more slowly when its curvature is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
 * high and faster when its curvature is lower.  If the step size needs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
 * adjustment we adjust it so that we step either twice as fast, or twice as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
 * slow until our step size is within range.  This modifies our stepping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
 * variables as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
 * Decreasing step size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
 * (See Graphics Gems/by A.Glassner,(Tutorial on forward differencing),601-602)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
 * V3 = oV3/8
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
 * V2 = oV2/4 - V3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
 * V1 = (oV1 - V2)/2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
 * Here V1-V3 stands for new values of the forward differencies and oV1 - oV3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
 * for the old ones
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
 * Using the equations above it's easy to calculating stepping variables for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
 * the increasing step size:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
 * V1 = 2*oV1 + oV2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
 * V2 = 4*oV2 + 4*oV3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
 * V3 = 8*oV3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
 * And then for not to running out of 32 bit precision we are performing 3 bit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
 * shift of the forward differencing precision (keeping in shift variable) in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
 * left or right direction depending on what is  happening (decreasing or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
 * increasing). So, all oV1 - oV3 variables should be thought as appropriately
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
 * shifted in regard to the V1 - V3.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
 * Taking all of the above into account we will have following:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
 * Decreasing step size:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
 * shift = shift + 3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
 * V3 keeps the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
 * V2 = 2*oV2 - V3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
 * V1 = 4*oV1 - V2/2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
 * Increasing step size:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
 * shift = shift - 3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
 * V1 = oV1/4 + oV2/8
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
 * V2 = oV2/2 + oV3/2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
 * V3 keeps the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
static void DrawMonotonicCubic(ProcessHandler* hnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
                               jfloat *coords,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
                               jboolean checkBounds,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
                               jint* pixelInfo)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
    jint x0 = (jint)(coords[0]*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
    jint y0 = (jint)(coords[1]*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
    jint xe = (jint)(coords[6]*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
    jint ye = (jint)(coords[7]*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
    /* Extracting fractional part of coordinates of first control point */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    jint px = (x0 & (~MDP_W_MASK)) << DF_CUB_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
    jint py = (y0 & (~MDP_W_MASK)) << DF_CUB_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
    /* Setting default boundary values for checking first and second forward
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
     * difference for the necessity of the restepping. See comments to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
     * boundary values in ProcessQuad for more info.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
    jint incStepBnd1 = DF_CUB_INC_BND;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
    jint incStepBnd2 = DF_CUB_INC_BND << 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
    jint decStepBnd1 = DF_CUB_DEC_BND;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
    jint decStepBnd2 = DF_CUB_DEC_BND << 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
    /* Setting default amount of steps */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
    jint count = DF_CUB_COUNT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
    /* Setting default shift for preparing to the midpoint rounding */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
    jint shift =  DF_CUB_SHIFT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
    jint ax = (jint)((-coords[0] + 3*coords[2] - 3*coords[4] +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
                coords[6])*CUB_A_MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
    jint ay = (jint)((-coords[1] + 3*coords[3] - 3*coords[5] +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
                coords[7])*CUB_A_MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
    jint bx = (jint)((3*coords[0] - 6*coords[2] +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
              3*coords[4])*CUB_B_MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
    jint by = (jint)((3*coords[1] - 6*coords[3] +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
              3*coords[5])*CUB_B_MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
    jint cx = (jint)((-3*coords[0] + 3*coords[2])*(CUB_C_MDP_MULT));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
    jint cy = (jint)((-3*coords[1] + 3*coords[3])*(CUB_C_MDP_MULT));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
    jint dddpx = 6*ax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
    jint dddpy = 6*ay;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
    jint ddpx = dddpx + bx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
    jint ddpy = dddpy + by;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
    jint dpx = ax + (bx>>1) + cx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
    jint dpy = ay + (by>>1) + cy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
    jint x1, y1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
    jint x2 = x0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
    jint y2 = y0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
    /* Calculating whole part of the first point of the curve */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
    jint x0w = x0 & MDP_W_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
    jint y0w = y0 & MDP_W_MASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
    jint dx = xe - x0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
    jint dy = ye - y0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
    while (count > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
        /* Perform decreasing step in 2 times if necessary */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
        while (
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
               /* The code below is an optimized version of the checks:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
                *   abs(ddpx) > decStepBnd1 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
                *   abs(ddpy) > decStepBnd1
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
                */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
               (juint)(ddpx + decStepBnd1) > (juint)decStepBnd2 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
               (juint)(ddpy + decStepBnd1) > (juint)decStepBnd2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
            ddpx = (ddpx<<1) - dddpx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
            ddpy = (ddpy<<1) - dddpy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
            dpx = (dpx<<2) - (ddpx>>1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
            dpy = (dpy<<2) - (ddpy>>1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
            count <<=1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
            decStepBnd1 <<=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
            decStepBnd2 <<=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
            incStepBnd1 <<=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
            incStepBnd2 <<=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
            px <<=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
            py <<=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
            shift += 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
        /* Perform increasing step in 2 times if necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
         * Note: we could do it only in even steps
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
        while (((count & 1) ^ 1) && shift > DF_CUB_SHIFT  &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
               /* The code below is an optimized version of the check:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
                *   abs(dpx) <= incStepBnd1 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
                *   abs(dpy) <= incStepBnd1
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
                */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
               (juint)(dpx + incStepBnd1) <= (juint)incStepBnd2 &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
               (juint)(dpy + incStepBnd1) <= (juint)incStepBnd2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
            dpx = (dpx>>2) + (ddpx>>3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
            dpy = (dpy>>2) + (ddpy>>3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
            ddpx = (ddpx + dddpx)>>1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
            ddpy = (ddpy + dddpy)>>1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
            count >>=1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
            decStepBnd1 >>=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
            decStepBnd2 >>=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
            incStepBnd1 >>=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
            incStepBnd2 >>=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
            px >>=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
            py >>=3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
            shift -= 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
        count--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
        /* We are performing one step less than necessary and use actual
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
         * (xe,ye) endpoint of the curve instead of calculated. This prevent
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
         * us from accumulated errors at the last point.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
        if (count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
            px += dpx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
            py += dpy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
            dpx += ddpx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
            dpy += ddpy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
            ddpx += dddpx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
            ddpy += dddpy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
            x1 = x2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
            y1 = y2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
            x2 = x0w + (px >> shift);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
            y2 = y0w + (py >> shift);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
            /* Checking that we are not running out of the endpoint and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
             * bounding violating coordinate.  The check is pretty simple
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
             * because the curve passed to the DrawMonotonicCubic already
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
             * splitted into the monotonic in X and Y pieces
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
            /* Bounding x2 by xe */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
            if (((xe-x2)^dx) < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
                x2 = xe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
            /* Bounding y2 by ye */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
            if (((ye-y2)^dy) < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
                y2 = ye;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
            hnd->pProcessFixedLine(hnd, x1, y1, x2, y2, pixelInfo, checkBounds,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
                                   JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
            hnd->pProcessFixedLine(hnd, x2, y2, xe, ye, pixelInfo, checkBounds,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
                                   JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
 * Checking size of the cubic curves and split them if necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
 * Calling DrawMonotonicCubic for the curves of the appropriate size.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
 * Note: coords array could be changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
static void ProcessMonotonicCubic(ProcessHandler* hnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
                                  jfloat *coords,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
                                  jint* pixelInfo) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
    jfloat coords1[8];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
    jfloat tx, ty;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
    jfloat xMin, xMax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
    jfloat yMin, yMax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
    xMin = xMax = coords[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
    yMin = yMax = coords[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
    CALC_MIN(xMin, coords[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
    CALC_MAX(xMax, coords[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
    CALC_MIN(yMin, coords[3]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
    CALC_MAX(yMax, coords[3]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
    CALC_MIN(xMin, coords[4]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
    CALC_MAX(xMax, coords[4]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
    CALC_MIN(yMin, coords[5]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
    CALC_MAX(yMax, coords[5]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
    CALC_MIN(xMin, coords[6]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
    CALC_MAX(xMax, coords[6]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
    CALC_MIN(yMin, coords[7]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
    CALC_MAX(yMax, coords[7]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
    if (hnd->clipMode == PH_MODE_DRAW_CLIP) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
       /* In case of drawing we could just skip curves which are completely
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
        * out of bounds
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
        */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
        if (hnd->dhnd->xMaxf < xMin || hnd->dhnd->xMinf > xMax ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
            hnd->dhnd->yMaxf < yMin || hnd->dhnd->yMinf > yMax) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
       /* In case of filling we could skip curves which are above,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
        * below and behind the right boundary of the visible area
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
        */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
        if (hnd->dhnd->yMaxf < yMin || hnd->dhnd->yMinf > yMax ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
            hnd->dhnd->xMaxf < xMin)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
       /* We could clamp x coordinates to the corresponding boundary
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
        * if the curve is completely behind the left one
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
        */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
        if (hnd->dhnd->xMinf > xMax) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
            coords[0] = coords[2] = coords[4] = coords[6] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
                hnd->dhnd->xMinf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
    if (xMax - xMin > MAX_CUB_SIZE || yMax - yMin > MAX_CUB_SIZE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
        coords1[6] = coords[6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
        coords1[7] = coords[7];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
        coords1[4] = (coords[4] + coords[6])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
        coords1[5] = (coords[5] + coords[7])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
        tx = (coords[2] + coords[4])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
        ty = (coords[3] + coords[5])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
        coords1[2] = (tx + coords1[4])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
        coords1[3] = (ty + coords1[5])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
        coords[2] =  (coords[0] + coords[2])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
        coords[3] =  (coords[1] + coords[3])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
        coords[4] = (coords[2] + tx)/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
        coords[5] = (coords[3] + ty)/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
        coords[6]=coords1[0]=(coords[4] + coords1[2])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
        coords[7]=coords1[1]=(coords[5] + coords1[3])/2.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
        ProcessMonotonicCubic(hnd, coords, pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
        ProcessMonotonicCubic(hnd, coords1, pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
        DrawMonotonicCubic(hnd, coords,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
                           /* Set checkBounds parameter if curve intersects
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
                            * boundary of the visible area. We know that the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
                            * curve is visible, so the check is pretty simple
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
                            */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
                           hnd->dhnd->xMinf > xMin || hnd->dhnd->xMaxf < xMax ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
                           hnd->dhnd->yMinf > yMin || hnd->dhnd->yMaxf < yMax,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
                           pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
 * Bite the piece of the cubic curve from start point till the point
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
 * corresponding to the specified parameter then call ProcessMonotonicCubic for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
 * the bitten part.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
 * Note: coords array will be changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
static void ProcessFirstMonotonicPartOfCubic(ProcessHandler* hnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
                                             jfloat* coords, jint* pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
                                             jfloat t)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
    jfloat coords1[8];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
    jfloat tx, ty;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
    coords1[0] = coords[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
    coords1[1] = coords[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
    tx = coords[2] + t*(coords[4] - coords[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
    ty = coords[3] + t*(coords[5] - coords[3]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
    coords1[2] =  coords[0] + t*(coords[2] - coords[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
    coords1[3] =  coords[1] + t*(coords[3] - coords[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
    coords1[4] = coords1[2] + t*(tx - coords1[2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
    coords1[5] = coords1[3] + t*(ty - coords1[3]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
    coords[4] = coords[4] + t*(coords[6] - coords[4]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
    coords[5] = coords[5] + t*(coords[7] - coords[5]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
    coords[2] = tx + t*(coords[4] - tx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
    coords[3] = ty + t*(coords[5] - ty);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
    coords[0]=coords1[6]=coords1[4] + t*(coords[2] - coords1[4]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
    coords[1]=coords1[7]=coords1[5] + t*(coords[3] - coords1[5]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
    ProcessMonotonicCubic(hnd, coords1, pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
 * Split cubic curve into monotonic in X and Y parts. Calling ProcessCubic for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
 * each monotonic piece of the curve.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
 * Note: coords array could be changed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
static void ProcessCubic(ProcessHandler* hnd, jfloat* coords, jint* pixelInfo)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
    /* Temporary array for holding parameters corresponding to the extreme in X
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
     * and Y points. The values are inside the (0,1) range (0 and 1 excluded)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
     * and in ascending order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
    double params[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
    jint cnt = 0, i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
    /* Simple check for monotonicity in X before searching for the extreme
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
     * points of the X(t) function. We first check if the curve is monotonic in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
     * X by seeing if all of the X coordinates are strongly ordered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
    if ((coords[0] > coords[2] || coords[2] > coords[4] ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
         coords[4] > coords[6]) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
        (coords[0] < coords[2] || coords[2] < coords[4] ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
         coords[4] < coords[6]))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
        /* Searching for extreme points of the X(t) function  by solving
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
         * dX(t)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
         * ----  = 0 equation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
         *  dt
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
        double ax = -coords[0] + 3*coords[2] - 3*coords[4] + coords[6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
        double bx = 2*(coords[0] - 2*coords[2] + coords[4]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
        double cx = -coords[0] + coords[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
        SOLVEQUADINRANGE(ax,bx,cx,params,cnt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
    /* Simple check for monotonicity in Y before searching for the extreme
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
     * points of the Y(t) function. We first check if the curve is monotonic in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
     * Y by seeing if all of the Y coordinates are strongly ordered.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
    if ((coords[1] > coords[3] || coords[3] > coords[5] ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
         coords[5] > coords[7]) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
        (coords[1] < coords[3] || coords[3] < coords[5] ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
         coords[5] < coords[7]))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
        /* Searching for extreme points of the Y(t) function by solving
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
         * dY(t)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
         * ----- = 0 equation
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
         *  dt
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
        double ay = -coords[1] + 3*coords[3] - 3*coords[5] + coords[7];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
        double by = 2*(coords[1] - 2*coords[3] + coords[5]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
        double cy = -coords[1] + coords[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
        SOLVEQUADINRANGE(ay,by,cy,params,cnt);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
    if (cnt > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
        /* Sorting parameter values corresponding to the extremum points of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
         * the curve. We are using insertion sort because of tiny size of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
         * array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
        jint j;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
        for(i = 1; i < cnt; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
            double value = params[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
            for (j = i - 1; j >= 0 && params[j] > value; j--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
                params[j + 1] = params[j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
            params[j + 1] = value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
        /* Processing obtained monotonic parts */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
        ProcessFirstMonotonicPartOfCubic(hnd, coords, pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
                                         (jfloat)params[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
        for (i = 1; i < cnt; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
            double param = params[i] - params[i-1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
            if (param > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
                ProcessFirstMonotonicPartOfCubic(hnd, coords, pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
                    /* Scale parameter to match with rest of the curve */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
                    (float)(param/(1.0 - params[i - 1])));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
    ProcessMonotonicCubic(hnd,coords,pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
static void ProcessLine(ProcessHandler* hnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
                        jfloat *coord1, jfloat *coord2, jint* pixelInfo) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
    jfloat xMin, yMin, xMax, yMax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
    jint X1, Y1, X2, Y2, X3, Y3, res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
    jboolean clipped = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
    jfloat x1 = coord1[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
    jfloat y1 = coord1[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
    jfloat x2 = coord2[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
    jfloat y2 = coord2[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
    jfloat x3,y3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
    jboolean lastClipped;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
    xMin = hnd->dhnd->xMinf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
    yMin = hnd->dhnd->yMinf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
    xMax = hnd->dhnd->xMaxf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
    yMax = hnd->dhnd->yMaxf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
    TESTANDCLIP(yMin, yMax, y1, x1, y2, x2, jfloat, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
    if (res == CRES_INVISIBLE) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
    clipped = IS_CLIPPED(res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
    TESTANDCLIP(yMin, yMax, y2, x2, y1, x1, jfloat, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
    if (res == CRES_INVISIBLE) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
    lastClipped = IS_CLIPPED(res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
    clipped = clipped || lastClipped;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
    if (hnd->clipMode == PH_MODE_DRAW_CLIP) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
        TESTANDCLIP(xMin, xMax,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
                    x1, y1, x2, y2, jfloat, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
        if (res == CRES_INVISIBLE) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
        clipped = clipped || IS_CLIPPED(res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
        TESTANDCLIP(xMin, xMax,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
                    x2, y2, x1, y1, jfloat, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
        if (res == CRES_INVISIBLE) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
        lastClipped = lastClipped || IS_CLIPPED(res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
        clipped = clipped || lastClipped;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
        X1 = (jint)(x1*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
        Y1 = (jint)(y1*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
        X2 = (jint)(x2*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
        Y2 = (jint)(y2*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
        hnd->pProcessFixedLine(hnd, X1, Y1, X2, Y2, pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
                               clipped, /* enable boundary checking in case
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
                                           of clipping to avoid entering
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
                                           out of bounds which could
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
                                           happens during rounding
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
                                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
                               lastClipped /* Notify pProcessFixedLine that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
                                              this is the end of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
                                              subpath (because of exiting
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
                                              out of boundaries)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
                                            */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
                               );
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
        /* Clamping starting from first vertex of the the processed segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
        CLIPCLAMP(xMin, xMax, x1, y1, x2, y2, x3, y3, jfloat, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
        X1 = (jint)(x1*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
        Y1 = (jint)(y1*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
        /* Clamping only by left boundary */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
        if (res == CRES_MIN_CLIPPED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
            X3 = (jint)(x3*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
            Y3 = (jint)(y3*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
            hnd->pProcessFixedLine(hnd, X3, Y3, X1, Y1, pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
                                   JNI_FALSE, lastClipped);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
        } else if (res == CRES_INVISIBLE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
        /* Clamping starting from last vertex of the the processed segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
        CLIPCLAMP(xMin, xMax, x2, y2, x1, y1, x3, y3, jfloat, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
        /* Checking if there was a clip by right boundary */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
        lastClipped = lastClipped || (res == CRES_MAX_CLIPPED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
        X2 = (jint)(x2*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
        Y2 = (jint)(y2*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
        hnd->pProcessFixedLine(hnd, X1, Y1, X2, Y2, pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
                               JNI_FALSE, lastClipped);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
        /* Clamping only by left boundary */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
        if (res == CRES_MIN_CLIPPED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
            X3 = (jint)(x3*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
            Y3 = (jint)(y3*MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
            hnd->pProcessFixedLine(hnd, X2, Y2, X3, Y3, pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
                                   JNI_FALSE, lastClipped);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
jboolean ProcessPath(ProcessHandler* hnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
                     jfloat transXf, jfloat transYf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
                     jfloat* coords, jint maxCoords,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
                     jbyte* types, jint numTypes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
    jfloat tCoords[8];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
    jfloat closeCoord[2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
    jint pixelInfo[5];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
    jboolean skip = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
    jboolean subpathStarted = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
    jfloat lastX, lastY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
    int i, index = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
    pixelInfo[0] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
    /* Adding support of the KEY_STROKE_CONTROL rendering hint.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
     * Now we are supporting two modes: "pixels at centers" and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
     * "pixels at corners".
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
     * First one is disabled by default but could be enabled by setting
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
     * VALUE_STROKE_PURE to the rendering hint. It means that pixel at the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
     * screen (x,y) has (x + 0.5, y + 0.5) float coordinates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
     * Second one is enabled by default and means straightforward mapping
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
     * (x,y) --> (x,y)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
    if (hnd->stroke == PH_STROKE_PURE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
        closeCoord[0] = -0.5f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
        closeCoord[1] = -0.5f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
        transXf -= 0.5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
        transYf -= 0.5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
        closeCoord[0] = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
        closeCoord[1] = 0.0f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
    /* Adjusting boundaries to the capabilities of the ProcessPath code */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
    ADJUST(hnd->dhnd->xMin, LOWER_OUT_BND, UPPER_OUT_BND);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
    ADJUST(hnd->dhnd->yMin, LOWER_OUT_BND, UPPER_OUT_BND);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
    ADJUST(hnd->dhnd->xMax, LOWER_OUT_BND, UPPER_OUT_BND);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
    ADJUST(hnd->dhnd->yMax, LOWER_OUT_BND, UPPER_OUT_BND);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
    /*                Setting up fractional clipping box
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
     * We are using following float -> int mapping:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
     *      xi = floor(xf + 0.5)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
     * So, fractional values that hit the [xmin, xmax) integer interval will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
     * situated inside the [xmin-0.5, xmax - 0.5) fractional interval. We are
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
     * using EPSF constant to provide that upper boundary is not included.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
    hnd->dhnd->xMinf = hnd->dhnd->xMin - 0.5f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
    hnd->dhnd->yMinf = hnd->dhnd->yMin - 0.5f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
    hnd->dhnd->xMaxf = hnd->dhnd->xMax - 0.5f - EPSF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
    hnd->dhnd->yMaxf = hnd->dhnd->yMax - 0.5f - EPSF;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
    for (i = 0; i < numTypes; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
        switch (types[i]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
            case java_awt_geom_PathIterator_SEG_MOVETO:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
                if (index + 2 <= maxCoords) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
                    /* Performing closing of the unclosed segments */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
                    if (subpathStarted & !skip) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
                        if (hnd->clipMode == PH_MODE_FILL_CLIP) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
                            if (tCoords[0] != closeCoord[0] ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
                                tCoords[1] != closeCoord[1])
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
                            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
                                ProcessLine(hnd, tCoords, closeCoord,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
                                            pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
                        hnd->pProcessEndSubPath(hnd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
                    tCoords[0] = coords[index++] + transXf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
                    tCoords[1] = coords[index++] + transYf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
                    /* Checking SEG_MOVETO coordinates if they are out of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
                     * [LOWER_BND, UPPER_BND] range.  This check also handles
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
                     * NaN and Infinity values. Skipping next path segment in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
                     * case of invalid data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1539
                    if (tCoords[0] < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
                        tCoords[0] > LOWER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
                        tCoords[1] < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
                        tCoords[1] > LOWER_BND)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
                    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
                        subpathStarted = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
                        skip = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
                        closeCoord[0] = tCoords[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
                        closeCoord[1] = tCoords[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
                        skip = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1552
                    return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
            case java_awt_geom_PathIterator_SEG_LINETO:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
                if (index + 2 <= maxCoords) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
                    lastX = tCoords[2] = coords[index++] + transXf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
                    lastY = tCoords[3] = coords[index++] + transYf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
                    /* Checking SEG_LINETO coordinates if they are out of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
                     * [LOWER_BND, UPPER_BND] range.  This check also handles
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
                     * NaN and Infinity values. Ignoring current path segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
                     * in case  of invalid data. If segment is skipped its
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
                     * endpoint (if valid) is used to begin new subpath.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1565
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1566
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1567
                    if (lastX < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1568
                        lastX > LOWER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1569
                        lastY < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1570
                        lastY > LOWER_BND)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1571
                    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1572
                        if (skip) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1573
                            tCoords[0] = closeCoord[0] = lastX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1574
                            tCoords[1] = closeCoord[1] = lastY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1575
                            subpathStarted = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1576
                            skip = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1577
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1578
                            ProcessLine(hnd, tCoords, tCoords + 2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1579
                                        pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1580
                            tCoords[0] = lastX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1581
                            tCoords[1] = lastY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1582
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1583
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1584
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1585
                    return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1586
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1587
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1588
            case java_awt_geom_PathIterator_SEG_QUADTO:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1589
                if (index + 4 <= maxCoords) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1590
                    tCoords[2] = coords[index++] + transXf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1591
                    tCoords[3] = coords[index++] + transYf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1592
                    lastX = tCoords[4] = coords[index++] + transXf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1593
                    lastY = tCoords[5] = coords[index++] + transYf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1594
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1595
                    /* Checking SEG_QUADTO coordinates if they are out of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1596
                     * [LOWER_BND, UPPER_BND] range.  This check also handles
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1597
                     * NaN and Infinity values. Ignoring current path segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1598
                     * in case  of invalid endpoints's data.  Equivalent to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1599
                     * the SEG_LINETO if endpoint coordinates are valid but
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1600
                     * there are invalid data among other coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1601
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1602
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1603
                    if (lastX < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1604
                        lastX > LOWER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1605
                        lastY < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1606
                        lastY > LOWER_BND)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1607
                    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1608
                        if (skip) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1609
                            tCoords[0] = closeCoord[0] = lastX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1610
                            tCoords[1] = closeCoord[1] = lastY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1611
                            subpathStarted = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1612
                            skip = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1613
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1614
                            if (tCoords[2] < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1615
                                tCoords[2] > LOWER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1616
                                tCoords[3] < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1617
                                tCoords[3] > LOWER_BND)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1618
                            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1619
                                ProcessQuad(hnd, tCoords, pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1620
                            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1621
                                ProcessLine(hnd, tCoords,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1622
                                            tCoords + 4, pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1623
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1624
                            tCoords[0] = lastX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1625
                            tCoords[1] = lastY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1628
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1629
                    return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
            case java_awt_geom_PathIterator_SEG_CUBICTO:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
                    if (index + 6 <= maxCoords) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1634
                    tCoords[2] = coords[index++] + transXf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1635
                    tCoords[3] = coords[index++] + transYf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1636
                    tCoords[4] = coords[index++] + transXf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1637
                    tCoords[5] = coords[index++] + transYf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1638
                    lastX = tCoords[6] = coords[index++] + transXf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1639
                    lastY = tCoords[7] = coords[index++] + transYf;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1640
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1641
                    /* Checking SEG_CUBICTO coordinates if they are out of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1642
                     * [LOWER_BND, UPPER_BND] range.  This check also handles
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1643
                     * NaN and Infinity values. Ignoring current path segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
                     * in case  of invalid endpoints's data.  Equivalent to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
                     * the SEG_LINETO if endpoint coordinates are valid but
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
                     * there are invalid data among other coordinates
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1647
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1648
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1649
                    if (lastX < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1650
                        lastX > LOWER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1651
                        lastY < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1652
                        lastY > LOWER_BND)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1653
                    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1654
                        if (skip) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1655
                            tCoords[0] = closeCoord[0] = tCoords[6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1656
                            tCoords[1] = closeCoord[1] = tCoords[7];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1657
                            subpathStarted = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1658
                            skip = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1659
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1660
                            if (tCoords[2] < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
                                tCoords[2] > LOWER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1662
                                tCoords[3] < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1663
                                tCoords[3] > LOWER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1664
                                tCoords[4] < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1665
                                tCoords[4] > LOWER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1666
                                tCoords[5] < UPPER_BND &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1667
                                tCoords[5] > LOWER_BND)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1668
                            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1669
                                ProcessCubic(hnd, tCoords, pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1670
                            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1671
                                ProcessLine(hnd, tCoords, tCoords + 6,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1672
                                            pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1674
                            tCoords[0] = lastX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1675
                            tCoords[1] = lastY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
                    return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1680
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1681
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1682
            case java_awt_geom_PathIterator_SEG_CLOSE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1683
                if (subpathStarted && !skip) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1684
                    skip = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1685
                    if (tCoords[0] != closeCoord[0] ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1686
                        tCoords[1] != closeCoord[1])
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1687
                    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
                        ProcessLine(hnd, tCoords, closeCoord, pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1689
                        /* Storing last path's point for using in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
                         * following segments without initial moveTo
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
                         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1692
                        tCoords[0] = closeCoord[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
                        tCoords[1] = closeCoord[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1694
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
                    hnd->pProcessEndSubPath(hnd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1697
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1698
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1699
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1700
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1701
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1702
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1703
    /* Performing closing of the unclosed segments */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1704
    if (subpathStarted & !skip) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1705
        if (hnd->clipMode == PH_MODE_FILL_CLIP) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1706
            if (tCoords[0] != closeCoord[0] ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1707
                tCoords[1] != closeCoord[1])
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1708
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1709
                ProcessLine(hnd, tCoords, closeCoord,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1710
                            pixelInfo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1711
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1712
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1713
        hnd->pProcessEndSubPath(hnd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1714
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1715
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1716
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1717
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1718
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1719
/* TODO Add checking of the result of the malloc/realloc functions to handle
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1720
 * out of memory error and don't leak earlier allocated data
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1721
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1722
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1723
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1724
#define ALLOC(ptr, type, n) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1725
    ptr = (type *)malloc((n)*sizeof(type))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1726
#define REALLOC(ptr, type, n) \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1727
    ptr = (type *)realloc(ptr, (n)*sizeof(type))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1728
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1729
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1730
struct _Edge;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1731
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1732
typedef struct _Point {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1733
    jint x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1734
    jint y;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1735
    jboolean lastPoint;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1736
    struct _Point* prev;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1737
    struct _Point* next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1738
    struct _Point* nextByY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1739
    jboolean endSL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1740
    struct _Edge* edge;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1741
} Point;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1742
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1743
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1744
typedef struct _Edge {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1745
    jint          x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1746
    jint          dx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1747
    Point*        p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1748
    jint          dir;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1749
    struct _Edge* prev;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1750
    struct _Edge* next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1751
} Edge;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1752
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1753
/* Size of the default buffer in the FillData structure. This buffer is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1754
 * replaced with heap allocated in case of large paths.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1755
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1756
#define DF_MAX_POINT 256
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1757
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1758
/* Following structure accumulates points of the non-continuous flattened
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1759
 * path during iteration through the origin path's segments . The end
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1760
 * of the each subpath is marked as lastPoint flag set at the last point
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1761
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1762
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1763
typedef struct {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1764
    Point   *plgPnts;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1765
    Point   dfPlgPnts[DF_MAX_POINT];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1766
    jint    plgSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1767
    jint    plgMax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1768
    jint    plgYMin;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1769
    jint    plgYMax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1770
} FillData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1771
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1772
#define FD_INIT(PTR)                                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1773
    do {                                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1774
        (PTR)->plgPnts = (PTR)->dfPlgPnts;                                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1775
        (PTR)->plgSize = 0;                                                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1776
        (PTR)->plgMax = DF_MAX_POINT;                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1777
    } while(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1778
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1779
#define FD_ADD_POINT(PTR, X, Y, LASTPT)                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1780
    do {                                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1781
        Point* _pnts = (PTR)->plgPnts;                                      \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1782
        jint _size = (PTR)->plgSize;                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1783
        if (_size >= (PTR)->plgMax) {                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1784
            jint newMax = (PTR)->plgMax*2;                                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1785
            if ((PTR)->plgPnts == (PTR)->dfPlgPnts) {                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1786
                (PTR)->plgPnts = (Point*)malloc(newMax*sizeof(Point));      \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1787
                memcpy((PTR)->plgPnts, _pnts, _size*sizeof(Point));         \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1788
            } else {                                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1789
                (PTR)->plgPnts = (Point*)realloc(                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1790
                    _pnts, newMax*sizeof(Point));                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1791
            }                                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1792
            _pnts = (PTR)->plgPnts;                                         \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1793
            (PTR)->plgMax = newMax;                                         \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1794
        }                                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1795
        _pnts += _size;                                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1796
        _pnts->x = X;                                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1797
        _pnts->y = Y;                                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1798
        _pnts->lastPoint = LASTPT;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1799
        if (_size) {                                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1800
            if ((PTR)->plgYMin > Y) (PTR)->plgYMin = Y;                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1801
            if ((PTR)->plgYMax < Y) (PTR)->plgYMax = Y;                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1802
        } else {                                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1803
            (PTR)->plgYMin = Y;                                             \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1804
            (PTR)->plgYMax = Y;                                             \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1805
        }                                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1806
        (PTR)->plgSize = _size + 1;                                         \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1807
    } while(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1808
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1809
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1810
#define FD_FREE_POINTS(PTR)                                                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1811
    do {                                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1812
        if ((PTR)->plgPnts != (PTR)->dfPlgPnts) {                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1813
            free((PTR)->plgPnts);                                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1814
        }                                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1815
    } while(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1816
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1817
#define FD_IS_EMPTY(PTR) (!((PTR)->plgSize))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1818
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1819
#define FD_IS_ENDED(PTR) ((PTR)->plgPnts[(PTR)->plgSize - 1].lastPoint)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1820
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1821
#define FD_SET_ENDED(PTR)                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1822
    do {                                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1823
        (PTR)->plgPnts[(PTR)->plgSize - 1].lastPoint = JNI_TRUE;            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1824
    } while(0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1825
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1826
#define PFD(HND) ((FillData*)(HND)->pData)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1827
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1828
/* Bubble sorting in the ascending order of the linked list. This
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1829
 * implementation stops processing the list if there were no changes during the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1830
 * previous pass.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1831
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1832
 * LIST - ptr to the ptr to the first element of the list
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1833
 * ETYPE - type of the element in the list
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1834
 * NEXT - accessor to the next field in the list element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1835
 * GET_LKEY - accessor to the key of the list element
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1836
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1837
#define LBUBBLE_SORT(LIST, ETYPE, NEXT, GET_LKEY)                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1838
    do {                                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1839
        ETYPE *p, *q, *r, *s = NULL, *temp ;                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1840
        jint wasSwap = 1;                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1841
        /* r precedes p and s points to the node up to which comparisons    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1842
         * are to be made */                                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1843
        while ( s != NEXT(*LIST) && wasSwap) {                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1844
            r = p = *LIST;                                                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1845
            q = NEXT(p);                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1846
            wasSwap = 0;                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1847
            while ( p != s ) {                                              \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1848
                if (GET_LKEY(p) >= GET_LKEY(q)) {                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1849
                    wasSwap = 1;                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1850
                    if ( p == *LIST ) {                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1851
                        temp = NEXT(q);                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1852
                        NEXT(q) = p ;                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1853
                        NEXT(p) = temp ;                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1854
                        *LIST = q ;                                         \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1855
                        r = q ;                                             \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1856
                    } else {                                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1857
                        temp = NEXT(q);                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1858
                        NEXT(q) = p ;                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1859
                        NEXT(p) = temp ;                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1860
                        NEXT(r) = q ;                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1861
                        r = q ;                                             \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1862
                    }                                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1863
                } else {                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1864
                    r = p ;                                                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1865
                    p = NEXT(p);                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1866
                }                                                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1867
                q = NEXT(p);                                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1868
                if ( q == s ) s = p ;                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1869
            }                                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1870
        }                                                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1871
    } while(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1872
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1873
/* Accessors for the Edge structure to work with LBUBBLE_SORT */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1874
#define GET_ACTIVE_KEY(a) (a->x)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1875
#define GET_ACTIVE_NEXT(a) ((a)->next)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1876
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1877
/* TODO: Implement stack/heap allocation technique for active edges
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1878
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1879
#define DELETE_ACTIVE(head,pnt)                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1880
do {                                                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1881
    Edge *prevp = pnt->prev;                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1882
    Edge *nextp = pnt->next;                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1883
    if (prevp) {                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1884
        prevp->next = nextp;                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1885
    } else {                                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1886
        head = nextp;                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1887
    }                                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1888
    if (nextp) {                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1889
        nextp->prev = prevp;                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1890
    }                                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1891
} while(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1892
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1893
#define INSERT_ACTIVE(head,pnt,cy)                                  \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1894
do {                                                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1895
    Point *np = pnt->next;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1896
    Edge *ne = active + nact;                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1897
    if (pnt->y == np->y) {                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1898
        /* Skipping horizontal segments */                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1899
        break;                                                      \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1900
    } else {                                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1901
        jint dX = np->x - pnt->x;                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1902
        jint dY = np->y - pnt->y;                                   \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1903
        jint dy;                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1904
        if (pnt->y < np->y) {                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1905
            ne->dir = -1;                                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1906
            ne->p = pnt;                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1907
            ne->x = pnt->x;                                         \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1908
            dy = cy - pnt->y;                                       \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1909
        } else { /* pnt->y > np->y */                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1910
            ne->dir = 1;                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1911
            ne->p = np;                                             \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1912
            ne->x = np->x;                                          \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1913
            dy = cy - np->y;                                        \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1914
        }                                                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1915
                                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1916
        /* We need to worry only about dX because dY is in        */\
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1917
        /* denominator and abs(dy) < MDP_MULT (cy is a first      */\
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1918
        /* scanline of the scan converted segment and we subtract */\
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1919
        /* y coordinate of the nearest segment's end from it to   */\
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1920
        /* obtain dy)                                             */\
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1921
        if (ABS32(dX) > CALC_BND) {                                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1922
            ne->dx = (jint)((((jdouble)dX)*MDP_MULT)/dY);           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1923
            ne->x += (jint)((((jdouble)dX)*dy)/dY);                 \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1924
        } else {                                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1925
            ne->dx = ((dX)<<MDP_PREC)/dY;                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1926
            ne->x += (dX*dy)/dY;                                    \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1927
        }                                                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1928
    }                                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1929
    ne->next = head;                                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1930
    ne->prev = NULL;                                                \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1931
    if (head) {                                                     \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1932
        head->prev = ne;                                            \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1933
    }                                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1934
    head = active + nact;                                           \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1935
    pnt->edge = head;                                               \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1936
    nact++;                                                         \
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1937
} while(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1938
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1939
void FillPolygon(ProcessHandler* hnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1940
                 jint fillRule) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1941
    jint k, y, xl, xr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1942
    jint drawing;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1943
    Edge* activeList, *active;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1944
    Edge* curEdge, *prevEdge;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1945
    jint nact;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1946
    jint n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1947
    Point* pt, *curpt, *ept;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1948
    Point** yHash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1949
    Point** curHash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1950
    jint rightBnd = hnd->dhnd->xMax - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1951
    FillData* pfd = (FillData*)(hnd->pData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1952
    jint yMin = pfd->plgYMin;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1953
    jint yMax = pfd->plgYMax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1954
    jint hashSize = ((yMax - yMin)>>MDP_PREC) + 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1955
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1956
    /* Because of support of the KEY_STROKE_CONTROL hint we are performing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1957
     * shift of the coordinates at the higher level
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1958
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1959
    jint hashOffset = ((yMin - 1) & MDP_W_MASK);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1960
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1961
// TODO creating lists using fake first element to avoid special casing of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1962
// the first element in the list (which otherwise should be performed in each
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1963
// list operation)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1964
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1965
    /* Winding counter */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1966
    jint counter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1967
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1968
    /* Calculating mask to be applied to the winding counter */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1969
    jint counterMask =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1970
        (fillRule == java_awt_geom_PathIterator_WIND_NON_ZERO)? -1:1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1971
    pt = pfd->plgPnts;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1972
    n = pfd->plgSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1973
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1974
    if (n <=1) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1975
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1976
    ALLOC(yHash, Point*, hashSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1977
    for (k = 0; k < hashSize; k++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1978
        yHash[k] = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1979
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1980
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1981
    ALLOC(active, Edge, n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1982
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1983
    /* Creating double linked list (prev, next links) describing path order and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1984
     * hash table with points which fall between scanlines. nextByY link is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1985
     * used for the points which are between same scanlines. Scanlines are
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1986
     * passed through the centers of the pixels.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1987
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1988
    curpt = pt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1989
    curpt->prev = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1990
    ept = pt + n - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1991
    for (curpt = pt; curpt != ept; curpt++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1992
        Point* nextpt = curpt + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1993
        curHash =  yHash + ((curpt->y - hashOffset - 1) >> MDP_PREC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1994
        curpt->nextByY = *curHash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1995
        *curHash = curpt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1996
        curpt->next = nextpt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1997
        nextpt->prev = curpt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1998
        curpt->edge = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1999
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2000
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2001
    curHash =  yHash + ((ept->y - hashOffset - 1) >> MDP_PREC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2002
    ept->nextByY = *curHash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2003
    *curHash = ept;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2004
    ept->next = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2005
    ept->edge = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2006
    nact = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2007
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2008
    activeList = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2009
    for (y=hashOffset + MDP_MULT,k = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2010
         y<=yMax && k < hashSize; y += MDP_MULT, k++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2011
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2012
        for(pt = yHash[k];pt; pt=pt->nextByY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2013
            /* pt->y should be inside hashed interval
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2014
             * assert(y-MDP_MULT <= pt->y && pt->y < y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2015
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2016
            if (pt->prev && !pt->prev->lastPoint) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2017
                if (pt->prev->edge && pt->prev->y <= y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2018
                    DELETE_ACTIVE(activeList, pt->prev->edge);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2019
                    pt->prev->edge = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2020
                } else  if (pt->prev->y > y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2021
                    INSERT_ACTIVE(activeList, pt->prev, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2022
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2023
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2024
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2025
            if (!pt->lastPoint && pt->next) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2026
                if (pt->edge && pt->next->y <= y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2027
                    DELETE_ACTIVE(activeList, pt->edge);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2028
                    pt->edge = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2029
                } else if (pt->next->y > y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2030
                    INSERT_ACTIVE(activeList, pt, y);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2031
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2032
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2033
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2034
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2035
        if (!activeList) continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2036
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2037
        /* We could not use O(N) Radix sort here because in most cases list of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2038
         * edges almost sorted. So, bubble sort (O(N^2))is working much
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2039
         * better. Note, in case of array of edges Shell sort is more
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2040
         * efficient.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2041
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2042
        LBUBBLE_SORT((&activeList), Edge, GET_ACTIVE_NEXT, GET_ACTIVE_KEY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2043
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2044
        /* Correction of the back links in the double linked edge list */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2045
        curEdge=activeList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2046
        prevEdge = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2047
        while (curEdge) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2048
            curEdge->prev = prevEdge;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2049
            prevEdge = curEdge;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2050
            curEdge = curEdge->next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2051
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2052
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2053
        xl = xr = hnd->dhnd->xMin;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2054
        curEdge = activeList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2055
        counter = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2056
        drawing = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2057
        for(;curEdge; curEdge = curEdge->next) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2058
            counter += curEdge->dir;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2059
            if ((counter & counterMask) && !drawing) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2060
                xl = (curEdge->x + MDP_MULT - 1)>>MDP_PREC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2061
                drawing = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2062
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2063
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2064
            if (!(counter & counterMask) && drawing) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2065
                xr = (curEdge->x - 1)>>MDP_PREC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2066
                if (xl <= xr) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2067
                    hnd->dhnd->pDrawScanline(hnd->dhnd, xl, xr, y >> MDP_PREC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2068
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2069
                drawing = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2070
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2071
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2072
            curEdge->x += curEdge->dx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2073
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2074
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2075
        /* Performing drawing till the right boundary (for correct rendering
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2076
         * shapes clipped at the right side)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2077
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2078
        if (drawing && xl <= rightBnd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2079
            hnd->dhnd->pDrawScanline(hnd->dhnd, xl, rightBnd, y >> MDP_PREC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2080
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2081
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2082
    free(active);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2083
    free(yHash);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2084
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2085
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2086
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2087
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2088
void  StoreFixedLine(ProcessHandler* hnd,jint x1,jint y1,jint x2,jint y2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2089
                     jint* pixelInfo,jboolean checkBounds,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2090
                     jboolean endSubPath)  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2091
    FillData* pfd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2092
    jint outXMin, outXMax, outYMin, outYMax;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2093
    jint x3, y3, res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2094
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2095
    /* There is no need to round line coordinates to the forward differencing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2096
     * precision anymore. Such a rounding was used for preventing the curve go
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2097
     * out the endpoint (this sometimes does not help). The problem was fixed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2098
     * in the forward differencing loops.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2099
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2100
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2101
    if (checkBounds) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2102
        jboolean lastClipped = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2103
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2104
        /* This function is used only for filling shapes, so there is no
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2105
         * check for the type of clipping
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2106
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2107
        outXMin = (jint)(hnd->dhnd->xMinf * MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2108
        outXMax = (jint)(hnd->dhnd->xMaxf * MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2109
        outYMin = (jint)(hnd->dhnd->yMinf * MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2110
        outYMax = (jint)(hnd->dhnd->yMaxf * MDP_MULT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2111
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2112
        TESTANDCLIP(outYMin, outYMax, y1, x1, y2, x2, jint, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2113
        if (res == CRES_INVISIBLE) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2114
        TESTANDCLIP(outYMin, outYMax, y2, x2, y1, x1, jint, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2115
        if (res == CRES_INVISIBLE) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2116
        lastClipped = IS_CLIPPED(res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2117
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2118
        /* Clamping starting from first vertex of the the processed segment */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2119
        CLIPCLAMP(outXMin, outXMax, x1, y1, x2, y2, x3, y3, jint, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2120
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2121
        /* Clamping only by left boundary */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2122
        if (res == CRES_MIN_CLIPPED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2123
            StoreFixedLine(hnd, x3, y3, x1, y1, pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2124
                           JNI_FALSE, lastClipped);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2125
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2126
        } else if (res == CRES_INVISIBLE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2127
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2128
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2129
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2130
        /* Clamping starting from last vertex of the the processed segment */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2131
        CLIPCLAMP(outXMin, outXMax, x2, y2, x1, y1, x3, y3, jint, res);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2132
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2133
        /* Checking if there was a clip by right boundary */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2134
        lastClipped = lastClipped || (res == CRES_MAX_CLIPPED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2135
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2136
        StoreFixedLine(hnd, x1, y1, x2, y2, pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2137
                         JNI_FALSE, lastClipped);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2138
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2139
        /* Clamping only by left boundary */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2140
        if (res == CRES_MIN_CLIPPED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2141
            StoreFixedLine(hnd, x2, y2, x3, y3, pixelInfo,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2142
                           JNI_FALSE, lastClipped);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2143
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2144
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2145
        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2146
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2147
    pfd = (FillData*)(hnd->pData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2148
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2149
    /* Adding first point of the line only in case of empty or just finished
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2150
     * path
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2151
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2152
    if (FD_IS_EMPTY(pfd) || FD_IS_ENDED(pfd)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2153
        FD_ADD_POINT(pfd, x1, y1, JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2154
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2155
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2156
    FD_ADD_POINT(pfd, x2, y2, JNI_FALSE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2157
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2158
    if (endSubPath) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2159
        FD_SET_ENDED(pfd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2160
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2161
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2162
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2163
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2164
static void endSubPath(ProcessHandler* hnd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2165
    FillData* pfd = (FillData*)(hnd->pData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2166
    if (!FD_IS_EMPTY(pfd)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2167
        FD_SET_ENDED(pfd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2168
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2169
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2170
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2171
static void stubEndSubPath(ProcessHandler* hnd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2172
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2173
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2174
jboolean doFillPath(DrawHandler* dhnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2175
                    jint transX, jint transY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2176
                    jfloat* coords, jint maxCoords,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2177
                    jbyte* types, jint numTypes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2178
                    PHStroke stroke, jint fillRule)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2179
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2180
    jint res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2181
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2182
    FillData fillData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2183
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2184
    ProcessHandler hnd =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2185
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2186
        &StoreFixedLine,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2187
        &endSubPath,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2188
        NULL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2189
        PH_STROKE_DEFAULT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2190
        PH_MODE_FILL_CLIP,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2191
        NULL
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2192
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2193
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2194
    /* Initialization of the following fields in the declaration of the hnd
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2195
     * above causes warnings on sun studio compiler with  -xc99=%none option
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2196
     * applied (this option means compliance with C90 standard instead of C99)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2197
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2198
    hnd.dhnd = dhnd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2199
    hnd.pData = &fillData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2200
    hnd.stroke = stroke;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2201
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2202
    FD_INIT(&fillData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2203
    res = ProcessPath(&hnd, (jfloat)transX, (jfloat)transY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2204
                      coords, maxCoords, types, numTypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2205
    if (!res) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2206
        FD_FREE_POINTS(&fillData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2207
        return JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2208
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2209
    FillPolygon(&hnd, fillRule);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2210
    FD_FREE_POINTS(&fillData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2211
    return JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2212
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2213
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2214
jboolean doDrawPath(DrawHandler* dhnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2215
                    void (*pProcessEndSubPath)(ProcessHandler*),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2216
                    jint transX, jint transY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2217
                    jfloat* coords, jint maxCoords,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2218
                    jbyte* types, jint numTypes, PHStroke stroke)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2219
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2220
    ProcessHandler hnd =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2221
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2222
        &ProcessFixedLine,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2223
        NULL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2224
        NULL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2225
        PH_STROKE_DEFAULT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2226
        PH_MODE_DRAW_CLIP,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2227
        NULL
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2228
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2229
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2230
    /* Initialization of the following fields in the declaration of the hnd
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2231
     * above causes warnings on sun studio compiler with  -xc99=%none option
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2232
     * applied (this option means compliance with C90 standard instead of C99)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2233
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2234
    hnd.dhnd = dhnd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2235
    hnd.stroke = stroke;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2236
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2237
    hnd.pProcessEndSubPath = (pProcessEndSubPath == NULL)?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2238
        stubEndSubPath : pProcessEndSubPath;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2239
    return ProcessPath(&hnd, (jfloat)transX, (jfloat)transY, coords, maxCoords,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2240
                       types, numTypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2241
}