|
|
@@ -1,6 +1,8 @@
|
|
|
package net.ranides.assira.ui.parsers;
|
|
|
|
|
|
import lombok.experimental.UtilityClass;
|
|
|
+import net.ranides.assira.generic.ValueUtils;
|
|
|
+import net.ranides.assira.grammar.G4Node;
|
|
|
import net.ranides.assira.grammar.G4Selector;
|
|
|
import net.ranides.assira.grammar.G4SelectorBuilder;
|
|
|
import net.ranides.assira.ui.model.CssUnit;
|
|
|
@@ -22,50 +24,154 @@ public class ParseCssUnit {
|
|
|
.valueForToken(UiGrammarParser.CSS2_UNIT_Q, CssUnit.Q)
|
|
|
.valueForToken(UiGrammarParser.CSS2_UNIT_IN, CssUnit.IN)
|
|
|
.valueForToken(UiGrammarParser.CSS2_UNIT_PC, CssUnit.PC)
|
|
|
+
|
|
|
.valueForToken(UiGrammarParser.CSS2_UNIT_EM, CssUnit.EM)
|
|
|
- .valueForToken(UiGrammarParser.CSS2_UNIT_REM, CssUnit.REM)
|
|
|
.valueForToken(UiGrammarParser.CSS2_UNIT_EX, CssUnit.EX)
|
|
|
+ .valueForToken(UiGrammarParser.CSS2_UNIT_CAP, CssUnit.CAP)
|
|
|
+ .valueForToken(UiGrammarParser.CSS2_UNIT_CH, CssUnit.CH)
|
|
|
+ .valueForToken(UiGrammarParser.CSS2_UNIT_IC, CssUnit.IC)
|
|
|
.valueForToken(UiGrammarParser.CSS2_UNIT_LH, CssUnit.LH)
|
|
|
+
|
|
|
+ .valueForToken(UiGrammarParser.CSS2_UNIT_REM, CssUnit.REM)
|
|
|
+ .valueForToken(UiGrammarParser.CSS2_UNIT_REX, CssUnit.REX)
|
|
|
+ .valueForToken(UiGrammarParser.CSS2_UNIT_RCAP, CssUnit.RCAP)
|
|
|
+ .valueForToken(UiGrammarParser.CSS2_UNIT_RCH, CssUnit.RCH)
|
|
|
+ .valueForToken(UiGrammarParser.CSS2_UNIT_RIC, CssUnit.RIC)
|
|
|
.valueForToken(UiGrammarParser.CSS2_UNIT_RLH, CssUnit.RLH)
|
|
|
+
|
|
|
.valueForToken(UiGrammarParser.CSS2_UNIT_VB, CssUnit.VB)
|
|
|
.valueForToken(UiGrammarParser.CSS2_UNIT_VI, CssUnit.VI)
|
|
|
.valueForToken(UiGrammarParser.CSS2_UNIT_VW, CssUnit.VW)
|
|
|
.valueForToken(UiGrammarParser.CSS2_UNIT_VH, CssUnit.VH)
|
|
|
- .valueForToken(UiGrammarParser.CSS2_UNIT_SVW, CssUnit.SVW)
|
|
|
- .valueForToken(UiGrammarParser.CSS2_UNIT_SVH, CssUnit.SVH)
|
|
|
- .valueForToken(UiGrammarParser.CSS2_UNIT_LVW, CssUnit.LVW)
|
|
|
- .valueForToken(UiGrammarParser.CSS2_UNIT_LVH, CssUnit.LVH)
|
|
|
- .valueForToken(UiGrammarParser.CSS2_UNIT_BVW, CssUnit.BVW)
|
|
|
- .valueForToken(UiGrammarParser.CSS2_UNIT_BVH, CssUnit.BVH)
|
|
|
.prepare();
|
|
|
|
|
|
- public static final G4Selector<Integer> NUMERIC = new G4SelectorBuilder<Integer>()
|
|
|
- .withName("CssUnit:NUMERIC")
|
|
|
+ public static final G4Selector<Integer> LENGTH = new G4SelectorBuilder<Integer>()
|
|
|
+ .withName("CssUnit:LENGTH")
|
|
|
.withParser(GrammarBase.PARSER)
|
|
|
- .mapRule(UiGrammarParser.RULE_numberUnit, node -> {
|
|
|
-
|
|
|
+ .mapRule(UiGrammarParser.RULE_length, node -> {
|
|
|
Number number = ParsePrimitives.NUMBER.single(node.child("number"));
|
|
|
CssUnit unit = UNIT.single(node.child("unit"));
|
|
|
- switch (unit) {
|
|
|
- case PX:
|
|
|
- return number.intValue();
|
|
|
- case PT:
|
|
|
- return pt2px(number);
|
|
|
- case EM:
|
|
|
- return pt2px(GrammarBase.component(node).getFont().getSize());
|
|
|
- case EX:
|
|
|
- JComponent component = GrammarBase.component(node);
|
|
|
- FontMetrics metrics = component.getFontMetrics(component.getFont());
|
|
|
- double h = metrics.getStringBounds("x", component.getGraphics()).getHeight();
|
|
|
- return (int)Math.round(h);
|
|
|
- default:
|
|
|
- throw new UnsupportedOperationException("Unsupported unit: " + unit);
|
|
|
- }
|
|
|
+ return Math.round(length(node, number, unit).floatValue());
|
|
|
|
|
|
})
|
|
|
.prepare();
|
|
|
|
|
|
- private static int pt2px(Number number) {
|
|
|
- return (int) Math.round((4.0 * number.doubleValue()) / 3.0);
|
|
|
+ public static Number length(G4Node node, Number number, CssUnit unit) {
|
|
|
+ double v = number.doubleValue();
|
|
|
+
|
|
|
+ switch (unit) {
|
|
|
+ case PX:
|
|
|
+ return number;
|
|
|
+ case PT:
|
|
|
+ return 1.3333 * v;
|
|
|
+ case CM:
|
|
|
+ return 37.8000 * v;
|
|
|
+ case MM:
|
|
|
+ return 3.7800 * v;
|
|
|
+ case Q:
|
|
|
+ return 0.0945 * v;
|
|
|
+ case IN:
|
|
|
+ return 96.0000 * v;
|
|
|
+ case PC:
|
|
|
+ return 16.0000 * v;
|
|
|
+
|
|
|
+ case EM:
|
|
|
+ return v * computeEm(GrammarBase.component(node));
|
|
|
+ case EX:
|
|
|
+ return v * computeEx(GrammarBase.component(node));
|
|
|
+ case CAP:
|
|
|
+ return v * computeCap(GrammarBase.component(node));
|
|
|
+ case CH:
|
|
|
+ return v * computeCh(GrammarBase.component(node));
|
|
|
+ case IC:
|
|
|
+ return v * computeIc(GrammarBase.component(node));
|
|
|
+ case LH:
|
|
|
+ return v * computeLh(GrammarBase.component(node));
|
|
|
+
|
|
|
+ case REM:
|
|
|
+ return v * computeEm(GrammarBase.component(node).getRootPane());
|
|
|
+ case REX:
|
|
|
+ return v * computeEx(GrammarBase.component(node).getRootPane());
|
|
|
+ case RCAP:
|
|
|
+ return v * computeCap(GrammarBase.component(node).getRootPane());
|
|
|
+ case RCH:
|
|
|
+ return v * computeCh(GrammarBase.component(node).getRootPane());
|
|
|
+ case RIC:
|
|
|
+ return v * computeIc(GrammarBase.component(node).getRootPane());
|
|
|
+ case RLH:
|
|
|
+ return v * computeLh(GrammarBase.component(node).getRootPane());
|
|
|
+
|
|
|
+ case VW:
|
|
|
+ return v * computeVw(GrammarBase.component(node));
|
|
|
+ case VH:
|
|
|
+ return v * computeVh(GrammarBase.component(node));
|
|
|
+ case VMAX:
|
|
|
+ return v * computeVmax(GrammarBase.component(node));
|
|
|
+ case VMIN:
|
|
|
+ return v * computeVmin(GrammarBase.component(node));
|
|
|
+ case VB:
|
|
|
+ return v * computeVb(GrammarBase.component(node));
|
|
|
+ case VI:
|
|
|
+ return v * computeVi(GrammarBase.component(node));
|
|
|
+
|
|
|
+ default:
|
|
|
+ throw new UnsupportedOperationException("Unsupported unit: " + unit);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double computeEx(JComponent component) {
|
|
|
+ FontMetrics metrics = component.getFontMetrics(component.getFont());
|
|
|
+ return metrics.getStringBounds("x", component.getGraphics()).getHeight();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double computeCap(JComponent component) {
|
|
|
+ FontMetrics metrics = component.getFontMetrics(component.getFont());
|
|
|
+ return metrics.getStringBounds("A", component.getGraphics()).getHeight();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double computeCh(JComponent component) {
|
|
|
+ FontMetrics metrics = component.getFontMetrics(component.getFont());
|
|
|
+ return metrics.getStringBounds("0", component.getGraphics()).getWidth();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double computeEm(JComponent component) {
|
|
|
+ return 1.3333 * component.getFont().getSize();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double computeVh(JComponent component) {
|
|
|
+ return component.getRootPane().getContentPane().getHeight() / 100.0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double computeVw(JComponent component) {
|
|
|
+ return component.getRootPane().getContentPane().getHeight() / 100.0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double computeVmax(JComponent component) {
|
|
|
+ Container pane = component.getRootPane().getContentPane();
|
|
|
+ return Math.max(pane.getHeight(), pane.getWidth()) / 100.0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double computeVmin(JComponent component) {
|
|
|
+ Container pane = component.getRootPane().getContentPane();
|
|
|
+ return Math.max(pane.getHeight(), pane.getWidth()) / 100.0;
|
|
|
}
|
|
|
+
|
|
|
+ private static double computeVb(JComponent component) {
|
|
|
+ return ValueUtils.or(component.getParent(), component).getWidth() / 100.0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double computeVi(JComponent component) {
|
|
|
+ return ValueUtils.or(component.getParent(), component).getHeight() / 100.0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double computeIc(JComponent component) {
|
|
|
+ FontMetrics metrics = component.getFontMetrics(component.getFont());
|
|
|
+ return metrics.getStringBounds("水", component.getGraphics()).getWidth();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double computeLh(JComponent component) {
|
|
|
+ FontMetrics metrics = component.getFontMetrics(component.getFont());
|
|
|
+ return metrics.getHeight();
|
|
|
+ }
|
|
|
+
|
|
|
}
|