RFR: 8230833: LabeledSkinBase computes wrong height with ContentDisplay.GRAPHIC_ONLY [v4]
Karthik P K
kpk at openjdk.org
Thu Feb 9 14:40:17 UTC 2023
On Wed, 8 Feb 2023 19:57:46 GMT, Andy Goryachev <angorya at openjdk.org> wrote:
>> Previously both `textWidth` and `graphicWidth` were calculated regardless of the condition. In the updated code calculation of `graphicWidth` is moved to `else` block so that one unnecessary calculation is avoided. Since `textWidth` is used in 2 more conditions in `else` block, calculated it before the start of `if` block.
>>
>> Since `isIgnoreText()` does more than just checking for `ContentDisplay` value, further reordering `if-else` statements generates different result than expected.
>> So this further leads to question previously raised by @hjohn, if `isIgnoreText()` and `isIgnoreGraphic()` should only check for ContetDisplay type or check for conditions like null/empty graphic or text as well. If this needs to be separated, again it gives raise to more conditions in the `computePrefWidth()` method.
>>
>> Added boolean in the beginning as suggested.
>
> no, what I meant is try to make sure that any operations with text (and some other calls) are made only when they are needed.
>
> For example, this code avoids calling anything to do with text and font when isIgnoreText == true.
>
> I also noticed that there is a field called `textWidth`; to avoid confusion I renamed the local variable from textWidth to `txWidth`.
>
>
> /** {@inheritDoc} */
> @Override
> protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset,
> double leftInset) {
> // Get the preferred width of the text
> final Labeled labeled = getSkinnable();
>
> boolean isIgnoreText = isIgnoreText();
> double widthPadding = leftInset + rightInset;
>
> double txWidth;
> if (isIgnoreText) {
> txWidth = 0.0;
> } else {
> widthPadding += (leftLabelPadding() + rightLabelPadding());
>
> String cleanText = getCleanText();
> boolean emptyText = cleanText == null || cleanText.isEmpty();
> if (emptyText) {
> txWidth = 0.0;
> } else {
> Font font = text.getFont();
> txWidth = Utils.computeTextWidth(font, cleanText, 0);
> }
> }
>
> double width;
> if (isIgnoreGraphic()) {
> width = txWidth;
> } else {
> // Fix for RT-39889
> double grWidth = graphic == null ? 0.0
> : Utils.boundedSize(graphic.prefWidth(-1), graphic.minWidth(-1), graphic.maxWidth(-1));
>
> if (isIgnoreText) {
> width = grWidth;
> } else {
> ContentDisplay cd = labeled.getContentDisplay();
> if (cd == ContentDisplay.LEFT || cd == ContentDisplay.RIGHT) {
> width = txWidth + labeled.getGraphicTextGap() + grWidth;
> } else {
> width = Math.max(txWidth, grWidth);
> }
> }
> }
>
> return width + widthPadding;
> }
>
>
> I suggest we apply a similar treatment to the second method being modified.
Updated `computePrefWidth()` method.
Please refer to my comment at the end regarding `computePrefHeight()` method optimization observations.
>> Since `clenText` is used in `textHeight` calculation, this cannot be avoided before the `if-else` block as `if-else` block is not re-ordered now. Please refer to the previous comment for the details on `computePrefHeight()` method.
>
> please see my earlier code sample, it is possible.
> cleanText is only needed to get the textWidth, and that is only needed when isIgnoreText == false.
> Also note that `textWidth` here is a local and hides an instance field with the same name. Rename the local?
Changed local variable name.
Please refer to my comment at the end regarding `computePrefHeight()` method optimization.
-------------
PR: https://git.openjdk.org/jfx/pull/996
More information about the openjfx-dev
mailing list