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

De-dupe gradient stops #2081

Merged
merged 2 commits into from May 27, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -142,14 +142,12 @@ private GradientColor addOpacityStopsToGradientIfNeeded(GradientColor gradientCo
}
}

int newColorPoints = colorPoints + opacityStops;
float[] newPositions = new float[newColorPoints];
// Pre-SKIA (Oreo) devices render artifacts when there is two stops in the same position.
// As a result, we have to de-dupe the merge color and opacity stop positions.
float[] newPositions = mergeUniqueElements(gradientColor.getPositions(), opacityStopPositions);
int newColorPoints = newPositions.length;
int[] newColors = new int[newColorPoints];

System.arraycopy(gradientColor.getPositions(), 0, newPositions, 0, colorPoints);
System.arraycopy(opacityStopPositions, 0, newPositions, colorPoints, opacityStops);
Arrays.sort(newPositions);

for (int i = 0; i < newColorPoints; i++) {
float position = newPositions[i];
int colorStopIndex = Arrays.binarySearch(colorStopPositions, position);
Expand Down Expand Up @@ -223,4 +221,60 @@ private int getColorInBetweenOpacityStops(float position, int color, float[] opa
}
throw new IllegalArgumentException("Unreachable code.");
}

/**
* Takes two sorted float arrays and merges their elements while removing duplicates.
*/
protected static float[] mergeUniqueElements(float[] arrayA, float[] arrayB) {
if (arrayA.length == 0) {
return arrayB;
} else if (arrayB.length == 0) {
return arrayA;
}

int aIndex = 0;
int bIndex = 0;
int mergedIndex = 0;
int numDuplicates = 0;
// This will be the merged list but may be longer than what is needed if there are duplicates.
// If there are, the 0 elements at the end need to be truncated.
float[] mergedNotTruncated = new float[arrayA.length + arrayB.length];
for (int i = 0; i < mergedNotTruncated.length; i++) {
final float a;
if (aIndex < arrayA.length) {
a = arrayA[aIndex];
} else {
a = Float.NaN;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

nit could be elvis

Suggested change
final float a;
if (aIndex < arrayA.length) {
a = arrayA[aIndex];
} else {
a = Float.NaN;
}
final float a = aIndex < arrayA.length ? arrayA[aIndex] : Float.NaN

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

👍


final float b;
if (bIndex < arrayB.length) {
b = arrayB[bIndex];
} else {
b = Float.NaN;
}

if (Float.isNaN(b) || a < b) {
mergedNotTruncated[mergedIndex++] = a;
Copy link
Contributor

Choose a reason for hiding this comment

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

isn't mergeIndex can be replaced by i?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yup!

aIndex++;
} else if (Float.isNaN(a) || b < a) {
mergedNotTruncated[mergedIndex++] = b;
bIndex++;
} else {
mergedNotTruncated[mergedIndex++] = a;
aIndex++;
bIndex++;
numDuplicates++;
}
}

if (numDuplicates == 0) {
return mergedNotTruncated;
}


float[] merged = new float[mergedNotTruncated.length - numDuplicates];
System.arraycopy(mergedNotTruncated, 0, merged, 0, merged.length);
return merged;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit:

Suggested change
float[] merged = new float[mergedNotTruncated.length - numDuplicates];
System.arraycopy(mergedNotTruncated, 0, merged, 0, merged.length);
return merged;
return Arrays.copyOf(mergedNotTruncated, mergedNotTruncated.lengh - numDuplicates);

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done!

}
}
@@ -0,0 +1,4 @@
import static org.junit.Assert.*;
public class GradientColorParserTest {

}