Added transparent text support

Added border color
This commit is contained in:
James Munson
2019-07-01 15:46:43 -07:00
5 changed files with 77 additions and 45 deletions

View File

@@ -26,6 +26,7 @@
package net.runelite.client.plugins.grounditems;
import java.awt.Color;
import net.runelite.client.config.Alpha;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@@ -57,6 +58,7 @@ public interface GroundItemsConfig extends Config
position = 2,
parent = "colorsStub"
)
@Alpha
default Color defaultColor()
{
return Color.WHITE;
@@ -69,6 +71,7 @@ public interface GroundItemsConfig extends Config
position = 3,
parent = "colorsStub"
)
@Alpha
default Color highlightedColor()
{
return Color.decode("#AA00FF");
@@ -81,6 +84,7 @@ public interface GroundItemsConfig extends Config
position = 4,
parent = "colorsStub"
)
@Alpha
default Color hiddenColor()
{
return Color.GRAY;
@@ -319,6 +323,7 @@ public interface GroundItemsConfig extends Config
position = 23,
parent = "lowValueStub"
)
@Alpha
default Color lowValueColor()
{
return Color.decode("#66B2FF");
@@ -366,6 +371,7 @@ public interface GroundItemsConfig extends Config
position = 27,
parent = "mediumValueStub"
)
@Alpha
default Color mediumValueColor()
{
return Color.decode("#99FF99");
@@ -413,6 +419,7 @@ public interface GroundItemsConfig extends Config
position = 31,
parent = "highValueStub"
)
@Alpha
default Color highValueColor()
{
return Color.decode("#FF9600");
@@ -460,6 +467,7 @@ public interface GroundItemsConfig extends Config
position = 35,
parent = "insaneValueStub"
)
@Alpha
default Color insaneValueColor()
{
return Color.decode("#FF66B2");
@@ -618,4 +626,16 @@ public interface GroundItemsConfig extends Config
{
return false;
}
@Alpha
@ConfigItem(
keyName = "bordercolor",
name = "Border color",
description = "Change the border color",
position = 49
)
default Color bordercolor()
{
return new Color(0, 0, 0, 150);
}
}

View File

@@ -109,8 +109,6 @@ public class GroundItemsOverlay extends Overlay
{
return null;
}
final FontMetrics fm = graphics.getFontMetrics();
final Player player = client.getLocalPlayer();
if (player == null || client.getViewportWidget() == null)
@@ -118,6 +116,8 @@ public class GroundItemsOverlay extends Overlay
return null;
}
final FontMetrics fm = graphics.getFontMetrics();
offsetMap.clear();
final LocalPoint localLocation = player.getLocalLocation();
final Point mousePos = client.getMouseCanvasPosition();
@@ -376,7 +376,8 @@ public class GroundItemsOverlay extends Overlay
if (config.toggleOutline())
{
graphics.setColor(Color.BLACK);
final Color bordercolor = config.bordercolor();
graphics.setColor(bordercolor);
graphics.drawString(itemString, textX + 1, textY + 1);
graphics.drawString(itemString, textX - 1, textY - 1);
graphics.drawString(itemString, textX - 1, textY + 1);
@@ -388,7 +389,6 @@ public class GroundItemsOverlay extends Overlay
textComponent.setPosition(new java.awt.Point(textX, textY));
textComponent.render(graphics);
}
return null;
}

View File

@@ -124,6 +124,7 @@ public class GroundItemsPlugin extends Plugin
private static final int EXAMINE_ITEM = MenuAction.EXAMINE_ITEM_GROUND.getId();
private static final int WALK = MenuAction.WALK.getId();
@Getter(AccessLevel.PACKAGE)
@Setter(AccessLevel.PACKAGE)
private Map.Entry<Rectangle, GroundItem> textBoxBounds;

View File

