This implements a couple of CSS shorthands. More specifically this is
padding, margin and border(-*) which all map to more specific
attributes. Makes the planet look even better:
http://kennke.org/~roman/planet5.png
2006-12-01 Roman Kennke <[EMAIL PROTECTED]>
* gnu/javax/swing/text/html/css/BorderStyle.java: New class for
handling border styles.
* gnu/javax/swing/text/html/css/BorderWidth.java
(isValid): New method.
* gnu/javax/swing/text/html/css/Length.java
(isValid): New method.
* javax/swing/text/html/CSS.java
(addInternal): Added shorthand parsing for border, padding and
margin.
(parseBackgroundShorthand): Added API docs.
(parsePaddingShorthand): New method. Handles padding shorthand
values.
(parseMarginShorthand): New method. Handles margin shorthand
values.
(parseBorderShorthand): New method. Handles border shorthand
values.
* javax/swing/text/html/StyleSheet.java
(translateHTMLToCSS): Set specific padding attributes.
(BoxPainter.BoxPainter): Don't handle PADDING and MARGIN here.
These shorthands are now handled in CSS.
(BoxPainter.paint): Exclude the outer margin.
/Roman
Index: gnu/javax/swing/text/html/css/BorderStyle.java
===================================================================
RCS file: gnu/javax/swing/text/html/css/BorderStyle.java
diff -N gnu/javax/swing/text/html/css/BorderStyle.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gnu/javax/swing/text/html/css/BorderStyle.java 1 Dec 2006 20:31:34 -0000
@@ -0,0 +1,64 @@
+/* BorderStyle.java -- Utility for dealing with border styles
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.swing.text.html.css;
+
+/**
+ * Utility class for handling border styles.
+ */
+public class BorderStyle
+{
+
+ /**
+ * Determines if a given value makes up a valid border style value.
+ *
+ * @param value the value to check
+ *
+ * @return <code>true</code> when this is a valid border style,
+ * <code>false</code> otherwise
+ */
+ public static boolean isValidStyle(String value)
+ {
+ return value.equals("none") || value.equals("hidden")
+ || value.equals("dotted") || value.equals("dashed")
+ || value.equals("solid") || value.equals("double")
+ || value.equals("groove") || value.equals("ridge")
+ || value.equals("inset") || value.equals("outset");
+
+ }
+}
Index: gnu/javax/swing/text/html/css/BorderWidth.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/javax/swing/text/html/css/BorderWidth.java,v
retrieving revision 1.1
diff -u -1 -5 -r1.1 BorderWidth.java
--- gnu/javax/swing/text/html/css/BorderWidth.java 7 Nov 2006 12:57:12 -0000 1.1
+++ gnu/javax/swing/text/html/css/BorderWidth.java 1 Dec 2006 20:31:34 -0000
@@ -51,16 +51,28 @@
* Creates a new BorderWidth instance.
*
* @param val the CSS value to be interpreted
*/
public BorderWidth(String val)
{
super(val);
if (val.equals("thin"))
floatValue = 1.F;
else if (val.equals("medium"))
floatValue = 2.F;
else if (val.equals("thick"))
floatValue = 3.F;
}
+ /**
+ * Checks if the specified value makes up a valid border-width value.
+ *
+ * @param value the value to check
+ *
+ * @return <code>true</code> if the value is a valid border-width
+ */
+ public static boolean isValid(String value)
+ {
+ return value.equals("thin") || value.equals("medium")
+ || value.equals("thick") || Length.isValid(value);
+ }
}
Index: gnu/javax/swing/text/html/css/Length.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/javax/swing/text/html/css/Length.java,v
retrieving revision 1.6
diff -u -1 -5 -r1.6 Length.java
--- gnu/javax/swing/text/html/css/Length.java 1 Dec 2006 14:43:43 -0000 1.6
+++ gnu/javax/swing/text/html/css/Length.java 1 Dec 2006 20:31:34 -0000
@@ -219,16 +219,65 @@
{
return isFontEXRelative;
}
/**
* Returns <code>true</code> when the length value is a percentage
* value, <code>false</code> otherwise.
*
* @return <code>true</code> when the length value is a percentage
* value, <code>false</code> otherwise
*/
public boolean isPercentage()
{
return isPercentage;
}
+
+ /**
+ * Checks if the specified value makes up a valid length value.
+ *
+ * @param value the value to check
+ *
+ * @return <code>true</code> if the value is a valid length
+ */
+ public static boolean isValid(String value)
+ {
+ boolean isValid = true;
+ int px = value.indexOf("px");
+ int em = value.indexOf("em");
+ int ex = value.indexOf("ex");
+ int pc = value.indexOf('%');
+ try
+ {
+ if (px != -1)
+ {
+ Integer.parseInt(value.substring(0, px));
+ }
+ else if (em != -1)
+ {
+ Integer.parseInt(value.substring(0, em));
+ }
+ else if (ex != -1)
+ {
+ Integer.parseInt(value.substring(0, ex));
+ }
+ else if (pc != -1)
+ {
+ Integer.parseInt(value.substring(0, ex));
+ }
+ else
+ {
+ Integer.parseInt(value);
+ }
+ }
+ catch (NumberFormatException nfe)
+ {
+ isValid = false;
+ }
+ return isValid;
+ }
+
+ public String toString()
+ {
+ return value;
+ }
}
Index: javax/swing/text/html/CSS.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/html/CSS.java,v
retrieving revision 1.11
diff -u -1 -5 -r1.11 CSS.java
--- javax/swing/text/html/CSS.java 17 Nov 2006 22:12:11 -0000 1.11
+++ javax/swing/text/html/CSS.java 1 Dec 2006 20:31:34 -0000
@@ -25,30 +25,31 @@
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package javax.swing.text.html;
+import gnu.javax.swing.text.html.css.BorderStyle;
import gnu.javax.swing.text.html.css.BorderWidth;
import gnu.javax.swing.text.html.css.CSSColor;
import gnu.javax.swing.text.html.css.FontSize;
import gnu.javax.swing.text.html.css.FontStyle;
import gnu.javax.swing.text.html.css.FontWeight;
import gnu.javax.swing.text.html.css.Length;
import java.io.Serializable;
import java.util.HashMap;
import java.util.StringTokenizer;
import javax.swing.text.MutableAttributeSet;
/**
* Provides CSS attributes to be used by the HTML view classes. The constants
@@ -405,31 +406,31 @@
new Attribute("border-bottom-style", false, null);
static final Attribute BORDER_LEFT_STYLE =
new Attribute("border-left-style", false, null);
static final Attribute BORDER_RIGHT_STYLE =
new Attribute("border-right-style", false, null);
static final Attribute BORDER_TOP_COLOR =
new Attribute("border-top-color", false, null);
static final Attribute BORDER_BOTTOM_COLOR =
new Attribute("border-bottom-color", false, null);
static final Attribute BORDER_LEFT_COLOR =
new Attribute("border-left-color", false, null);
static final Attribute BORDER_RIGHT_COLOR =
new Attribute("border-right-color", false, null);
static final Attribute BORDER_SPACING =
new Attribute("border-spacing", false, null);
-
+
/**
* The attribute string.
*/
String attStr;
/**
* Indicates if this attribute should be inherited from it's parent or
* not.
*/
boolean isInherited;
/**
* A default value for this attribute if one exists, otherwise null.
*/
String defaultValue;
@@ -525,30 +526,200 @@
o = new Length(v);
else if (att == Attribute.BORDER_WIDTH || att == Attribute.BORDER_TOP_WIDTH
|| att == Attribute.BORDER_LEFT_WIDTH
|| att == Attribute.BORDER_RIGHT_WIDTH
|| att == Attribute.BORDER_BOTTOM_WIDTH)
o = new BorderWidth(v);
else
o = v;
return o;
}
static void addInternal(MutableAttributeSet atts, Attribute a, String v)
{
if (a == Attribute.BACKGROUND)
parseBackgroundShorthand(atts, v);
+ else if (a == Attribute.PADDING)
+ parsePaddingShorthand(atts, v);
+ else if (a == Attribute.MARGIN)
+ parseMarginShorthand(atts, v);
+ else if (a == Attribute.BORDER || a == Attribute.BORDER_LEFT
+ || a == Attribute.BORDER_RIGHT || a == Attribute.BORDER_TOP
+ || a == Attribute.BORDER_BOTTOM)
+ parseBorderShorthand(atts, v, a);
}
+ /**
+ * Parses the background shorthand and translates it to more specific
+ * background attributes.
+ *
+ * @param atts the attributes
+ * @param v the value
+ */
private static void parseBackgroundShorthand(MutableAttributeSet atts,
String v)
{
StringTokenizer tokens = new StringTokenizer(v, " ");
while (tokens.hasMoreElements())
{
String token = tokens.nextToken();
if (CSSColor.isValidColor(token))
atts.addAttribute(Attribute.BACKGROUND_COLOR,
new CSSColor(token));
}
}
+
+ /**
+ * Parses the padding shorthand and translates to the specific padding
+ * values.
+ *
+ * @param atts the attributes
+ * @param v the actual value
+ */
+ private static void parsePaddingShorthand(MutableAttributeSet atts, String v)
+ {
+ StringTokenizer tokens = new StringTokenizer(v, " ");
+ int numTokens = tokens.countTokens();
+ if (numTokens == 1)
+ {
+ Length l = new Length(tokens.nextToken());
+ atts.addAttribute(Attribute.PADDING_BOTTOM, l);
+ atts.addAttribute(Attribute.PADDING_LEFT, l);
+ atts.addAttribute(Attribute.PADDING_RIGHT, l);
+ atts.addAttribute(Attribute.PADDING_TOP, l);
+ }
+ else if (numTokens == 2)
+ {
+ Length l1 = new Length(tokens.nextToken());
+ Length l2 = new Length(tokens.nextToken());
+ atts.addAttribute(Attribute.PADDING_BOTTOM, l1);
+ atts.addAttribute(Attribute.PADDING_TOP, l1);
+ atts.addAttribute(Attribute.PADDING_LEFT, l2);
+ atts.addAttribute(Attribute.PADDING_RIGHT, l2);
+ }
+ else if (numTokens == 3)
+ {
+ Length l1 = new Length(tokens.nextToken());
+ Length l2 = new Length(tokens.nextToken());
+ Length l3 = new Length(tokens.nextToken());
+ atts.addAttribute(Attribute.PADDING_TOP, l1);
+ atts.addAttribute(Attribute.PADDING_LEFT, l2);
+ atts.addAttribute(Attribute.PADDING_RIGHT, l2);
+ atts.addAttribute(Attribute.PADDING_BOTTOM, l3);
+ }
+ else
+ {
+ Length l1 = new Length(tokens.nextToken());
+ Length l2 = new Length(tokens.nextToken());
+ Length l3 = new Length(tokens.nextToken());
+ Length l4 = new Length(tokens.nextToken());
+ atts.addAttribute(Attribute.PADDING_TOP, l1);
+ atts.addAttribute(Attribute.PADDING_RIGHT, l2);
+ atts.addAttribute(Attribute.PADDING_BOTTOM, l3);
+ atts.addAttribute(Attribute.PADDING_LEFT, l4);
+ }
+ }
+
+ /**
+ * Parses the margin shorthand and translates to the specific margin
+ * values.
+ *
+ * @param atts the attributes
+ * @param v the actual value
+ */
+ private static void parseMarginShorthand(MutableAttributeSet atts, String v)
+ {
+ StringTokenizer tokens = new StringTokenizer(v, " ");
+ int numTokens = tokens.countTokens();
+ if (numTokens == 1)
+ {
+ Length l = new Length(tokens.nextToken());
+ System.err.println("margin: " + l);
+ atts.addAttribute(Attribute.MARGIN_BOTTOM, l);
+ atts.addAttribute(Attribute.MARGIN_LEFT, l);
+ atts.addAttribute(Attribute.MARGIN_RIGHT, l);
+ atts.addAttribute(Attribute.MARGIN_TOP, l);
+ }
+ else if (numTokens == 2)
+ {
+ Length l1 = new Length(tokens.nextToken());
+ Length l2 = new Length(tokens.nextToken());
+ atts.addAttribute(Attribute.MARGIN_BOTTOM, l1);
+ atts.addAttribute(Attribute.MARGIN_TOP, l1);
+ atts.addAttribute(Attribute.MARGIN_LEFT, l2);
+ atts.addAttribute(Attribute.MARGIN_RIGHT, l2);
+ }
+ else if (numTokens == 3)
+ {
+ Length l1 = new Length(tokens.nextToken());
+ Length l2 = new Length(tokens.nextToken());
+ Length l3 = new Length(tokens.nextToken());
+ atts.addAttribute(Attribute.MARGIN_TOP, l1);
+ atts.addAttribute(Attribute.MARGIN_LEFT, l2);
+ atts.addAttribute(Attribute.MARGIN_RIGHT, l2);
+ atts.addAttribute(Attribute.MARGIN_BOTTOM, l3);
+ }
+ else
+ {
+ Length l1 = new Length(tokens.nextToken());
+ Length l2 = new Length(tokens.nextToken());
+ Length l3 = new Length(tokens.nextToken());
+ Length l4 = new Length(tokens.nextToken());
+ atts.addAttribute(Attribute.MARGIN_TOP, l1);
+ atts.addAttribute(Attribute.MARGIN_RIGHT, l2);
+ atts.addAttribute(Attribute.MARGIN_BOTTOM, l3);
+ atts.addAttribute(Attribute.MARGIN_LEFT, l4);
+ }
+ }
+
+ /**
+ * Parses the CSS border shorthand attribute and translates it to the
+ * more specific border attributes.
+ *
+ * @param atts the attribute
+ * @param value the value
+ */
+ private static void parseBorderShorthand(MutableAttributeSet atts,
+ String value, Attribute cssAtt)
+ {
+ StringTokenizer tokens = new StringTokenizer(value, " ");
+ while (tokens.hasMoreTokens())
+ {
+ String token = tokens.nextToken();
+ if (BorderStyle.isValidStyle(token))
+ {
+ if (cssAtt == Attribute.BORDER_LEFT || cssAtt == Attribute.BORDER)
+ atts.addAttribute(Attribute.BORDER_LEFT_STYLE, token);
+ if (cssAtt == Attribute.BORDER_RIGHT || cssAtt == Attribute.BORDER)
+ atts.addAttribute(Attribute.BORDER_RIGHT_STYLE, token);
+ if (cssAtt == Attribute.BORDER_BOTTOM || cssAtt == Attribute.BORDER)
+ atts.addAttribute(Attribute.BORDER_BOTTOM_STYLE, token);
+ if (cssAtt == Attribute.BORDER_TOP || cssAtt == Attribute.BORDER)
+ atts.addAttribute(Attribute.BORDER_TOP_STYLE, token);
+ }
+ else if (BorderWidth.isValid(token))
+ {
+ BorderWidth w = new BorderWidth(token);
+ if (cssAtt == Attribute.BORDER_LEFT || cssAtt == Attribute.BORDER)
+ atts.addAttribute(Attribute.BORDER_LEFT_WIDTH, w);
+ if (cssAtt == Attribute.BORDER_RIGHT || cssAtt == Attribute.BORDER)
+ atts.addAttribute(Attribute.BORDER_RIGHT_WIDTH, w);
+ if (cssAtt == Attribute.BORDER_BOTTOM || cssAtt == Attribute.BORDER)
+ atts.addAttribute(Attribute.BORDER_BOTTOM_WIDTH, w);
+ if (cssAtt == Attribute.BORDER_TOP || cssAtt == Attribute.BORDER)
+ atts.addAttribute(Attribute.BORDER_TOP_WIDTH, w);
+ }
+ else if (CSSColor.isValidColor(token))
+ {
+ CSSColor c = new CSSColor(token);
+ if (cssAtt == Attribute.BORDER_LEFT || cssAtt == Attribute.BORDER)
+ atts.addAttribute(Attribute.BORDER_LEFT_COLOR, c);
+ if (cssAtt == Attribute.BORDER_RIGHT || cssAtt == Attribute.BORDER)
+ atts.addAttribute(Attribute.BORDER_RIGHT_COLOR, c);
+ if (cssAtt == Attribute.BORDER_BOTTOM || cssAtt == Attribute.BORDER)
+ atts.addAttribute(Attribute.BORDER_BOTTOM_COLOR, c);
+ if (cssAtt == Attribute.BORDER_TOP || cssAtt == Attribute.BORDER)
+ atts.addAttribute(Attribute.BORDER_TOP_COLOR, c);
+ }
+ }
+ }
}
Index: javax/swing/text/html/StyleSheet.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/html/StyleSheet.java,v
retrieving revision 1.21
diff -u -1 -5 -r1.21 StyleSheet.java
--- javax/swing/text/html/StyleSheet.java 1 Dec 2006 14:43:43 -0000 1.21
+++ javax/swing/text/html/StyleSheet.java 1 Dec 2006 20:31:35 -0000
@@ -731,32 +731,37 @@
cssAttr = addAttribute(cssAttr, CSS.Attribute.BORDER_SPACING,
new Length(o.toString()));
// For table cells and headers, fetch the cellpadding value from the
// parent table and set it as CSS padding attribute.
HTML.Tag tag = (HTML.Tag)
htmlAttrSet.getAttribute(StyleConstants.NameAttribute);
if ((tag == HTML.Tag.TD || tag == HTML.Tag.TH)
&& htmlAttrSet instanceof Element)
{
Element el = (Element) htmlAttrSet;
AttributeSet tableAttrs = el.getParentElement().getParentElement()
.getAttributes();
o = tableAttrs.getAttribute(HTML.Attribute.CELLPADDING);
if (o != null)
- cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING,
- new Length(o.toString()));
+ {
+ Length l = new Length(o.toString());
+ cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING_BOTTOM, l);
+ cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING_LEFT, l);
+ cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING_RIGHT, l);
+ cssAttr = addAttribute(cssAttr, CSS.Attribute.PADDING_TOP, l);
+ }
}
// TODO: Add more mappings.
return cssAttr;
}
/**
* Adds an attribute to the given set and returns a new set. This is implemented
* to convert StyleConstants attributes to CSS before forwarding them to the superclass.
* The StyleConstants attribute do not have corresponding CSS entry, the attribute
* is stored (but will likely not be used).
*
* @param old - the old set
* @param key - the non-null attribute key
* @param value - the attribute value
* @return the updated set
@@ -1143,69 +1148,56 @@
/**
* The background color.
*/
private Color background;
/**
* Package-private constructor.
*
* @param as - AttributeSet for painter
*/
BoxPainter(AttributeSet as, StyleSheet ss)
{
float emBase = ss.getEMBase(as);
float exBase = ss.getEXBase(as);
// Fetch margins.
- Length l = (Length) as.getAttribute(CSS.Attribute.MARGIN);
- if (l != null)
- {
- l.setFontBases(emBase, exBase);
- topInset = bottomInset = leftInset = rightInset = l.getValue();
- }
- l = (Length) as.getAttribute(CSS.Attribute.MARGIN_LEFT);
+ Length l = (Length) as.getAttribute(CSS.Attribute.MARGIN_LEFT);
if (l != null)
{
l.setFontBases(emBase, exBase);
leftInset = l.getValue();
}
l = (Length) as.getAttribute(CSS.Attribute.MARGIN_RIGHT);
if (l != null)
{
l.setFontBases(emBase, exBase);
rightInset = l.getValue();
}
l = (Length) as.getAttribute(CSS.Attribute.MARGIN_TOP);
if (l != null)
{
l.setFontBases(emBase, exBase);
topInset = l.getValue();
}
l = (Length) as.getAttribute(CSS.Attribute.MARGIN_BOTTOM);
if (l != null)
{
l.setFontBases(emBase, exBase);
bottomInset = l.getValue();
}
// Fetch padding.
- l = (Length) as.getAttribute(CSS.Attribute.PADDING);
- if (l != null)
- {
- l.setFontBases(emBase, exBase);
- leftPadding = rightPadding = topPadding = bottomPadding =
- l.getValue();
- }
l = (Length) as.getAttribute(CSS.Attribute.PADDING_LEFT);
if (l != null)
{
l.setFontBases(emBase, exBase);
leftPadding = l.getValue();
}
l = (Length) as.getAttribute(CSS.Attribute.PADDING_RIGHT);
if (l != null)
{
l.setFontBases(emBase, exBase);
rightPadding = l.getValue();
}
l = (Length) as.getAttribute(CSS.Attribute.PADDING_TOP);
if (l != null)
{
@@ -1275,39 +1267,42 @@
}
/**
* Paints the CSS box according to the attributes given. This should
* paint the border, padding and background.
*
* @param g - the graphics configuration
* @param x - the x coordinate
* @param y - the y coordinate
* @param w - the width of the allocated area
* @param h - the height of the allocated area
* @param v - the view making the request
*/
public void paint(Graphics g, float x, float y, float w, float h, View v)
{
-
+ int inX = (int) (x + leftInset);
+ int inY = (int) (y + topInset);
+ int inW = (int) (w - leftInset - rightInset);
+ int inH = (int) (h - topInset - bottomInset);
if (background != null)
{
g.setColor(background);
- g.fillRect((int) x, (int) y, (int) w, (int) h);
+ g.fillRect(inX, inY, inW, inH);
}
if (border != null)
{
- border.paintBorder(null, g, (int) x, (int) y, (int) w, (int) h);
+ border.paintBorder(null, g, inX, inY, inW, inH);
}
}
}
/**
* This class carries out some of the CSS list formatting duties. Implementations
* of this class enable views to present the CSS formatting while not knowing anything
* about how the CSS values are being cached.
*
* @author Lillian Angel ([EMAIL PROTECTED])
*/
public static class ListPainter implements Serializable
{
/**