summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Kennke <roman@kennke.org>2006-12-03 23:42:33 +0000
committerRoman Kennke <roman@kennke.org>2006-12-03 23:42:33 +0000
commitef6b84aade6d448833cd6803e72298d2f6a46e28 (patch)
tree547680ac350161d39ccca44d4f9b2059a2aedc87
parent0f9ff258ee247db5f3e60be53caf3a3c2a076e5a (diff)
downloadclasspath-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.
-rw-r--r--ChangeLog25
-rw-r--r--javax/swing/text/BoxView.java89
-rw-r--r--javax/swing/text/html/BlockView.java250
-rw-r--r--javax/swing/text/html/CSS.java16
4 files changed, 295 insertions, 85 deletions
diff --git a/ChangeLog b/ChangeLog
index 269a566fc..d80c84181 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,30 @@
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.
+
+2006-12-04 Roman Kennke <kennke@aicas.com>
+
* gnu/javax/swing/text/html/parser/support/Parser.java
(Sgml): Consume any whitespace that immediately follows
and sgml insertion.
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