コード例 #1
0
        public static float Calculate (Rule rule, DOMElement element) {
            try {
                // Cut unnecessary parts
                string value = rule.Value.Split(new[] { "calc(" }, StringSplitOptions.None)[1];
                value = value.ToLower();

                if (value[value.Length - 1] != ')') return -1f;
                else value = value.Substring(0, value.Length - 1);

                if (value.Length < 2) return -1f;

                // Cut pixel unit
                value = Compute(rule, element, value, Unit.Px, false);

                foreach (Unit unit in CSSUnits.allUnits) value = Compute(rule, element, value, unit);

                if (value == null) {
                    Console.WriteLine("Calc function isn't correct!");

                    return -1f;
                } else {
                    return float.Parse(new DataTable().Compute(value, "").ToString().Replace(',', '.'), CultureInfo.InvariantCulture.NumberFormat);
                }
            } catch (Exception exception) {
                Console.WriteLine(exception.Message);

                return -1f;
            }
        }
コード例 #2
0
        /// <summary>
        //  Calculates x times the size of the current font
        /// </summary>
        public static float EmToPx(Rule rule, DOMElement element)
        {
            float fontSize = (element.Parent != null) ? element.Parent.Style.Font.Size : 16; // 16 - Document font-size

            if (element.Style.Font != null)
            {
                fontSize = element.Style.Font.Size;
            }

            return(fontSize * rule.ComputedValue.Value);
        }
コード例 #3
0
        /// <summary>
        /// Calculates pixels from percent
        /// </summary>
        public static float PercentToPx(Rule rule, DOMElement element)
        {
            if (rule.Property == "width")
            {
                float parentWidth = (element.Parent != null) ? element.Parent.ComputedStyle.Size.Width : LayoutEngine.htmlDocument.Width;

                return((rule.ComputedValue.ValueBeforeComputing / 100) * parentWidth);
            }
            else if (rule.Property == "height")
            {
                float parentHeight = (element.Parent != null) ? element.Parent.Style.Size.Height : LayoutEngine.htmlDocument.Height;

                return((rule.ComputedValue.ValueBeforeComputing / 100) * parentHeight);
            }

            return(0f);
        }
コード例 #4
0
        public static CSSValue ParseValue(Rule rule, DOMElement element)
        {
            CSSValue cssValue = new CSSValue();

            if (rule.Value.StartsWith("calc("))
            {
                cssValue.Unit      = Unit.CalcFunc;
                rule.ComputedValue = cssValue;

                return(cssValue);
            }
            else
            {
                List <string> array = Regex.Split(rule.Value, @"[^0-9\.]+").Where(c => c != "." && c.Trim() != "").ToList();

                if (array.Count > 0 && rule.Value.Length > 2)
                {
                    float value      = float.Parse(array[0], CultureInfo.InvariantCulture.NumberFormat);
                    int   startIndex = value.ToString().Length;

                    string unitType = rule.Value.Substring(startIndex, rule.Value.Length - startIndex).ToLower();
                    cssValue.Value = value;

                    foreach (Unit unit in allUnits)
                    {
                        string abbreviation = GetUnitAbbreviation(unit);

                        if (unitType == abbreviation)
                        {
                            cssValue.Unit = unit;
                        }
                    }

                    rule.ComputedValue = cssValue;

                    cssValue.Value = ConvertAnyUnitToPixels(rule, element);
                    cssValue.ValueBeforeComputing = value;

                    return(cssValue);
                }
            }

            return(null);
        }
