Ranides Atterwim 2 лет назад
Родитель
Сommit
f1fd1e4c43

+ 3 - 0
assira.junit/src/main/java/net/ranides/assira/junit/ImageAssert.java

@@ -14,6 +14,9 @@ public class ImageAssert {
     public static void assertEquals(String expected, BufferedImage value) throws IOException {
         URL resource = ImageAssert.class.getClassLoader().getResource(expected);
         if(resource == null) {
+            File outputFile = new File("target/out_" + expected.replace("/", "_"));
+            ImageIO.write(value, "bmp", outputFile);
+
             fail("Expected resource not found: " + expected);
         }
         BufferedImage expectedImage = ImageIO.read(resource);

+ 84 - 7
assira.ui/src/main/java/net/ranides/assira/ui/primitives/CssParser.java

@@ -161,6 +161,31 @@ public class CssParser {
         .valueForToken(CssGrammarParser.SWING_BORDER_bevel_soft, CssBorderStyle.SWING_BEVEL_SOFT)
         .prepare();
 
+    public static final G4Selector<Integer> NUMBER_UNIT = new G4SelectorBuilder<Integer>()
+        .withName("CSS:number-unit")
+        .withParser(PARSER)
+        .mapRule(CssGrammarParser.RULE_numberUnit, node -> {
+            Number number = NUMBER.single(node.child("number"));
+            CssUnit unit = SIZE_UNIT.single(node.child("unit"));
+            switch (unit) {
+                case PX:
+                    return number.intValue();
+                case PT:
+                    return pt2px(number);
+                case EM:
+                    return pt2px(node.get(COMPONENT).get().getFont().getSize());
+                case EX:
+                    JComponent component = node.get(COMPONENT).get();
+                    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);
+            }
+        })
+        .prepare();
+
+
     public static final G4Selector<Integer> BORDER_SIZE_COMPONENT = new G4SelectorBuilder<Integer>()
         //<editor-fold desc="G4Selector">
         .withName("CSS:border-size")
@@ -229,18 +254,70 @@ public class CssParser {
                 .map(v -> BORDER_SIZE.single(v));
 
             switch (style) {
-                case SOLID:
+                case SOLID: {
                     Color icolor = color.orElseGet(() -> node.get(COMPONENT).get().getBackground());
                     CssBorderSize isize = size.orElse(CssBorderSize.SINGLE);
-                    if(isize.isSimple()) {
+                    if (isize.isSimple()) {
                         return BorderFactory.createLineBorder(icolor, isize.getSize());
                     } else {
                         return BorderFactory.createMatteBorder(isize.top, isize.left, isize.bottom, isize.right, icolor);
                     }
+                }
                 case OUTSET:
-                    return CustomBevelBorder.newInstance(size.map(CssBorderSize::getLeft), color, CustomBevelBorder.RAISED);
+                    return CustomBevelBorder.newInstance(size.map(CssBorderSize::getSize), color, CustomBevelBorder.RAISED);
                 case INSET:
-                    return CustomBevelBorder.newInstance(size.map(CssBorderSize::getLeft), color, CustomBevelBorder.LOWERED);
+                    return CustomBevelBorder.newInstance(size.map(CssBorderSize::getSize), color, CustomBevelBorder.LOWERED);
+                case DASHED: {
+                    Color icolor = color.orElseGet(() -> node.get(COMPONENT).get().getBackground());
+                    int isize = size.orElse(CssBorderSize.SINGLE).getSize();
+                    return BorderFactory.createDashedBorder(icolor, isize, 3.0f, 3.0f, false);
+                }
+                case DOTTED: {
+                    Color icolor = color.orElseGet(() -> node.get(COMPONENT).get().getBackground());
+                    int isize = size.orElse(CssBorderSize.SINGLE).getSize();
+                    return BorderFactory.createDashedBorder(icolor, isize, 1.0f, 1.0f, true);
+                }
+                case DOUBLE: {
+                    Color icolor = color.orElseGet(() -> node.get(COMPONENT).get().getBackground());
+                    int isize = size.orElse(CssBorderSize.SINGLE).getSize();
+
+                    return BorderFactory.createCompoundBorder(
+                        BorderFactory.createCompoundBorder(
+                            BorderFactory.createLineBorder(icolor, isize),
+                            BorderFactory.createEmptyBorder(isize, isize, isize, isize)
+                        ),
+                        BorderFactory.createLineBorder(icolor, isize)
+                    );
+                }
+                case GROOVE: {
+                    return BorderFactory.createCompoundBorder(
+                        CustomBevelBorder.newInstance(size.map(CssBorderSize::getSize), color, CustomBevelBorder.LOWERED),
+                        CustomBevelBorder.newInstance(size.map(CssBorderSize::getSize), color, CustomBevelBorder.RAISED)
+                    );
+                }
+                case RIDGE: {
+                    return BorderFactory.createCompoundBorder(
+                        CustomBevelBorder.newInstance(size.map(CssBorderSize::getSize), color, CustomBevelBorder.RAISED),
+                        CustomBevelBorder.newInstance(size.map(CssBorderSize::getSize), color, CustomBevelBorder.LOWERED)
+                    );
+                }
+//                case SWING_ETCHED: {
+//                    List<Color> colors = node.children("color").map(v -> COLOR.single(v)).list();
+//                    Object color1;
+//                    Object color2;
+//                    if(colors.size() == 1) {
+//                        Color color0 = colors.get(0);
+//                        color1 = color0.brighter();
+//                        color2 = color0.darker();
+//                    } else {
+//                        color1 = colors.get(0);
+//                        color2 = colors.get(1);
+//                    }
+//
+//                    Integer size0 = node.children("numberUnit").single().map(v -> NUMBER_UNIT.single(v)).get();
+//
+//                    BorderFactory.createEtchedBorder(size0, )
+//                }
                 default:
                     throw new UnsupportedOperationException("Unsupported border style: " + style);
             }
@@ -358,8 +435,8 @@ public class CssParser {
         INSET,
         OUTSET,
 
-        SWING_ETCHED,
-        SWING_BEVEL,
-        SWING_BEVEL_SOFT,
+        SWING_ETCHED,           //
+        SWING_BEVEL,            //
+        SWING_BEVEL_SOFT,       //
     }
 }

+ 22 - 7
assira.ui/src/test/java/net/ranides/assira/ui/primitives/CssParserTest.java

@@ -315,15 +315,30 @@ public class CssParserTest {
         panel.setBackground(new Color(128,192,192));
         panel.setForeground(Color.RED);
 
-        ImageAssert.assertEquals("borders/border1a.bmp", paintBorder(panel, CssParser.border(panel, "solid 1px #f00")));
+        ImageAssert.assertEquals("borders/border1solid1.bmp", paintBorder(panel, CssParser.border(panel, "solid 1px #f00")));
+        ImageAssert.assertEquals("borders/border1solid2.bmp", paintBorder(panel, CssParser.border(panel, "solid #800 1px 2px 3px 4px")));
 
-        ImageAssert.assertEquals("borders/border1b.bmp", paintBorder(panel, CssParser.border(panel, "outset 1px #f00")));
-        ImageAssert.assertEquals("borders/border1c.bmp", paintBorder(panel, CssParser.border(panel, "outset 4px #800")));
-        ImageAssert.assertEquals("borders/border1d.bmp", paintBorder(panel, CssParser.border(panel, "outset 4px")));
-        ImageAssert.assertEquals("borders/border1e.bmp", paintBorder(panel, CssParser.border(panel, "outset #800")));
-        ImageAssert.assertEquals("borders/border1f.bmp", paintBorder(panel, CssParser.border(panel, "outset")));
+        ImageAssert.assertEquals("borders/border1outset1.bmp", paintBorder(panel, CssParser.border(panel, "outset 1px #f00")));
+        ImageAssert.assertEquals("borders/border1outset2.bmp", paintBorder(panel, CssParser.border(panel, "outset 4px #800")));
+        ImageAssert.assertEquals("borders/border1outset3.bmp", paintBorder(panel, CssParser.border(panel, "outset 4px")));
+        ImageAssert.assertEquals("borders/border1outset4.bmp", paintBorder(panel, CssParser.border(panel, "outset #800")));
+        ImageAssert.assertEquals("borders/border1outset5.bmp", paintBorder(panel, CssParser.border(panel, "outset")));
 
-        ImageAssert.assertEquals("borders/border1g.bmp", paintBorder(panel, CssParser.border(panel, "solid #800 1px 2px 3px 4px")));
+
+        ImageAssert.assertEquals("borders/border1dashed1.bmp", paintBorder(panel, CssParser.border(panel, "dashed #ff0 1px")));
+        ImageAssert.assertEquals("borders/border1dashed2.bmp", paintBorder(panel, CssParser.border(panel, "dashed #ff0 4px")));
+
+        ImageAssert.assertEquals("borders/border1dotted1.bmp", paintBorder(panel, CssParser.border(panel, "dotted #ff0 1px")));
+        ImageAssert.assertEquals("borders/border1dotted2.bmp", paintBorder(panel, CssParser.border(panel, "dotted #ff0 4px")));
+
+        ImageAssert.assertEquals("borders/border1double1.bmp", paintBorder(panel, CssParser.border(panel, "double #ff0 1px")));
+        ImageAssert.assertEquals("borders/border1double2.bmp", paintBorder(panel, CssParser.border(panel, "double #ff0 4px")));
+
+        ImageAssert.assertEquals("borders/border1groove1.bmp", paintBorder(panel, CssParser.border(panel, "groove 1px")));
+        ImageAssert.assertEquals("borders/border1groove2.bmp", paintBorder(panel, CssParser.border(panel, "groove 4px")));
+
+        ImageAssert.assertEquals("borders/border1ridge1.bmp", paintBorder(panel, CssParser.border(panel, "ridge 1px")));
+        ImageAssert.assertEquals("borders/border1ridge2.bmp", paintBorder(panel, CssParser.border(panel, "ridge 4px")));
     }
 
     @Test

BIN
assira.ui/src/test/resources/borders/border1dashed1.bmp


BIN
assira.ui/src/test/resources/borders/border1dashed2.bmp


BIN
assira.ui/src/test/resources/borders/border1dotted1.bmp


BIN
assira.ui/src/test/resources/borders/border1dotted2.bmp


BIN
assira.ui/src/test/resources/borders/border1double1.bmp


BIN
assira.ui/src/test/resources/borders/border1double2.bmp


BIN
assira.ui/src/test/resources/borders/border1groove1.bmp


BIN
assira.ui/src/test/resources/borders/border1groove2.bmp


assira.ui/src/test/resources/borders/border1b.bmp → assira.ui/src/test/resources/borders/border1outset1.bmp


assira.ui/src/test/resources/borders/border1c.bmp → assira.ui/src/test/resources/borders/border1outset2.bmp


assira.ui/src/test/resources/borders/border1d.bmp → assira.ui/src/test/resources/borders/border1outset3.bmp


assira.ui/src/test/resources/borders/border1e.bmp → assira.ui/src/test/resources/borders/border1outset4.bmp


assira.ui/src/test/resources/borders/border1f.bmp → assira.ui/src/test/resources/borders/border1outset5.bmp


BIN
assira.ui/src/test/resources/borders/border1ridge1.bmp


BIN
assira.ui/src/test/resources/borders/border1ridge2.bmp


assira.ui/src/test/resources/borders/border1a.bmp → assira.ui/src/test/resources/borders/border1solid1.bmp


assira.ui/src/test/resources/borders/border1g.bmp → assira.ui/src/test/resources/borders/border1solid2.bmp