Apply default font to text with unicode characters

MacOS does not support fallback fonts, and any character not in our RS
fonts do not render correctly.

We only render unicode characters a handful of places, mostly for the
check mark/cross in overlays, and on the icon text field suggestion
button. So this sets the font of those places to the default system font
which can render them correctly.
This commit is contained in:
Adam
2021-01-30 13:14:33 -05:00
parent 243929826b
commit ca56ef1082
8 changed files with 83 additions and 43 deletions

View File

@@ -34,6 +34,7 @@ import static net.runelite.api.MenuAction.RUNELITE_OVERLAY_CONFIG;
import net.runelite.api.Varbits;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.ui.FontManager;
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
import net.runelite.client.ui.overlay.OverlayMenuEntry;
import net.runelite.client.ui.overlay.OverlayPanel;
@@ -82,6 +83,7 @@ public class BarrowsBrotherSlainOverlay extends OverlayPanel
panelComponent.getChildren().add(LineComponent.builder()
.left(brother.getName())
.right(slain)
.rightFont(FontManager.getDefaultFont())
.rightColor(brotherSlain ? Color.GREEN : Color.RED)
.build());
}

View File

@@ -45,6 +45,7 @@ import net.runelite.api.coords.LocalPoint;
import net.runelite.api.coords.WorldPoint;
import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR;
import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin;
import static net.runelite.client.plugins.cluescrolls.clues.Enemy.*;
import net.runelite.client.plugins.cluescrolls.clues.emote.Emote;
import static net.runelite.client.plugins.cluescrolls.clues.emote.Emote.*;
import static net.runelite.client.plugins.cluescrolls.clues.emote.Emote.BULL_ROARER;
@@ -53,7 +54,7 @@ import static net.runelite.client.plugins.cluescrolls.clues.emote.STASHUnit.*;
import static net.runelite.client.plugins.cluescrolls.clues.emote.STASHUnit.SHANTAY_PASS;
import net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirement;
import static net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirements.*;
import static net.runelite.client.plugins.cluescrolls.clues.Enemy.*;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.ui.overlay.components.LineComponent;
import net.runelite.client.ui.overlay.components.PanelComponent;
@@ -258,6 +259,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu
panelComponent.getChildren().add(LineComponent.builder()
.left("STASH Unit:")
.right(stashUnitBuilt ? UNICODE_CHECK_MARK : UNICODE_BALLOT_X)
.rightFont(FontManager.getDefaultFont())
.rightColor(stashUnitBuilt ? Color.GREEN : Color.RED)
.build());
}
@@ -292,6 +294,7 @@ public class EmoteClue extends ClueScroll implements TextClueScroll, LocationClu
.left(requirement.getCollectiveName(client))
.leftColor(TITLED_CONTENT_COLOR)
.right(combinedFulfilled ? UNICODE_CHECK_MARK : UNICODE_BALLOT_X)
.rightFont(FontManager.getDefaultFont())
.rightColor(equipmentFulfilled ? Color.GREEN : (combinedFulfilled ? Color.ORANGE : Color.RED))
.build());
}

View File

@@ -41,6 +41,7 @@ import net.runelite.client.plugins.cluescrolls.clues.item.AnyRequirementCollecti
import net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirement;
import net.runelite.client.plugins.cluescrolls.clues.item.RangeItemRequirement;
import net.runelite.client.plugins.cluescrolls.clues.item.SingleItemRequirement;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.ui.overlay.components.LineComponent;
import net.runelite.client.ui.overlay.components.PanelComponent;
@@ -134,6 +135,7 @@ public class FaloTheBardClue extends ClueScroll implements TextClueScroll, NpcCl
.left(requirement.getCollectiveName(plugin.getClient()))
.leftColor(TITLED_CONTENT_COLOR)
.right(inventoryFulfilled ? "\u2713" : "\u2717")
.rightFont(FontManager.getDefaultFont())
.rightColor(inventoryFulfilled ? Color.GREEN : Color.RED)
.build());
}

View File

@@ -25,6 +25,11 @@
package net.runelite.client.plugins.cluescrolls.clues;
import com.google.common.collect.ImmutableSet;
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@@ -34,25 +39,21 @@ import net.runelite.api.ItemID;
import net.runelite.api.NPC;
import net.runelite.api.Point;
import net.runelite.api.TileObject;
import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR;
import net.runelite.client.plugins.cluescrolls.ClueScrollPlugin;
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_BORDER_COLOR;
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_FILL_COLOR;
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.CLICKBOX_HOVER_BORDER_COLOR;
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET;
import net.runelite.client.plugins.cluescrolls.clues.item.AnyRequirementCollection;
import static net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirements.*;
import net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirement;
import static net.runelite.client.plugins.cluescrolls.clues.item.ItemRequirements.*;
import net.runelite.client.plugins.cluescrolls.clues.item.SingleItemRequirement;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.overlay.OverlayUtil;
import net.runelite.client.ui.overlay.components.LineComponent;
import net.runelite.client.ui.overlay.components.PanelComponent;
import net.runelite.client.ui.overlay.components.TitleComponent;
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static net.runelite.client.plugins.cluescrolls.ClueScrollOverlay.TITLED_CONTENT_COLOR;
import static net.runelite.client.plugins.cluescrolls.ClueScrollWorldOverlay.IMAGE_Z_OFFSET;
@Getter
public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, NamedObjectClueScroll
@@ -379,6 +380,7 @@ public class SkillChallengeClue extends ClueScroll implements NpcClueScroll, Nam
.left(requirement.getCollectiveName(plugin.getClient()))
.leftColor(TITLED_CONTENT_COLOR)
.right(combinedFulfilled ? "\u2713" : "\u2717")
.rightFont(FontManager.getDefaultFont())
.rightColor(equipmentFulfilled || (combinedFulfilled && !requireEquipped) ? Color.GREEN : (combinedFulfilled ? Color.ORANGE : Color.RED))
.build());
}