コード例 #5
0
        public static float ConvertAnyUnitToPixels(Rule rule, DOMElement element)
        {
            CSSValue cssValue = rule.ComputedValue;

            if (cssValue.Unit == Unit.Px)
            {
                return(cssValue.Value);
            }
            else if (cssValue.Unit == Unit.Cm)
            {
                return(CSSUnitsConverter.CmToPX(cssValue.Value));
            }
            else if (cssValue.Unit == Unit.Mm)
            {
                return(CSSUnitsConverter.MmToPX(cssValue.Value));
            }
            else if (cssValue.Unit == Unit.In)
            {
                return(CSSUnitsConverter.InToPX(cssValue.Value));
            }
            else if (cssValue.Unit == Unit.Percent)
            {
                return(CSSUnitsConverter.PercentToPx(rule, element));
            }
            else if (cssValue.Unit == Unit.Pt)
            {
                return(CSSUnitsConverter.PtToPX(cssValue.Value));
            }
            else if (cssValue.Unit == Unit.Em)
            {
                return(CSSUnitsConverter.EmToPx(rule, element));
            }
            else if (cssValue.Unit == Unit.Vh)
            {
                return(CSSUnitsConverter.VhToPx(rule, element));
            }
            else if (cssValue.Unit == Unit.Vw)
            {
                return(CSSUnitsConverter.VwToPx(rule, element));
            }

            return(-1f);
        }
コード例 #6
0
        private static string Compute (Rule rule, DOMElement element, string calcString, Unit unitType, bool convert = true) {
            while (true) {
                string unit = CSSUnits.GetUnitAbbreviation(unitType);

                int unitStartIndex = calcString.IndexOf(unit);
                int unitEndIndex = unitStartIndex + unit.Length;

                // If there is no unit
                if (unitStartIndex == -1) break;

                // Get starting value index
                int valueStartIndex = GetStartIndex(calcString, unitStartIndex);
                if (valueStartIndex == unitStartIndex) return null;

                // Get and parse value
                string value = calcString.Substring(valueStartIndex, unitStartIndex - valueStartIndex);
                float parsedValue = float.Parse(value, CultureInfo.InvariantCulture.NumberFormat);

                // Compute the value
                if (convert) {
                    rule.ComputedValue.Unit = unitType;
                    rule.ComputedValue.ValueBeforeComputing = parsedValue;
                    rule.ComputedValue.Value = parsedValue;
                }

                float computedValue = (convert) ? CSSUnits.ConvertAnyUnitToPixels(rule, element) : parsedValue;

                // Replace string with computed value
                StringBuilder stringBuilder = new StringBuilder(calcString);
                stringBuilder.Remove(valueStartIndex, unitStartIndex - valueStartIndex + unit.Length);
                stringBuilder.Insert(valueStartIndex, computedValue.ToString().Replace(',', '.'));

                calcString = stringBuilder.ToString();
            }

            return calcString;
        }
