Exemplo n.º 1
0
        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()));
        }
Exemplo n.º 2
0
        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]-->
            ");
        }