Index: javax/swing/text/DefaultStyledDocument.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultStyledDocument.java,v
retrieving revision 1.9
diff -u -r1.9 DefaultStyledDocument.java
--- javax/swing/text/DefaultStyledDocument.java 13 Sep 2005 23:44:50 -0000 1.9
+++ javax/swing/text/DefaultStyledDocument.java 14 Sep 2005 21:21:09 -0000
@@ -1108,11 +1108,11 @@
// joined with the previous element.
if (specs.size() == 0)
{
- if (attr.isEqual(prev.getAttributes()))
+ if (prev.getAttributes().isEqual(attr))
spec.setDirection(ElementSpec.JoinPreviousDirection);
}
// Check if we could probably be joined with the next element.
- else if (attr.isEqual(next.getAttributes()))
+ else if (next.getAttributes().isEqual(attr))
spec.setDirection(ElementSpec.JoinNextDirection);
specs.add(spec);
Index: javax/swing/text/GlyphView.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/GlyphView.java,v
retrieving revision 1.6
diff -u -r1.6 GlyphView.java
--- javax/swing/text/GlyphView.java 13 Sep 2005 23:14:11 -0000 1.6
+++ javax/swing/text/GlyphView.java 14 Sep 2005 21:21:10 -0000
@@ -431,8 +431,13 @@
*/
public int getBoundedPosition(GlyphView v, int p0, float x, float len)
{
- // TODO: Implement this properly.
- throw new AssertionError("Not yet implemented.");
+ TabExpander te = v.getTabExpander();
+ Segment txt = v.getText(p0, v.getEndOffset());
+ Font font = v.getFont();
+ FontMetrics fm = v.getContainer().getFontMetrics(font);
+ int pos = Utilities.getTabbedTextOffset(txt, fm, (int) x,
+ (int) (x + len), te, p0, false);
+ return pos;
}
/**
@@ -446,10 +451,15 @@
*
* @return the model location that represents the specified view location
*/
- public int viewToModel(GlyphView v, float x, float y, Shape a, Bias[] biasRet)
+ public int viewToModel(GlyphView v, float x, float y, Shape a,
+ Bias[] biasRet)
{
- // TODO: Implement this properly.
- throw new AssertionError("Not yet implemented.");
+ Rectangle b = a.getBounds();
+ assert b.contains(x, y) : "The coordinates are expected to be within the "
+ + "view's bounds: x=" + x + ", y=" + y
+ + "a=" + a;
+ int pos = getBoundedPosition(v, v.getStartOffset(), b.x, x - b.x);
+ return pos;
}
}
@@ -550,7 +560,6 @@
View parent = getParent();
if (parent instanceof TabExpander)
tabEx = (TabExpander) parent;
- // TODO: Figure out how to determine the x parameter.
span = painter.getSpan(this, getStartOffset(), getEndOffset(),
tabEx, 0.F);
}
@@ -611,12 +620,11 @@
*/
public TabExpander getTabExpander()
{
- // TODO: Figure out if this is correct.
TabExpander te = null;
View parent = getParent();
- if (parent instanceof ParagraphView)
- te = (ParagraphView) parent;
+ if (parent instanceof TabExpander)
+ te = (TabExpander) parent;
return te;
}
@@ -664,18 +672,6 @@
}
/**
- * Returns the starting offset in the document model of the portion
- * of text that this view is responsible for.
- *
- * @return the starting offset in the document model of the portion
- * of text that this view is responsible for
- */
- public int getBeginIndex()
- {
- return getElement().getStartOffset();
- }
-
- /**
* Returns the start offset in the document model of the portion
* of text that this view is responsible for.
*
@@ -895,40 +891,113 @@
if (goodBreakLocation != BreakIterator.DONE)
breakLocation = goodBreakLocation;
- GlyphView brokenView = (GlyphView) clone();
- brokenView.startOffset = p0;
- brokenView.endOffset = breakLocation;
+ View brokenView = createFragment(p0, breakLocation);
return brokenView;
}
+ /**
+ * Determines how well the specified view location is suitable for inserting
+ * a line break. If axis
is View.Y_AXIS
, then
+ * this method forwards to the superclass, if axis
is
+ * View.X_AXIS
then this method returns
+ * address@hidden View#ExcellentBreakWeight} if there is a suitable break location
+ * (usually whitespace) within the specified view span, or
+ * address@hidden View#GoodBreakWeight} if not.
+ *
+ * @param axis the axis along which the break weight is requested
+ * @param pos the starting view location
+ * @param len the length of the span at which the view should be broken
+ *
+ * @return the break weight
+ */
public int getBreakWeight(int axis, float pos, float len)
{
- // FIXME: Implement me.
- throw new AssertionError("Not yet implemented.");
+ int weight;
+ if (axis == Y_AXIS)
+ weight = super.getBreakWeight(axis, pos, len);
+ else
+ {
+ // Determine the model locations at pos and pos + len.
+ int spanX = (int) getPreferredSpan(X_AXIS);
+ int spanY = (int) getPreferredSpan(Y_AXIS);
+ Rectangle dummyAlloc = new Rectangle(0, 0, spanX, spanY);
+ Position.Bias[] biasRet = new Position.Bias[1];
+ int offset1 = viewToModel(pos, spanY / 2, dummyAlloc, biasRet);
+ int offset2 = viewToModel(pos, spanY / 2, dummyAlloc, biasRet);
+ Segment txt = getText(offset1, offset2);
+ BreakIterator lineBreaker = BreakIterator.getLineInstance();
+ lineBreaker.setText(txt);
+ int breakLoc = lineBreaker.previous();
+ if (breakLoc == offset1)
+ weight = View.BadBreakWeight;
+ else if(breakLoc == BreakIterator.DONE)
+ weight = View.GoodBreakWeight;
+ else
+ weight = View.ExcellentBreakWeight;
+ }
+ return weight;
}
+ /**
+ * Receives notification that some text attributes have changed within the
+ * text fragment that this view is responsible for. This calls
+ * address@hidden View#preferenceChanged(View, boolean, boolean)} on the parent for
+ * both width and height.
+ *
+ * @param e the document event describing the change; not used here
+ * @param a the view allocation on screen; not used here
+ * @param vf the view factory; not used here
+ */
public void changedUpdate(DocumentEvent e, Shape a, ViewFactory vf)
{
- // FIXME: Implement me.
- throw new AssertionError("Not yet implemented.");
+ getParent().preferenceChanged(this, true, true);
}
+ /**
+ * Receives notification that some text has been inserted within the
+ * text fragment that this view is responsible for. This calls
+ * address@hidden View#preferenceChanged(View, boolean, boolean)} on the parent for
+ * width.
+ *
+ * @param e the document event describing the change; not used here
+ * @param a the view allocation on screen; not used here
+ * @param vf the view factory; not used here
+ */
public void insertUpdate(DocumentEvent e, Shape a, ViewFactory vf)
{
- // FIXME: Implement me.
- throw new AssertionError("Not yet implemented.");
+ getParent().preferenceChanged(this, true, false);
}
+ /**
+ * Receives notification that some text has been removed within the
+ * text fragment that this view is responsible for. This calls
+ * address@hidden View#preferenceChanged(View, boolean, boolean)} on the parent for
+ * width.
+ *
+ * @param e the document event describing the change; not used here
+ * @param a the view allocation on screen; not used here
+ * @param vf the view factory; not used here
+ */
public void removeUpdate(DocumentEvent e, Shape a, ViewFactory vf)
{
- // FIXME: Implement me.
- throw new AssertionError("Not yet implemented.");
+ getParent().preferenceChanged(this, true, false);
}
+ /**
+ * Creates a fragment view of this view that starts at p0
and
+ * ends at p1
.
+ *
+ * @param p0 the start location for the fragment view
+ * @param p1 the end location for the fragment view
+ *
+ * @return the fragment view
+ */
public View createFragment(int p0, int p1)
{
- // FIXME: Implement me.
- throw new AssertionError("Not yet implemented.");
+ GlyphView fragment = (GlyphView) clone();
+ fragment.startOffset = p0;
+ fragment.endOffset = p1;
+ return fragment;
}
/**
Index: javax/swing/text/Utilities.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/Utilities.java,v
retrieving revision 1.7
diff -u -r1.7 Utilities.java
--- javax/swing/text/Utilities.java 2 Jul 2005 20:32:51 -0000 1.7
+++ javax/swing/text/Utilities.java 14 Sep 2005 21:21:10 -0000
@@ -195,4 +195,89 @@
return maxWidth;
}
+
+ /**
+ * Provides a facility to map screen coordinates into a model location. For a
+ * given text fragment and start location within this fragment, this method
+ * determines the model location so that the resulting fragment fits best
+ * into the span [x0, x]
.
+ *
+ * The parameter round
controls which model location is returned
+ * if the view coordinates are on a character: If round
is
+ * true
, then the result is rounded up to the next character, so
+ * that the resulting fragment is the smallest fragment that is larger than
+ * the specified span. If round
is false
, then the
+ * resulting fragment is the largest fragment that is smaller than the
+ * specified span.
+ *
+ * @param s the text segment
+ * @param fm the font metrics to use
+ * @param x0 the starting screen location
+ * @param x the target screen location at which the requested fragment should
+ * end
+ * @param te the tab expander to use; if this is null
, TABs are
+ * expanded to one space character
+ * @param p0 the starting model location
+ * @param round if true
round up to the next location, otherwise
+ * round down to the current location
+ *
+ * @return the model location, so that the resulting fragment fits within the
+ * specified span
+ */
+ public static final int getTabbedTextOffset(Segment s, FontMetrics fm, int x0,
+ int x, TabExpander te, int p0,
+ boolean round)
+ {
+ // At the end of the for loop, this holds the requested model location
+ int pos;
+ int currentX = x0;
+ for (pos = p0; pos < s.getEndIndex(); pos++)
+ {
+ char nextChar = s.array[pos];
+ if (nextChar != '\n')
+ currentX += fm.charWidth(nextChar);
+ else
+ {
+ if (te == null)
+ currentX += fm.charWidth(' ');
+ else
+ currentX = (int) te.nextTabStop(currentX, pos);
+ }
+ if (currentX >= x)
+ {
+ if (! round)
+ pos--;
+ break;
+ }
+ }
+ return pos;
+ }
+
+ /**
+ * Provides a facility to map screen coordinates into a model location. For a
+ * given text fragment and start location within this fragment, this method
+ * determines the model location so that the resulting fragment fits best
+ * into the span [x0, x]
.
+ *
+ * This method rounds up to the next location, so that the resulting fragment
+ * will be the smallest fragment of the text, that is greater than the
+ * specified span.
+ *
+ * @param s the text segment
+ * @param fm the font metrics to use
+ * @param x0 the starting screen location
+ * @param x the target screen location at which the requested fragment should
+ * end
+ * @param te the tab expander to use; if this is null
, TABs are
+ * expanded to one space character
+ * @param p0 the starting model location
+ *
+ * @return the model location, so that the resulting fragment fits within the
+ * specified span
+ */
+ public static final int getTabbedTextOffset(Segment s, FontMetrics fm, int x0,
+ int x, TabExpander te, int p0)
+ {
+ return getTabbedTextOffset(s, fm, x0, x, te, p0, true);
+ }
}