private static void NormalizeHintsOffsets(IList <GradientColorStop> result) { // normalize all except last for (int i = 0; i < result.Count - 1; ++i) { GradientColorStop stopColor = result[i]; if (stopColor.GetHintOffsetType() == GradientColorStop.HintOffsetType.RELATIVE_ON_GRADIENT) { double currentStopOffset = stopColor.GetOffset(); double nextStopOffset = result[i + 1].GetOffset(); if (currentStopOffset != nextStopOffset) { double hintOffset = (stopColor.GetHintOffset() - currentStopOffset) / (nextStopOffset - currentStopOffset); stopColor.SetHint(hintOffset, GradientColorStop.HintOffsetType.RELATIVE_BETWEEN_COLORS); } else { // if stops has the same offset, then no hint needed stopColor.SetHint(0, GradientColorStop.HintOffsetType.NONE); } } } // the last color hint is not needed as even with pad and reflect it won't be used result[result.Count - 1].SetHint(0, GradientColorStop.HintOffsetType.NONE); }
private static IList <GradientColorStop> CopyStopsAndNormalizeAbsoluteOffsets(IList <GradientColorStop> toNormalize , double baseVectorLength) { double lastUsedOffset = double.NegativeInfinity; IList <GradientColorStop> copy = new List <GradientColorStop>(toNormalize.Count); foreach (GradientColorStop stop in toNormalize) { double offset = stop.GetOffset(); GradientColorStop.OffsetType offsetType = stop.GetOffsetType(); if (offsetType == GradientColorStop.OffsetType.ABSOLUTE) { offsetType = GradientColorStop.OffsetType.RELATIVE; offset /= baseVectorLength; } if (offsetType == GradientColorStop.OffsetType.RELATIVE) { if (offset < lastUsedOffset) { offset = lastUsedOffset; } lastUsedOffset = offset; } GradientColorStop result = new GradientColorStop(stop, offset, offsetType); double hintOffset = stop.GetHintOffset(); GradientColorStop.HintOffsetType hintOffsetType = stop.GetHintOffsetType(); if (hintOffsetType == GradientColorStop.HintOffsetType.ABSOLUTE_ON_GRADIENT) { hintOffsetType = GradientColorStop.HintOffsetType.RELATIVE_ON_GRADIENT; hintOffset /= baseVectorLength; } if (hintOffsetType == GradientColorStop.HintOffsetType.RELATIVE_ON_GRADIENT) { if (hintOffset < lastUsedOffset) { hintOffset = lastUsedOffset; } lastUsedOffset = hintOffset; } result.SetHint(hintOffset, hintOffsetType); copy.Add(result); } return(copy); }
private static IList <GradientColorStop> AdjustNormalizedStopsToCoverDomain(IList <GradientColorStop> normalizedStops , double[] targetDomain, GradientSpreadMethod spreadMethod) { IList <GradientColorStop> adjustedStops = new List <GradientColorStop>(); GradientColorStop lastColorStop = normalizedStops[normalizedStops.Count - 1]; double originalIntervalEnd = lastColorStop.GetOffset(); double originalIntervalStart = normalizedStops[0].GetOffset(); double originalIntervalLength = originalIntervalEnd - originalIntervalStart; if (originalIntervalLength <= ZERO_EPSILON) { return(JavaUtil.ArraysAsList(new GradientColorStop(lastColorStop, targetDomain[0], GradientColorStop.OffsetType .RELATIVE), new GradientColorStop(lastColorStop, targetDomain[1], GradientColorStop.OffsetType.RELATIVE ))); } double startIntervalsShift = Math.Floor((targetDomain[0] - originalIntervalStart) / originalIntervalLength ); double iterationOffset = originalIntervalStart + (originalIntervalLength * startIntervalsShift); bool isIterationInverse = spreadMethod == GradientSpreadMethod.REFLECT && Math.Abs(startIntervalsShift) % 2 != 0; int currentIterationIndex = isIterationInverse ? normalizedStops.Count - 1 : 0; double lastComputedOffset = iterationOffset; while (lastComputedOffset <= targetDomain[1]) { GradientColorStop currentStop = normalizedStops[currentIterationIndex]; lastComputedOffset = isIterationInverse ? iterationOffset + originalIntervalEnd - currentStop.GetOffset() : iterationOffset + currentStop.GetOffset() - originalIntervalStart; GradientColorStop computedStop = new GradientColorStop(currentStop, lastComputedOffset, GradientColorStop.OffsetType .RELATIVE); if (lastComputedOffset < targetDomain[0] && !adjustedStops.IsEmpty()) { adjustedStops[0] = computedStop; } else { adjustedStops.Add(computedStop); } if (isIterationInverse) { --currentIterationIndex; if (currentIterationIndex < 0) { iterationOffset += originalIntervalLength; isIterationInverse = false; currentIterationIndex = 1; } } else { ++currentIterationIndex; if (currentIterationIndex == normalizedStops.Count) { iterationOffset += originalIntervalLength; isIterationInverse = spreadMethod == GradientSpreadMethod.REFLECT; currentIterationIndex = isIterationInverse ? normalizedStops.Count - 2 : 0; } } // check the next iteration type to set the correct stop color hint for just added stop if (isIterationInverse) { GradientColorStop nextColor = normalizedStops[currentIterationIndex]; // this method should be invoked only after the normalization. it means that // the hint offset type for each stop is either relative to colors interval // (i.e. for inverse iteration we need to inverse the hint offset), or is none // (i.e. the hint offset value should be ignored) computedStop.SetHint(1 - nextColor.GetHintOffset(), nextColor.GetHintOffsetType()); } else { computedStop.SetHint(currentStop.GetHintOffset(), currentStop.GetHintOffsetType()); } } return(adjustedStops); }