View File

@@ -24,17 +24,25 @@
*/
package net.runelite.client.ui;
import javax.swing.text.StyleContext;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.GraphicsEnvironment;
import java.io.IOException;
import javax.swing.text.StyleContext;
import lombok.Getter;
public class FontManager
{
@Getter
private static final Font runescapeFont;
@Getter
private static final Font runescapeSmallFont;
@Getter
private static final Font runescapeBoldFont;
@Getter
private static final Font defaultFont;
@Getter
private static final Font defaultBoldFont;
static
{
@@ -48,7 +56,7 @@ public class FontManager
ge.registerFont(font);
runescapeFont = StyleContext.getDefaultStyleContext()
.getFont(font.getName(), Font.PLAIN, 16);
.getFont(font.getName(), Font.PLAIN, 16);
ge.registerFont(runescapeFont);
Font smallFont = Font.createFont(Font.TRUETYPE_FONT,
@@ -57,16 +65,16 @@ public class FontManager
ge.registerFont(smallFont);
runescapeSmallFont = StyleContext.getDefaultStyleContext()
.getFont(smallFont.getName(), Font.PLAIN, 16);
.getFont(smallFont.getName(), Font.PLAIN, 16);
ge.registerFont(runescapeSmallFont);
Font boldFont = Font.createFont(Font.TRUETYPE_FONT,
FontManager.class.getResourceAsStream("runescape_bold.ttf"))
.deriveFont(Font.BOLD, 16);
FontManager.class.getResourceAsStream("runescape_bold.ttf"))
.deriveFont(Font.BOLD, 16);
ge.registerFont(boldFont);
runescapeBoldFont = StyleContext.getDefaultStyleContext()
.getFont(boldFont.getName(), Font.BOLD, 16);
.getFont(boldFont.getName(), Font.BOLD, 16);
ge.registerFont(runescapeBoldFont);
}
catch (FontFormatException ex)
@@ -77,20 +85,8 @@ public class FontManager
{
throw new RuntimeException("Font file not found.", ex);
}
}
public static Font getRunescapeFont()
{
return runescapeFont;
}
public static Font getRunescapeSmallFont()
{
return runescapeSmallFont;
}
public static Font getRunescapeBoldFont()
{
return runescapeBoldFont;
defaultFont = new Font(Font.DIALOG, Font.PLAIN, 16);
defaultBoldFont = new Font(Font.DIALOG, Font.BOLD, 16);
}
}

View File

