gdx-studio
git clone https://git.pyrossh.dev/gdx-studio
An IDE for creating Games using libgdx and Java supported on all platforms Android, iOS, Desktop
src_libs/com/badlogic/gdx/tools/hiero/unicodefont/effects/OutlineWobbleEffect.java
| a62d533 | 1 | /* |
| a62d533 | 2 | * Copyright 2006 Jerry Huxtable |
| a62d533 | 3 | * |
| a62d533 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the |
| a62d533 | 5 | * License. You may obtain a copy of the License at |
| a62d533 | 6 | * |
| a62d533 | 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
| a62d533 | 8 | * |
| a62d533 | 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" |
| a62d533 | 10 | * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language |
| a62d533 | 11 | * governing permissions and limitations under the License. |
| a62d533 | 12 | */ |
| a62d533 | 13 | |
| a62d533 | 14 | package com.badlogic.gdx.tools.hiero.unicodefont.effects; |
| a62d533 | 15 | |
| a62d533 | 16 | import java.awt.BasicStroke; |
| a62d533 | 17 | import java.awt.Color; |
| a62d533 | 18 | import java.awt.Shape; |
| a62d533 | 19 | import java.awt.Stroke; |
| a62d533 | 20 | import java.awt.geom.FlatteningPathIterator; |
| a62d533 | 21 | import java.awt.geom.GeneralPath; |
| a62d533 | 22 | import java.awt.geom.PathIterator; |
| a62d533 | 23 | import java.util.Iterator; |
| a62d533 | 24 | import java.util.List; |
| a62d533 | 25 | |
| a62d533 | 26 | /** @author Jerry Huxtable |
| a62d533 | 27 | * @author Nathan Sweet */ |
| a62d533 | 28 | public class OutlineWobbleEffect extends OutlineEffect {
|
| a62d533 | 29 | float detail = 1; |
| a62d533 | 30 | float amplitude = 1; |
| a62d533 | 31 | |
| a62d533 | 32 | public OutlineWobbleEffect () {
|
| a62d533 | 33 | setStroke(new WobbleStroke()); |
| a62d533 | 34 | } |
| a62d533 | 35 | |
| a62d533 | 36 | public OutlineWobbleEffect (int width, Color color) {
|
| a62d533 | 37 | super(width, color); |
| a62d533 | 38 | } |
| a62d533 | 39 | |
| a62d533 | 40 | public String toString () {
|
| a62d533 | 41 | return "Outline (Wobble)"; |
| a62d533 | 42 | } |
| a62d533 | 43 | |
| a62d533 | 44 | public List getValues () {
|
| a62d533 | 45 | List values = super.getValues(); |
| a62d533 | 46 | values.remove(2); // Remove "Join". |
| a62d533 | 47 | values.add(EffectUtil.floatValue("Detail", detail, 1, 50, "This setting controls how detailed the outline will be. "
|
| a62d533 | 48 | + "Smaller numbers cause the outline to have more detail.")); |
| a62d533 | 49 | values.add(EffectUtil.floatValue("Amplitude", amplitude, 0.5f, 50, "This setting controls the amplitude of the outline."));
|
| a62d533 | 50 | return values; |
| a62d533 | 51 | } |
| a62d533 | 52 | |
| a62d533 | 53 | public void setValues (List values) {
|
| a62d533 | 54 | super.setValues(values); |
| a62d533 | 55 | for (Iterator iter = values.iterator(); iter.hasNext();) {
|
| a62d533 | 56 | Value value = (Value)iter.next(); |
| a62d533 | 57 | if (value.getName().equals("Detail")) {
|
| a62d533 | 58 | detail = ((Float)value.getObject()).floatValue(); |
| a62d533 | 59 | } else if (value.getName().equals("Amplitude")) {
|
| a62d533 | 60 | amplitude = ((Float)value.getObject()).floatValue(); |
| a62d533 | 61 | } |
| a62d533 | 62 | } |
| a62d533 | 63 | } |
| a62d533 | 64 | |
| a62d533 | 65 | class WobbleStroke implements Stroke {
|
| a62d533 | 66 | private static final float FLATNESS = 1; |
| a62d533 | 67 | |
| a62d533 | 68 | public Shape createStrokedShape (Shape shape) {
|
| a62d533 | 69 | GeneralPath result = new GeneralPath(); |
| a62d533 | 70 | shape = new BasicStroke(getWidth(), BasicStroke.CAP_SQUARE, getJoin()).createStrokedShape(shape); |
| a62d533 | 71 | PathIterator it = new FlatteningPathIterator(shape.getPathIterator(null), FLATNESS); |
| a62d533 | 72 | float points[] = new float[6]; |
| a62d533 | 73 | float moveX = 0, moveY = 0; |
| a62d533 | 74 | float lastX = 0, lastY = 0; |
| a62d533 | 75 | float thisX = 0, thisY = 0; |
| a62d533 | 76 | int type = 0; |
| a62d533 | 77 | float next = 0; |
| a62d533 | 78 | while (!it.isDone()) {
|
| a62d533 | 79 | type = it.currentSegment(points); |
| a62d533 | 80 | switch (type) {
|
| a62d533 | 81 | case PathIterator.SEG_MOVETO: |
| a62d533 | 82 | moveX = lastX = randomize(points[0]); |
| a62d533 | 83 | moveY = lastY = randomize(points[1]); |
| a62d533 | 84 | result.moveTo(moveX, moveY); |
| a62d533 | 85 | next = 0; |
| a62d533 | 86 | break; |
| a62d533 | 87 | |
| a62d533 | 88 | case PathIterator.SEG_CLOSE: |
| a62d533 | 89 | points[0] = moveX; |
| a62d533 | 90 | points[1] = moveY; |
| a62d533 | 91 | // Fall into.... |
| a62d533 | 92 | |
| a62d533 | 93 | case PathIterator.SEG_LINETO: |
| a62d533 | 94 | thisX = randomize(points[0]); |
| a62d533 | 95 | thisY = randomize(points[1]); |
| a62d533 | 96 | float dx = thisX - lastX; |
| a62d533 | 97 | float dy = thisY - lastY; |
| a62d533 | 98 | float distance = (float)Math.sqrt(dx * dx + dy * dy); |
| a62d533 | 99 | if (distance >= next) {
|
| a62d533 | 100 | float r = 1.0f / distance; |
| a62d533 | 101 | while (distance >= next) {
|
| a62d533 | 102 | float x = lastX + next * dx * r; |
| a62d533 | 103 | float y = lastY + next * dy * r; |
| a62d533 | 104 | result.lineTo(randomize(x), randomize(y)); |
| a62d533 | 105 | next += detail; |
| a62d533 | 106 | } |
| a62d533 | 107 | } |
| a62d533 | 108 | next -= distance; |
| a62d533 | 109 | lastX = thisX; |
| a62d533 | 110 | lastY = thisY; |
| a62d533 | 111 | break; |
| a62d533 | 112 | } |
| a62d533 | 113 | it.next(); |
| a62d533 | 114 | } |
| a62d533 | 115 | |
| a62d533 | 116 | return result; |
| a62d533 | 117 | } |
| a62d533 | 118 | |
| a62d533 | 119 | private float randomize (float x) {
|
| a62d533 | 120 | return x + (float)Math.random() * amplitude * 2 - 1; |
| a62d533 | 121 | } |
| a62d533 | 122 | } |
| a62d533 | 123 | } |