diff options
author | Roman Kennke <roman@kennke.org> | 2006-12-03 23:42:33 +0000 |
---|---|---|
committer | Roman Kennke <roman@kennke.org> | 2006-12-03 23:42:33 +0000 |
commit | ef6b84aade6d448833cd6803e72298d2f6a46e28 (patch) | |
tree | 547680ac350161d39ccca44d4f9b2059a2aedc87 /javax | |
parent | 0f9ff258ee247db5f3e60be53caf3a3c2a076e5a (diff) | |
download | classpath-ef6b84aade6d448833cd6803e72298d2f6a46e28.tar.gz |
2006-12-04 Roman Kennke <kennke@aicas.com>
* javax/swing/text/BoxView.java
(paint): Replaced painting algorithm with more simple and more
reliable painting of the box.
* javax/swing/text/html/BlockView.java
(PositionInfo): New inner class. Stores additional CSS positioning
information.
(positionInfo): New field.
(BlockView): Initialize positionInfo field.
(fetchLayoutInfo): New helper method. Fetches additional
CSS positioning information.
(layoutMajorAxis): Perform additional CSS layout.
(layoutMinorAxis): Perform additional CSS layout.
(positionView): New helper method.
(replace): Overridden to fetch additional layout information.
* javax/swing/text/html/CSS.java
(Attribute.POSITION): New field.
(Attribute.LEFT): New field.
(Attribute.RIGHT): New field.
(Attribute.TOP): New field.
(Attribute.BOTTOM): New field.
(getValue): Create Length for left, right, top and bottom
attributes.
Diffstat (limited to 'javax')
-rw-r--r-- | javax/swing/text/BoxView.java | 89 | ||||
-rw-r--r-- | javax/swing/text/html/BlockView.java | 250 | ||||
-rw-r--r-- | javax/swing/text/html/CSS.java | 16 |
3 files changed, 270 insertions, 85 deletions
diff --git a/javax/swing/text/BoxView.java b/javax/swing/text/BoxView.java index 72bc07e75..0754d9b9b 100644 --- a/javax/swing/text/BoxView.java +++ b/javax/swing/text/BoxView.java @@ -285,89 +285,14 @@ public class BoxView // This returns a cached instance. alloc = getInsideAllocation(alloc); - // The following algorithm optimizes painting of a BoxView by taking - // advantage of the layout order of the box children. - // - // 1. It first searches a child that which's allocation is inside the clip. - // This is accomplished by an efficient binary search. This assumes - // that the children of the BoxView are laid out in the same order - // as their index within the view. This is true for the BoxView, but - // might not be the case for all subclasses. - // 2. Starting from the found view, it paints the children in both - // directions until the first view is hit that is outside the clip. - - // First we search a child view that is inside the clip. - - // Fetch the clip rect and calculate the center point of it. - clipRect = g.getClipBounds(clipRect); - int cX = clipRect.x + clipRect.width / 2; - int cY = clipRect.y + clipRect.height / 2; - - int viewCount = getViewCount(); - int up = viewCount; - int low = 0; - int mid = (up - low) / 2; - View start = getView(mid); - - int newMid; - // Use another cached instance here to avoid allocations during - // painting. - tmpRect.setBounds(alloc); - // This modifies tmpRect. - childAllocation(mid, tmpRect); - while (! clipRect.intersects(tmpRect)) - { - if (isBefore(cX, cY, tmpRect)) - { - up = mid; - newMid = (up - low) / 2 + low; - mid = (newMid == mid) ? newMid - 1 : newMid; - } - else if (isAfter(cX, cY, tmpRect)) - { - low = mid; - newMid = (up - low) / 2 + low; - mid = (newMid == mid) ? newMid + 1 : newMid; - } - else - break; - if (mid >= 0 && mid < viewCount) - { - start = getView(mid); - tmpRect.setBounds(alloc); - childAllocation(mid, tmpRect); - } - else - break; - } - - if (mid >= 0 && mid < viewCount) + int count = getViewCount(); + for (int i = 0; i < count; i++) { - // Ok, we found one view that is inside the clip rect. Now paint the - // children before it that are inside the clip. - boolean inClip = true; - for (int i = mid - 1; i >= 0 && inClip; i--) - { - start = getView(i); - tmpRect.setBounds(alloc); - childAllocation(i, tmpRect); - inClip = clipRect.intersects(tmpRect); - if (inClip) - paintChild(g, tmpRect, i); - } - - // Now paint the found view and all views after it that lie inside the - // clip. - inClip = true; - for (int i = mid; i < viewCount && inClip; i++) - { - start = getView(i); - tmpRect.setBounds(alloc); - childAllocation(i, tmpRect); - inClip = clipRect.intersects(tmpRect); - if (inClip) - paintChild(g, tmpRect, i); - } + View child = getView(i); + tmpRect.setBounds(alloc); + childAllocation(i, tmpRect); + if (g.hitClip(tmpRect.x, tmpRect.y, tmpRect.width, tmpRect.height)) + paintChild(g, tmpRect, i); } } diff --git a/javax/swing/text/html/BlockView.java b/javax/swing/text/html/BlockView.java index 82bd8604e..9e4d9310d 100644 --- a/javax/swing/text/html/BlockView.java +++ b/javax/swing/text/html/BlockView.java @@ -44,6 +44,7 @@ import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Shape; +import java.util.HashMap; import javax.swing.SizeRequirements; import javax.swing.event.DocumentEvent; @@ -60,6 +61,81 @@ public class BlockView extends BoxView { /** + * Stores information about child positioning according to the + * CSS attributes position, left, right, top and bottom. + */ + private static class PositionInfo + { + // TODO: Use enums when available. + + /** + * Static positioning. This is the default and is thus rarely really + * used. + */ + static final int STATIC = 0; + + /** + * Relative positioning. The box is teaked relative to its static + * computed bounds. + */ + static final int RELATIVE = 1; + + /** + * Absolute positioning. The box is moved relative to the parent's box. + */ + static final int ABSOLUTE = 2; + + /** + * Like ABSOLUTE, with some fixation against the viewport (not yet + * implemented). + */ + static final int FIXED = 3; + + /** + * The type according to the constants of this class. + */ + int type; + + /** + * The left constraint, null if not set. + */ + Length left; + + /** + * The right constraint, null if not set. + */ + Length right; + + /** + * The top constraint, null if not set. + */ + Length top; + + /** + * The bottom constraint, null if not set. + */ + Length bottom; + + /** + * Creates a new PositionInfo object. + * + * @param typ the type to set + * @param l the left constraint + * @param r the right constraint + * @param t the top constraint + * @param b the bottom constraint + */ + PositionInfo(int typ, Length l, Length r, Length t, Length b) + { + type = typ; + left = l; + right = r; + top = t; + bottom = b; + } + } + + /** * The attributes for this view. */ private AttributeSet attributes; @@ -77,6 +153,11 @@ public class BlockView extends BoxView private Length[] cssSpans; /** + * Stores additional CSS layout information. + */ + private HashMap positionInfo; + + /** * Creates a new view that represents an html box. * This can be used for a number of elements. * @@ -87,6 +168,7 @@ public class BlockView extends BoxView { super(elem, axis); cssSpans = new Length[2]; + positionInfo = new HashMap(); } /** @@ -283,6 +365,102 @@ public class BlockView extends BoxView offsets[i] = 0; spans[i] = Math.max(min, targetSpan); } + + // Adjust according to CSS position info. + positionView(targetSpan, axis, i, offsets, spans); + } + } + + /** + * Overridden to perform additional CSS layout (absolute/relative + * positioning). + */ + protected void layoutMajorAxis(int targetSpan, int axis, + int[] offsets, int[] spans) + { + super.layoutMajorAxis(targetSpan, axis, offsets, spans); + + // Adjust according to CSS position info. + int viewCount = getViewCount(); + for (int i = 0; i < viewCount; i++) + { + positionView(targetSpan, axis, i, offsets, spans); + } + } + + /** + * Positions a view according to any additional CSS constraints. + * + * @param targetSpan the target span + * @param axis the axis + * @param i the index of the view + * @param offsets the offsets get placed here + * @param spans the spans get placed here + */ + private void positionView(int targetSpan, int axis, int i, int[] offsets, + int[] spans) + { + View view = getView(i); + PositionInfo pos = (PositionInfo) positionInfo.get(view); + if (pos != null) + { + int p0 = -1; + int p1 = -1; + if (axis == X_AXIS) + { + Length l = pos.left; + if (l != null) + p0 = (int) l.getValue(targetSpan); + l = pos.right; + if (l != null) + p1 = (int) l.getValue(targetSpan); + } + else + { + Length l = pos.top; + if (l != null) + p0 = (int) l.getValue(targetSpan); + l = pos.bottom; + if (l != null) + p1 = (int) l.getValue(targetSpan); + } + if (pos.type == PositionInfo.ABSOLUTE + || pos.type == PositionInfo.FIXED) + { + if (p0 != -1) + { + offsets[i] = p0; + if (p1 != -1) + { + // Overrides computed width. (Possibly overconstrained + // when the width attribute was set too.) + spans[i] = targetSpan - p1 - offsets[i]; + } + } + else if (p1 != -1) + { + // Preserve any computed width. + offsets[i] = targetSpan - p1 - spans[i]; + } + } + else if (pos.type == PositionInfo.RELATIVE) + { + if (p0 != -1) + { + offsets[i] += p0; + if (p1 != -1) + { + // Overrides computed width. (Possibly overconstrained + // when the width attribute was set too.) + spans[i] = spans[i] - p0 - p1 - offsets[i]; + } + } + else if (p1 != -1) + { + // Preserve any computed width. + offsets[i] -= p1; + } + } } } @@ -305,7 +483,7 @@ public class BlockView extends BoxView painter.paint(g, rect.x, rect.y, rect.width, rect.height, this); super.paint(g, a); } - + /** * Fetches the attributes to use when painting. * @@ -469,4 +647,74 @@ public class BlockView extends BoxView HTMLDocument doc = (HTMLDocument) getDocument(); return doc.getStyleSheet(); } + + /** + * Overridden to fetch additional CSS layout information. + */ + public void replace(int offset, int length, View[] views) + { + // First remove unneeded stuff. + for (int i = 0; i < length; i++) + { + View child = getView(i + offset); + positionInfo.remove(child); + } + + // Call super to actually replace the views. + super.replace(offset, length, views); + + // Now fetch the position infos for the new views. + for (int i = 0; i < views.length; i++) + { + fetchLayoutInfo(views[i]); + } + } + + /** + * Fetches and stores the layout info for the specified view. + * + * @param view the view for which the layout info is stored + */ + private void fetchLayoutInfo(View view) + { + AttributeSet atts = view.getAttributes(); + Object o = atts.getAttribute(CSS.Attribute.POSITION); + if (o != null && o instanceof String && ! o.equals("static")) + { + int type; + if (o.equals("relative")) + type = PositionInfo.RELATIVE; + else if (o.equals("absolute")) + type = PositionInfo.ABSOLUTE; + else if (o.equals("fixed")) + type = PositionInfo.FIXED; + else + type = PositionInfo.STATIC; + + if (type != PositionInfo.STATIC) + { + StyleSheet ss = getStyleSheet(); + float emBase = ss.getEMBase(atts); + float exBase = ss.getEXBase(atts); + Length left = (Length) atts.getAttribute(CSS.Attribute.LEFT); + if (left != null) + left.setFontBases(emBase, exBase); + Length right = (Length) atts.getAttribute(CSS.Attribute.RIGHT); + if (right != null) + right.setFontBases(emBase, exBase); + Length top = (Length) atts.getAttribute(CSS.Attribute.TOP); + if (top != null) + top.setFontBases(emBase, exBase); + Length bottom = (Length) atts.getAttribute(CSS.Attribute.BOTTOM); + if (bottom != null) + bottom.setFontBases(emBase, exBase); + if (left != null || right != null || top != null || bottom != null) + { + PositionInfo pos = new PositionInfo(type, left, right, top, + bottom); + positionInfo.put(view, pos); + } + } + } + } } diff --git a/javax/swing/text/html/CSS.java b/javax/swing/text/html/CSS.java index 0d1eeb762..294d47fb2 100644 --- a/javax/swing/text/html/CSS.java +++ b/javax/swing/text/html/CSS.java @@ -418,7 +418,17 @@ public class CSS implements Serializable new Attribute("border-right-color", false, null); static final Attribute BORDER_SPACING = new Attribute("border-spacing", false, null); - + static final Attribute POSITION = + new Attribute("position", false, null); + static final Attribute LEFT = + new Attribute("left", false, null); + static final Attribute RIGHT = + new Attribute("right", false, null); + static final Attribute TOP = + new Attribute("top", false, null); + static final Attribute BOTTOM = + new Attribute("bottom", false, null); + /** * The attribute string. */ @@ -522,7 +532,9 @@ public class CSS implements Serializable || att == Attribute.HEIGHT || att == Attribute.PADDING || att == Attribute.PADDING_BOTTOM || att == Attribute.PADDING_LEFT || att == Attribute.PADDING_RIGHT - || att == Attribute.PADDING_TOP) + || att == Attribute.PADDING_TOP + || att == Attribute.LEFT || att == Attribute.RIGHT + || att == Attribute.TOP || att == Attribute.BOTTOM) o = new Length(v); else if (att == Attribute.BORDER_WIDTH || att == Attribute.BORDER_TOP_WIDTH || att == Attribute.BORDER_LEFT_WIDTH |