// TODO: DEVSIX-4136 opacity is not supported now. // The opacity should be equal to 'parentOpacity * stopRenderer.getStopOpacity() * stopColor[3]' private IList <GradientColorStop> ParseStops(float parentOpacity) { IList <GradientColorStop> stopsList = new List <GradientColorStop>(); foreach (StopSvgNodeRenderer stopRenderer in GetChildStopRenderers()) { float[] stopColor = stopRenderer.GetStopColor(); double offset = stopRenderer.GetOffset(); stopsList.Add(new GradientColorStop(stopColor, offset, GradientColorStop.OffsetType.RELATIVE)); } if (!stopsList.IsEmpty()) { GradientColorStop firstStop = stopsList[0]; if (firstStop.GetOffset() > 0) { stopsList.Add(0, new GradientColorStop(firstStop, 0f, GradientColorStop.OffsetType.RELATIVE)); } GradientColorStop lastStop = stopsList[stopsList.Count - 1]; if (lastStop.GetOffset() < 1) { stopsList.Add(new GradientColorStop(lastStop, 1f, GradientColorStop.OffsetType.RELATIVE)); } } return(stopsList); }
private static void AddStopColors(AbstractLinearGradientBuilder builder, IList <String> argumentsList, int stopsStartIndex, float emValue, float remValue) { GradientColorStop lastCreatedStopColor = null; int lastStopIndex = argumentsList.Count - 1; for (int i = stopsStartIndex; i <= lastStopIndex; ++i) { String argument = argumentsList[i]; IList <String> elementsList = new List <String>(); CssDeclarationValueTokenizer tokenizer = new CssDeclarationValueTokenizer(argument); CssDeclarationValueTokenizer.Token nextToken; while ((nextToken = tokenizer.GetNextValidToken()) != null) { elementsList.Add(nextToken.GetValue()); } // cases: color, color + offset, color + offset + offset, offset (hint) if (elementsList.IsEmpty() || elementsList.Count > 3) { throw new StyledXMLParserException(MessageFormatUtil.Format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE , argument)); } if (CssUtils.IsColorProperty(elementsList[0])) { float[] rgba = CssUtils.ParseRgbaColor(elementsList[0]); if (elementsList.Count == 1) { UnitValue offset = i == stopsStartIndex ? new UnitValue(UnitValue.PERCENT, 0f) : i == lastStopIndex ? new UnitValue(UnitValue.PERCENT, 100f) : null; lastCreatedStopColor = CreateStopColor(rgba, offset); builder.AddColorStop(lastCreatedStopColor); } else { for (int j = 1; j < elementsList.Count; ++j) { if (CssUtils.IsNumericValue(elementsList[j])) { // the numeric value is invalid in linear gradient function. // So check it here as parsing method will use the default pt metric throw new StyledXMLParserException(MessageFormatUtil.Format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE , argument)); } UnitValue offset = CssUtils.ParseLengthValueToPt(elementsList[j], emValue, remValue); if (offset == null) { throw new StyledXMLParserException(MessageFormatUtil.Format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE , argument)); } lastCreatedStopColor = CreateStopColor(rgba, offset); builder.AddColorStop(lastCreatedStopColor); } } } else { // it should be a color hint case if (elementsList.Count != 1 || lastCreatedStopColor == null || lastCreatedStopColor.GetHintOffsetType() != GradientColorStop.HintOffsetType.NONE || i == lastStopIndex) { // hint is not a single value, or no color at the beginning, // or two hints in a row, or hint as a last value throw new StyledXMLParserException(MessageFormatUtil.Format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE , argument)); } UnitValue hint = CssUtils.ParseLengthValueToPt(elementsList[0], emValue, remValue); if (hint == null) { throw new StyledXMLParserException(MessageFormatUtil.Format(StyledXMLParserException.INVALID_GRADIENT_COLOR_STOP_VALUE , argument)); } if (hint.GetUnitType() == UnitValue.PERCENT) { lastCreatedStopColor.SetHint(hint.GetValue() / 100, GradientColorStop.HintOffsetType.RELATIVE_ON_GRADIENT); } else { lastCreatedStopColor.SetHint(hint.GetValue(), GradientColorStop.HintOffsetType.ABSOLUTE_ON_GRADIENT); } } } }