public CssCoordinate CalculateBackgroundAxisOrigin(string axis, CssCoordinate coordinate) { bool isX = axis.Equals("x", StringComparison.InvariantCultureIgnoreCase); bool isBackgroundRepeat = HasAttribute("background-repeat") && GetAttribute("background-repeat").Equals("repeat", StringComparison.InvariantCultureIgnoreCase); string position = isX ? coordinate.X : coordinate.Y; string origin = isX ? coordinate.X : coordinate.Y; float positionFloat; float originFloat; if (position.Contains("%")) { var percentage = CssUnitParser.Parse(position); if (isBackgroundRepeat) { positionFloat = percentage.Value; originFloat = percentage.Value; } else { float computed = (-50 + (percentage.Value * 100)) / 100; positionFloat = computed; originFloat = computed; } } else if (isBackgroundRepeat) { positionFloat = isX ? 0.5f : 0f; originFloat = isX ? 0.5f : 0f; } else { positionFloat = isX ? 0f : -0.5f; originFloat = isX ? 0f : -0.5f; } return(new CssCoordinate(originFloat.ToString(), positionFloat.ToString())); }
public string RenderWithBackground(string content) { CssParsedUnit containerWidth = CssUnitParser.Parse($"{GetContainerOuterWidth()}"); bool isFullWidth = IsFullWidth(); bool isPercentage = containerWidth.Unit.Equals("%", StringComparison.InvariantCultureIgnoreCase); CssCoordinate backgroundPosition = GetBackgroundPosition(); // LR: Convert direction to Percentage X switch (backgroundPosition.X) { case "left": backgroundPosition.X = "0%"; break; case "center": backgroundPosition.X = "50%"; break; case "right": backgroundPosition.X = "100%"; break; default: if (!backgroundPosition.X.ToString().Contains("%")) { backgroundPosition.X = "50%"; } break; } // LR: Convert direction to Percentage Y switch (backgroundPosition.Y) { case "top": backgroundPosition.Y = "0%"; break; case "center": backgroundPosition.Y = "50%"; break; case "bottom": backgroundPosition.Y = "100%"; break; default: if (!backgroundPosition.Y.ToString().Contains("%")) { backgroundPosition.Y = "0%"; } break; } // LR: Calculate position to origin // X = Axis Origin, Y = Axis Position // This logic is different when using repeat or no-repeat var originX = CalculateBackgroundAxisOrigin("x", backgroundPosition); var originY = CalculateBackgroundAxisOrigin("y", backgroundPosition); Dictionary <string, string> vSizeAttributes = new Dictionary <string, string>(); // If background size is either cover or contain, we tell VML to keep the aspect // and fill the entire element. if (GetAttribute("background-size").Equals("cover", StringComparison.InvariantCultureIgnoreCase) || GetAttribute("background-size").Equals("contain", StringComparison.InvariantCultureIgnoreCase)) { vSizeAttributes = new Dictionary <string, string> { { "size", "1,1" }, { "aspect", GetAttribute("background-size").Equals("cover", StringComparison.InvariantCultureIgnoreCase) ? "atleast" : "atmost" }, }; } else if (!GetAttribute("background-size").Equals("auto", StringComparison.InvariantCultureIgnoreCase)) { string backgroundSize = GetAttribute("background-size"); var bgSplit = backgroundSize.Split(' '); if (bgSplit.Length.Equals(1)) { vSizeAttributes = new Dictionary <string, string> { { "size", GetAttribute("background-size") }, { "aspect", "atmost" }, // reproduces height auto }; } else { vSizeAttributes = new Dictionary <string, string> { { "size", backgroundSize.Replace(' ', ',') }, }; } } var vmlType = GetAttribute("background-repeat").Equals("no-repeat", StringComparison.InvariantCultureIgnoreCase) ? "frame" : "tile"; if (GetAttribute("background-size").Equals("auto", StringComparison.InvariantCultureIgnoreCase)) { vmlType = "tile"; // If no size provided, keep old behavior because outlook can't use original image size with "frame" // Also ensure that images are still cropped the same way originX = new CssCoordinate("0.5", "0.5"); originY = new CssCoordinate("0", "0"); } return($@" <!--[if mso | IE]> <v:rect {HtmlAttributes(new Dictionary<string, string> { { "style", isFullWidth ? InlineCss(new Dictionary<string, string>{ { "mso-width-percent", "1000"} }) : InlineCss(new Dictionary<string, string>{ { "width", $"{GetContainerOuterWidth()}px" } }) }, { "xmlns:v", "urn:schemas-microsoft-com:vml"}, { "fill", "true"}, { "stroke", "false"}, })}> <v:fill {HtmlAttributes(new Dictionary<string, string> { { "origin", $"{originX.X}, {originY.X}"}, { "position", $"{originX.Y}, {originY.Y}" }, { "src", GetAttribute("background-url") }, { "color", GetAttribute("background-color") }, { "type", vmlType } }.MergeLeft(vSizeAttributes))} /> <v:textbox style=""mso-fit-shape-to-text:true"" inset=""0,0,0,0""> <![endif]--> {content} <!--[if mso | IE]> </v:textbox> </v:rect> <![endif]--> "); }