Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 78759 Details for
Bug 194278
Ability to customize FlowUtilities used by TextFlow and ParagraphTextLayout
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
final patch
Bugzilla194278.txt (text/plain), 40.52 KB, created by
Cherie Revells
on 2007-09-19 11:18:35 EDT
(
hide
)
Description:
final patch
Filename:
MIME Type:
Creator:
Cherie Revells
Created:
2007-09-19 11:18:35 EDT
Size:
40.52 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.draw2d >Index: src/org/eclipse/draw2d/text/FlowUtilities.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/text/FlowUtilities.java,v >retrieving revision 1.56 >diff -u -r1.56 FlowUtilities.java >--- src/org/eclipse/draw2d/text/FlowUtilities.java 4 Apr 2006 12:43:12 -0000 1.56 >+++ src/org/eclipse/draw2d/text/FlowUtilities.java 19 Sep 2007 15:03:44 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2005 IBM Corporation and others. >+ * Copyright (c) 2000, 2007 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -15,24 +15,30 @@ > > import org.eclipse.swt.SWT; > import org.eclipse.swt.graphics.Font; >+import org.eclipse.swt.graphics.Rectangle; > import org.eclipse.swt.graphics.TextLayout; > import org.eclipse.swt.widgets.Display; > > import org.eclipse.draw2d.FigureUtilities; >+import org.eclipse.draw2d.TextUtilities; > > /** > * Utility class for FlowFigures. > * @author hudsonr > * @since 2.1 > */ >-class FlowUtilities >- extends FigureUtilities >+public class FlowUtilities > { > > interface LookAhead { > int getWidth(); > } >-private static int ELLIPSIS_SIZE; >+ >+/** >+ * a singleton default instance >+ */ >+public static FlowUtilities INSTANCE = new FlowUtilities(); >+ > private static final BreakIterator INTERNAL_LINE_BREAK = BreakIterator.getLineInstance(); > private static TextLayout layout; > >@@ -61,10 +67,21 @@ > return Math.min(macNL, unixNL); > } > >-private static float getAverageCharWidth(TextFragmentBox fragment, Font font) { >- if (fragment.getWidth() > 0 && fragment.length != 0) >- return fragment.getWidth() / (float)fragment.length; >- return getFontMetrics(font).getAverageCharWidth(); >+/** >+ * Gets the average character width. >+ * >+ * @param fragment the supplied TextFragmentBox to use for calculation. >+ * if the length is 0 or if the width is or below 0, >+ * the average character width is taken from standard >+ * font metrics. >+ * @param font the font to use in case the TextFragmentBox conditions >+ * above are true. >+ * @return the average character width >+ */ >+protected float getAverageCharWidth(TextFragmentBox fragment, Font font) { >+ if (fragment.getWidth() > 0 && fragment.length != 0) >+ return fragment.getWidth() / (float)fragment.length; >+ return FigureUtilities.getFontMetrics(font).getAverageCharWidth(); > } > > static int getBorderAscent(InlineFlow owner) { >@@ -129,34 +146,28 @@ > } > } > >-private static int measureString(TextFragmentBox frag, String string, int guess, Font font) { >- if (frag.requiresBidi()) { >- // The text and/or could have changed if the lookAhead was invoked. This will >- // happen at most once. >- TextLayout layout = getTextLayout(); >- layout.setText(string); >- layout.setFont(font); >- return layout.getBounds(0, guess - 1).width; >- } else >- return getStringDimension(string.substring(0, guess), font).x; >-} >- >-static void setupFragment(TextFragmentBox frag, Font f, String s) { >- if (frag.getWidth() == -1 || frag.isTruncated()) { >- int width; >- if (s.length() == 0 || frag.length == 0) >- width = 0; >- else if (frag.requiresBidi()) { >- TextLayout textLayout = getTextLayout(); >- textLayout.setFont(f); >- textLayout.setText(s); >- width = textLayout.getBounds(0, frag.length - 1).width; >- } else >- width = getStringDimension(s.substring(0, frag.length), f).x; >- if (frag.isTruncated()) >- width += ELLIPSIS_SIZE; >- frag.setWidth(width); >- } >+private int measureString(TextFragmentBox frag, String string, int guess, Font font) { >+ if (frag.requiresBidi()) { >+ // The text and/or could have changed if the lookAhead was invoked. This will >+ // happen at most once. >+ return getTextLayoutBounds(string, font, 0, guess - 1).width; >+ } else >+ return getTextUtilities().getStringExtents(string.substring(0, guess), font).width; >+} >+ >+protected void setupFragment(TextFragmentBox frag, Font f, String s) { >+ if (frag.getWidth() == -1 || frag.isTruncated()) { >+ int width; >+ if (s.length() == 0 || frag.length == 0) >+ width = 0; >+ else if (frag.requiresBidi()) { >+ width = getTextLayoutBounds(s, f, 0, frag.length - 1).width; >+ } else >+ width = getTextUtilities().getStringExtents(s.substring(0, frag.length), f).width; >+ if (frag.isTruncated()) >+ width += getEllipsisWidth(f); >+ frag.setWidth(width); >+ } > } > > /** >@@ -172,7 +183,7 @@ > * @return the number of characters that will fit in the given space; can be 0 (eg., when > * the first character of the given string is a newline) > */ >-public static int wrapFragmentInContext(TextFragmentBox frag, String string, >+protected int wrapFragmentInContext(TextFragmentBox frag, String string, > FlowContext context, LookAhead lookahead, Font font, int wrapping) { > frag.setTruncated(false); > int strLen = string.length(); >@@ -245,61 +256,59 @@ > continue; > } > >- if (guessSize <= availableWidth) { >- min = guess; >- frag.setWidth(guessSize); >- if (guessSize == availableWidth) >- max = guess + 1; >- } else >- max = guess; >- } >- >- int result = min; >- boolean continueOnLine = false; >- if (min == strLen) { >- //Everything fits >- if (string.charAt(strLen - 1) == ' ') { >- if (frag.getWidth() == -1) { >- frag.length = result; >- frag.setWidth(measureString(frag, string, result, font)); >- } >- if (lookahead.getWidth() > availableWidth - frag.getWidth()) { >- frag.length = result - 1; >- frag.setWidth(-1); >- } else >- frag.length = result; >- } else { >- continueOnLine = !canBreakAfter(string.charAt(strLen - 1)); >- frag.length = result; >- } >- } else if (min == firstDelimiter) { >- //move result past the delimiter >- frag.length = result; >- if (string.charAt(min) == '\r') { >- result++; >- if (++min < strLen && string.charAt(min) == '\n') >- result++; >- } else if (string.charAt(min) == '\n') >- result++; >- } else if (string.charAt(min) == ' ' >- || canBreakAfter(string.charAt(min - 1)) >- || INTERNAL_LINE_BREAK.isBoundary(min)) { >- frag.length = min; >- if (string.charAt(min) == ' ') >- result++; >- else if (string.charAt(min - 1) == ' ') { >- frag.length--; >- frag.setWidth(-1); >- } >- } else out: { >- // In the middle of an unbreakable offset >- result = INTERNAL_LINE_BREAK.preceding(min); >- if (result == 0) { >- switch (wrapping) { >- case ParagraphTextLayout.WORD_WRAP_TRUNCATE : >- ELLIPSIS_SIZE = FigureUtilities >- .getStringExtents(TextFlow.ELLIPSIS, font).width; >- int truncatedWidth = availableWidth - ELLIPSIS_SIZE; >+ if (guessSize <= availableWidth) { >+ min = guess; >+ frag.setWidth(guessSize); >+ if (guessSize == availableWidth) >+ max = guess + 1; >+ } else >+ max = guess; >+ } >+ >+ int result = min; >+ boolean continueOnLine = false; >+ if (min == strLen) { >+ //Everything fits >+ if (string.charAt(strLen - 1) == ' ') { >+ if (frag.getWidth() == -1) { >+ frag.length = result; >+ frag.setWidth(measureString(frag, string, result, font)); >+ } >+ if (lookahead.getWidth() > availableWidth - frag.getWidth()) { >+ frag.length = result - 1; >+ frag.setWidth(-1); >+ } else >+ frag.length = result; >+ } else { >+ continueOnLine = !canBreakAfter(string.charAt(strLen - 1)); >+ frag.length = result; >+ } >+ } else if (min == firstDelimiter) { >+ //move result past the delimiter >+ frag.length = result; >+ if (string.charAt(min) == '\r') { >+ result++; >+ if (++min < strLen && string.charAt(min) == '\n') >+ result++; >+ } else if (string.charAt(min) == '\n') >+ result++; >+ } else if (string.charAt(min) == ' ' >+ || canBreakAfter(string.charAt(min - 1)) >+ || INTERNAL_LINE_BREAK.isBoundary(min)) { >+ frag.length = min; >+ if (string.charAt(min) == ' ') >+ result++; >+ else if (string.charAt(min - 1) == ' ') { >+ frag.length--; >+ frag.setWidth(-1); >+ } >+ } else out: { >+ // In the middle of an unbreakable offset >+ result = INTERNAL_LINE_BREAK.preceding(min); >+ if (result == 0) { >+ switch (wrapping) { >+ case ParagraphTextLayout.WORD_WRAP_TRUNCATE : >+ int truncatedWidth = availableWidth - getEllipsisWidth(font); > if (truncatedWidth > 0) { > //$TODO this is very slow. It should be using avgCharWidth to go faster > while (min > 0) { >@@ -312,24 +321,56 @@ > } else > frag.length = 0; > frag.setTruncated(true); >- result = INTERNAL_LINE_BREAK.following(max - 1); >- break out; >+ result = INTERNAL_LINE_BREAK.following(max - 1); >+ break out; > >- default: >- result = min; >- break; >- } >- } >- frag.length = result; >- if (string.charAt(result - 1) == ' ') >- frag.length--; >- frag.setWidth(-1); >- } >- >- setupFragment(frag, font, string); >- context.addToCurrentLine(frag); >- context.setContinueOnSameLine(continueOnLine); >- return result; >+ default: >+ result = min; >+ break; >+ } >+ } >+ frag.length = result; >+ if (string.charAt(result - 1) == ' ') >+ frag.length--; >+ frag.setWidth(-1); >+ } >+ >+ setupFragment(frag, font, string); >+ context.addToCurrentLine(frag); >+ context.setContinueOnSameLine(continueOnLine); >+ return result; > } > >+/** >+ * @see TextLayout#getBounds() >+ */ >+protected Rectangle getTextLayoutBounds(String s, Font f, int start, int end) { >+ TextLayout textLayout = getTextLayout(); >+ textLayout.setFont(f); >+ textLayout.setText(s); >+ return textLayout.getBounds(start, end); >+} >+ >+/** >+ * Returns an instance of a <code>TextUtililities</code> class on which >+ * text calculations can be performed. Clients may override to customize. >+ * >+ * @return the <code>TextUtililities</code> instance >+ * @since 3.4 >+ */ >+protected TextUtilities getTextUtilities() { >+ return TextUtilities.INSTANCE; >+} >+ >+/** >+ * Gets the ellipsis width. >+ * >+ * @param font >+ * the font to be used in the calculation >+ * @return the width of the ellipsis >+ * @since 3.4 >+ */ >+private int getEllipsisWidth(Font font) { >+ return getTextUtilities().getStringExtents(TextFlow.ELLIPSIS, font).width; >+} > } >Index: src/org/eclipse/draw2d/text/TextFlow.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/text/TextFlow.java,v >retrieving revision 1.55 >diff -u -r1.55 TextFlow.java >--- src/org/eclipse/draw2d/text/TextFlow.java 14 Feb 2006 20:13:32 -0000 1.55 >+++ src/org/eclipse/draw2d/text/TextFlow.java 19 Sep 2007 15:03:44 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2005 IBM Corporation and others. >+ * Copyright (c) 2000, 2007 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -12,12 +12,11 @@ > > import org.eclipse.swt.SWT; > import org.eclipse.swt.graphics.Color; >-import org.eclipse.swt.graphics.FontMetrics; > import org.eclipse.swt.graphics.TextLayout; > > import org.eclipse.draw2d.ColorConstants; >-import org.eclipse.draw2d.FigureUtilities; > import org.eclipse.draw2d.Graphics; >+import org.eclipse.draw2d.TextUtilities; > import org.eclipse.draw2d.geometry.Dimension; > import org.eclipse.draw2d.geometry.Point; > import org.eclipse.draw2d.geometry.Rectangle; >@@ -95,7 +94,7 @@ > text = text.substring(1, index + 1); > > if (bidiInfo == null) >- width[0] += FlowUtilities.getStringExtents(text, getFont()).width; >+ width[0] += getTextUtilities().getStringExtents(text, getFont()).width; > else { > TextLayout textLayout = FlowUtilities.getTextLayout(); > textLayout.setFont(getFont()); >@@ -175,8 +174,7 @@ > } > > int getAscent() { >- FontMetrics fm = FigureUtilities.getFontMetrics(getFont()); >- return fm.getHeight() - fm.getDescent(); >+ return getTextUtilities().getAscent(getFont()); > } > > /** >@@ -267,7 +265,7 @@ > if (trailing && offset < box.length) > offset++; > String substring = getText().substring(box.offset, box.offset + offset); >- result.x = FigureUtilities.getStringExtents(substring, getFont()).width; >+ result.x = getTextUtilities().getStringExtents(substring, getFont()).width; > } else { > TextLayout layout = FlowUtilities.getTextLayout(); > layout.setFont(getFont()); >@@ -283,7 +281,7 @@ > } > > int getDescent() { >- return FigureUtilities.getFontMetrics(getFont()).getDescent(); >+ return getTextUtilities().getDescent(getFont()); > } > > /** >@@ -485,7 +483,7 @@ > g.getClip(Rectangle.SINGLETON); > int yStart = Rectangle.SINGLETON.y; > int yEnd = Rectangle.SINGLETON.bottom(); >- >+ > for (int i = 0; i < fragments.size(); i++) { > frag = (TextFragmentBox)fragments.get(i); > // g.drawLine(frag.getX(), frag.getLineRoot().getVisibleTop(), >@@ -499,7 +497,7 @@ > //Break loop at first non-visible fragment > if (yEnd < frag.getLineRoot().getVisibleTop()) > break; >- >+ > String draw = getBidiSubstring(frag, i); > > if (frag.isTruncated()) >@@ -629,4 +627,25 @@ > return Math.max(0, y - (box.getBaseline() + box.getLineRoot().getDescent())); > } > >+/** >+ * Gets the <code>FlowUtilities</code> instance to be used in measurement >+ * calculations. >+ * >+ * @return a <code>FlowUtilities</code> instance >+ * @since 3.2 >+ */ >+protected FlowUtilities getFlowUtilities() { >+ return FlowUtilities.INSTANCE; >+} >+ >+/** >+ * Gets the <code>TextUtilities</code> instance to be used in measurement >+ * calculations. >+ * >+ * @return a <code>TextUtilities</code> instance >+ * @since 3.2 >+ */ >+protected TextUtilities getTextUtilities() { >+ return TextUtilities.INSTANCE; >+} > } >\ No newline at end of file >Index: src/org/eclipse/draw2d/text/SimpleTextLayout.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/text/SimpleTextLayout.java,v >retrieving revision 1.10 >diff -u -r1.10 SimpleTextLayout.java >--- src/org/eclipse/draw2d/text/SimpleTextLayout.java 7 Sep 2005 21:34:54 -0000 1.10 >+++ src/org/eclipse/draw2d/text/SimpleTextLayout.java 19 Sep 2007 15:03:44 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2005 IBM Corporation and others. >+ * Copyright (c) 2000, 2007 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -21,9 +21,9 @@ > public class SimpleTextLayout extends TextLayout { > > private static final String[] DELIMITERS = { >- "\r\n", //$NON-NLS-1$ >- "\n", //$NON-NLS-1$ >- "\r"};//$NON-NLS-1$ >+ "\r\n", //$NON-NLS-1$ >+ "\n", //$NON-NLS-1$ >+ "\r"};//$NON-NLS-1$ > > private static int result; > private static int delimeterLength; >@@ -33,49 +33,50 @@ > * @param flow the TextFlow > */ > public SimpleTextLayout(TextFlow flow) { >- super (flow); >+ super (flow); > } > > /** > * @see org.eclipse.draw2d.text.FlowFigureLayout#layout() > */ > protected void layout() { >- TextFlow textFlow = (TextFlow)getFlowFigure(); >- String text = textFlow.getText(); >- List fragments = textFlow.getFragments(); >- Font font = textFlow.getFont(); >- TextFragmentBox fragment; >- int i = 0; >- int offset = 0; >- >- do { >- nextLineBreak(text, offset); >- fragment = getFragment(i++, fragments); >- fragment.length = result - offset; >- fragment.offset = offset; >- fragment.setWidth(-1); >- FlowUtilities.setupFragment(fragment, font, text); >- getContext().addToCurrentLine(fragment); >- getContext().endLine(); >- offset = result + delimeterLength; >- } while (offset < text.length()); >- //Remove the remaining unused fragments. >- while (i < fragments.size()) >- fragments.remove(i++); >+ TextFlow textFlow = (TextFlow)getFlowFigure(); >+ String text = textFlow.getText(); >+ List fragments = textFlow.getFragments(); >+ Font font = textFlow.getFont(); >+ TextFragmentBox fragment; >+ int i = 0; >+ int offset = 0; >+ FlowUtilities flowUtilities = textFlow.getFlowUtilities(); >+ >+ do { >+ nextLineBreak(text, offset); >+ fragment = getFragment(i++, fragments); >+ fragment.length = result - offset; >+ fragment.offset = offset; >+ fragment.setWidth(-1); >+ flowUtilities.setupFragment(fragment, font, text); >+ getContext().addToCurrentLine(fragment); >+ getContext().endLine(); >+ offset = result + delimeterLength; >+ } while (offset < text.length()); >+ //Remove the remaining unused fragments. >+ while (i < fragments.size()) >+ fragments.remove(i++); > } > > private int nextLineBreak(String text, int offset) { >- result = text.length(); >- delimeterLength = 0; >- int current; >- for (int i = 0; i < DELIMITERS.length; i++) { >- current = text.indexOf(DELIMITERS[i], offset); >- if (current != -1 && current < result) { >- result = current; >- delimeterLength = DELIMITERS[i].length(); >- } >- } >- return result; >+ result = text.length(); >+ delimeterLength = 0; >+ int current; >+ for (int i = 0; i < DELIMITERS.length; i++) { >+ current = text.indexOf(DELIMITERS[i], offset); >+ if (current != -1 && current < result) { >+ result = current; >+ delimeterLength = DELIMITERS[i].length(); >+ } >+ } >+ return result; > } > > } >Index: src/org/eclipse/draw2d/text/ParagraphTextLayout.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/text/ParagraphTextLayout.java,v >retrieving revision 1.31 >diff -u -r1.31 ParagraphTextLayout.java >--- src/org/eclipse/draw2d/text/ParagraphTextLayout.java 1 Jun 2005 19:56:30 -0000 1.31 >+++ src/org/eclipse/draw2d/text/ParagraphTextLayout.java 19 Sep 2007 15:03:44 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2005 IBM Corporation and others. >+ * Copyright (c) 2000, 2007 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -20,7 +20,7 @@ > * @since 2.1 > */ > public class ParagraphTextLayout >- extends TextLayout >+ extends TextLayout > { > > /** >@@ -48,23 +48,23 @@ > * @param flow the TextFlow > */ > public ParagraphTextLayout(TextFlow flow) { >- super(flow); >+ super(flow); > } > > /** > * Constructs the layout with the specified TextFlow and wrapping style. The wrapping > * style must be one of: > * <UL> >- * <LI>{@link #WORD_WRAP_HARD}</LI> >- * <LI>{@link #WORD_WRAP_SOFT}</LI> >- * <LI>{@link #WORD_WRAP_TRUNCATE}</LI> >+ * <LI>{@link #WORD_WRAP_HARD}</LI> >+ * <LI>{@link #WORD_WRAP_SOFT}</LI> >+ * <LI>{@link #WORD_WRAP_TRUNCATE}</LI> > * </UL> > * @param flow the textflow > * @param style the style of wrapping > */ > public ParagraphTextLayout(TextFlow flow, int style) { >- this(flow); >- wrappingStyle = style; >+ this(flow); >+ wrappingStyle = style; > } > > /** >@@ -75,133 +75,134 @@ > * @return the requested segment > */ > private String[] getSegments(String text, int levelInfo[]) { >- if (levelInfo.length == 1) >- return new String[] {text}; >- >- String result[] = new String[levelInfo.length / 2 + 1]; >- >- int i; >- int endOffset; >- int beginOffset = 0; >- >- for (i = 0; i < result.length - 1; i++) { >- endOffset = levelInfo[i * 2 + 1]; >- result[i] = text.substring(beginOffset, endOffset); >- beginOffset = endOffset; >- } >- endOffset = text.length(); >- result[i] = text.substring(beginOffset, endOffset); >- return result; >+ if (levelInfo.length == 1) >+ return new String[] {text}; >+ >+ String result[] = new String[levelInfo.length / 2 + 1]; >+ >+ int i; >+ int endOffset; >+ int beginOffset = 0; >+ >+ for (i = 0; i < result.length - 1; i++) { >+ endOffset = levelInfo[i * 2 + 1]; >+ result[i] = text.substring(beginOffset, endOffset); >+ beginOffset = endOffset; >+ } >+ endOffset = text.length(); >+ result[i] = text.substring(beginOffset, endOffset); >+ return result; > } > > class SegmentLookahead implements FlowUtilities.LookAhead { >- private int seg = -1; >- private String segs[]; >- private int[] width; >- private final int trailingBorderSize; >- SegmentLookahead(String segs[], int trailingBorderSize) { >- this.segs = segs; >- this.trailingBorderSize = trailingBorderSize; >- } >- public int getWidth() { >- if (width == null) { >- width = new int[1]; >- int startingIndex = seg + 1; >- TextFlow textFlow = (TextFlow)getFlowFigure(); >- >- if (startingIndex == segs.length) { >- width[0] += trailingBorderSize; >- getContext().getWidthLookahead(textFlow, width); >- } else { >- String rest = segs[startingIndex]; >- for (int k = startingIndex + 1; k < segs.length; k++) >- rest += segs[k]; >- if (!textFlow.addLeadingWordWidth(rest, width)) { >- width[0] += trailingBorderSize; >- getContext().getWidthLookahead(textFlow, width); >- } >- } >- } >- return width[0]; >- } >- public void setIndex(int value) { >- this.seg = value; >- width = null; >- } >+ private int seg = -1; >+ private String segs[]; >+ private int[] width; >+ private final int trailingBorderSize; >+ SegmentLookahead(String segs[], int trailingBorderSize) { >+ this.segs = segs; >+ this.trailingBorderSize = trailingBorderSize; >+ } >+ public int getWidth() { >+ if (width == null) { >+ width = new int[1]; >+ int startingIndex = seg + 1; >+ TextFlow textFlow = (TextFlow)getFlowFigure(); >+ >+ if (startingIndex == segs.length) { >+ width[0] += trailingBorderSize; >+ getContext().getWidthLookahead(textFlow, width); >+ } else { >+ String rest = segs[startingIndex]; >+ for (int k = startingIndex + 1; k < segs.length; k++) >+ rest += segs[k]; >+ if (!textFlow.addLeadingWordWidth(rest, width)) { >+ width[0] += trailingBorderSize; >+ getContext().getWidthLookahead(textFlow, width); >+ } >+ } >+ } >+ return width[0]; >+ } >+ public void setIndex(int value) { >+ this.seg = value; >+ width = null; >+ } > } > > /** > * @see org.eclipse.draw2d.text.FlowFigureLayout#layout() > */ > protected void layout() { >- TextFlow textFlow = (TextFlow)getFlowFigure(); >- int offset = 0; >- >- FlowContext context = getContext(); >- List fragments = textFlow.getFragments(); >- Font font = textFlow.getFont(); >- int fragIndex = 0; >- int advance = 0; >- >- TextFragmentBox fragment; >- int levelInfo[] = (textFlow.getBidiInfo() == null) >- ? new int[] {-1} >- : textFlow.getBidiInfo().levelInfo; >- >- String segment, segments[] = getSegments(textFlow.getText(), levelInfo); >- FlowBorder border = null; >- if (textFlow.getBorder() instanceof FlowBorder) >- border = (FlowBorder)textFlow.getBorder(); >- >- SegmentLookahead lookahead = new SegmentLookahead(segments, border == null ? 0 : border.getRightMargin()); >- int seg; >- >- if (border != null) { >- fragment = getFragment(fragIndex++, fragments); >- fragment.setBidiLevel(levelInfo[0]); >- fragment.setTruncated(false); >- fragment.offset = fragment.length = -1; >- fragment.setWidth(border.getLeftMargin() + border.getInsets(textFlow).left); >- if (context.getRemainingLineWidth() >- < fragment.getWidth() + lookahead.getWidth()) >- context.endLine(); >- context.addToCurrentLine(fragment); >- } >- >- for (seg = 0; seg < segments.length; seg++) { >- segment = segments[seg]; >- lookahead.setIndex(seg); >- >- do { >- fragment = getFragment(fragIndex++, fragments); >- >- fragment.offset = offset; >- fragment.setBidiLevel(levelInfo[seg * 2]); >- >- advance = FlowUtilities.wrapFragmentInContext(fragment, segment, >- context, lookahead, font, wrappingStyle); >- segment = segment.substring(advance); >- offset += advance; >- if ((segment.length() > 0 >- || fragment.length < advance) >- || fragment.isTruncated()) >- context.endLine(); >- } while (segment.length() > 0 >- || (!fragment.isTruncated() && fragment.length < advance)); >- } >- >- if (border != null) { >- fragment = getFragment(fragIndex++, fragments); >- fragment.setBidiLevel(levelInfo[0]); >- fragment.setTruncated(false); >- fragment.offset = fragment.length = -1; >- fragment.setWidth(border.getRightMargin() + border.getInsets(textFlow).right); >- context.addToCurrentLine(fragment); >- } >- >- //Remove the remaining unused fragments. >- while (fragIndex < fragments.size()) >- fragments.remove(fragments.size() - 1); >+ TextFlow textFlow = (TextFlow)getFlowFigure(); >+ int offset = 0; >+ >+ FlowContext context = getContext(); >+ List fragments = textFlow.getFragments(); >+ Font font = textFlow.getFont(); >+ int fragIndex = 0; >+ int advance = 0; >+ >+ TextFragmentBox fragment; >+ int levelInfo[] = (textFlow.getBidiInfo() == null) >+ ? new int[] {-1} >+ : textFlow.getBidiInfo().levelInfo; >+ >+ String segment, segments[] = getSegments(textFlow.getText(), levelInfo); >+ FlowBorder border = null; >+ if (textFlow.getBorder() instanceof FlowBorder) >+ border = (FlowBorder)textFlow.getBorder(); >+ >+ SegmentLookahead lookahead = new SegmentLookahead(segments, border == null ? 0 : border.getRightMargin()); >+ int seg; >+ >+ if (border != null) { >+ fragment = getFragment(fragIndex++, fragments); >+ fragment.setBidiLevel(levelInfo[0]); >+ fragment.setTruncated(false); >+ fragment.offset = fragment.length = -1; >+ fragment.setWidth(border.getLeftMargin() + border.getInsets(textFlow).left); >+ if (context.getRemainingLineWidth() >+ < fragment.getWidth() + lookahead.getWidth()) >+ context.endLine(); >+ context.addToCurrentLine(fragment); >+ } >+ >+ FlowUtilities flowUtilities = textFlow.getFlowUtilities(); >+ for (seg = 0; seg < segments.length; seg++) { >+ segment = segments[seg]; >+ lookahead.setIndex(seg); >+ >+ do { >+ fragment = getFragment(fragIndex++, fragments); >+ >+ fragment.offset = offset; >+ fragment.setBidiLevel(levelInfo[seg * 2]); >+ >+ advance = flowUtilities.wrapFragmentInContext(fragment, segment, >+ context, lookahead, font, wrappingStyle); >+ segment = segment.substring(advance); >+ offset += advance; >+ if ((segment.length() > 0 >+ || fragment.length < advance) >+ || fragment.isTruncated()) >+ context.endLine(); >+ } while (segment.length() > 0 >+ || (!fragment.isTruncated() && fragment.length < advance)); >+ } >+ >+ if (border != null) { >+ fragment = getFragment(fragIndex++, fragments); >+ fragment.setBidiLevel(levelInfo[0]); >+ fragment.setTruncated(false); >+ fragment.offset = fragment.length = -1; >+ fragment.setWidth(border.getRightMargin() + border.getInsets(textFlow).right); >+ context.addToCurrentLine(fragment); >+ } >+ >+ //Remove the remaining unused fragments. >+ while (fragIndex < fragments.size()) >+ fragments.remove(fragments.size() - 1); > } > > } >Index: src/org/eclipse/draw2d/Label.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Label.java,v >retrieving revision 1.20 >diff -u -r1.20 Label.java >--- src/org/eclipse/draw2d/Label.java 22 Mar 2007 14:00:25 -0000 1.20 >+++ src/org/eclipse/draw2d/Label.java 19 Sep 2007 15:03:44 -0000 >@@ -115,12 +115,12 @@ > case EAST: > case WEST: > alignOnHeight(textLocation, getTextSize(), textAlignment); >- alignOnHeight(iconLocation, iconSize, iconAlignment); >+ alignOnHeight(iconLocation, getIconSize(), iconAlignment); > break; > case NORTH: > case SOUTH: > alignOnWidth(textLocation, getSubStringTextSize(), textAlignment); >- alignOnWidth(iconLocation, iconSize, iconAlignment); >+ alignOnWidth(iconLocation, getIconSize(), iconAlignment); > break; > } > } >@@ -134,16 +134,16 @@ > * @since 2.0 > */ > protected Dimension calculateLabelSize(Dimension txtSize) { >- int gap = iconTextGap; >+ int gap = getIconTextGap(); > if (getIcon() == null || getText().equals("")) //$NON-NLS-1$ > gap = 0; > Dimension d = new Dimension(0, 0); > if (textPlacement == WEST || textPlacement == EAST) { >- d.width = iconSize.width + gap + txtSize.width; >- d.height = Math.max(iconSize.height, txtSize.height); >+ d.width = getIconSize().width + gap + txtSize.width; >+ d.height = Math.max(getIconSize().height, txtSize.height); > } else { >- d.width = Math.max(iconSize.width, txtSize.width); >- d.height = iconSize.height + gap + txtSize.height; >+ d.width = Math.max(getIconSize().width, txtSize.width); >+ d.height = getIconSize().height + gap + txtSize.height; > } > return d; > } >@@ -195,7 +195,7 @@ > } > > private void calculatePlacement() { >- int gap = iconTextGap; >+ int gap = getIconTextGap(); > if (icon == null || text.equals("")) //$NON-NLS-1$ > gap = 0; > Insets insets = getInsets(); >@@ -203,7 +203,7 @@ > switch(textPlacement) { > case EAST: > iconLocation.x = insets.left; >- textLocation.x = iconSize.width + gap + insets.left; >+ textLocation.x = getIconSize().width + gap + insets.left; > break; > case WEST: > textLocation.x = insets.left; >@@ -214,7 +214,7 @@ > iconLocation.y = getTextSize().height + gap + insets.top; > break; > case SOUTH: >- textLocation.y = iconSize.height + gap + insets.top; >+ textLocation.y = getIconSize().height + gap + insets.top; > iconLocation.y = insets.top; > } > } >@@ -228,7 +228,7 @@ > * @since 2.0 > */ > protected Dimension calculateSubStringTextSize() { >- return FigureUtilities.getTextExtents(getSubStringText(), getFont()); >+ return getTextUtilities().getTextExtents(getSubStringText(), getFont()); > } > > /** >@@ -241,7 +241,7 @@ > * @since 2.0 > */ > protected Dimension calculateTextSize() { >- return FigureUtilities.getTextExtents(getText(), getFont()); >+ return getTextUtilities().getTextExtents(getText(), getFont()); > } > > private void clearLocations() { >@@ -277,7 +277,7 @@ > */ > public Rectangle getIconBounds() { > Rectangle bounds = getBounds(); >- return new Rectangle(bounds.getLocation().translate(getIconLocation()), iconSize); >+ return new Rectangle(bounds.getLocation().translate(getIconLocation()), getIconSize()); > } > > /** >@@ -313,8 +313,8 @@ > minSize.setSize(getLayoutManager().getMinimumSize(this, w, h)); > > Dimension labelSize = >- calculateLabelSize(FigureUtilities.getTextExtents(ELLIPSIS, getFont()) >- .intersect(FigureUtilities.getTextExtents(getText(), getFont()))); >+ calculateLabelSize(getTextUtilities().getTextExtents(getTruncationString(), getFont()) >+ .intersect(getTextUtilities().getTextExtents(getText(), getFont()))); > Insets insets = getInsets(); > labelSize.expand(insets.getWidth(), insets.getHeight()); > minSize.union(labelSize); >@@ -360,15 +360,15 @@ > > Dimension effectiveSize = getTextSize().getExpanded(-widthShrink, 0); > Font currentFont = getFont(); >- int dotsWidth = FigureUtilities.getTextWidth(ELLIPSIS, currentFont); >+ int dotsWidth = getTextUtilities().getTextExtents(getTruncationString(), currentFont).width; > > if (effectiveSize.width < dotsWidth) > effectiveSize.width = dotsWidth; > >- int subStringLength = FigureUtilities.getLargestSubstringConfinedTo(text, >+ int subStringLength = getTextUtilities().getLargestSubstringConfinedTo(text, > currentFont, > effectiveSize.width - dotsWidth); >- subStringText = new String(text.substring(0, subStringLength) + ELLIPSIS); >+ subStringText = new String(text.substring(0, subStringLength) + getTruncationString()); > return subStringText; > } > >@@ -551,7 +551,7 @@ > * @since 2.0 > */ > public void setIconDimension(Dimension d) { >- if (d.equals(iconSize)) >+ if (d.equals(getIconSize())) > return; > iconSize = d; > revalidate(); >@@ -654,4 +654,36 @@ > repaint(); > } > >+/** >+ * Gets the <code>TextUtilities</code> instance to be used in measurement >+ * calculations. >+ * >+ * @return a <code>TextUtilities</code> instance >+ * @since 3.2 >+ */ >+public TextUtilities getTextUtilities() { >+ return TextUtilities.INSTANCE; >+} >+ >+/** >+ * Gets the string that will be appended to the text when the label is >+ * truncated. By default, this returns an ellipsis. >+ * >+ * @return the string to append to the text when truncated >+ * @since 3.4 >+ */ >+protected String getTruncationString() { >+ return ELLIPSIS; >+} >+ >+/** >+ * Gets the icon size >+ * >+ * @return the icon size >+ * @since 3.4 >+ */ >+protected Dimension getIconSize() { >+ return iconSize; >+} >+ > } >Index: src/org/eclipse/draw2d/FigureUtilities.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FigureUtilities.java,v >retrieving revision 1.34 >diff -u -r1.34 FigureUtilities.java >--- src/org/eclipse/draw2d/FigureUtilities.java 24 Apr 2006 18:15:12 -0000 1.34 >+++ src/org/eclipse/draw2d/FigureUtilities.java 19 Sep 2007 15:03:44 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2000, 2005 IBM Corporation and others. >+ * Copyright (c) 2000, 2007 IBM Corporation and others. > * All rights reserved. This program and the accompanying materials > * are made available under the terms of the Eclipse Public License v1.0 > * which accompanies this distribution, and is available at >@@ -114,48 +114,6 @@ > } > > /** >- * Returns the largest substring of <i>s</i> in Font <i>f</i> that can be confined to the >- * number of pixels in <i>availableWidth<i>. >- * >- * @param s the original string >- * @param f the font >- * @param availableWidth the available width >- * @return the largest substring that fits in the given width >- * @since 2.0 >- */ >-static int getLargestSubstringConfinedTo(String s, Font f, int availableWidth) { >- FontMetrics metrics = getFontMetrics(f); >- int min, max; >- float avg = metrics.getAverageCharWidth(); >- min = 0; >- max = s.length() + 1; >- >- //The size of the current guess >- int guess = 0, >- guessSize = 0; >- while ((max - min) > 1) { >- //Pick a new guess size >- // New guess is the last guess plus the missing width in pixels >- // divided by the average character size in pixels >- guess = guess + (int)((availableWidth - guessSize) / avg); >- >- if (guess >= max) guess = max - 1; >- if (guess <= min) guess = min + 1; >- >- //Measure the current guess >- guessSize = getTextExtents(s.substring(0, guess), f).width; >- >- if (guessSize < availableWidth) >- //We did not use the available width >- min = guess; >- else >- //We exceeded the available width >- max = guess; >- } >- return min; >-} >- >-/** > * Returns the Dimensions of the given text, converting newlines and tabs appropriately. > * > * @param text the text >Index: src/org/eclipse/draw2d/TextUtilities.java >=================================================================== >RCS file: src/org/eclipse/draw2d/TextUtilities.java >diff -N src/org/eclipse/draw2d/TextUtilities.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/draw2d/TextUtilities.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,126 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.draw2d; >+ >+import org.eclipse.swt.graphics.Font; >+import org.eclipse.swt.graphics.FontMetrics; >+ >+import org.eclipse.draw2d.geometry.Dimension; >+ >+/** >+ * Provides miscellaneous text operations. Clients may subclass this class if >+ * necessary. >+ * >+ * @author crevells >+ * @since 3.4 >+ */ >+public class TextUtilities { >+ >+ /** >+ * a singleton default instance >+ */ >+ public static TextUtilities INSTANCE = new TextUtilities(); >+ >+ /** >+ * Returns the Dimensions of <i>s</i> in Font <i>f</i>. >+ * >+ * @param s >+ * the string >+ * @param f >+ * the font >+ * @return the dimensions of the given string >+ */ >+ public Dimension getStringExtents(String s, Font f) { >+ return FigureUtilities.getStringExtents(s, f); >+ } >+ >+ /** >+ * Returns the Dimensions of the given text, converting newlines and tabs >+ * appropriately. >+ * >+ * @param s >+ * the text >+ * @param f >+ * the font >+ * @return the dimensions of the given text >+ */ >+ public Dimension getTextExtents(String s, Font f) { >+ return FigureUtilities.getTextExtents(s, f); >+ } >+ >+ /** >+ * Gets the font's ascent. >+ * >+ * @param font >+ * @return the font's ascent >+ */ >+ public int getAscent(Font font) { >+ FontMetrics fm = FigureUtilities.getFontMetrics(font); >+ return fm.getHeight() - fm.getDescent(); >+ } >+ >+ /** >+ * Gets the font's descent. >+ * >+ * @param font >+ * @return the font's descent >+ */ >+ public int getDescent(Font font) { >+ return FigureUtilities.getFontMetrics(font).getDescent(); >+ } >+ >+ /** >+ * Returns the largest substring of <i>s</i> in Font <i>f</i> that can be >+ * confined to the number of pixels in <i>availableWidth<i>. >+ * >+ * @param s >+ * the original string >+ * @param f >+ * the font >+ * @param availableWidth >+ * the available width >+ * @return the largest substring that fits in the given width >+ */ >+ public int getLargestSubstringConfinedTo(String s, Font f, >+ int availableWidth) { >+ FontMetrics metrics = FigureUtilities.getFontMetrics(f); >+ int min, max; >+ float avg = metrics.getAverageCharWidth(); >+ min = 0; >+ max = s.length() + 1; >+ >+ // The size of the current guess >+ int guess = 0, guessSize = 0; >+ while ((max - min) > 1) { >+ // Pick a new guess size >+ // New guess is the last guess plus the missing width in pixels >+ // divided by the average character size in pixels >+ guess = guess + (int) ((availableWidth - guessSize) / avg); >+ >+ if (guess >= max) >+ guess = max - 1; >+ if (guess <= min) >+ guess = min + 1; >+ >+ // Measure the current guess >+ guessSize = getTextExtents(s.substring(0, guess), f).width; >+ >+ if (guessSize < availableWidth) >+ // We did not use the available width >+ min = guess; >+ else >+ // We exceeded the available width >+ max = guess; >+ } >+ return min; >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
ahunter.eclipse
:
iplog+
Actions:
View
|
Diff
Attachments on
bug 194278
:
75271
|
77732
| 78759 |
79072