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