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 import sun.awt.geom.PathConsumer2D;
28 
29 final class PathSimplifier implements PathConsumer2D {
30 
31     // distance threshold in pixels (device)
32     private static final float PIX_THRESHOLD = MarlinProperties.getPathSimplifierPixelTolerance();
33 
34     private static final float SQUARE_TOLERANCE = PIX_THRESHOLD * PIX_THRESHOLD;
35 
36     // members:
37     private PathConsumer2D delegate;
38     private float cx, cy;
39 
PathSimplifier()40     PathSimplifier() {
41     }
42 
init(final PathConsumer2D delegate)43     PathSimplifier init(final PathConsumer2D delegate) {
44         this.delegate = delegate;
45         return this; // fluent API
46     }
47 
48     @Override
pathDone()49     public void pathDone() {
50         delegate.pathDone();
51     }
52 
53     @Override
closePath()54     public void closePath() {
55         delegate.closePath();
56     }
57 
58     @Override
getNativeConsumer()59     public long getNativeConsumer() {
60         return 0;
61     }
62 
63     @Override
quadTo(final float x1, final float y1, final float xe, final float ye)64     public void quadTo(final float x1, final float y1,
65                        final float xe, final float ye)
66     {
67         // Test if curve is too small:
68         float dx = (xe - cx);
69         float dy = (ye - cy);
70 
71         if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) {
72             // check control points P1:
73             dx = (x1 - cx);
74             dy = (y1 - cy);
75 
76             if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) {
77                 return;
78             }
79         }
80         delegate.quadTo(x1, y1, xe, ye);
81         // final end point:
82         cx = xe;
83         cy = ye;
84     }
85 
86     @Override
curveTo(final float x1, final float y1, final float x2, final float y2, final float xe, final float ye)87     public void curveTo(final float x1, final float y1,
88                         final float x2, final float y2,
89                         final float xe, final float ye)
90     {
91         // Test if curve is too small:
92         float dx = (xe - cx);
93         float dy = (ye - cy);
94 
95         if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) {
96             // check control points P1:
97             dx = (x1 - cx);
98             dy = (y1 - cy);
99 
100             if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) {
101                 // check control points P2:
102                 dx = (x2 - cx);
103                 dy = (y2 - cy);
104 
105                 if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) {
106                     return;
107                 }
108             }
109         }
110         delegate.curveTo(x1, y1, x2, y2, xe, ye);
111         // final end point:
112         cx = xe;
113         cy = ye;
114     }
115 
116     @Override
moveTo(final float xe, final float ye)117     public void moveTo(final float xe, final float ye) {
118         delegate.moveTo(xe, ye);
119         // starting point:
120         cx = xe;
121         cy = ye;
122     }
123 
124     @Override
lineTo(final float xe, final float ye)125     public void lineTo(final float xe, final float ye) {
126         // Test if segment is too small:
127         float dx = (xe - cx);
128         float dy = (ye - cy);
129 
130         if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) {
131             return;
132         }
133         delegate.lineTo(xe, ye);
134         // final end point:
135         cx = xe;
136         cy = ye;
137     }
138 }
139