Skip to content

Commit c5e3aba

Browse files
fix: Update material color implementation to 13th June 2025
Signed-off-by: Andy Scherzinger <[email protected]>
1 parent 335efa9 commit c5e3aba

File tree

3 files changed

+59
-5
lines changed

3 files changed

+59
-5
lines changed

material-color-utilities/src/main/java/dynamiccolor/ColorSpec2025.java

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,10 +1210,21 @@ public DynamicColor primaryFixed() {
12101210
.setPalette((s) -> s.primaryPalette)
12111211
.setTone(
12121212
(s) -> {
1213-
DynamicScheme tempS = DynamicScheme.from(s, /* isDark= */ false);
1213+
DynamicScheme tempS =
1214+
DynamicScheme.from(s, /* isDark= */ false, /* contrastLevel= */ 0.0);
12141215
return primaryContainer().getTone(tempS);
12151216
})
12161217
.setIsBackground(true)
1218+
.setBackground(
1219+
(s) -> {
1220+
if (s.platform == PHONE) {
1221+
return s.isDark ? surfaceBright() : surfaceDim();
1222+
} else {
1223+
return null;
1224+
}
1225+
})
1226+
.setContrastCurve(
1227+
(s) -> s.platform == PHONE && s.contrastLevel > 0 ? getContrastCurve(1.5) : null)
12171228
.build();
12181229
return super.primaryFixed().toBuilder()
12191230
.extendSpecVersion(SpecVersion.SPEC_2025, color2025)
@@ -1280,10 +1291,21 @@ public DynamicColor secondaryFixed() {
12801291
.setPalette((s) -> s.secondaryPalette)
12811292
.setTone(
12821293
(s) -> {
1283-
DynamicScheme tempS = DynamicScheme.from(s, /* isDark= */ false);
1294+
DynamicScheme tempS =
1295+
DynamicScheme.from(s, /* isDark= */ false, /* contrastLevel= */ 0.0);
12841296
return secondaryContainer().getTone(tempS);
12851297
})
12861298
.setIsBackground(true)
1299+
.setBackground(
1300+
(s) -> {
1301+
if (s.platform == PHONE) {
1302+
return s.isDark ? surfaceBright() : surfaceDim();
1303+
} else {
1304+
return null;
1305+
}
1306+
})
1307+
.setContrastCurve(
1308+
(s) -> s.platform == PHONE && s.contrastLevel > 0 ? getContrastCurve(1.5) : null)
12871309
.build();
12881310
return super.secondaryFixed().toBuilder()
12891311
.extendSpecVersion(SpecVersion.SPEC_2025, color2025)
@@ -1350,10 +1372,21 @@ public DynamicColor tertiaryFixed() {
13501372
.setPalette((s) -> s.tertiaryPalette)
13511373
.setTone(
13521374
(s) -> {
1353-
DynamicScheme tempS = DynamicScheme.from(s, /* isDark= */ false);
1375+
DynamicScheme tempS =
1376+
DynamicScheme.from(s, /* isDark= */ false, /* contrastLevel= */ 0.0);
13541377
return tertiaryContainer().getTone(tempS);
13551378
})
13561379
.setIsBackground(true)
1380+
.setBackground(
1381+
(s) -> {
1382+
if (s.platform == PHONE) {
1383+
return s.isDark ? surfaceBright() : surfaceDim();
1384+
} else {
1385+
return null;
1386+
}
1387+
})
1388+
.setContrastCurve(
1389+
(s) -> s.platform == PHONE && s.contrastLevel > 0 ? getContrastCurve(1.5) : null)
13571390
.build();
13581391
return super.tertiaryFixed().toBuilder()
13591392
.extendSpecVersion(SpecVersion.SPEC_2025, color2025)

material-color-utilities/src/main/java/dynamiccolor/DynamicScheme.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,15 @@ public DynamicScheme(
152152
}
153153

154154
public static DynamicScheme from(DynamicScheme other, boolean isDark) {
155+
return from(other, isDark, other.contrastLevel);
156+
}
157+
158+
public static DynamicScheme from(DynamicScheme other, boolean isDark, double contrastLevel) {
155159
return new DynamicScheme(
156160
other.sourceColorHct,
157161
other.variant,
158162
isDark,
159-
other.contrastLevel,
163+
contrastLevel,
160164
other.platform,
161165
other.specVersion,
162166
other.primaryPalette,

material-color-utilities/src/main/java/palettes/TonalPalette.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@ private TonalPalette(double hue, double chroma, Hct keyColor) {
7979
public int tone(int tone) {
8080
Integer color = cache.get(tone);
8181
if (color == null) {
82-
color = Hct.from(this.hue, this.chroma, tone).toInt();
82+
if (tone == 99 && Hct.isYellow(this.hue)) {
83+
color = averageArgb(this.tone(98), this.tone(100));
84+
} else {
85+
color = Hct.from(this.hue, this.chroma, tone).toInt();
86+
}
8387
cache.put(tone, color);
8488
}
8589
return color;
@@ -105,6 +109,19 @@ public Hct getKeyColor() {
105109
return this.keyColor;
106110
}
107111

112+
private int averageArgb(int argb1, int argb2) {
113+
int red1 = (argb1 >>> 16) & 0xff;
114+
int green1 = (argb1 >>> 8) & 0xff;
115+
int blue1 = argb1 & 0xff;
116+
int red2 = (argb2 >>> 16) & 0xff;
117+
int green2 = (argb2 >>> 8) & 0xff;
118+
int blue2 = argb2 & 0xff;
119+
int red = Math.round((red1 + red2) / 2f);
120+
int green = Math.round((green1 + green2) / 2f);
121+
int blue = Math.round((blue1 + blue2) / 2f);
122+
return (255 << 24 | (red & 255) << 16 | (green & 255) << 8 | (blue & 255)) >>> 0;
123+
}
124+
108125
/** Key color is a color that represents the hue and chroma of a tonal palette. */
109126
private static final class KeyColor {
110127
private final double hue;

0 commit comments

Comments
 (0)