コード例 #7
0
        private static void SetPositions(List <DOMElement> elements)
        {
            foreach (DOMElement element in elements)
            {
                if (elements.IndexOf(element) > 0)
                {
                    DOMElement prevElement = elements[elements.IndexOf(element) - 1];

                    if (element.Style.Display == Display.InlineBlock || element.Style.Display == Display.TableCell)
                    {
                        element.ComputedStyle.Position.Y = prevElement.ComputedStyle.Position.Y + element.ComputedStyle.Padding.Top;
                        element.ComputedStyle.Position.X = 0;

                        if (prevElement.Style.Display == element.Style.Display)
                        {
                            element.ComputedStyle.Position.X += prevElement.ComputedStyle.Position.X + prevElement.ComputedStyle.Size.Width;
                        }
                        else
                        {
                            element.ComputedStyle.Position.Y += prevElement.ComputedStyle.Size.Height + prevElement.Style.Margin.Bottom + element.Style.Margin.Top;
                        }

                        element.ComputedStyle.Position.X += (prevElement.Style.Margin.Right >= element.Style.Margin.Left)
                            ? prevElement.Style.Margin.Right
                            : element.Style.Margin.Left;
                    }
                    else if (element.Style.Display == Display.Block || element.Style.Display == Display.TableRow || element.Style.Display == Display.Table)
                    {
                        element.ComputedStyle.Position.Y = prevElement.ComputedStyle.Position.Y + prevElement.ComputedStyle.Size.Height;
                        if (element.Parent != null)
                        {
                            element.ComputedStyle.Position.X = element.Parent.ComputedStyle.Position.X + element.ComputedStyle.Padding.Left;
                        }

                        element.ComputedStyle.Position.Y += (prevElement.Style.Margin.Bottom >= element.Style.Margin.Top)
                            ? prevElement.Style.Margin.Bottom
                            : element.Style.Margin.Top;

                        element.ComputedStyle.Position.X += (prevElement.Style.Margin.Right >= element.Style.Margin.Left)
                            ? prevElement.Style.Margin.Right
                            : element.Style.Margin.Left;
                    }

                    if (prevElement.Style.Display == Display.None)
                    {
                        element.ComputedStyle.Position.X = prevElement.ComputedStyle.Position.X;
                        element.ComputedStyle.Position.Y = prevElement.ComputedStyle.Position.Y;
                    }
                }
                else
                {
                    element.ComputedStyle.Position.Y = element.Style.Margin.Top;
                    element.ComputedStyle.Position.X = element.Style.Margin.Left;

                    if (element.Parent != null)
                    {
                        element.ComputedStyle.Position.Y += element.Parent.ComputedStyle.Position.Y;
                        element.ComputedStyle.Position.X += element.Parent.ComputedStyle.Position.X;
                    }

                    element.ComputedStyle.Position.Y += element.ComputedStyle.Padding.Top;
                    element.ComputedStyle.Position.X += element.ComputedStyle.Padding.Left;
                }

                if (element.Children.Count > 0)
                {
                    SetPositions(element.Children);
                }
            }
        }
コード例 #8
0
ファイル: HTML.cs プロジェクト: xnerhu/layout-engine
        private static List <DOMElement> GetDOMTree(List <Element> elements)
        {
            List <DOMElement> domElements = new List <DOMElement>();
            List <DOMElement> domTree     = new List <DOMElement>();

            for (int x = 0; x < elements.Count; x++)
            {
                // Initialize an DOMElement.
                DOMElement domElement = new DOMElement()
                {
                    Level = elements[x].Level
                };

                if (elements[x].Type == ElementType.Text)
                {
                    domElement.Content = elements[x].Content;
                    domElement.Type    = DOMElementType.Text;
                }
                else if (elements[x].Type == ElementType.Tag)
                {
                    domElement.Type = DOMElementType.Normal;
                    domElement.Tag  = elements[x].Tag;
                }

                bool canBeProcessed = false;

                if (elements[x].Type == ElementType.Text)
                {
                    canBeProcessed = true;
                }
                else if (elements[x].Type == ElementType.Tag)
                {
                    canBeProcessed = elements[x].Tag.Type == TagType.Opening || elements[x].Tag.Type == TagType.SelfClosing;
                }

                if (elements[x].Level != 0)
                {
                    if (canBeProcessed)
                    {
                        DOMElement parent = null;

                        // Get parent of current DOMElement.
                        for (int y = domElements.Count - 1; y >= 0; y--)
                        {
                            if (domElements[y].Level == domElement.Level - 1)
                            {
                                parent = domElements[y];
                                break;
                            }
                        }

                        if (parent != null)
                        {
                            // Set parent of current DOMElement.
                            domElement.Parent = parent;
                            // Add current DOMElement to parent's children list.
                            parent.Children.Add(domElement);
                        }
                    }
                }
                else
                {
                    if (canBeProcessed)
                    {
                        // Add DOMElements to domTree that have only level 0.
                        domTree.Add(domElement);
                    }
                }

                domElements.Add(domElement);
            }

            return(domTree);
        }
コード例 #9
0
 /// <summary>
 //  Calculates x percent of viewport width
 /// </summary>
 public static float VwToPx(Rule rule, DOMElement element)
 {
     return(rule.ComputedValue.Value / 100 * LayoutEngine.htmlDocument.getViewport().Width);
 }