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