private static PdfFunction ConstructSingleGradientSegmentFunction(GradientColorStop from, GradientColorStop to) { double exponent = 1d; float[] fromColor = from.GetRgbArray(); float[] toColor = to.GetRgbArray(); if (from.GetHintOffsetType() == GradientColorStop.HintOffsetType.RELATIVE_BETWEEN_COLORS) { double hintOffset = from.GetHintOffset(); if (hintOffset <= 0d + ZERO_EPSILON) { fromColor = toColor; } else { if (hintOffset >= 1d - ZERO_EPSILON) { toColor = fromColor; } else { // similar to css color hint logic exponent = Math.Log(0.5) / Math.Log(hintOffset); } } } return(new PdfFunction.Type2(new PdfArray(new float[] { 0f, 1f }), null, new PdfArray(fromColor), new PdfArray (toColor), new PdfNumber(exponent))); }
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 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); }