Worked around a Java issue with rendering fonts with AffineTransforms
This commit is contained in:
@@ -38,7 +38,7 @@ public class ImageGenerator {
|
||||
final JSONObject cardsObject = (JSONObject) parser.parse(reader);
|
||||
for (Map.Entry<String, JSONObject> cardEntry : (Set<Map.Entry<String, JSONObject>>) cardsObject.entrySet()) {
|
||||
final String cardId = cardEntry.getKey();
|
||||
if (cardId.equals("40_3") || cardId.equals("40_17") || cardId.equals("40_19")) {
|
||||
// if (cardId.equals("40_3") || cardId.equals("40_17") || cardId.equals("40_19")) {
|
||||
BufferedImage bufferedImage = new BufferedImage(jsonImageRecipe.getWidth(), jsonImageRecipe.getHeight(), BufferedImage.TYPE_INT_RGB);
|
||||
jsonImageRecipe.renderImage(properties, cardEntry.getValue(), bufferedImage);
|
||||
|
||||
@@ -52,7 +52,7 @@ public class ImageGenerator {
|
||||
writer.setOutput(outputStream);
|
||||
writer.write(null, new IIOImage(bufferedImage, null, null), jpegParams);
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
} catch (IOException | ParseException e) {
|
||||
throw new ImageGenerationException("Unable to generate image", e);
|
||||
|
||||
@@ -27,7 +27,6 @@ public class JSONImageRecipe implements ImageRecipe {
|
||||
private int height;
|
||||
private List<LayerRecipe> layers = new LinkedList<>();
|
||||
private Map<Path, Image> imageCache = new HashMap<>();
|
||||
private Map<FontDefinition, Font> fontCache = new HashMap<>();
|
||||
private Map<String, Function<RenderContext, ?>> functionMap;
|
||||
|
||||
public JSONImageRecipe(File file) {
|
||||
@@ -93,14 +92,25 @@ public class JSONImageRecipe implements ImageRecipe {
|
||||
map.put(fontEntry.getKey(), createFontProvider(fontEntry.getValue()));
|
||||
}
|
||||
Map<String, String> glyphMap = (JSONObject) jsonLayer.get("glyphs");
|
||||
Function<RenderContext, Paint> paint = createPaintProvider(jsonLayer.get("paint"), "black");
|
||||
|
||||
Function<String, Function<RenderContext, Font>> fontStyleProvider = map::get;
|
||||
Function<RenderContext, TextBox> textBox = createTextBoxProvider(jsonLayer.get("box"));
|
||||
final Function<RenderContext, Float> minYStart = createFloatProvider(jsonLayer.get("minYStart"));
|
||||
Map<String, Number> yShiftsMap = (JSONObject) jsonLayer.get("yShifts");
|
||||
|
||||
return new TextBoxLayerRecipe(
|
||||
fontStyleProvider,
|
||||
s -> glyphMap.get(s),
|
||||
s -> glyphMap.get(s), paint,
|
||||
s -> {
|
||||
if (yShiftsMap == null)
|
||||
return 0f;
|
||||
final Number value = yShiftsMap.get(s);
|
||||
if (value == null)
|
||||
return 0f;
|
||||
else
|
||||
return value.floatValue();
|
||||
},
|
||||
text, textBox, minYStart);
|
||||
} else if (type.equalsIgnoreCase("rotate")) {
|
||||
final LayerRecipe layer = createLayerRecipe((JSONObject) jsonLayer.get("layer"));
|
||||
@@ -256,16 +266,11 @@ public class JSONImageRecipe implements ImageRecipe {
|
||||
final Path path = pathProvider.apply(renderContext);
|
||||
final float size = sizeProvider.apply(renderContext);
|
||||
final int style = styleProvider.apply(renderContext);
|
||||
|
||||
FontDefinition fontDefinition = new FontDefinition(size, style, path);
|
||||
return fontCache.computeIfAbsent(fontDefinition,
|
||||
fontDefinition1 -> {
|
||||
try {
|
||||
return Font.createFont(Font.TRUETYPE_FONT, path.toFile()).deriveFont(style, size);
|
||||
} catch (FontFormatException | IOException e) {
|
||||
throw new ImageGenerationException("Unable to get font", e);
|
||||
}
|
||||
});
|
||||
try {
|
||||
return Font.createFont(Font.TRUETYPE_FONT, path.toFile()).deriveFont(style, size);
|
||||
} catch (FontFormatException | IOException e) {
|
||||
throw new ImageGenerationException("Unable to get font", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -468,6 +473,12 @@ public class JSONImageRecipe implements ImageRecipe {
|
||||
}
|
||||
|
||||
private Function<RenderContext, Float> createFloatProvider(Object value) {
|
||||
return createFloatProvider(value, null);
|
||||
}
|
||||
|
||||
private Function<RenderContext, Float> createFloatProvider(Object value, Float defaultValue) {
|
||||
if (value == null && defaultValue != null)
|
||||
return renderContext -> defaultValue;
|
||||
if (value instanceof Number) {
|
||||
return renderContext -> ((Number) value).floatValue();
|
||||
} else if (value instanceof JSONObject) {
|
||||
@@ -539,31 +550,4 @@ public class JSONImageRecipe implements ImageRecipe {
|
||||
graphics.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private class FontDefinition {
|
||||
private float size;
|
||||
private int style;
|
||||
private Path fontPath;
|
||||
|
||||
public FontDefinition(float size, int style, Path fontPath) {
|
||||
this.size = size;
|
||||
this.style = style;
|
||||
this.fontPath = fontPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
FontDefinition that = (FontDefinition) o;
|
||||
return Float.compare(that.size, size) == 0 &&
|
||||
style == that.style &&
|
||||
fontPath.equals(that.fontPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(size, style, fontPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import java.util.function.Function;
|
||||
public class TextBoxLayerRecipe implements LayerRecipe {
|
||||
private Function<String, Function<RenderContext, Font>> fontStyleProvider;
|
||||
private Function<String, String> glyphProvider;
|
||||
private Function<RenderContext, Paint> paint;
|
||||
private Function<String, Float> yShifts;
|
||||
private Function<RenderContext, String[]> text;
|
||||
private Function<RenderContext, TextBox> textBox;
|
||||
private Function<RenderContext, Float> minYStart;
|
||||
@@ -21,11 +23,15 @@ public class TextBoxLayerRecipe implements LayerRecipe {
|
||||
public TextBoxLayerRecipe(
|
||||
Function<String, Function<RenderContext, Font>> fontStyleProvider,
|
||||
Function<String, String> glyphProvider,
|
||||
Function<RenderContext, Paint> paint,
|
||||
Function<String, Float> yShifts,
|
||||
Function<RenderContext, String[]> text,
|
||||
Function<RenderContext, TextBox> textBox,
|
||||
Function<RenderContext, Float> minYStart) {
|
||||
this.fontStyleProvider = fontStyleProvider;
|
||||
this.glyphProvider = glyphProvider;
|
||||
this.paint = paint;
|
||||
this.yShifts = yShifts;
|
||||
this.text = text;
|
||||
this.textBox = textBox;
|
||||
this.minYStart = minYStart;
|
||||
@@ -46,6 +52,8 @@ public class TextBoxLayerRecipe implements LayerRecipe {
|
||||
// graphics.fillRect(box.getX(), box.getY(), box.getWidth(), box.getHeight());
|
||||
// graphics.setColor(Color.BLACK);
|
||||
|
||||
graphics.setPaint(paint.apply(renderContext));
|
||||
|
||||
FontRenderContext frc = graphics.getFontRenderContext();
|
||||
|
||||
// Dry run to check for height
|
||||
@@ -96,21 +104,19 @@ public class TextBoxLayerRecipe implements LayerRecipe {
|
||||
AttributedString string = new AttributedString(resultText.toString());
|
||||
parseText(text, new TextParsingCallback() {
|
||||
private int index = 0;
|
||||
private boolean lowered = false;
|
||||
private float yShift = 0;
|
||||
|
||||
@Override
|
||||
public void appendText(String text, String style) {
|
||||
String resultStyle = (style != null) ? style : "default";
|
||||
Font font = fontStyleProvider.apply(resultStyle).apply(renderContext);
|
||||
if (resultStyle.equals("glyph") && !lowered) {
|
||||
font = font.deriveFont(AffineTransform.getTranslateInstance(0, 3));
|
||||
lowered = true;
|
||||
} else if (!resultStyle.equals("glyph") && lowered) {
|
||||
font = font.deriveFont(AffineTransform.getTranslateInstance(0, -3));
|
||||
lowered = false;
|
||||
final float value = yShifts.apply(resultStyle);
|
||||
float result = value - yShift;
|
||||
if (result != 0) {
|
||||
font = font.deriveFont(AffineTransform.getTranslateInstance(0, result));
|
||||
yShift = value;
|
||||
}
|
||||
string.addAttribute(TextAttribute.FONT, font, index, index + text.length());
|
||||
string.addAttribute(TextAttribute.FOREGROUND, Color.BLACK, index, index + text.length());
|
||||
index += text.length();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -690,30 +690,11 @@
|
||||
},
|
||||
{
|
||||
"comment": "Strength text",
|
||||
"type": "text",
|
||||
"type": "textBox",
|
||||
"paint": "white",
|
||||
"dropShadow": true,
|
||||
"font": {
|
||||
"type": "ttf",
|
||||
"path": {
|
||||
"type": "resolve",
|
||||
"parent": {
|
||||
"type": "property",
|
||||
"name": "lotro.resources.folder"
|
||||
},
|
||||
"child": {
|
||||
"type": "property",
|
||||
"name": "numbers.font"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"type": "property",
|
||||
"name": "numbers.size"
|
||||
},
|
||||
"style": 0
|
||||
},
|
||||
"text": {
|
||||
"type": "append",
|
||||
"type": "appendText",
|
||||
"values": [
|
||||
{
|
||||
"type": "optional",
|
||||
@@ -727,15 +708,65 @@
|
||||
"type": "cardPropertyGreaterThanZero",
|
||||
"name": "strength"
|
||||
},
|
||||
"value": "+"
|
||||
"value": "[symbol]+[/symbol]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "cardProperty",
|
||||
"name": "strength"
|
||||
"type": "replace",
|
||||
"source": {
|
||||
"type": "cardProperty",
|
||||
"name": "strength"
|
||||
},
|
||||
"match": "-",
|
||||
"with": "[symbol]-[/symbol]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"font": {
|
||||
"default": {
|
||||
"type": "ttf",
|
||||
"path": {
|
||||
"type": "resolve",
|
||||
"parent": {
|
||||
"type": "property",
|
||||
"name": "lotro.resources.folder"
|
||||
},
|
||||
"child": {
|
||||
"type": "property",
|
||||
"name": "numbers.font"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"type": "property",
|
||||
"name": "numbers.size"
|
||||
},
|
||||
"style": 0
|
||||
},
|
||||
"symbol": {
|
||||
"type": "ttf",
|
||||
"path": {
|
||||
"type": "resolve",
|
||||
"parent": {
|
||||
"type": "property",
|
||||
"name": "lotro.resources.folder"
|
||||
},
|
||||
"child": {
|
||||
"type": "property",
|
||||
"name": "numbers.font"
|
||||
}
|
||||
},
|
||||
"size": 29,
|
||||
"style": 0
|
||||
}
|
||||
},
|
||||
"glyphs": {
|
||||
"shire": "#",
|
||||
"dwarven": "@"
|
||||
},
|
||||
"yShifts": {
|
||||
"symbol": -10
|
||||
},
|
||||
"minYStart": 1,
|
||||
"box": {
|
||||
"type": "box",
|
||||
"x": 45,
|
||||
@@ -773,30 +804,11 @@
|
||||
},
|
||||
{
|
||||
"comment": "Vitality text",
|
||||
"type": "text",
|
||||
"type": "textBox",
|
||||
"paint": "white",
|
||||
"dropShadow": true,
|
||||
"font": {
|
||||
"type": "ttf",
|
||||
"path": {
|
||||
"type": "resolve",
|
||||
"parent": {
|
||||
"type": "property",
|
||||
"name": "lotro.resources.folder"
|
||||
},
|
||||
"child": {
|
||||
"type": "property",
|
||||
"name": "numbers.font"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"type": "property",
|
||||
"name": "numbers.size"
|
||||
},
|
||||
"style": 0
|
||||
},
|
||||
"text": {
|
||||
"type": "append",
|
||||
"type": "appendText",
|
||||
"values": [
|
||||
{
|
||||
"type": "optional",
|
||||
@@ -810,15 +822,65 @@
|
||||
"type": "cardPropertyGreaterThanZero",
|
||||
"name": "vitality"
|
||||
},
|
||||
"value": "+"
|
||||
"value": "[symbol]+[/symbol]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "cardProperty",
|
||||
"name": "vitality"
|
||||
"type": "replace",
|
||||
"source": {
|
||||
"type": "cardProperty",
|
||||
"name": "vitality"
|
||||
},
|
||||
"match": "-",
|
||||
"with": "[symbol]-[/symbol]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"font": {
|
||||
"default": {
|
||||
"type": "ttf",
|
||||
"path": {
|
||||
"type": "resolve",
|
||||
"parent": {
|
||||
"type": "property",
|
||||
"name": "lotro.resources.folder"
|
||||
},
|
||||
"child": {
|
||||
"type": "property",
|
||||
"name": "numbers.font"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"type": "property",
|
||||
"name": "numbers.size"
|
||||
},
|
||||
"style": 0
|
||||
},
|
||||
"symbol": {
|
||||
"type": "ttf",
|
||||
"path": {
|
||||
"type": "resolve",
|
||||
"parent": {
|
||||
"type": "property",
|
||||
"name": "lotro.resources.folder"
|
||||
},
|
||||
"child": {
|
||||
"type": "property",
|
||||
"name": "numbers.font"
|
||||
}
|
||||
},
|
||||
"size": 29,
|
||||
"style": 0
|
||||
}
|
||||
},
|
||||
"glyphs": {
|
||||
"shire": "#",
|
||||
"dwarven": "@"
|
||||
},
|
||||
"yShifts": {
|
||||
"symbol": -10
|
||||
},
|
||||
"minYStart": 1,
|
||||
"box": {
|
||||
"type": "box",
|
||||
"x": 45,
|
||||
@@ -856,29 +918,11 @@
|
||||
},
|
||||
{
|
||||
"comment": "Resistance text",
|
||||
"type": "text",
|
||||
"type": "textBox",
|
||||
"paint": "white",
|
||||
"font": {
|
||||
"type": "ttf",
|
||||
"path": {
|
||||
"type": "resolve",
|
||||
"parent": {
|
||||
"type": "property",
|
||||
"name": "lotro.resources.folder"
|
||||
},
|
||||
"child": {
|
||||
"type": "property",
|
||||
"name": "numbers.font"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"type": "property",
|
||||
"name": "numbers.size"
|
||||
},
|
||||
"style": 0
|
||||
},
|
||||
"dropShadow": true,
|
||||
"text": {
|
||||
"type": "append",
|
||||
"type": "appendText",
|
||||
"values": [
|
||||
{
|
||||
"type": "optional",
|
||||
@@ -892,15 +936,65 @@
|
||||
"type": "cardPropertyGreaterThanZero",
|
||||
"name": "resistance"
|
||||
},
|
||||
"value": "+"
|
||||
"value": "[symbol]+[/symbol]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "cardProperty",
|
||||
"name": "resistance"
|
||||
"type": "replace",
|
||||
"source": {
|
||||
"type": "cardProperty",
|
||||
"name": "resistance"
|
||||
},
|
||||
"match": "-",
|
||||
"with": "[symbol]-[/symbol]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"font": {
|
||||
"default": {
|
||||
"type": "ttf",
|
||||
"path": {
|
||||
"type": "resolve",
|
||||
"parent": {
|
||||
"type": "property",
|
||||
"name": "lotro.resources.folder"
|
||||
},
|
||||
"child": {
|
||||
"type": "property",
|
||||
"name": "numbers.font"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"type": "property",
|
||||
"name": "numbers.size"
|
||||
},
|
||||
"style": 0
|
||||
},
|
||||
"symbol": {
|
||||
"type": "ttf",
|
||||
"path": {
|
||||
"type": "resolve",
|
||||
"parent": {
|
||||
"type": "property",
|
||||
"name": "lotro.resources.folder"
|
||||
},
|
||||
"child": {
|
||||
"type": "property",
|
||||
"name": "numbers.font"
|
||||
}
|
||||
},
|
||||
"size": 29,
|
||||
"style": 0
|
||||
}
|
||||
},
|
||||
"glyphs": {
|
||||
"shire": "#",
|
||||
"dwarven": "@"
|
||||
},
|
||||
"yShifts": {
|
||||
"symbol": -10
|
||||
},
|
||||
"minYStart": 1,
|
||||
"box": {
|
||||
"type": "box",
|
||||
"x": 45,
|
||||
@@ -1028,6 +1122,9 @@
|
||||
"shire": "#",
|
||||
"dwarven": "@"
|
||||
},
|
||||
"yShifts": {
|
||||
"glyph": 3
|
||||
},
|
||||
"minYStart": 0.10,
|
||||
"box": {
|
||||
"type": "box",
|
||||
|
||||
Reference in New Issue
Block a user