JDK-4931896 : speed up the HTML renderer
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.4.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2003-10-02
  • Updated: 2017-05-16
  • Resolved: 2004-03-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 b43Fixed
Related Reports
Relates :  
Description
the synopsis says it all

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger-beta2 FIXED IN: tiger-beta2 INTEGRATED IN: tiger-b43 tiger-beta2
24-08-2004

EVALUATION Name: pzR10082 Date: 11/18/2003 A number of View layout methods were optimized for efficiency: - method calls were removed results of which were not used. - InlineView caches result of getLongestWordSpan(). - BodyBlockView doesn't perform layout if its host container has not been layed out yet. ###@###.### ======================================================================
24-08-2004

SUGGESTED FIX s + * where a potential break is desired >= 0 + * @return the fragment of the view that represents the + * given span. + * @since 1.5 + * @see javax.swing.text.View#breakView + */ + public View breakView(int axis, int offset, float pos, float len) { + View v = super.breakView(axis, offset, pos, len); + longestWordSpan = -1.0f; + return v; + } + + /** * Fetch the span of the longest word in the view. */ float getLongestWordSpan() { + if (longestWordSpan < 0.0f) { + longestWordSpan = calculateLongestWordSpan(); + } + return longestWordSpan; + } + + float calculateLongestWordSpan() { // find the longest word float span = 0; try { *************** *** 175,187 **** } else { nowrap = false; } - - HTMLDocument doc = (HTMLDocument)getDocument(); - // fetches background color from stylesheet if specified - Color bg = doc.getBackground(a); - if (bg != null) { - setBackground(bg); - } } --- 246,251 ---- *************** *** 192,196 **** private boolean nowrap; private AttributeSet attr; ! } --- 256,260 ---- private boolean nowrap; private AttributeSet attr; ! private float longestWordSpan = -1.0f; } ###@###.### ======================================================================
24-08-2004

