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 26 package com.sun.marlin; 27 28 public final class DPathSimplifier implements DPathConsumer2D { 29 30 // distance threshold in pixels (device) 31 private static final double PIX_THRESHOLD = MarlinProperties.getPathSimplifierPixelTolerance(); 32 // squared tolerance in pixels 33 private static final double SQUARE_TOLERANCE = PIX_THRESHOLD * PIX_THRESHOLD; 34 35 // members: 36 private DPathConsumer2D delegate; 37 // current reference point 38 private double cx, cy; 39 // flag indicating if the given point was skipped 40 private boolean skipped; 41 // last skipped point 42 private double sx, sy; 43 44 DPathSimplifier() { 45 } 46 47 public DPathSimplifier init(final DPathConsumer2D delegate) { 48 this.delegate = delegate; 49 skipped = false; 50 return this; // fluent API 51 } 52 53 private void finishPath() { 54 if (skipped) { 55 _lineTo(sx, sy); 56 } 57 } 58 59 @Override 60 public void pathDone() { 61 finishPath(); 62 delegate.pathDone(); 63 } 64 65 @Override 66 public void closePath() { 67 finishPath(); 68 delegate.closePath(); 69 } 70 71 @Override 72 public void moveTo(final double xe, final double ye) { 73 finishPath(); 74 delegate.moveTo(xe, ye); 75 cx = xe; 76 cy = ye; 77 } 78 79 @Override 80 public void lineTo(final double xe, final double ye) { 81 // Test if segment is too small: 82 double dx = (xe - cx); 83 double dy = (ye - cy); 84 85 if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) { 86 skipped = true; 87 sx = xe; 88 sy = ye; 89 return; 90 } 91 _lineTo(xe, ye); 92 } 93 94 private void _lineTo(final double xe, final double ye) { 95 delegate.lineTo(xe, ye); 96 cx = xe; 97 cy = ye; 98 skipped = false; 99 } 100 101 @Override 102 public void quadTo(final double x1, final double y1, 103 final double xe, final double ye) 104 { 105 // Test if curve is too small: 106 double dx = (xe - cx); 107 double dy = (ye - cy); 108 109 if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) { 110 // check control points P1: 111 dx = (x1 - cx); 112 dy = (y1 - cy); 113 114 if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) { 115 skipped = true; 116 sx = xe; 117 sy = ye; 118 return; 119 } 120 } 121 delegate.quadTo(x1, y1, xe, ye); 122 cx = xe; 123 cy = ye; 124 skipped = false; 125 } 126 127 @Override 128 public void curveTo(final double x1, final double y1, 129 final double x2, final double y2, 130 final double xe, final double ye) 131 { 132 // Test if curve is too small: 133 double dx = (xe - cx); 134 double dy = (ye - cy); 135 136 if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) { 137 // check control points P1: 138 dx = (x1 - cx); 139 dy = (y1 - cy); 140 141 if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) { 142 // check control points P2: 143 dx = (x2 - cx); 144 dy = (y2 - cy); 145 146 if ((dx * dx + dy * dy) <= SQUARE_TOLERANCE) { 147 skipped = true; 148 sx = xe; 149 sy = ye; 150 return; 151 } 152 } 153 } 154 delegate.curveTo(x1, y1, x2, y2, xe, ye); 155 cx = xe; 156 cy = ye; 157 skipped = false; 158 } 159 }