diff options
author | Roman Kennke <roman@kennke.org> | 2006-12-01 14:43:42 +0000 |
---|---|---|
committer | Roman Kennke <roman@kennke.org> | 2006-12-01 14:43:42 +0000 |
commit | 5bce0abfef6817e4299bc0640baf46b5f873d530 (patch) | |
tree | 07707896fdf219b9fac9903a491fd67beaa0e22f /javax/swing/text/html | |
parent | 73ee7fab7219cb0edb4ded57f73dea804846d6b2 (diff) | |
download | classpath-5bce0abfef6817e4299bc0640baf46b5f873d530.tar.gz |
2006-11-30 Roman Kennke <kennke@aicas.com>
* 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.
Diffstat (limited to 'javax/swing/text/html')
-rw-r--r-- | javax/swing/text/html/BlockView.java | 17 | ||||
-rw-r--r-- | javax/swing/text/html/CSSBorder.java | 19 | ||||
-rw-r--r-- | javax/swing/text/html/HTMLDocument.java | 73 | ||||
-rw-r--r-- | javax/swing/text/html/ImageView.java | 56 | ||||
-rw-r--r-- | javax/swing/text/html/ParagraphView.java | 7 | ||||
-rw-r--r-- | javax/swing/text/html/StyleSheet.java | 82 | ||||
-rw-r--r-- | javax/swing/text/html/TableView.java | 38 |
7 files changed, 212 insertions, 80 deletions
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 * */ @@ -697,16 +702,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(); @@ -1652,6 +1648,34 @@ public class HTMLDocument extends DefaultStyledDocument } /** + * 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 @@ -111,6 +111,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. * * @param element the element, represented by this image view. @@ -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 @@ -255,6 +255,11 @@ class TableView Length[] columnWidths; /** + * The table width. + */ + private Length width; + + /** * Indicates if the grid setup is ok. */ boolean gridValid; @@ -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); + } } /** |