SUGGESTED FIX Name: pzR10082 Date: 11/18/2003 *** /net/crown/export1/zpm/webrev/src/share/classes/javax/swing/text/BoxView.java- Mon Nov 10 14:20:02 2003 --- BoxView.java Mon Nov 10 13:14:03 2003 *************** *** 737,752 **** * first pass, calculate the preferred sizes * and the flexibility to adjust the sizes. */ - long minimum = 0; - long maximum = 0; long preferred = 0; int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); spans[i] = (int) v.getPreferredSpan(axis); preferred += spans[i]; - minimum += v.getMinimumSpan(axis); - maximum += v.getMaximumSpan(axis); } /* --- 737,748 ---- *************** *** 757,792 **** // determine the adjustment to be made long desiredAdjustment = targetSpan - preferred; float adjustmentFactor = 0.0f; ! if (desiredAdjustment != 0) { ! float maximumAdjustment = (desiredAdjustment > 0) ? ! maximum - preferred : preferred - minimum; ! if (maximumAdjustment == 0.0f) { ! adjustmentFactor = 0.0f; ! } ! else { ! adjustmentFactor = desiredAdjustment / maximumAdjustment; ! adjustmentFactor = Math.min(adjustmentFactor, 1.0f); ! adjustmentFactor = Math.max(adjustmentFactor, -1.0f); ! } ! } // make the adjustments int totalOffset = 0; for (int i = 0; i < n; i++) { - View v = getView(i); offsets[i] = totalOffset; ! int availableSpan = (adjustmentFactor > 0.0f) ? ! (int) v.getMaximumSpan(axis) - spans[i] : ! spans[i] - (int) v.getMinimumSpan(axis); ! float adjF = adjustmentFactor * availableSpan; ! if (adjF < 0) { ! adjF -= .5f; ! } ! else { ! adjF += .5f; } - int adj = (int)adjF; - spans[i] += adj; totalOffset = (int) Math.min((long) totalOffset + (long) spans[i], Integer.MAX_VALUE); } } --- 753,790 ---- // determine the adjustment to be made long desiredAdjustment = targetSpan - preferred; float adjustmentFactor = 0.0f; ! int[] diffs = null; + if (desiredAdjustment != 0) { + long totalSpan = 0; + diffs = new int[n]; + for (int i = 0; i < n; i++) { + View v = getView(i); + int tmp; + if (desiredAdjustment < 0) { + tmp = (int)v.getMinimumSpan(axis); + diffs[i] = spans[i] - tmp; + } else { + tmp = (int)v.getMaximumSpan(axis); + diffs[i] = tmp - spans[i]; + } + totalSpan += tmp; + } + + float maximumAdjustment = Math.abs(totalSpan - preferred); + adjustmentFactor = desiredAdjustment / maximumAdjustment; + adjustmentFactor = Math.min(adjustmentFactor, 1.0f); + adjustmentFactor = Math.max(adjustmentFactor, -1.0f); + } + // make the adjustments int totalOffset = 0; for (int i = 0; i < n; i++) { offsets[i] = totalOffset; ! if (desiredAdjustment != 0) { ! float adjF = adjustmentFactor * diffs[i]; ! spans[i] += Math.round(adjF); } totalOffset = (int) Math.min((long) totalOffset + (long) spans[i], Integer.MAX_VALUE); } } *************** *** 812,818 **** int n = getViewCount(); for (int i = 0; i < n; i++) { View v = getView(i); - int min = (int) v.getMinimumSpan(axis); int max = (int) v.getMaximumSpan(axis); if (max < targetSpan) { // can't make the child this wide, align it --- 810,815 ---- *************** *** 821,826 **** --- 818,824 ---- spans[i] = max; } else { // make it the target width, or as small as it can get. + int min = (int)v.getMinimumSpan(axis); offsets[i] = 0; spans[i] = Math.max(min, targetSpan); } *** /net/crown/export1/zpm/webrev/src/share/classes/javax/swing/text/FlowView.java- Mon Nov 10 14:20:02 2003 --- FlowView.java Mon Nov 10 13:14:03 2003 *************** *** 32,37 **** --- 32,39 ---- */ public abstract class FlowView extends BoxView { + private final static FlowStrategy STRATEGY = new FlowStrategy(); + /** * Constructs a FlowView for the given element. * *************** *** 41,47 **** public FlowView(Element elem, int axis) { super(elem, axis); layoutSpan = Short.MAX_VALUE; ! strategy = new FlowStrategy(); } /** --- 43,49 ---- public FlowView(Element elem, int axis) { super(elem, axis); layoutSpan = Short.MAX_VALUE; ! strategy = STRATEGY; } /** *************** *** 448,454 **** final int flowAxis = fv.getFlowAxis(); boolean forcedBreak = false; ! while (pos < end && spanLeft >= 0) { View v = createView(fv, pos, spanLeft, rowIndex); if ((v == null) || (spanLeft == 0 --- 450,456 ---- final int flowAxis = fv.getFlowAxis(); boolean forcedBreak = false; ! while (pos < end && spanLeft > 0) { View v = createView(fv, pos, spanLeft, rowIndex); if ((v == null) || (spanLeft == 0 *** /net/crown/export1/zpm/webrev/src/share/classes/javax/swing/text/html/BRView.java- Mon Nov 10 14:20:05 2003 --- BRView.java Mon Nov 10 13:14:04 2003 *************** *** 23,30 **** */ public BRView(Element elem) { super(elem); - StyleSheet sheet = getStyleSheet(); - attr = sheet.getViewAttributes(this); } /** --- 23,28 ---- *************** *** 39,44 **** return super.getBreakWeight(axis, pos, len); } } - AttributeSet attr; } - --- 37,40 ---- *** /net/crown/export1/zpm/webrev/src/share/classes/javax/swing/text/html/BlockView.java- Mon Nov 10 14:20:04 2003 --- BlockView.java Mon Nov 10 13:14:04 2003 *************** *** 222,228 **** for (int i = 0; i < n; i++) { View v = getView(i); int min = (int) v.getMinimumSpan(axis); ! int max = (int) v.getMaximumSpan(axis); // check for percentage span AttributeSet a = v.getAttributes(); --- 222,228 ---- for (int i = 0; i < n; i++) { View v = getView(i); int min = (int) v.getMinimumSpan(axis); ! int max; // check for percentage span AttributeSet a = v.getAttributes(); *************** *** 231,238 **** // bound the span to the percentage specified min = Math.max((int) lv.getValue(targetSpan), min); max = min; ! } ! // assign the offset and span for the child if (max < targetSpan) { // can't make the child this wide, align it --- 231,240 ---- // bound the span to the percentage specified min = Math.max((int) lv.getValue(targetSpan), min); max = min; ! } else { ! max = (int)v.getMaximumSpan(axis); ! } ! // assign the offset and span for the child if (max < targetSpan) { // can't make the child this wide, align it *** /net/crown/export1/zpm/webrev/src/share/classes/javax/swing/text/html/HTMLEditorKit.java- Mon Nov 10 14:20:05 2003 --- HTMLEditorKit.java Mon Nov 10 13:14:04 2003 *************** *** 839,847 **** String target = (anchor != null) ? (String)anchor.getAttribute(HTML.Attribute.TARGET) : null; if ((target == null) || (target.equals(""))) { - target = hdoc.getBaseTarget(); - } - if ((target == null) || (target.equals(""))) { target = "_self"; } linkEvent = new HTMLFrameHyperlinkEvent(html, HyperlinkEvent. --- 839,844 ---- *************** *** 1187,1196 **** r.maximum = Integer.MAX_VALUE; return r; } protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) { - //idk - //Thread.currentThread().dumpStack(); - //idk Container container = getContainer(); Container parentContainer; if (container != null --- 1184,1191 ---- r.maximum = Integer.MAX_VALUE; return r; } + protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) { Container container = getContainer(); Container parentContainer; if (container != null *************** *** 1212,1250 **** viewPort.addComponentListener(this); cachedViewPort = new WeakReference(viewPort); } - int n = getViewCount(); - componentVisibleWidth = viewPort.getExtentSize().width; - Insets insets = container.getInsets(); - viewVisibleWidth = componentVisibleWidth - insets.left - getLeftInset(); - //try to use viewVisibleWidth if it is smaller than targetSpan - targetSpan = Math.min(targetSpan, viewVisibleWidth); - Object key = (axis == X_AXIS) ? CSS.Attribute.WIDTH : CSS.Attribute.HEIGHT; - - for (int i = 0; i < n; i++) { - View v = getView(i); - int min = (int) v.getMinimumSpan(axis); - int max = (int) v.getMaximumSpan(axis); - - // check for percentage span - AttributeSet a = v.getAttributes(); - CSS.LengthValue lv = (CSS.LengthValue) a.getAttribute(key); - if ((lv != null) && lv.isPercentage()) { - // bound the span to the percentage specified - min = Math.max((int) lv.getValue(targetSpan),min); - max = min; - } ! if (max < targetSpan) { ! // can't make the child this wide, align it ! float align = v.getAlignment(axis); ! offsets[i] = (int) ((targetSpan - max) * align); ! spans[i] = max; ! } else { ! // make it the target width, or as small as it can get. ! offsets[i] = 0; ! spans[i] = Math.max(min, targetSpan); ! } ! } } else { if (cachedViewPort != null) { Object cachedObject; --- 1207,1220 ---- viewPort.addComponentListener(this); cachedViewPort = new WeakReference(viewPort); } ! componentVisibleWidth = viewPort.getExtentSize().width; ! if (componentVisibleWidth > 0) { ! Insets insets = container.getInsets(); ! viewVisibleWidth = componentVisibleWidth - insets.left - getLeftInset(); ! // try to use viewVisibleWidth if it is smaller than targetSpan ! targetSpan = Math.min(targetSpan, viewVisibleWidth); ! } } else { if (cachedViewPort != null) { Object cachedObject; *************** *** 1253,1260 **** } cachedViewPort = null; } - super.layoutMinorAxis(targetSpan,axis,offsets,spans); } } public void setParent(View parent) { --- 1223,1230 ---- } cachedViewPort = null; } } + super.layoutMinorAxis(targetSpan, axis, offsets, spans); } public void setParent(View parent) { *** /net/crown/export1/zpm/webrev/src/share/classes/javax/swing/text/html/InlineView.java- Mon Nov 10 14:20:03 2003 --- InlineView.java Mon Nov 10 14:19:55 2003 *************** *** 6,12 **** */ package javax.swing.text.html; - import java.awt.Color; import java.awt.Container; import java.awt.Shape; import java.awt.FontMetrics; --- 6,11 ---- *************** *** 35,40 **** --- 34,73 ---- } /** + * Gives notification that something was inserted into + * the document in a location that this view is responsible for. + * If either parameter is <code>null</code>, behavior of this method is + * implementation dependent. + * + * @param e the change information from the associated document + * @param a the current allocation of the view + * @param f the factory to use to rebuild if the view has children + * @since 1.5 + * @see View#insertUpdate + */ + public void insertUpdate(DocumentEvent e, Shape a, ViewFactory f) { + super.insertUpdate(e, a, f); + longestWordSpan = -1.0f; + } + + /** + * Gives notification that something was removed from the document + * in a location that this view is responsible for. + * If either parameter is <code>null</code>, behavior of this method is + * implementation dependent. + * + * @param e the change information from the associated document + * @param a the current allocation of the view + * @param f the factory to use to rebuild if the view has children + * @since 1.5 + * @see View#removeUpdate + */ + public void removeUpdate(DocumentEvent e, Shape a, ViewFactory f) { + super.removeUpdate(e, a, f); + longestWordSpan = -1.0f; + } + + /** * Gives notification from the document that attributes were changed * in a location that this view is responsible for. * *************** *** 105,113 **** --- 138,184 ---- } /** + * Tries to break this view on the given axis. Refer to + * {@link javax.swing.text.View#breakView} for a complete + * description of this method. + * <p>Behavior of this method is unspecified in case <code>axis</code> + * is neither <code>View.X_AXIS</code> nor <code>View.Y_AXIS</code>, and + * in case <code>offset</code>, <code>pos</code>, or <code>len</code> + * is null. + * + * @param axis may be either <code>View.X_AXIS</code> or + * <code>View.Y_AXIS</code> + * @param offset the location in the document model + * that a broken fragment would occupy >= 0. This + * would be the starting offset of the fragment + * returned + * @param pos the position along the axis that the + * broken view would occupy >= 0. This may be useful for + * things like tab calculations + * @param len specifies the distance along the axi
24-08-2004