From 5bce0abfef6817e4299bc0640baf46b5f873d530 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 1 Dec 2006 14:43:42 +0000 Subject: 2006-11-30 Roman Kennke * gnu/javax/swing/text/html/css/Length.java (emBase): New field. (exBase): New field. (isFontEMRelative): New field. (isFontEXRelative): New field. (Length): Recognize and setup EM and EX relative values. (getValue): Handle EM and EX relative values. (isEMRelative): New method. (isEXRelative): New method. (setEMBase): New method. (setEXBase): New method. (setFontBases): New method. * gnu/javax/swing/text/html/parser/support/Parser.java (_handleEmptyTag): Use new isBlock() helper method. (_handleEndTag_remaining): Use new isBlock() helper method. (_handleStartTag): Consume whitespace after block start tag. (Comment): Consume whitespace after a comment. (isBlock): New helper method. (readAttributes): Consider all characters in unquoted attribute values. * javax/swing/text/html/BlockView.java (layoutMinorAxis): Use cached span value. (paint): Added debug code (commented out). (setPropertiesFromAttributes): Set the EM and EX base on lengths. * javax/swing/text/html/CSSBorder.java (CSSBorder): Take StyleSheet as argument. Call getBorderWidth() with stylesheet. (getBorderWidth): Set the EM and EX base on the length values. * javax/swing/text/html/HTMLDocument.java (HTMLReader.ParagraphAction.end): Do not set the inParagraph field. (HTMLReader.ParagraphAction.start): Do not set the inParagraph field. (HTMLReader.inImpliedParagraph): Removed. (HTMLReader.inParagraph): Removed. (HTMLReader.parseStack): New field. (HTMLReader.addContent): Use new paragraph handling. (HTMLReader.addSpecialElement): Use new paragraph handling. (HTMLReader.blockClose): Use new paragraph handling. (HTMLReader.blockOpen): Use new paragraph handling. (HTMLReader.inImpliedParagraph): New helper method. (HTMLReader.inParagraph): New helper method. * javax/swing/text/html/ImageView.java (attributes): New field. Caches view attributes. (spans): New field. Caches CSS spans. (getAttributes): Correctly setup CSS view attributes. (getPreferredSpan): Use caches spans. (getStyleSheet): Use the view's getDocument() method. (setPropertiesFromAttributes): Cache spans and setup EM and EX. (updateSize): Use cached spans. * javax/swing/text/html/ParagraphView.java (setPropertiesFromAttributes): Setup EM and EX. * javax/swing/text/html/StyleSheet.java (BoxPainter.BoxPainter): Setup EM and EX correctly. (getEMBase): New helper method. (getEXBase): New helper method. * javax/swing/text/html/TableView.java (width): New field. Caches the table width. (calculateMinorAxisRequirements): Use caches span. (setPropertiesFromAttributes): Cache span and setup EM/EX. (updateGrid): Correctly setup EM/EX. --- ChangeLog | 62 ++++++++++++ gnu/javax/swing/text/html/css/Length.java | 106 ++++++++++++++++++++- .../swing/text/html/parser/support/Parser.java | 35 +++++-- javax/swing/text/html/BlockView.java | 17 +++- javax/swing/text/html/CSSBorder.java | 19 ++-- javax/swing/text/html/HTMLDocument.java | 73 ++++++++------ javax/swing/text/html/ImageView.java | 56 +++++++---- javax/swing/text/html/ParagraphView.java | 7 ++ javax/swing/text/html/StyleSheet.java | 82 +++++++++++++--- javax/swing/text/html/TableView.java | 38 ++++++-- 10 files changed, 404 insertions(+), 91 deletions(-) diff --git a/ChangeLog b/ChangeLog index 42162df60..c454872e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,65 @@ +2006-11-30 Roman Kennke + + * gnu/javax/swing/text/html/css/Length.java + (emBase): New field. + (exBase): New field. + (isFontEMRelative): New field. + (isFontEXRelative): New field. + (Length): Recognize and setup EM and EX relative values. + (getValue): Handle EM and EX relative values. + (isEMRelative): New method. + (isEXRelative): New method. + (setEMBase): New method. + (setEXBase): New method. + (setFontBases): New method. + * gnu/javax/swing/text/html/parser/support/Parser.java + (_handleEmptyTag): Use new isBlock() helper method. + (_handleEndTag_remaining): Use new isBlock() helper method. + (_handleStartTag): Consume whitespace after block start tag. + (Comment): Consume whitespace after a comment. + (isBlock): New helper method. + (readAttributes): Consider all characters in unquoted attribute + values. + * javax/swing/text/html/BlockView.java + (layoutMinorAxis): Use cached span value. + (paint): Added debug code (commented out). + (setPropertiesFromAttributes): Set the EM and EX base on lengths. + * javax/swing/text/html/CSSBorder.java + (CSSBorder): Take StyleSheet as argument. Call getBorderWidth() + with stylesheet. + (getBorderWidth): Set the EM and EX base on the length values. + * javax/swing/text/html/HTMLDocument.java + (HTMLReader.ParagraphAction.end): Do not set the inParagraph field. + (HTMLReader.ParagraphAction.start): Do not set the inParagraph field. + (HTMLReader.inImpliedParagraph): Removed. + (HTMLReader.inParagraph): Removed. + (HTMLReader.parseStack): New field. + (HTMLReader.addContent): Use new paragraph handling. + (HTMLReader.addSpecialElement): Use new paragraph handling. + (HTMLReader.blockClose): Use new paragraph handling. + (HTMLReader.blockOpen): Use new paragraph handling. + (HTMLReader.inImpliedParagraph): New helper method. + (HTMLReader.inParagraph): New helper method. + * javax/swing/text/html/ImageView.java + (attributes): New field. Caches view attributes. + (spans): New field. Caches CSS spans. + (getAttributes): Correctly setup CSS view attributes. + (getPreferredSpan): Use caches spans. + (getStyleSheet): Use the view's getDocument() method. + (setPropertiesFromAttributes): Cache spans and setup EM and EX. + (updateSize): Use cached spans. + * javax/swing/text/html/ParagraphView.java + (setPropertiesFromAttributes): Setup EM and EX. + * javax/swing/text/html/StyleSheet.java + (BoxPainter.BoxPainter): Setup EM and EX correctly. + (getEMBase): New helper method. + (getEXBase): New helper method. + * javax/swing/text/html/TableView.java + (width): New field. Caches the table width. + (calculateMinorAxisRequirements): Use caches span. + (setPropertiesFromAttributes): Cache span and setup EM/EX. + (updateGrid): Correctly setup EM/EX. + 2006-11-30 Roman Kennke * javax/swing/text/html/FormSubmitEvent.java: New class. diff --git a/gnu/javax/swing/text/html/css/Length.java b/gnu/javax/swing/text/html/css/Length.java index 339e2a2e0..06e1ce1ac 100644 --- a/gnu/javax/swing/text/html/css/Length.java +++ b/gnu/javax/swing/text/html/css/Length.java @@ -61,6 +61,26 @@ public class Length */ private boolean isPercentage; + /** + * Indicates a length value that is relative to the font size (em). + */ + private boolean isFontEMRelative; + + /** + * Indicates a length value that is relative to the font size (ex). + */ + private boolean isFontEXRelative; + + /** + * The EM base size. + */ + private float emBase; + + /** + * The EX base size. + */ + private float exBase; + /** * Creates a new length converter instance. * @@ -68,9 +88,14 @@ public class Length */ public Length(String val) { + isFontEMRelative = false; + isFontEXRelative = false; + isPercentage = false; value = val; int i = value.indexOf("px"); int percent = value.indexOf("%"); + int em = value.indexOf("em"); + int ex = value.indexOf("ex"); try { floatValue = 0.0F; @@ -85,13 +110,24 @@ public class Length String sub = value.substring(0, percent); floatValue = Float.parseFloat(sub) / 100; } + else if (em != -1) + { + isFontEMRelative = true; + String sub = value.substring(0, em); + floatValue = Float.parseFloat(sub); + } + else if (ex != -1) + { + isFontEXRelative = true; + String sub = value.substring(0, ex); + floatValue = Float.parseFloat(sub); + } else { - // TODO: Implement other length options. floatValue = Float.parseFloat(value); } } - catch (NumberFormatException ex) + catch (NumberFormatException exc) { // Don't let such small problems interrupt CSS parsing. System.err.println("couldn't parse: " + val); @@ -112,18 +148,78 @@ public class Length * Returns the absolute span for the case when this length value is * a relative value. * - * @param available the target span + * @param base the base span * * @return the absolute span */ - public float getValue(float available) + public float getValue(float base) { float span = floatValue; if (isPercentage) - span *= available; + span *= base; + else if (isFontEMRelative) + span *= emBase; + else if (isFontEXRelative) + span *= exBase; return span; } + /** + * Sets the font relative EM base. + * + * @param base the font relative EM base + */ + public void setEMBase(float base) + { + emBase = base; + } + + /** + * Sets the font relative EX base. + * + * @param base the font relative EX base + */ + public void setEXBase(float base) + { + exBase = base; + } + + /** + * Sets the font relative base values. + * + * @param emBase the EM base + * @param exBase the EX base + */ + public void setFontBases(float emBase, float exBase) + { + setEMBase(emBase); + setEXBase(exBase); + } + + /** + * Returns true when this length value is an em font relative value. In + * order to get correct results, you need the exBase property set up + * correctly. + * + * @return true when this length value is an ex font relative value + */ + public boolean isFontEMRelative() + { + return isFontEMRelative; + } + + /** + * Returns true when this length value is an ex font relative value. In + * order to get correct results, you need the emBase property set up + * correctly. + * + * @return true when this length value is an ex font relative value + */ + public boolean isFontEXRelative() + { + return isFontEXRelative; + } + /** * Returns true when the length value is a percentage * value, false otherwise. diff --git a/gnu/javax/swing/text/html/parser/support/Parser.java b/gnu/javax/swing/text/html/parser/support/Parser.java index f6747ef84..f04c58138 100644 --- a/gnu/javax/swing/text/html/parser/support/Parser.java +++ b/gnu/javax/swing/text/html/parser/support/Parser.java @@ -498,6 +498,9 @@ public class Parser mustBe(t.kind); } hTag = new Token(start, last); + + // Consume any whitespace immediately following a comment. + optional(WS); handleComment(); } @@ -983,13 +986,15 @@ public class Parser + next.getImage() + "'"); attrValue = value.getImage(); } - else if (next.kind == SLASH) - // The slash in this context is treated as the ordinary - // character, not as a token. The slash may be part of + else if (next.kind == SLASH || next.kind == OTHER) + // The slash and other characters (like %) in this context is + // treated as the ordinary + // character, not as a token. The character may be part of // the unquoted URL. { StringBuffer image = new StringBuffer(value.getImage()); - while (next.kind == NUMTOKEN || next.kind == SLASH) + while (next.kind == NUMTOKEN || next.kind == SLASH + || next.kind == OTHER) { image.append(getNextToken().getImage()); next = getTokenAhead(); @@ -1186,7 +1191,7 @@ public class Parser // it. // For some unknown reason a FRAME tag is not treated as block element. // However in this case it should be treated as such. - if (h.isBlock() || h == HTML.Tag.FRAME) + if (isBlock(h)) optional(WS); } catch (ChangedCharSetException ex) @@ -1226,7 +1231,7 @@ public class Parser // When a block tag is closed, consume whitespace that follows after // it. - if (h.isBlock()) + if (isBlock(h)) optional(WS); if (h == HTML.Tag.TITLE) @@ -1255,6 +1260,9 @@ public class Parser HTML.Tag h = tag.getHTMLTag(); + if (isBlock(h)) + optional(WS); + if (h.isPreformatted()) preformatted++; @@ -1502,4 +1510,19 @@ public class Parser { error("Whitespace here is not permitted"); } + + /** + * Returns true when the specified tag should be considered a block tag + * wrt whitespace handling. We need this special handling, since there + * are a couple of tags that we must treat as block tags but which aren't + * officially block tags. + * + * @param tag the tag to check + * @return true when the specified tag should be considered a block tag + * wrt whitespace handling + */ + private boolean isBlock(HTML.Tag tag) + { + return tag.isBlock() || tag == HTML.Tag.STYLE || tag == HTML.Tag.FRAME; + } } diff --git a/javax/swing/text/html/BlockView.java b/javax/swing/text/html/BlockView.java index 2e781412c..82bd8604e 100644 --- a/javax/swing/text/html/BlockView.java +++ b/javax/swing/text/html/BlockView.java @@ -40,6 +40,7 @@ package javax.swing.text.html; import gnu.javax.swing.text.html.css.Length; +import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Shape; @@ -255,16 +256,13 @@ public class BlockView extends BoxView int[] offsets, int[] spans) { int viewCount = getViewCount(); - CSS.Attribute spanAtt = axis == X_AXIS ? CSS.Attribute.WIDTH - : CSS.Attribute.HEIGHT; for (int i = 0; i < viewCount; i++) { View view = getView(i); int min = (int) view.getMinimumSpan(axis); int max; // Handle CSS span value of child. - AttributeSet atts = view.getAttributes(); - Length length = (Length) atts.getAttribute(spanAtt); + Length length = cssSpans[axis]; if (length != null) { min = Math.max((int) length.getValue(targetSpan), min); @@ -299,6 +297,11 @@ public class BlockView extends BoxView public void paint(Graphics g, Shape a) { Rectangle rect = a instanceof Rectangle ? (Rectangle) a : a.getBounds(); + + // Debug output. Shows blocks in green rectangles. + // g.setColor(Color.GREEN); + // g.drawRect(rect.x, rect.y, rect.width, rect.height); + painter.paint(g, rect.x, rect.y, rect.width, rect.height, this); super.paint(g, a); } @@ -446,8 +449,14 @@ public class BlockView extends BoxView } // Fetch width and height. + float emBase = ss.getEMBase(attributes); + float exBase = ss.getEXBase(attributes); cssSpans[X_AXIS] = (Length) attributes.getAttribute(CSS.Attribute.WIDTH); + if (cssSpans[X_AXIS] != null) + cssSpans[X_AXIS].setFontBases(emBase, exBase); cssSpans[Y_AXIS] = (Length) attributes.getAttribute(CSS.Attribute.HEIGHT); + if (cssSpans[Y_AXIS] != null) + cssSpans[Y_AXIS].setFontBases(emBase, exBase); } /** diff --git a/javax/swing/text/html/CSSBorder.java b/javax/swing/text/html/CSSBorder.java index 540955494..fff6b01a1 100644 --- a/javax/swing/text/html/CSSBorder.java +++ b/javax/swing/text/html/CSSBorder.java @@ -40,12 +40,10 @@ package javax.swing.text.html; import gnu.javax.swing.text.html.css.BorderWidth; import gnu.javax.swing.text.html.css.CSSColor; -import gnu.javax.swing.text.html.css.Length; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.Insets; import javax.swing.border.Border; @@ -140,7 +138,7 @@ class CSSBorder * * @param atts the attribute set that contains the border spec */ - CSSBorder(AttributeSet atts) + CSSBorder(AttributeSet atts, StyleSheet ss) { // Determine the border styles. int style = getBorderStyle(atts, CSS.Attribute.BORDER_STYLE); @@ -179,20 +177,20 @@ class CSSBorder rightColor = color; // Determine the border widths. - int width = getBorderWidth(atts, CSS.Attribute.BORDER_WIDTH); + int width = getBorderWidth(atts, CSS.Attribute.BORDER_WIDTH, ss); if (width == -1) width = 0; top = bottom = left = right = width; - width = getBorderWidth(atts, CSS.Attribute.BORDER_TOP_WIDTH); + width = getBorderWidth(atts, CSS.Attribute.BORDER_TOP_WIDTH, ss); if (width >= 0) top = width; - width = getBorderWidth(atts, CSS.Attribute.BORDER_BOTTOM_WIDTH); + width = getBorderWidth(atts, CSS.Attribute.BORDER_BOTTOM_WIDTH, ss); if (width >= 0) bottom = width; - width = getBorderWidth(atts, CSS.Attribute.BORDER_LEFT_WIDTH); + width = getBorderWidth(atts, CSS.Attribute.BORDER_LEFT_WIDTH, ss); if (width >= 0) left = width; - width = getBorderWidth(atts, CSS.Attribute.BORDER_RIGHT_WIDTH); + width = getBorderWidth(atts, CSS.Attribute.BORDER_RIGHT_WIDTH, ss); if (width >= 0) right = width; } @@ -264,12 +262,15 @@ class CSSBorder * * @return the width, or -1 of none has been set */ - private int getBorderWidth(AttributeSet atts, CSS.Attribute key) + private int getBorderWidth(AttributeSet atts, CSS.Attribute key, + StyleSheet ss) { int width = -1; Object o = atts.getAttribute(key); if (o instanceof BorderWidth) { + BorderWidth w = (BorderWidth) o; + w.setFontBases(ss.getEMBase(atts), ss.getEXBase(atts)); width = (int) ((BorderWidth) o).getValue(); } return width; diff --git a/javax/swing/text/html/HTMLDocument.java b/javax/swing/text/html/HTMLDocument.java index 4f849f391..c4f4222ec 100644 --- a/javax/swing/text/html/HTMLDocument.java +++ b/javax/swing/text/html/HTMLDocument.java @@ -650,7 +650,12 @@ public class HTMLDocument extends DefaultStyledDocument protected MutableAttributeSet charAttr = new SimpleAttributeSet(); protected Vector parseBuffer = new Vector(); - + + /** + * The parse stack. It holds the current element tree path. + */ + private Stack parseStack = new Stack(); + /** * A stack for character attribute sets * */ @@ -696,16 +701,6 @@ public class HTMLDocument extends DefaultStyledDocument */ boolean inPreTag = false; - /** - * True when we are inside a paragraph (P, H1-H6, P-IMPLIED). - */ - boolean inParagraph = false; - - /** - * True when we are currently inside an implied paragraph. - */ - boolean inImpliedParagraph = false; - /** * This is true when we are inside a style tag. This will add text * content inside this style tag beeing parsed as CSS. @@ -948,7 +943,6 @@ public class HTMLDocument extends DefaultStyledDocument public void start(HTML.Tag t, MutableAttributeSet a) { super.start(t, a); - inParagraph = true; } /** @@ -958,7 +952,6 @@ public class HTMLDocument extends DefaultStyledDocument public void end(HTML.Tag t) { super.end(t); - inParagraph = false; } } @@ -1638,9 +1631,12 @@ public class HTMLDocument extends DefaultStyledDocument */ protected void blockOpen(HTML.Tag t, MutableAttributeSet attr) { - if (inImpliedParagraph) + if (inImpliedParagraph()) blockClose(HTML.Tag.IMPLIED); + // Push the new tag on top of the stack. + parseStack.push(t); + DefaultStyledDocument.ElementSpec element; AbstractDocument.AttributeContext ctx = getAttributeContext(); @@ -1651,6 +1647,34 @@ public class HTMLDocument extends DefaultStyledDocument parseBuffer.addElement(element); } + /** + * Returns true when we are currently inside a paragraph, either + * a real one or an implied, false otherwise. + * + * @return + */ + private boolean inParagraph() + { + boolean inParagraph = false; + if (! parseStack.isEmpty()) + { + HTML.Tag top = (HTML.Tag) parseStack.peek(); + inParagraph = top == HTML.Tag.P || top == HTML.Tag.IMPLIED; + } + return inParagraph; + } + + private boolean inImpliedParagraph() + { + boolean inParagraph = false; + if (! parseStack.isEmpty()) + { + HTML.Tag top = (HTML.Tag) parseStack.peek(); + inParagraph = top == HTML.Tag.IMPLIED; + } + return inParagraph; + } + /** * Instructs the parse buffer to close the block element associated with * the given HTML.Tag @@ -1661,13 +1685,12 @@ public class HTMLDocument extends DefaultStyledDocument { DefaultStyledDocument.ElementSpec element; - if (inImpliedParagraph) - { - inImpliedParagraph = false; - inParagraph = false; - if (t != HTML.Tag.IMPLIED) - blockClose(HTML.Tag.IMPLIED); - } + if (inImpliedParagraph() && t != HTML.Tag.IMPLIED) + blockClose(HTML.Tag.IMPLIED); + + // Pull the token from the stack. + if (! parseStack.isEmpty()) // Just to be sure. + parseStack.pop(); // If the previous tag is a start tag then we insert a synthetic // content tag. @@ -1711,11 +1734,9 @@ public class HTMLDocument extends DefaultStyledDocument protected void addContent(char[] data, int offs, int length, boolean generateImpliedPIfNecessary) { - if (generateImpliedPIfNecessary && (! inParagraph) && (! inPreTag)) + if (generateImpliedPIfNecessary && ! inParagraph()) { blockOpen(HTML.Tag.IMPLIED, new SimpleAttributeSet()); - inParagraph = true; - inImpliedParagraph = true; } AbstractDocument.AttributeContext ctx = getAttributeContext(); @@ -1760,11 +1781,9 @@ public class HTMLDocument extends DefaultStyledDocument */ protected void addSpecialElement(HTML.Tag t, MutableAttributeSet a) { - if (t != HTML.Tag.FRAME && ! inParagraph && ! inImpliedParagraph) + if (t != HTML.Tag.FRAME && ! inParagraph()) { blockOpen(HTML.Tag.IMPLIED, new SimpleAttributeSet()); - inParagraph = true; - inImpliedParagraph = true; } a.addAttribute(StyleConstants.NameAttribute, t); diff --git a/javax/swing/text/html/ImageView.java b/javax/swing/text/html/ImageView.java index f073c6d05..050eb16e2 100644 --- a/javax/swing/text/html/ImageView.java +++ b/javax/swing/text/html/ImageView.java @@ -110,6 +110,16 @@ public class ImageView extends View */ private ImageObserver observer; + /** + * The CSS width and height. + */ + private Length[] spans; + + /** + * The cached attributes. + */ + private AttributeSet attributes; + /** * Creates the image view that represents the given element. * @@ -221,12 +231,9 @@ public class ImageView extends View */ public AttributeSet getAttributes() { - StyleSheet styles = getStyleSheet(); - if (styles == null) - return super.getAttributes(); - else - return CombinedAttributes.combine(super.getAttributes(), - styles.getViewAttributes(this)); + if (attributes == null) + attributes = getStyleSheet().getViewAttributes(this); + return attributes; } /** @@ -318,9 +325,8 @@ public class ImageView extends View if (axis == View.X_AXIS) { - Object w = attrs.getAttribute(CSS.Attribute.WIDTH); - if (w instanceof Length) - return ((Length) w).getValue(); + if (spans[axis] != null) + return spans[axis].getValue(); else if (image != null) return image.getWidth(getContainer()); else @@ -328,9 +334,8 @@ public class ImageView extends View } else if (axis == View.Y_AXIS) { - Object w = attrs.getAttribute(CSS.Attribute.HEIGHT); - if (w instanceof Length) - return ((Length) w).getValue(); + if (spans[axis] != null) + return spans[axis].getValue(); else if (image != null) return image.getHeight(getContainer()); else @@ -347,11 +352,8 @@ public class ImageView extends View */ protected StyleSheet getStyleSheet() { - Document d = getElement().getDocument(); - if (d instanceof HTMLDocument) - return ((HTMLDocument) d).getStyleSheet(); - else - return null; + HTMLDocument doc = (HTMLDocument) getDocument(); + return doc.getStyleSheet(); } /** @@ -410,7 +412,21 @@ public class ImageView extends View */ protected void setPropertiesFromAttributes() { - // FIXME: Implement this properly. + AttributeSet atts = getAttributes(); + StyleSheet ss = getStyleSheet(); + float emBase = ss.getEMBase(atts); + float exBase = ss.getEXBase(atts); + spans = new Length[2]; + spans[X_AXIS] = (Length) atts.getAttribute(CSS.Attribute.WIDTH); + if (spans[X_AXIS] != null) + { + spans[X_AXIS].setFontBases(emBase, exBase); + } + spans[Y_AXIS] = (Length) atts.getAttribute(CSS.Attribute.HEIGHT); + if (spans[Y_AXIS] != null) + { + spans[Y_AXIS].setFontBases(emBase, exBase); + } } /** @@ -503,7 +519,7 @@ public class ImageView extends View { AttributeSet atts = getAttributes(); // Fetch width. - Length l = (Length) atts.getAttribute(CSS.Attribute.WIDTH); + Length l = spans[X_AXIS]; if (l != null) { newW = (int) l.getValue(); @@ -514,7 +530,7 @@ public class ImageView extends View newW = newIm.getWidth(observer); } // Fetch height. - l = (Length) atts.getAttribute(CSS.Attribute.HEIGHT); + l = spans[Y_AXIS]; if (l != null) { newH = (int) l.getValue(); diff --git a/javax/swing/text/html/ParagraphView.java b/javax/swing/text/html/ParagraphView.java index 8443515d3..d149627ff 100644 --- a/javax/swing/text/html/ParagraphView.java +++ b/javax/swing/text/html/ParagraphView.java @@ -153,8 +153,15 @@ public class ParagraphView (short) painter.getInset(BOTTOM, this), (short) painter.getInset(RIGHT, this)); + StyleSheet ss = getStyleSheet(); + float emBase = ss.getEMBase(attributes); + float exBase = ss.getEXBase(attributes); cssWidth = (Length) attributes.getAttribute(CSS.Attribute.WIDTH); + if (cssWidth != null) + cssWidth.setFontBases(emBase, exBase); cssHeight = (Length) attributes.getAttribute(CSS.Attribute.WIDTH); + if (cssHeight != null) + cssHeight.setFontBases(emBase, exBase); } } diff --git a/javax/swing/text/html/StyleSheet.java b/javax/swing/text/html/StyleSheet.java index 27d69bf4b..1f3d14b5e 100644 --- a/javax/swing/text/html/StyleSheet.java +++ b/javax/swing/text/html/StyleSheet.java @@ -52,6 +52,8 @@ import java.awt.Font; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.geom.Rectangle2D; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -882,7 +884,37 @@ public class StyleSheet extends StyleContext style |= fStyle.getValue(); return new Font(family, style, realSize); } - + + /** + * Determines the EM base value based on the specified attributes. + * + * @param atts the attibutes + * + * @return the EM base value + */ + float getEMBase(AttributeSet atts) + { + Font font = getFont(atts); + FontRenderContext ctx = new FontRenderContext(null, false, false); + Rectangle2D bounds = font.getStringBounds("M", ctx); + return (float) bounds.getWidth(); + } + + /** + * Determines the EX base value based on the specified attributes. + * + * @param atts the attibutes + * + * @return the EX base value + */ + float getEXBase(AttributeSet atts) + { + Font font = getFont(atts); + FontRenderContext ctx = new FontRenderContext(null, false, false); + Rectangle2D bounds = font.getStringBounds("x", ctx); + return (float) bounds.getHeight(); + } + /** * Resolves the fontsize for a given set of attributes. * @@ -1120,49 +1152,75 @@ public class StyleSheet extends StyleContext */ 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); if (l != null) - leftInset = l.getValue(); - else if (as.getAttribute(StyleConstants.NameAttribute) == HTML.Tag.UL) - System.err.println("UL margin left value: " + l + " atts: " + as); + { + l.setFontBases(emBase, exBase); + leftInset = l.getValue(); + } l = (Length) as.getAttribute(CSS.Attribute.MARGIN_RIGHT); if (l != null) - rightInset = l.getValue(); + { + l.setFontBases(emBase, exBase); + rightInset = l.getValue(); + } l = (Length) as.getAttribute(CSS.Attribute.MARGIN_TOP); if (l != null) - topInset = l.getValue(); + { + l.setFontBases(emBase, exBase); + topInset = l.getValue(); + } l = (Length) as.getAttribute(CSS.Attribute.MARGIN_BOTTOM); if (l != null) - bottomInset = l.getValue(); + { + 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) - leftPadding = l.getValue(); + { + l.setFontBases(emBase, exBase); + leftPadding = l.getValue(); + } l = (Length) as.getAttribute(CSS.Attribute.PADDING_RIGHT); if (l != null) - rightPadding = l.getValue(); + { + l.setFontBases(emBase, exBase); + rightPadding = l.getValue(); + } l = (Length) as.getAttribute(CSS.Attribute.PADDING_TOP); if (l != null) - topPadding = l.getValue(); + { + l.setFontBases(emBase, exBase); + topPadding = l.getValue(); + } l = (Length) as.getAttribute(CSS.Attribute.PADDING_BOTTOM); if (l != null) - bottomPadding = l.getValue(); + { + l.setFontBases(emBase, exBase); + bottomPadding = l.getValue(); + } // Determine border. - border = new CSSBorder(as); + border = new CSSBorder(as, ss); // Determine background. background = ss.getBackground(as); diff --git a/javax/swing/text/html/TableView.java b/javax/swing/text/html/TableView.java index 971d54cb6..c142462bc 100644 --- a/javax/swing/text/html/TableView.java +++ b/javax/swing/text/html/TableView.java @@ -254,6 +254,11 @@ class TableView */ Length[] columnWidths; + /** + * The table width. + */ + private Length width; + /** * Indicates if the grid setup is ok. */ @@ -358,13 +363,11 @@ class TableView r = super.calculateMinorAxisRequirements(axis, r); // Try to set the CSS width if it fits. - AttributeSet atts = getAttributes(); - Length l = (Length) atts.getAttribute(CSS.Attribute.WIDTH); - if (l != null) + if (width != null) { - int width = (int) l.getValue(); - if (r.minimum < width) - r.minimum = width; + int w = (int) width.getValue(); + if (r.minimum < w) + r.minimum = w; } // Adjust requirements when we have cell spacing. @@ -373,6 +376,7 @@ class TableView r.preferred += adjust; // Apply the alignment. + AttributeSet atts = getAttributes(); Object o = atts.getAttribute(CSS.Attribute.TEXT_ALIGN); r.alignment = 0.0F; if (o != null) @@ -665,6 +669,10 @@ class TableView { if (! gridValid) { + AttributeSet atts = getAttributes(); + StyleSheet ss = getStyleSheet(); + float emBase = ss.getEMBase(atts); + float exBase = ss.getEXBase(atts); int maxColumns = 0; int numRows = getViewCount(); for (int r = 0; r < numRows; r++) @@ -697,7 +705,10 @@ class TableView cv.getAttributes().getAttribute(CSS.Attribute.WIDTH); if (o != null && columnWidths[colIndex] == null && o instanceof Length) - columnWidths[colIndex]= (Length) o; + { + columnWidths[colIndex]= (Length) o; + columnWidths[colIndex].setFontBases(emBase, exBase); + } colIndex += cv.colSpan; } } @@ -741,12 +752,23 @@ class TableView private void setPropertiesFromAttributes() { // Fetch and parse cell spacing. - Object o = getAttributes().getAttribute(CSS.Attribute.BORDER_SPACING); + AttributeSet atts = getAttributes(); + StyleSheet ss = getStyleSheet(); + float emBase = ss.getEMBase(atts); + float exBase = ss.getEXBase(atts); + Object o = atts.getAttribute(CSS.Attribute.BORDER_SPACING); if (o != null && o instanceof Length) { Length l = (Length) o; + l.setFontBases(emBase, exBase); cellSpacing = (int) l.getValue(); } + o = atts.getAttribute(CSS.Attribute.WIDTH); + if (o != null && o instanceof Length) + { + width = (Length) o; + width.setFontBases(emBase, exBase); + } } /** -- cgit v1.2.1