Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gamutSpace to ColorSpace #369

Merged
merged 1 commit into from Jan 23, 2024
Merged

Add gamutSpace to ColorSpace #369

merged 1 commit into from Jan 23, 2024

Conversation

lloydk
Copy link
Collaborator

@lloydk lloydk commented Nov 28, 2023

Some colorspaces such as hsluv, okhsl and okhsv need to do gamut checking in a color space that is not their own space or their base space. For example hsluv needs to do gamut checking in the srgb color space.

A gamutSpace can now be specified when constructing a ColorSpace and a gamutSpace property has beed added to ColorSpace.

This PR is backwards compatible with existing color spaces and uses the "least bad" option of specifying "self" for the gamutSpace of polar color spaces that need to do gamut checking in their own color space (hpluv) as discussed here.

In the original inGamut method the coords were converted to the base space by directly calling the toBase method. This version of inGamut calls the to method on gamutSpace which will result in NaN values being converted to 0 before the gamut check. Not sure if this matters.

I've also added an optimization to override inGamut for unbounded spaces. If you don't think it's appropriate I can remove it.

Copy link

netlify bot commented Nov 28, 2023

Deploy Preview for colorjs ready!

Name Link
🔨 Latest commit 795a251
🔍 Latest deploy log https://app.netlify.com/sites/colorjs/deploys/65af048140c46e0008ecd434
😎 Deploy Preview https://deploy-preview-369--colorjs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@svgeesus
Copy link
Member

Some colorspaces such as hsluv, okhsl and okhsv need to do gamut checking in a color space that is not their own space or their base space

HSL, HSV and HWB already do this (they check in sRGB)

Copy link
Member

@LeaVerou LeaVerou left a comment

Choose a reason for hiding this comment

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

Thanks for this!
So sorry for the delay, somehow these PRs completely slipped through the cracks, I don't recall ever seeing them before!

Overall looks good, see comments for a few minor issues.

@@ -37,6 +37,7 @@ export interface Options {
cssId?: string | undefined;
referred?: string | undefined;
formats?: Record<string, Format> | undefined;
gamutSpace?: string | ColorSpace | null | undefined;
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn’t we restrict string to the specific supported keywords?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

string can be "self" or a spaceId. I added "self" to the list of types just to make it a bit more clear. Ideally we'd have a type alias for spaceId. Something like:

type SpaceId = string;

And then we could replace string with SpaceId.

src/space.js Outdated
Comment on lines 56 to 79
// Gamut space

this.gamutSpace = this;

if (options.gamutSpace) {
if (options.gamutSpace !== "self") {
this.gamutSpace = ColorSpace.get(options.gamutSpace);
}
}
else if (this.isPolar) {
// Do not check gamut through polar coordinates
this.gamutSpace = this.base;
}

// Optimize inGamut for unbounded spaces
if (this.gamutSpace.isUnbounded){
this.inGamut = (coords, options) => {
return true;
};
}

Copy link
Member

Choose a reason for hiding this comment

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

Minor nit: Setting this.gamutSpace to this and then undoing it later makes the logic hard to follow. I'd restructure a bit to avoid this, possibly via having two branches for the two main cases like:

if (options.gamutSpace) {
	// Gamut space explicitly specified
	...
}
else {
	// Gamut space not explicitly specified, fall back to sensible defaults
	...
}

Note that if the gamut space is unbounded, this.gamutSpace is effectively still this, we just override inGamut as a performance optimization.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've changed the code to look more like what you suggested.

src/space.js Show resolved Hide resolved
src/space.js Outdated
Comment on lines 62 to 63
// Do not check gamut through polar coordinates
this.gamutSpace = this.isPolar ? this.base : this;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Do not check gamut through polar coordinates
this.gamutSpace = this.isPolar ? this.base : this;
// No gamut space specified, calculate a sensible default
if (this.isPolar) {
// Do not check gamut through polar coordinates
this.gamutSpace = this.base;
}
else {
this.gamutSpace = this;
}

Copy link
Member

@LeaVerou LeaVerou left a comment

Choose a reason for hiding this comment

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

LGTM, see suggestions for clarity

Some colorspaces such as hsluv, okhsl and okhsv need to do
gamut checking in a color space that is not their own space or
their base space. For example hsluv needs to do gamut checking in
the srgb color space.

A gamutSpace can now be specified when constructing a ColorSpace and
a gamutSpace property has beed added to ColorSpace.

If a gamutSpace is not specified the following rules are used to
assign the gamutSpace property:

- if the color space is polar use the base space
- if the color space is not polar use the current space

Polar spaces that need to gamut check themselves (hpluv) can set the
gamutSpace option to "self" to avoid gamut checking using the base
space.
@lloydk
Copy link
Collaborator Author

lloydk commented Jan 23, 2024

LGTM, see suggestions for clarity

I've made the suggested changes.

@LeaVerou LeaVerou merged commit 5405997 into color-js:main Jan 23, 2024
4 checks passed
@LeaVerou
Copy link
Member

Merged, thanks!

(Btw you can click "Commit suggestion" to merge it in, you don't have to redo the changes yourself :) )

@lloydk lloydk deleted the gamutspace branch February 9, 2024 04:21
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.

None yet

3 participants