@@ -24,11 +24,15 @@
*/
package net.runelite.client.ui.overlay.components;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.font.GlyphVector;
import java.util.regex.Pattern;
import lombok.Setter;
import net.runelite.client.ui.overlay.RenderableEntity;
@@ -43,6 +47,7 @@ public class TextComponent implements RenderableEntity
private String text;
private Point position = new Point();
private Color color = Color.WHITE;
private Color borderColor = Color.BLACK;
public static String textWithoutColTags(String text)
{
@@ -64,28 +69,43 @@ public class TextComponent implements RenderableEntity
final String textWithoutCol = textWithoutColTags(textSplitOnCol);
final String colColor = textSplitOnCol.substring(textSplitOnCol.indexOf("=") + 1, textSplitOnCol.indexOf(">"));
// shadow
graphics.setColor(Color.BLACK);
graphics.drawString(textWithoutCol, x + 1, position.y + 1);
// actual text
graphics.setColor(Color.decode("#" + colColor));
graphics.drawString(textWithoutCol, x, position.y);
renderText(graphics, x, position.y, textWithoutCol, Color.decode("#" + colColor), borderColor);
x += fontMetrics.stringWidth(textWithoutCol);
}
}
else
{
// shadow
graphics.setColor(Color.BLACK);
graphics.drawString(text, position.x + 1, position.y + 1);
// actual text
graphics.setColor(color);
graphics.drawString(text, position.x, position.y);
renderText(graphics, position.x, position.y, text, color, borderColor);
}
return new Dimension(fontMetrics.stringWidth(text), fontMetrics.getHeight());
}
private void renderText(Graphics2D graphics, int x, int y, String text, Color color, Color border)
{
// remember previous composite
Composite originalComposite = graphics.getComposite();
// create a vector of the text
GlyphVector vector = graphics.getFont().createGlyphVector(graphics.getFontRenderContext(), text);
// compute the text shape
Shape stroke = vector.getOutline(x + 1, y + 1);
Shape shape = vector.getOutline(x, y);
// draw text border
graphics.setColor(border);
graphics.fill(stroke);
// replace the pixels instead of overlaying
graphics.setComposite(AlphaComposite.Src);
// draw actual text
graphics.setColor(color);
graphics.fill(shape);
// reset composite to original
graphics.setComposite(originalComposite);
}
}

View File

@@ -25,33 +25,24 @@
package net.runelite.client.ui.overlay.components;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import org.mockito.Mock;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class TextComponentTest
{
@Mock
private Graphics2D graphics;
private BufferedImage dest;
@Before
public void before()
{
when(graphics.getFontMetrics()).thenReturn(mock(FontMetrics.class));
dest = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
graphics = (Graphics2D) dest.getGraphics();
}
@Test
public void testRender()
{
@@ -59,29 +50,29 @@ public class TextComponentTest
textComponent.setText("test");
textComponent.setColor(Color.RED);
textComponent.render(graphics);
verify(graphics, times(2)).drawString(eq("test"), anyInt(), anyInt());
verify(graphics, atLeastOnce()).setColor(Color.RED);
}
@Test
public void testRender2()
{
TextComponent textComponent = new TextComponent();
textComponent.setText("<col=0000ff>test");
textComponent.render(graphics);
verify(graphics, times(2)).drawString(eq("test"), anyInt(), anyInt());
verify(graphics, atLeastOnce()).setColor(Color.BLUE);
}
@Test
public void testRender3()
{
TextComponent textComponent = new TextComponent();
textComponent.setText("<col=0000ff>test<col=00ff00> test");
textComponent.render(graphics);
verify(graphics, atLeastOnce()).drawString(eq("test"), anyInt(), anyInt());
verify(graphics, atLeastOnce()).drawString(eq(" test"), anyInt(), anyInt());
verify(graphics, atLeastOnce()).setColor(Color.BLUE);
verify(graphics, atLeastOnce()).setColor(Color.GREEN);
}
@After
public void after()
{
graphics.dispose();
dest.flush();
}
}