1 /*
2  * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package sun.java2d.marlin;
26 
27 final class DPathSimplifier implements DPathConsumer2D {
28 
29     // distance threshold in pixels (device)
30     private static final double PIX_THRESHOLD = MarlinProperties.getPathSimplifierPixelTolerance();
31 
32     private static final double SQUARE_TOLERANCE = PIX_THRESHOLD * PIX_THRESHOLD;
33 
34     // members:
35     private DPathConsumer2D delegate;
36     private double cx, cy;
37 
DPathSimplifier()38     DPathSimplifier() {
39     }
40 
init(final DPathConsumer2D delegate)41     DPathSimplifier init(final DPathConsumer2D delegate) {
42         this.delegate = delegate;
43         return this; // fluent API
44     }
45 
46     @Override
pathDone()47     public void pathDone() {
48         delegate.pathDone();
49     }
50 
51     @Override
closePath()52     public void closePath() {
53         delegate.closePath();
54     }
55 
56     @Override
getNativeConsumer()57     public long getNativeConsumer() {
58         return 0;
59     }
60 
61     @Override
quadTo(final double x1, final double y1, final double xe, final double ye)62     public void quadTo(final double x1, final double y1,
63                        final double xe, final double ye)
64     {
65         // Test if curve is too small:
66         double dx = (xe - cx);
67         double dy = (ye - cy);
68 
69         if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) {
70             // check control points P1:
71             dx = (x1 - cx);
72             dy = (y1 - cy);
73 
74             if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) {
75                 return;
76             }
77         }
78         delegate.quadTo(x1, y1, xe, ye);
79         // final end point:
80         cx = xe;
81         cy = ye;
82     }
83 
84     @Override
curveTo(final double x1, final double y1, final double x2, final double y2, final double xe, final double ye)85     public void curveTo(final double x1, final double y1,
86                         final double x2, final double y2,
87                         final double xe, final double ye)
88     {
89         // Test if curve is too small:
90         double dx = (xe - cx);
91         double dy = (ye - cy);
92 
93         if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) {
94             // check control points P1:
95             dx = (x1 - cx);
96             dy = (y1 - cy);
97 
98             if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) {
99                 // check control points P2:
100                 dx = (x2 - cx);
101                 dy = (y2 - cy);
102 
103                 if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) {
104                     return;
105                 }
106             }
107         }
108         delegate.curveTo(x1, y1, x2, y2, xe, ye);
109         // final end point:
110         cx = xe;
111         cy = ye;
112     }
113 
114     @Override
moveTo(final double xe, final double ye)115     public void moveTo(final double xe, final double ye) {
116         delegate.moveTo(xe, ye);
117         // starting point:
118         cx = xe;
119         cy = ye;
120     }
121 
122     @Override
lineTo(final double xe, final double ye)123     public void lineTo(final double xe, final double ye) {
124         // Test if segment is too small:
125         double dx = (xe - cx);
126         double dy = (ye - cy);
127 
128         if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) {
129             return;
130         }
131         delegate.lineTo(xe, ye);
132         // final end point:
133         cx = xe;
134         cy = ye;
135     }
136 }
137