@@ -29,6 +29,7 @@ package net.runelite.client.ui.components;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
@@ -125,7 +126,7 @@ public class IconTextField extends JPanel
textField.addMouseListener(hoverEffect);
innerTxt.addMouseListener(hoverEffect);
clearButton = createRHSButton(ColorScheme.PROGRESS_ERROR_COLOR, Color.PINK);
clearButton = createRHSButton(ColorScheme.PROGRESS_ERROR_COLOR, Color.PINK, FontManager.getRunescapeBoldFont());
clearButton.setText("×");
clearButton.addActionListener(evt ->
{
@@ -192,7 +193,7 @@ public class IconTextField extends JPanel
}
});
suggestionButton = createRHSButton(ColorScheme.LIGHT_GRAY_COLOR, ColorScheme.MEDIUM_GRAY_COLOR);
suggestionButton = createRHSButton(ColorScheme.LIGHT_GRAY_COLOR, ColorScheme.MEDIUM_GRAY_COLOR, FontManager.getDefaultBoldFont());
suggestionButton.setText("");
suggestionButton.addActionListener(e ->
{
@@ -237,11 +238,11 @@ public class IconTextField extends JPanel
add(rhsButtons, BorderLayout.EAST);
}
private JButton createRHSButton(Color fg, Color rollover)
private JButton createRHSButton(Color fg, Color rollover, Font font)
{
JButton b = new JButton();
b.setPreferredSize(new Dimension(30, 0));
b.setFont(FontManager.getRunescapeBoldFont());
b.setFont(font);
b.setBorder(null);
b.setRolloverEnabled(true);
SwingUtil.removeButtonDecorations(b);

View File

@@ -28,6 +28,7 @@ import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
@@ -50,6 +51,10 @@ public class LineComponent implements LayoutableRenderableEntity
@Builder.Default
private Color rightColor = Color.WHITE;
private Font leftFont;
private Font rightFont;
@Builder.Default
private Point preferredLocation = new Point();
@@ -67,13 +72,16 @@ public class LineComponent implements LayoutableRenderableEntity
final String left = MoreObjects.firstNonNull(this.left, "");
final String right = MoreObjects.firstNonNull(this.right, "");
final FontMetrics metrics = graphics.getFontMetrics();
final Font leftFont = MoreObjects.firstNonNull(this.leftFont, graphics.getFont());
final Font rightFont = MoreObjects.firstNonNull(this.rightFont, graphics.getFont());
final FontMetrics lfm = graphics.getFontMetrics(leftFont), rfm = graphics.getFontMetrics(rightFont);
final int fmHeight = Math.max(lfm.getHeight(), rfm.getHeight());
final int baseX = preferredLocation.x;
final int baseY = preferredLocation.y + metrics.getHeight();
final int baseY = preferredLocation.y + fmHeight;
int x = baseX;
int y = baseY;
final int leftFullWidth = getLineWidth(left, metrics);
final int rightFullWidth = getLineWidth(right, metrics);
final int leftFullWidth = getLineWidth(left, lfm);
final int rightFullWidth = getLineWidth(right, rfm);
final TextComponent textComponent = new TextComponent();
if (preferredSize.width < leftFullWidth + rightFullWidth)
@@ -87,8 +95,8 @@ public class LineComponent implements LayoutableRenderableEntity
leftSmallWidth -= rightSmallWidth;
}
final String[] leftSplitLines = lineBreakText(left, leftSmallWidth, metrics);
final String[] rightSplitLines = lineBreakText(right, rightSmallWidth, metrics);
final String[] leftSplitLines = lineBreakText(left, leftSmallWidth, lfm);
final String[] rightSplitLines = lineBreakText(right, rightSmallWidth, rfm);
int lineCount = Math.max(leftSplitLines.length, rightSplitLines.length);
@@ -100,19 +108,21 @@ public class LineComponent implements LayoutableRenderableEntity
textComponent.setPosition(new Point(x, y));
textComponent.setText(leftText);
textComponent.setColor(leftColor);
textComponent.setFont(leftFont);
textComponent.render(graphics);
}
if (i < rightSplitLines.length)
{
final String rightText = rightSplitLines[i];
textComponent.setPosition(new Point(x + preferredSize.width - getLineWidth(rightText, metrics), y));
textComponent.setPosition(new Point(x + preferredSize.width - getLineWidth(rightText, rfm), y));
textComponent.setText(rightText);
textComponent.setColor(rightColor);
textComponent.setFont(rightFont);
textComponent.render(graphics);
}
y += metrics.getHeight();
y += fmHeight;
}
final Dimension dimension = new Dimension(preferredSize.width, y - baseY);
@@ -126,6 +136,7 @@ public class LineComponent implements LayoutableRenderableEntity
textComponent.setPosition(new Point(x, y));
textComponent.setText(left);
textComponent.setColor(leftColor);
textComponent.setFont(leftFont);
textComponent.render(graphics);
}
@@ -134,10 +145,11 @@ public class LineComponent implements LayoutableRenderableEntity
textComponent.setPosition(new Point(x + preferredSize.width - rightFullWidth, y));
textComponent.setText(right);
textComponent.setColor(rightColor);
textComponent.setFont(rightFont);
textComponent.render(graphics);
}
y += metrics.getHeight();
y += fmHeight;
final Dimension dimension = new Dimension(preferredSize.width, y - baseY);
bounds.setLocation(preferredLocation);

View File

@@ -26,10 +26,12 @@ package net.runelite.client.ui.overlay.components;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import lombok.Setter;
import net.runelite.client.ui.overlay.RenderableEntity;
import net.runelite.client.util.ColorUtil;
@@ -45,10 +47,22 @@ public class TextComponent implements RenderableEntity
private Point position = new Point();
private Color color = Color.WHITE;
private boolean outline;
/**
* The text font.
*/
@Nullable
private Font font;
@Override
public Dimension render(Graphics2D graphics)
{
Font originalFont = null;
if (font != null)
{
originalFont = graphics.getFont();
graphics.setFont(font);
}
final FontMetrics fontMetrics = graphics.getFontMetrics();
if (COL_TAG_PATTERN_W_LOOKAHEAD.matcher(text).find())
@@ -105,6 +119,14 @@ public class TextComponent implements RenderableEntity
graphics.drawString(text, position.x, position.y);
}
return new Dimension(fontMetrics.stringWidth(text), fontMetrics.getHeight());
int width = fontMetrics.stringWidth(text);
int height = fontMetrics.getHeight();
if (originalFont != null)
{
graphics.setFont(originalFont);
}
return new Dimension(width, height);
}
}