Skip to content

Provide a shared color blend helper in JFaceColors - #4489

Closed
vogella wants to merge 1 commit into
eclipse-platform:masterfrom
vogella:lv/jface-color-blend
Closed

vogella wants to merge 1 commit into
eclipse-platform:masterfrom
vogella:lv/jface-color-blend

Conversation

@vogella

@vogella vogella commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Blending two RGB values by a ratio was copied about a dozen times across platform.ui, each with its own parameter type and rounding. This adds JFaceColors.blend(RGB, RGB, double) as the single implementation in the lowest bundle all of them depend on. The existing public FormColors.blend and ColorUtil.blend now delegate to it and the private copies are removed. The integer percentage and 0.56 factor callers produce exactly the same colors as before, the remaining ones differ by at most one RGB step, and copies in other repositories can move to the new API once it is released.

Fixes #4486

@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

   867 files  ± 0     867 suites  ±0   49m 59s ⏱️ - 2m 40s
 8 466 tests + 5   8 224 ✅ + 5  242 💤 ±0  0 ❌ ±0 
21 276 runs  +15  20 593 ✅ +15  683 💤 ±0  0 ❌ ±0 

Results for commit f3faf8d. ± Comparison against base commit 01bea36.

♻️ This comment has been updated with latest results.

@vogella
vogella force-pushed the lv/jface-color-blend branch from c8fb1bc to 42a6276 Compare October 13, 2026 21:54
Blending two RGB values by a ratio was copied a dozen times across
platform.ui, with differing parameter types and rounding. The new
JFaceColors.blend is now the single implementation: FormColors.blend and
ColorUtil.blend delegate to it and the private copies are removed.
Colors stay the same, or differ by at most one RGB step where a copy
rounded differently.

Fixes eclipse-platform#4486

Assisted-by: multiple AI agents and layers of automated tooling 🤖
@vogella
vogella force-pushed the lv/jface-color-blend branch from 42a6276 to f3faf8d Compare October 13, 2026 21:57
@vogella
vogella requested a review from ptziegler October 14, 2026 05:55
Comment on lines +216 to +234
/**
* Blends two colors: a <code>ratio</code> of 1 returns <code>c1</code>, a
* <code>ratio</code> of 0 returns <code>c2</code>. Channel values are
* truncated and clamped to the valid range.
*
* @param ratio the share of <code>c1</code>, normally in [0,&nbsp;1]
* @since 3.41
*/
public static RGB blend(RGB c1, RGB c2, double ratio) {
return new RGB(blend(c1.red, c2.red, ratio), blend(c1.green, c2.green, ratio),
blend(c1.blue, c2.blue, ratio));
}

private static int blend(int v1, int v2, double ratio) {
// the epsilon keeps ratios like 0.3 from truncating exact results one step down
int v = (int) (ratio * v1 + (1 - ratio) * v2 + 1e-9);
return Math.clamp(v, 0, 255);
}

@laeubi laeubi Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method do not depend on anything of JFace or platform. For me it seems a much better place would be to add this to the SWT RGB class instead, what even would avoid needing to call a static method and instead I can call RGB blended = c1.blend(c2, 0.7).

This would also address the concerns from @ptziegler that JFaceColors actually documents a different purpose and make it even more broadly available.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually keep SWT super focused and so far all copies are in the surface of JFace. JFace usually server the "sugar on top of SWT" functionality. @akurtakov WDYT?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation, I understand the wish to keep SWT focused and to deduplicate the copies.

I still see it a bit differently:

  • The method only works on RGB and has nothing to do with JFace, so JFaceColors is not a natural home (see also @ptziegler's remark about its documented purpose).
  • "All copies are in JFace surface" does not seem fully accurate, as @merks noted, SWT itself blends in e.g. CBanner. So SWT is a consumer of the same functionality, which is an argument for putting it there.

To me there are two consistent options:

  1. It is generic and wanted functionality, then it belongs to SWT (e.g. RGB#blend(RGB, double)), where everyone benefits.
  2. It only looks similar in a few places, then I'd rather not add a public helper.
    The code is neither performance critical nor complicated, and a shared public method binds us and consumers to one set of rounding/clamping semantics (the PR itself notes that some callers differ by one step).

Putting it in JFaceColors sits in between: new public API to maintain, but not where it is most reusable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no personal strong preference here but I want to get the opinion of core SWT developers. Lets see if someone chips in. This stuff here is also not urgent, we have this copied code outside JFace and SWT since ages.

@merks merks Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe @HeikoKlare has an opinion as well...


An in general SWT might consider if eliminating pointless color copying might be worthwhile goal...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be fine with this in SWT's RGB. It's pure color math, needs no native code, and fits next to RGB(float, float, float) and getHSB(). Those were added in 3.2 for the same reason, and SWT itself still doesn't use them; their callers are in platform.ui.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. SWT's RGB class would be a fitting home for this functionality (both from OO perspective as well with respect to the scope of SWT). Using readable parameter names would also be great, at least but not exclusive to public API. It currently also looks like a mixture of semantics: the parameter name fragments and the javadoc speak of colors, whereas it''s about RGB values (and color is an SWT concept on top of it).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding API/implementation - my experience is that the closer one stays to css semantics (e.g. https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/color_value/color-mix ) the easier it is for the API to be understood and used.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It currently also looks like a mixture of semantics: the parameter name fragments and the javadoc speak of colors, whereas it''s about RGB values (and color is an SWT concept on top of it).

RGB is/was the device-less representation of a Color in SWT in the past, now Colors are not needed to be disposed its use becomes less useful from my point of view anyways and the are mostly exchangeable (even though theoretically a Color can use a different color model). On the other-hand for the same reason it wont hurt to have the same (delegating to the RGB class) code in the Color class as well.

@merks

merks commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

In terms of code simplification/reduction, this looks super. I too was going to observe there are even places in SWT doing blending, like CBanner. But I didn't have the idea of the RGB class...


Not directly related, so sorry for the digression, but I thought I'd point it out here anyway

SWT does color copying which I think is pointless now that colors don't need to be disposed, e.g.,

image

It even keeps a map for the copies in place and disposes the value of the map:

image

It could be simplified....

@vogella

vogella commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

@vogella vogella closed this Oct 14, 2026
@vogella
vogella deleted the lv/jface-color-blend branch October 14, 2026 22:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use the shared color blend helper from SWT

5 participants