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 40 PathSimplifier() { 41 } 42 43 PathSimplifier init(final PathConsumer2D delegate) { 44 this.delegate = delegate; 45 return this; // fluent API 46 } 47 48 @Override 49 public void pathDone() { 50 delegate.pathDone(); 51 } 52 53 @Override 54 public void closePath() { 55 delegate.closePath(); 56 } 57 58 @Override 59 public long getNativeConsumer() { 60 return 0; 61 } 62 63 @Override 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 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 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 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 }