|
|
@@ -1,9 +1,13 @@
|
|
|
package net.ranides.assira.ui.parsers;
|
|
|
|
|
|
import lombok.experimental.UtilityClass;
|
|
|
+import net.ranides.assira.generic.Ref;
|
|
|
import net.ranides.assira.grammar.G4Node;
|
|
|
import net.ranides.assira.grammar.G4Selector;
|
|
|
import net.ranides.assira.grammar.G4SelectorBuilder;
|
|
|
+import net.ranides.assira.text.StringUtils;
|
|
|
+import net.ranides.assira.ui.model.CssFontStyle;
|
|
|
+import net.ranides.assira.ui.model.CssFontWeight;
|
|
|
import net.ranides.grammars.generated.UiGrammarParser;
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
|
|
@@ -13,7 +17,7 @@ import java.awt.*;
|
|
|
@UtilityClass
|
|
|
public class ParseCssFont {
|
|
|
|
|
|
- public static final G4Selector<Integer> FONT_STYLE = new G4SelectorBuilder<Integer>()
|
|
|
+ public static final G4Selector<Integer> FONT_SWING_STYLE = new G4SelectorBuilder<Integer>()
|
|
|
.withName("CssFont:FONT_STYLE")
|
|
|
.withParser(GrammarBase.PARSER)
|
|
|
.valueForToken(UiGrammarParser.SWING_FONT_STYLE_PLAIN, Font.PLAIN)
|
|
|
@@ -22,25 +26,100 @@ public class ParseCssFont {
|
|
|
.valueForToken(UiGrammarParser.SWING_FONT_STYLE_BOLD_ITALIC, Font.BOLD | Font.ITALIC)
|
|
|
.prepare();
|
|
|
|
|
|
+ public static final G4Selector<CssFontStyle> FONT_CSS_STYLE = new G4SelectorBuilder<CssFontStyle>()
|
|
|
+ .withName("CssFont:FONT_CSS_STYLE")
|
|
|
+ .withParser(GrammarBase.PARSER)
|
|
|
+ .mapRule("fontStyle", node -> {
|
|
|
+ boolean italic = !node.children("CSS3_FONT_STYLE_ITALIC").isEmpty();
|
|
|
+ boolean oblique = !node.children("CSS3_FONT_STYLE_OBLIQUE").isEmpty();
|
|
|
+ double angle = oblique ? node.children("angle").single().map(ParseCssUnit.ANGLE::single).orElse(10.0) : 0.0;
|
|
|
+ return new CssFontStyle(italic, oblique, angle);
|
|
|
+ })
|
|
|
+ .prepare();
|
|
|
+
|
|
|
+ public static final G4Selector<CssFontWeight> FONT_CSS_WEIGHT = new G4SelectorBuilder<CssFontWeight>()
|
|
|
+ .withName("CssFont:FONT_CSS_STYLE")
|
|
|
+ .withParser(GrammarBase.PARSER)
|
|
|
+ .mapRule("fontWeight", node -> {
|
|
|
+ boolean bold = !node.children("CSS3_FONT_WEIGHT_BOLD").isEmpty();
|
|
|
+ boolean bolder = !node.children("CSS3_FONT_WEIGHT_LIGHTER").isEmpty();
|
|
|
+ boolean lighter = !node.children("CSS3_FONT_WEIGHT_BOLDER").isEmpty();
|
|
|
+ int absolute = node.children("numberInt").single().map(ParsePrimitives::parseInt).orElse(400);
|
|
|
+ return new CssFontWeight(bold, bolder, lighter, absolute);
|
|
|
+ })
|
|
|
+ .prepare();
|
|
|
+
|
|
|
+ public static final G4Selector<String> FONT_CSS_FAMILY = new G4SelectorBuilder<String>()
|
|
|
+ .withName("CssFont:FONT_CSS_FAMILY")
|
|
|
+ .withParser(GrammarBase.PARSER)
|
|
|
+ .mapRule(UiGrammarParser.RULE_word, node -> {
|
|
|
+ return node.text();
|
|
|
+ })
|
|
|
+ .mapToken(UiGrammarParser.TEXT, node -> {
|
|
|
+ return StringUtils.substr(node.text(), 1, -2);
|
|
|
+ })
|
|
|
+ .mapToken(UiGrammarParser.CSS3_FONT_GENERIC_SERIF, node -> {
|
|
|
+ return Font.SERIF;
|
|
|
+ })
|
|
|
+ .mapToken(UiGrammarParser.CSS3_FONT_GENERIC_SAN_SERIF, node -> {
|
|
|
+ return Font.SANS_SERIF;
|
|
|
+ })
|
|
|
+ .mapToken(UiGrammarParser.CSS3_FONT_GENERIC_MONOSPACE, node -> {
|
|
|
+ return Font.MONOSPACED;
|
|
|
+ })
|
|
|
+ .prepare();
|
|
|
+
|
|
|
public static final G4Selector<Font> FONT = new G4SelectorBuilder<Font>()
|
|
|
.withName("CssColor:FONT")
|
|
|
.withParser(GrammarBase.PARSER)
|
|
|
.mapRule("fontSwingLong", node -> {
|
|
|
- return createFont(node);
|
|
|
+ return createSwingFont(node);
|
|
|
})
|
|
|
.mapRule("fontSwingShort", node -> {
|
|
|
- return createFont(node);
|
|
|
+ return createSwingFont(node);
|
|
|
+ })
|
|
|
+ .mapRule("fontCss", node -> {
|
|
|
+ return createCssFont(node);
|
|
|
})
|
|
|
-
|
|
|
-
|
|
|
.prepare();
|
|
|
|
|
|
@NotNull
|
|
|
- private static Font createFont(G4Node node) {
|
|
|
+ private static Font createCssFont(G4Node node) {
|
|
|
+ int style = fontStyle(FONT_CSS_STYLE.optional(node), FONT_CSS_WEIGHT.optional(node));
|
|
|
+
|
|
|
+ int size = node.children("fontSize")
|
|
|
+ .map(ParseCssUnit.LENGTH::single).first()
|
|
|
+ .orElseGet( () -> GrammarBase.component(node).getParent().getFont().getSize());
|
|
|
+
|
|
|
+ String name = FONT_CSS_FAMILY.optional(node)
|
|
|
+ .orElseGet(() -> GrammarBase.component(node).getParent().getFont().getName());
|
|
|
+
|
|
|
+ return new Font(name, style, size);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static int fontStyle(Ref<CssFontStyle> style, Ref<CssFontWeight> weight) {
|
|
|
+ int attrs = 0;
|
|
|
+
|
|
|
+ if(style.isPresent()) {
|
|
|
+ CssFontStyle s = style.get();
|
|
|
+ if(s.isItalic() || (s.isOblique() && s.getObliqueAngle()>0)) {
|
|
|
+ attrs |= Font.ITALIC;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(weight.isPresent()) {
|
|
|
+ CssFontWeight w = weight.get();
|
|
|
+ if(w.isBold() || w.isBolder() || w.getAbsolute() > 400) {
|
|
|
+ attrs |= Font.BOLD;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return attrs;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static Font createSwingFont(G4Node node) {
|
|
|
String name = node.child("@name").text();
|
|
|
|
|
|
int style = node.children("@style")
|
|
|
- .map(FONT_STYLE::single).first()
|
|
|
+ .map(FONT_SWING_STYLE::single).first()
|
|
|
.orElse(Font.PLAIN);
|
|
|
|
|
|
int size = node.children("@size")
|