private static PdfFunction ConstructFunction(IList <GradientColorStop> toConstruct) { int functionsAmount = toConstruct.Count - 1; double[] bounds = new double[functionsAmount - 1]; IList <PdfFunction> type2Functions = new List <PdfFunction>(functionsAmount); GradientColorStop currentStop; GradientColorStop nextStop = toConstruct[0]; double domainStart = nextStop.GetOffset(); for (int i = 1; i < functionsAmount; ++i) { currentStop = nextStop; nextStop = toConstruct[i]; bounds[i - 1] = nextStop.GetOffset(); type2Functions.Add(ConstructSingleGradientSegmentFunction(currentStop, nextStop)); } currentStop = nextStop; nextStop = toConstruct[toConstruct.Count - 1]; type2Functions.Add(ConstructSingleGradientSegmentFunction(currentStop, nextStop)); double domainEnd = nextStop.GetOffset(); double[] encode = new double[functionsAmount * 2]; for (int i = 0; i < encode.Length; i += 2) { encode[i] = 0d; encode[i + 1] = 1d; } return(new PdfFunction.Type3(new PdfArray(new double[] { domainStart, domainEnd }), null, type2Functions, new PdfArray(bounds), new PdfArray(encode))); }
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); }
public virtual void CornerCasesTest() { GradientColorStop stopToTest = new GradientColorStop((float[])null, 1.5, GradientColorStop.OffsetType.AUTO ).SetHint(1.5, GradientColorStop.HintOffsetType.NONE); NUnit.Framework.Assert.AreEqual(new float[] { 0f, 0f, 0f }, stopToTest.GetRgbArray()); NUnit.Framework.Assert.AreEqual(0, stopToTest.GetOffset(), 1e-10); NUnit.Framework.Assert.AreEqual(GradientColorStop.OffsetType.AUTO, stopToTest.GetOffsetType()); NUnit.Framework.Assert.AreEqual(0, stopToTest.GetHintOffset(), 1e-10); NUnit.Framework.Assert.AreEqual(GradientColorStop.HintOffsetType.NONE, stopToTest.GetHintOffsetType()); }
public virtual void NormalizationTest() { GradientColorStop stopToTest = new GradientColorStop(new float[] { -0.5f, 1.5f, 0.5f, 0.5f }, 1.5, GradientColorStop.OffsetType .AUTO).SetHint(1.5, GradientColorStop.HintOffsetType.NONE); NUnit.Framework.Assert.AreEqual(new float[] { 0f, 1f, 0.5f }, stopToTest.GetRgbArray()); NUnit.Framework.Assert.AreEqual(0, stopToTest.GetOffset(), 1e-10); NUnit.Framework.Assert.AreEqual(GradientColorStop.OffsetType.AUTO, stopToTest.GetOffsetType()); NUnit.Framework.Assert.AreEqual(0, stopToTest.GetHintOffset(), 1e-10); NUnit.Framework.Assert.AreEqual(GradientColorStop.HintOffsetType.NONE, stopToTest.GetHintOffsetType()); }
private static void NormalizeAutoStops(IList <GradientColorStop> toNormalize) { System.Diagnostics.Debug.Assert(toNormalize[0].GetOffsetType() == GradientColorStop.OffsetType.RELATIVE); int firstAutoStopIndex = 1; GradientColorStop firstStopColor = toNormalize[0]; double prevOffset = firstStopColor.GetHintOffsetType() == GradientColorStop.HintOffsetType.RELATIVE_ON_GRADIENT ? firstStopColor.GetHintOffset() : firstStopColor.GetOffset(); for (int i = 1; i < toNormalize.Count; ++i) { GradientColorStop currentStop = toNormalize[i]; if (currentStop.GetOffsetType() == GradientColorStop.OffsetType.AUTO) { if (currentStop.GetHintOffsetType() == GradientColorStop.HintOffsetType.RELATIVE_ON_GRADIENT) { double hintOffset = currentStop.GetHintOffset(); NormalizeAutoStops(toNormalize, firstAutoStopIndex, i + 1, prevOffset, hintOffset); prevOffset = hintOffset; firstAutoStopIndex = i + 1; } } else { if (firstAutoStopIndex < i) { // current stop offset is relative double offset = currentStop.GetOffset(); NormalizeAutoStops(toNormalize, firstAutoStopIndex, i, prevOffset, offset); } firstAutoStopIndex = i + 1; prevOffset = currentStop.GetHintOffsetType() == GradientColorStop.HintOffsetType.RELATIVE_ON_GRADIENT ? currentStop .GetHintOffset() : currentStop.GetOffset(); } } // check whether the last interval has auto if (firstAutoStopIndex < toNormalize.Count) { double lastStopOffset = Math.Max(1, prevOffset); NormalizeAutoStops(toNormalize, firstAutoStopIndex, toNormalize.Count, prevOffset, lastStopOffset); } }
private static void AdjustStopsForPadIfNeeded(IList <GradientColorStop> stopsToConstruct, double[] coordinatesDomain ) { GradientColorStop firstStop = stopsToConstruct[0]; if (coordinatesDomain[0] < firstStop.GetOffset()) { stopsToConstruct.Add(0, new GradientColorStop(firstStop, coordinatesDomain[0], GradientColorStop.OffsetType .RELATIVE)); } GradientColorStop lastStop = stopsToConstruct[stopsToConstruct.Count - 1]; if (coordinatesDomain[1] > lastStop.GetOffset()) { stopsToConstruct.Add(new GradientColorStop(lastStop, coordinatesDomain[1], GradientColorStop.OffsetType.RELATIVE )); } }
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); }