示例#1
0
        /// <summary>
        /// Init.
        /// </summary>
        public CssParser(RAdapter adapter)
        {
            ArgChecker.AssertArgNotNull(adapter, "global");

            _valueParser = new CssValueParser(adapter);
            _adapter = adapter;
        }
示例#2
0
        static void CreateSvgEllipse(SvgElement parentNode, HtmlElement elem)
        {
            SvgEllipseSpec spec  = new SvgEllipseSpec();
            SvgEllipse     shape = new SvgEllipse(spec, elem);

            parentNode.AddChild(shape);

            foreach (WebDom.DomAttribute attr in elem.GetAttributeIterForward())
            {
                WebDom.WellknownName wellknownName = (WebDom.WellknownName)attr.LocalNameIndex;

                switch (wellknownName)
                {
                case WebDom.WellknownName.Svg_Cx:
                {
                    spec.X = UserMapUtil.ParseGenericLength(attr.Value);
                } break;

                case WebDom.WellknownName.Svg_Cy:
                {
                    spec.Y = UserMapUtil.ParseGenericLength(attr.Value);
                } break;

                case WellknownName.Svg_Rx:
                {
                    spec.RadiusX = UserMapUtil.ParseGenericLength(attr.Value);
                } break;

                case WellknownName.Svg_Ry:
                {
                    spec.RadiusY = UserMapUtil.ParseGenericLength(attr.Value);
                } break;

                case WebDom.WellknownName.Svg_Fill:
                {
                    spec.ActualColor = CssValueParser.GetActualColor(attr.Value);
                } break;

                case WebDom.WellknownName.Svg_Stroke:
                {
                    spec.StrokeColor = CssValueParser.GetActualColor(attr.Value);
                } break;

                case WebDom.WellknownName.Svg_Stroke_Width:
                {
                    spec.StrokeWidth = UserMapUtil.ParseGenericLength(attr.Value);
                } break;

                case WebDom.WellknownName.Svg_Transform:
                {
                    //TODO: parse svg transform function
                } break;

                default:
                {
                    //other attrs
                } break;
                }
            }
        }
示例#3
0
        private void CalcTableSize(RGraphics g)
        {
            if (Display != CssConstants.None)
            {
                RectanglesReset();
                MeasureWordsSize(g);
            }

            double width = ContainingBlock.Size.Width
                           - ContainingBlock.ActualPaddingLeft - ContainingBlock.ActualPaddingRight
                           - ContainingBlock.ActualBorderLeftWidth - ContainingBlock.ActualBorderRightWidth;
            double height = ContainingBlock.Size.Height
                            - ContainingBlock.ActualPaddingTop - ContainingBlock.ActualPaddingBottom
                            - ContainingBlock.ActualBorderTopWidth - ContainingBlock.ActualBorderBottomWidth;

            bool _widthSpecified  = false;
            bool _heightSpecified = false;

            if (Width != CssConstants.Auto && !string.IsNullOrEmpty(Width))
            {
                width           = CssValueParser.ParseLength(Width, width, this);
                _widthSpecified = width > 0 ? true : false;
            }
            if (Height != CssConstants.Auto && !string.IsNullOrEmpty(Height))
            {
                height           = CssValueParser.ParseLength(Height, height, this);
                _heightSpecified = height > 0 ? true : false;
            }
            Size = new RSize(_widthSpecified ? width : 0, _heightSpecified ? height : 0);
        }
示例#4
0
        /// <summary>
        /// Handle mouse up to handle selection and link click.
        /// </summary>
        /// <param name="parent">the control hosting the html to invalidate</param>
        /// <param name="e">the mouse event args</param>
        public void HandleMouseUp(Control parent, MouseEventArgs e)
        {
            ArgChecker.AssertArgNotNull(parent, "parent");
            ArgChecker.AssertArgNotNull(e, "e");

            if (_selectionHandler != null)
            {
                var inSelection = _selectionHandler.HandleMouseUp(parent, e.Button);
                if (!inSelection && (e.Button & MouseButtons.Left) != 0)
                {
                    var loc  = OffsetByScroll(e.Location);
                    var link = DomUtils.GetLinkBox(_root, loc);
                    if (link != null)
                    {
                        if (LinkClicked != null)
                        {
                            var args = new HtmlLinkClickedEventArgs(link.GetAttribute("href"));
                            LinkClicked(this, args);
                            if (args.Handled)
                            {
                                return;
                            }
                        }

                        CssValueParser.GoLink(link.GetAttribute("href", string.Empty), Bridge);
                    }
                }
            }
        }
示例#5
0
        /// <summary>
        /// Assigns words its width and height
        /// </summary>
        /// <param name="g"></param>
        internal void MeasureWordsSize(Graphics g)
        {
            // Check if measure white space if not yet done to measure once
            if (!_wordsSizeMeasured)
            {
                MeasureWordSpacing(g);

                if (HtmlTag != null && HtmlTag.Name == "img")
                {
                    var image = CssValueParser.GetImage(GetAttribute("src"), HtmlContainer.Bridge);
                    var word  = new CssBoxWord(this, image);
                    Words.Clear();
                    Words.Add(word);
                }
                else if (Words.Count > 0)
                {
                    foreach (var boxWord in Words)
                    {
                        var sf = new StringFormat();
                        sf.SetMeasurableCharacterRanges(new[] { new CharacterRange(0, boxWord.Text.Length) });

                        var regions = g.MeasureCharacterRanges(boxWord.Text, ActualFont, new RectangleF(0, 0, float.MaxValue, float.MaxValue), sf);

                        SizeF  s = regions[0].GetBounds(g).Size;
                        PointF p = regions[0].GetBounds(g).Location;

                        boxWord.LastMeasureOffset = new PointF(p.X, p.Y);
                        boxWord.Width             = s.Width + ActualWordSpacing;
                        boxWord.Height            = s.Height;
                    }
                }
                _wordsSizeMeasured = true;
            }
        }
示例#6
0
        /// <summary>
        /// Measures the bounds of box and children, recursively.<br/>
        /// Performs layout of the DOM structure creating lines by set bounds restrictions.
        /// </summary>
        /// <param name="g">Device context to use</param>
        protected override void PerformLayoutImp(IGraphics g)
        {
            if (Display == CssConstants.None)
            {
                return;
            }

            RectanglesReset();

            CssBox prevSibling = DomUtils.GetPreviousSibling(this);
            float  left        = ContainingBlock.Location.X + ContainingBlock.ActualPaddingLeft + ActualMarginLeft +
                                 ContainingBlock.ActualBorderLeftWidth;
            float top = (prevSibling == null && ParentBox != null
                             ? ParentBox.ClientTop
                             : ParentBox == null ? Location.Y : 0) + MarginTopCollapse(prevSibling) +
                        (prevSibling != null ? prevSibling.ActualBottom + prevSibling.ActualBorderBottomWidth : 0);

            Location     = new PointF(left, top);
            ActualBottom = top;

            //width at 100% (or auto)
            float minwidth = GetMinimumWidth();
            float width    = ContainingBlock.Size.Width
                             - ContainingBlock.ActualPaddingLeft - ContainingBlock.ActualPaddingRight
                             - ContainingBlock.ActualBorderLeftWidth - ContainingBlock.ActualBorderRightWidth
                             - ActualMarginLeft - ActualMarginRight - ActualBorderLeftWidth - ActualBorderRightWidth;

            //Check width if not auto
            if (Width != CssConstants.Auto && !string.IsNullOrEmpty(Width))
            {
                width = CssValueParser.ParseLength(Width, width, this);
            }

            if (width < minwidth || width >= 9999)
            {
                width = minwidth;
            }

            float height = ActualHeight;

            if (height < 1)
            {
                height = Size.Height + ActualBorderTopWidth + ActualBorderBottomWidth;
            }
            if (height < 1)
            {
                height = 2;
            }
            if (height <= 2 && ActualBorderTopWidth < 1 && ActualBorderBottomWidth < 1)
            {
                BorderTopStyle    = BorderBottomStyle = CssConstants.Solid;
                BorderTopWidth    = "1px";
                BorderBottomWidth = "1px";
            }

            Size = new SizeF(width, height);

            ActualBottom = Location.Y + ActualPaddingTop + ActualPaddingBottom + height;
        }
示例#7
0
        public CssValue Parse(string cssValue)
        {
            var parser = new CssValueParser();

            parser.SetContext(cssValue);
            var val = parser.DoParse();

            return(val);
        }
示例#8
0
        /// <summary>
        /// Gets the white space width of the specified box
        /// </summary>
        /// <param name="g"></param>
        /// <param name="box"></param>
        /// <returns></returns>
        public static float WhiteSpace(Graphics g, CssBoxProperties box)
        {
            float w = MeasureWhitespace(g, box.ActualFont);

            if (!(String.IsNullOrEmpty(box.WordSpacing) || box.WordSpacing == CssConstants.Normal))
            {
                w += CssValueParser.ParseLength(box.WordSpacing, 0, box, true);
            }
            return(w);
        }
示例#9
0
        /// <summary>
        /// Gets the white space width of the specified box
        /// </summary>
        /// <param name="g"></param>
        /// <param name="box"></param>
        /// <returns></returns>
        public static double WhiteSpace(RGraphics g, CssBoxProperties box)
        {
            double w = box.ActualFont.GetWhitespaceWidth(g);

            if (!(String.IsNullOrEmpty(box.WordSpacing) || box.WordSpacing == CssConstants.Normal))
            {
                w += CssValueParser.ParseLength(box.WordSpacing, 0, box, true);
            }
            return(w);
        }
示例#10
0
        /// <summary>
        /// Measures the bounds of box and children, recursively.<br/>
        /// Performs layout of the DOM structure creating lines by set bounds restrictions.
        /// </summary>
        /// <param name="g">Device context to use</param>
        protected override void PerformLayoutImp(RGraphics g)
        {
            if (this.Display == CssConstants.None)
            {
                return;
            }

            this.RectanglesReset();

            var    prevSibling = DomUtils.GetPreviousSibling(this);
            double left        = this.ContainingBlock.Location.X + this.ContainingBlock.ActualPaddingLeft + this.ActualMarginLeft + this.ContainingBlock.ActualBorderLeftWidth;
            double top         = (prevSibling == null && this.ParentBox != null ? this.ParentBox.ClientTop : this.ParentBox == null ? this.Location.Y : 0) + this.MarginTopCollapse(prevSibling) + (prevSibling != null ? prevSibling.ActualBottom + prevSibling.ActualBorderBottomWidth : 0);

            this.Location     = new RPoint(left, top);
            this.ActualBottom = top;

            //width at 100% (or auto)
            double minwidth = this.GetMinimumWidth();
            double width    = this.ContainingBlock.Size.Width
                              - this.ContainingBlock.ActualPaddingLeft - this.ContainingBlock.ActualPaddingRight
                              - this.ContainingBlock.ActualBorderLeftWidth - this.ContainingBlock.ActualBorderRightWidth
                              - this.ActualMarginLeft - this.ActualMarginRight - this.ActualBorderLeftWidth - this.ActualBorderRightWidth;

            //Check width if not auto
            if (this.Width != CssConstants.Auto && !string.IsNullOrEmpty(this.Width))
            {
                width = CssValueParser.ParseLength(this.Width, width, this);
            }

            if (width < minwidth || width >= 9999)
            {
                width = minwidth;
            }

            double height = this.ActualHeight;

            if (height < 1)
            {
                height = this.Size.Height + this.ActualBorderTopWidth + this.ActualBorderBottomWidth;
            }
            if (height < 1)
            {
                height = 2;
            }
            if (height <= 2 && this.ActualBorderTopWidth < 1 && this.ActualBorderBottomWidth < 1)
            {
                this.BorderTopStyle    = this.BorderBottomStyle = CssConstants.Solid;
                this.BorderTopWidth    = "1px";
                this.BorderBottomWidth = "1px";
            }

            this.Size = new RSize(width, height);

            this.ActualBottom = this.Location.Y + this.ActualPaddingTop + this.ActualPaddingBottom + height;
        }
        /// <summary>
        /// Gets the available width for the whole table.
        /// It also sets the value of WidthSpecified
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// The table's width can be larger than the result of this method, because of the minimum
        /// size that individual boxes.
        /// </remarks>
        private double GetMaxTableWidth()
        {
            var tblen = new CssLength(_tableBox.MaxWidth);

            if (tblen.Number > 0)
            {
                _widthSpecified = true;
                return(CssValueParser.ParseLength(_tableBox.MaxWidth, _tableBox.ParentBox.AvailableWidth, _tableBox));
            }
            return(9999f);
        }
示例#12
0
        static CssLength SetLineHeight(this CssBox box, CssLength len)
        {
            //2014,2015,
            //from www.w3c.org/wiki/Css/Properties/line-height

            //line height in <percentage> :
            //The computed value if the property is percentage multiplied by the
            //element's computed font size.
            return(CssLength.MakePixelLength(
                       CssValueParser.ConvertToPx(len, box.GetEmHeight(), box)));
        }
示例#13
0
 /// <summary>
 /// Measures the width of whitespace between words (set <see cref="ActualWordSpacing"/>).
 /// </summary>
 protected void MeasureWordSpacing(RGraphics g)
 {
     if (double.IsNaN(ActualWordSpacing))
     {
         _actualWordSpacing = CssUtils.WhiteSpace(g, this);
         if (WordSpacing != CssConstants.Normal)
         {
             string len = RegexParserUtils.Search(RegexParserUtils.CssLength, WordSpacing);
             _actualWordSpacing += CssValueParser.ParseLength(len, 1, this);
         }
     }
 }
        public void SubArg()
        {
            var parser = new CssValueParser();

            parser.SetContext("fn(#fff)");
            var arg = parser.DoParse();

            Assert.IsTrue(parser.End);
            Assert.AreEqual(0, parser.Errors.Count);
            Assert.IsTrue(arg.IsValid);
            Assert.IsInstanceOfType(arg, typeof(CssSimpleValue));
            Assert.AreEqual("fn(#fff)", arg.ToString());
        }
        public void WithParenthesis()
        {
            var parser = new CssValueParser();

            parser.SetContext("(30%+10%)*3");
            var arg = parser.DoParse();

            Assert.IsTrue(parser.End);
            Assert.AreEqual(0, parser.Errors.Count);
            Assert.IsTrue(arg.IsValid);
            Assert.IsInstanceOfType(arg, typeof(CssArithmeticOperation));
            Assert.AreEqual("(30%+10%)*3", arg.ToString());
        }
示例#16
0
        /// <summary>
        /// Gets the available width for the whole table.
        /// It also sets the value of WidthSpecified
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// The table's width can be larger than the result of this method, because of the minimum
        /// size that individual boxes.
        /// </remarks>
        private float GetMaxTableWidth()
        {
            var tblen = new CssLength(_tableBox.MaxWidth);

            if (tblen.Number > 0)
            {
                _widthSpecified = true;
                return(tblen.IsPercentage ? CssValueParser.ParseNumber(tblen.Length, _tableBox.ParentBox.AvailableWidth) : tblen.Number);
            }
            else
            {
                return(9999f);
            }
        }
示例#17
0
        /// <summary>
        /// Gets the available width for the whole table.
        /// It also sets the value of WidthSpecified
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// The table's width can be larger than the result of this method, because of the minimum
        /// size that individual boxes.
        /// </remarks>
        private double GetAvailableTableWidth()
        {
            CssLength tblen = new CssLength(_tableBox.Width);

            if (tblen.Number > 0)
            {
                _widthSpecified = true;
                return(CssValueParser.ParseLength(_tableBox.Width, _tableBox.ParentBox.AvailableWidth, _tableBox));
            }
            else
            {
                return(_tableBox.ParentBox.AvailableWidth);
            }
        }
示例#18
0
        void CreateSvgPolygon(SvgElement parentNode, HtmlElement elem)
        {
            SvgPolygonSpec spec  = new SvgPolygonSpec();
            SvgPolygon     shape = new SvgPolygon(spec, elem);

            parentNode.AddChild(shape);
            foreach (WebDom.DomAttribute attr in elem.GetAttributeIterForward())
            {
                WebDom.WellknownName wellknownName = (WebDom.WellknownName)attr.LocalNameIndex;
                switch (wellknownName)
                {
                case WebDom.WellknownName.Svg_Points:
                {
                    //parse points
                    spec.Points = ParsePointList(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Fill:
                {
                    spec.FillColor = CssValueParser.GetActualColor(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Stroke:
                {
                    spec.StrokeColor = CssValueParser.GetActualColor(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Stroke_Width:
                {
                    spec.StrokeWidth = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Transform:
                {
                    //TODO: parse svg transform function
                }
                break;

                default:
                {
                    //other attrs
                }
                break;
                }
            }
        }
示例#19
0
 public void ParseCssBoxWidth(CssBox box)
 {
     if (!(_parentLength == 0 && box.Width.Trim().EndsWith("%")))
     {
         value = CssValueParser.ParseLength(box.Width, _parentLength, box);
     }
     if (!(_parentLength == 0 && box.MaxWidth.Trim().EndsWith("%")))
     {
         max = CssValueParser.ParseLength(box.MaxWidth, _parentLength, box);
     }
     if (!(_parentLength == 0 && box.MinWidth.Trim().EndsWith("%")))
     {
         min = CssValueParser.ParseLength(box.MinWidth, _parentLength, box);
     }
 }
示例#20
0
 public void ParseCssBoxHeight(CssBox box)
 {
     if (!(_parentLength == 0 && box.Height.Trim().EndsWith("%")))
     {
         value = CssValueParser.ParseLength(box.Height, _parentLength, box);
     }
     if (!(_parentLength == 0 && box.MaxHeight.Trim().EndsWith("%")))
     {
         max = CssValueParser.ParseLength(box.MaxHeight, _parentLength, box);
     }
     if (!(_parentLength == 0 && box.MinHeight.Trim().EndsWith("%")))
     {
         min = CssValueParser.ParseLength(box.MinHeight, _parentLength, box);
     }
 }
        public void Priority()
        {
            var parser = new CssValueParser();

            parser.SetContext("30%/fn(2,3)+10%*1.4+2*3");
            var arg = parser.DoParse();

            Assert.IsTrue(parser.End);
            Assert.AreEqual(0, parser.Errors.Count);
            Assert.IsTrue(arg.IsValid);
            Assert.IsInstanceOfType(arg, typeof(CssArithmeticOperation));
            Assert.AreEqual("30%/fn(2,3)+10%*1.4+2*3", arg.ToString());

            Assert.AreEqual("30%/fn(2,3)", ((CssArithmeticOperation)arg).Left.ToString());
            Assert.AreEqual("10%*1.4+2*3", ((CssArithmeticOperation)arg).Right.ToString());

            var o = ((CssArithmeticOperation)arg).Right;

            Assert.IsInstanceOfType(o, typeof(CssArithmeticOperation));
            Assert.AreEqual("10%*1.4", ((CssArithmeticOperation)o).Left.ToString());
            Assert.AreEqual("2*3", ((CssArithmeticOperation)o).Right.ToString());
        }
示例#22
0
        /// <summary>
        /// Gets the available width for the whole table.
        /// It also sets the value of <see cref="WidthSpecified"/>
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// The table's width can be larger than the result of this method, because of the minimum
        /// size that individual boxes.
        /// </remarks>
        private float GetAvailableWidth()
        {
            CssLength tblen = new CssLength(TableBox.Width);

            if (tblen.Number > 0)
            {
                _widthSpecified = true;

                if (tblen.IsPercentage)
                {
                    return(CssValueParser.ParseNumber(tblen.Length, TableBox.ParentBox.AvailableWidth));
                }
                else
                {
                    return(tblen.Number);
                }
            }
            else
            {
                return(TableBox.ParentBox.AvailableWidth);
            }
        }
示例#23
0
        static void CreateSvgGroupElement(SvgElement parentNode, HtmlElement elem)
        {
            SvgVisualSpec   spec            = new SvgVisualSpec();
            SvgGroupElement svgGroupElement = new SvgGroupElement(spec, elem);

            parentNode.AddChild(svgGroupElement);
            foreach (WebDom.DomAttribute attr in elem.GetAttributeIterForward())
            {
                WebDom.WellknownName wellknownName = (WebDom.WellknownName)attr.LocalNameIndex;
                switch (wellknownName)
                {
                case WebDom.WellknownName.Svg_Fill:
                {
                    spec.ActualColor = CssValueParser.GetActualColor(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Stroke:
                {
                    spec.StrokeColor = CssValueParser.GetActualColor(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Stroke_Width:
                {
                    spec.StrokeWidth = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                default:
                {
                    //other attrs
                }
                break;
                }
            }

            CreateSvgBoxContent(svgGroupElement, elem);
        }
示例#24
0
        /// <summary>
        /// Determine Row and Column Count, and ColumnWidths
        /// </summary>
        /// <returns></returns>
        private double CalculateCountAndWidth()
        {
            //Columns
            if (_columns.Count > 0)
            {
                _columnCount = _columns.Count;
            }
            else
            {
                foreach (CssBox b in _allRows)
                {
                    _columnCount = Math.Max(_columnCount, b.Boxes.Count);
                }
            }

            //Initialize column widths array with NaNs
            _columnWidths = new double[_columnCount];
            for (int i = 0; i < _columnWidths.Length; i++)
            {
                _columnWidths[i] = double.NaN;
            }

            double availCellSpace = GetAvailableCellWidth();

            if (_columns.Count > 0)
            {
                // Fill ColumnWidths array by scanning column widths
                for (int i = 0; i < _columns.Count; i++)
                {
                    CssLength len = new CssLength(_columns[i].Width); //Get specified width

                    if (len.Number > 0)                               //If some width specified
                    {
                        if (len.IsPercentage)                         //Get width as a percentage
                        {
                            _columnWidths[i] = CssValueParser.ParseNumber(_columns[i].Width, availCellSpace);
                        }
                        else if (len.Unit == CssUnit.Pixels || len.Unit == CssUnit.None)
                        {
                            _columnWidths[i] = len.Number; //Get width as an absolute-pixel value
                        }
                    }
                }
            }
            else
            {
                // Fill ColumnWidths array by scanning width in table-cell definitions
                foreach (CssBox row in _allRows)
                {
                    //Check for column width in table-cell definitions
                    for (int i = 0; i < _columnCount; i++)
                    {
                        if (i < 20 || double.IsNaN(_columnWidths[i])) // limit column width check
                        {
                            if (i < row.Boxes.Count && row.Boxes[i].Display == CssConstants.TableCell)
                            {
                                double len = CssValueParser.ParseLength(row.Boxes[i].Width, availCellSpace, row.Boxes[i]);
                                if (len > 0) //If some width specified
                                {
                                    int colspan = GetColSpan(row.Boxes[i]);
                                    len /= Convert.ToSingle(colspan);
                                    for (int j = i; j < i + colspan; j++)
                                    {
                                        _columnWidths[j] = double.IsNaN(_columnWidths[j]) ? len : Math.Max(_columnWidths[j], len);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(availCellSpace);
        }
示例#25
0
        /// <summary>
        /// Gets the span attribute of the tag of the specified box
        /// </summary>
        /// <param name="b"></param>
        private static int GetSpan(CssBox b)
        {
            double f = CssValueParser.ParseNumber(b.GetAttribute("span"), 1);

            return(Math.Max(1, Convert.ToInt32(f)));
        }
示例#26
0
        /// <summary>
        /// Write the given html tag with all its attributes and styles.
        /// </summary>
        /// <param name="sb">the string builder to write html into</param>
        /// <param name="box">the css box with the html tag to write</param>
        /// <param name="indent">the indent to use for nice formating</param>
        /// <param name="styleGen">Controls the way styles are generated when html is generated</param>
        private static void WriteHtmlTag(StringBuilder sb, CssBox box, int indent, HtmlGenerationStyle styleGen)
        {
            sb.Append(new string(' ', indent * 4));
            sb.AppendFormat("<{0}", box.HtmlTag.Name);

            // collect all element style properties incliding from stylesheet
            var tagStyles   = new Dictionary <string, string>();
            var tagCssBlock = box.HtmlContainer.CssData.GetCssBlock(box.HtmlTag.Name);

            if (tagCssBlock != null)
            {
                // atodo: handle selectors
                foreach (var cssBlock in tagCssBlock)
                {
                    foreach (var prop in cssBlock.Properties)
                    {
                        tagStyles[prop.Key] = prop.Value;
                    }
                }
            }

            if (box.HtmlTag.Attributes.Count > 0)
            {
                sb.Append(" ");
                foreach (var att in box.HtmlTag.Attributes)
                {
                    // handle image tags by inserting the image using base64 data
                    if (box.HtmlTag.Name == "img" && att.Key == "src" && (att.Value.StartsWith("property") || att.Value.StartsWith("method")))
                    {
                        var img = CssValueParser.GetImage(att.Value, box.HtmlContainer.Bridge);
                        if (img != null)
                        {
                            using (var buffer = new MemoryStream())
                            {
                                img.Save(buffer, ImageFormat.Png);
                                var base64 = Convert.ToBase64String(buffer.ToArray());
                                sb.AppendFormat("{0}=\"data:image/png;base64, {1}\" ", att.Key, base64);
                            }
                        }
                    }
                    else if (styleGen == HtmlGenerationStyle.Inline && att.Key == HtmlConstants.Style)
                    {
                        // if inline style add the styles to the collection
                        var block = CssParser.ParseCssBlockImp(box.HtmlTag.Name, box.HtmlTag.Attributes["style"]);
                        foreach (var prop in block.Properties)
                        {
                            tagStyles[prop.Key] = prop.Value;
                        }
                    }
                    else if (styleGen == HtmlGenerationStyle.Inline && att.Key == HtmlConstants.Class)
                    {
                        // if inline style convert the style class to actual properties and add to collection
                        var cssBlocks = box.HtmlContainer.CssData.GetCssBlock("." + att.Value);
                        if (cssBlocks != null)
                        {
                            // atodo: handle selectors
                            foreach (var cssBlock in cssBlocks)
                            {
                                foreach (var prop in cssBlock.Properties)
                                {
                                    tagStyles[prop.Key] = prop.Value;
                                }
                            }
                        }
                    }
                    else
                    {
                        sb.AppendFormat("{0}=\"{1}\" ", att.Key, att.Value);
                    }
                }

                sb.Remove(sb.Length - 1, 1);
            }

            // if inline style insert the style tag with all collected style properties
            if (styleGen == HtmlGenerationStyle.Inline && tagStyles.Count > 0)
            {
                sb.Append(" style=\"");
                foreach (var style in tagStyles)
                {
                    sb.AppendFormat("{0}: {1}; ", style.Key, style.Value);
                }
                sb.Remove(sb.Length - 1, 1);
                sb.Append("\"");
            }

            sb.AppendFormat("{0}>", box.HtmlTag.IsSingle ? "/" : "");
            sb.AppendLine();
        }
示例#27
0
        /// <summary>
        /// Analyzes the Table and assigns values to this CssTable object.
        /// To be called from the constructor
        /// </summary>
        private void Analyze(Graphics g)
        {
            #region Assign box kinds
            foreach (CssBox box in TableBox.Boxes)
            {
                switch (box.Display)
                {
                case CssConstants.TableCaption:
                    _caption = box;
                    break;

                case CssConstants.TableColumn:
                    for (int i = 0; i < GetSpan(box); i++)
                    {
                        Columns.Add(CreateColumn(box));
                    }
                    break;

                case CssConstants.TableColumnGroup:
                    if (box.Boxes.Count == 0)
                    {
                        int gspan = GetSpan(box);
                        for (int i = 0; i < gspan; i++)
                        {
                            Columns.Add(CreateColumn(box));
                        }
                    }
                    else
                    {
                        foreach (CssBox bb in box.Boxes)
                        {
                            int bbspan = GetSpan(bb);
                            for (int i = 0; i < bbspan; i++)
                            {
                                Columns.Add(CreateColumn(bb));
                            }
                        }
                    }
                    break;

                case CssConstants.TableFooterGroup:
                    if (FooterBox != null)
                    {
                        BodyRows.Add(box);
                    }
                    else
                    {
                        _footerBox = box;
                    }
                    break;

                case CssConstants.TableHeaderGroup:
                    if (HeaderBox != null)
                    {
                        BodyRows.Add(box);
                    }
                    else
                    {
                        _headerBox = box;
                    }
                    break;

                case CssConstants.TableRow:
                    BodyRows.Add(box);
                    break;

                case CssConstants.TableRowGroup:
                    foreach (CssBox childBox in box.Boxes)
                    {
                        if (childBox.Display == CssConstants.TableRow)
                        {
                            BodyRows.Add(childBox);
                        }
                    }
                    break;
                }
            }
            #endregion

            #region Gather AllRows

            if (HeaderBox != null)
            {
                _allRows.AddRange(HeaderBox.Boxes);
            }
            _allRows.AddRange(BodyRows);
            if (FooterBox != null)
            {
                _allRows.AddRange(FooterBox.Boxes);
            }

            #endregion

            #region Insert EmptyBoxes for vertical cell spanning

            if (!TableBox._tableFixed)
            {
                int           currow = 0;
                int           curcol = 0;
                List <CssBox> rows   = BodyRows;

                foreach (CssBox row in rows)
                {
                    curcol = 0;
                    for (int k = 0; k < row.Boxes.Count; k++)
                    {
                        CssBox cell    = row.Boxes[k];
                        int    rowspan = GetRowSpan(cell);
                        int    realcol = GetCellRealColumnIndex(row, cell); //Real column of the cell

                        for (int i = currow + 1; i < currow + rowspan; i++)
                        {
                            int colcount = 0;
                            for (int j = 0; j <= rows[i].Boxes.Count; j++)
                            {
                                if (colcount == realcol)
                                {
                                    rows[i].Boxes.Insert(colcount, new CssSpacingBox(TableBox, ref cell, currow));
                                    break;
                                }
                                colcount++;
                                realcol -= GetColSpan(rows[i].Boxes[j]) - 1;
                            }
                        }
                        curcol++;
                    }
                    currow++;
                }

                TableBox._tableFixed = true;
            }

            #endregion

            #region Determine Row and Column Count, and ColumnWidths

            //Rows
            _rowCount = BodyRows.Count + (HeaderBox != null ? HeaderBox.Boxes.Count : 0) + (FooterBox != null ? FooterBox.Boxes.Count : 0);

            //Columns
            if (Columns.Count > 0)
            {
                _columnCount = Columns.Count;
            }
            else
            {
                foreach (CssBox b in AllRows) //Check trhough rows
                {
                    _columnCount = Math.Max(_columnCount, b.Boxes.Count);
                }
            }

            //Initialize column widths array
            _columnWidths = new float[_columnCount];

            //Fill them with NaNs
            for (int i = 0; i < _columnWidths.Length; i++)
            {
                _columnWidths[i] = float.NaN;
            }

            float availCellSpace = GetAvailableCellWidth();

            if (Columns.Count > 0)
            {
                #region Fill ColumnWidths array by scanning column widths

                for (int i = 0; i < Columns.Count; i++)
                {
                    CssLength len = new CssLength(Columns[i].Width); //Get specified width

                    if (len.Number > 0)                              //If some width specified
                    {
                        if (len.IsPercentage)                        //Get width as a percentage
                        {
                            ColumnWidths[i] = CssValueParser.ParseNumber(Columns[i].Width, availCellSpace);
                        }
                        else if (len.Unit == CssUnit.Pixels || len.Unit == CssUnit.None)
                        {
                            ColumnWidths[i] = len.Number; //Get width as an absolute-pixel value
                        }
                    }
                }

                #endregion
            }
            else
            {
                #region Fill ColumnWidths array by scanning width in table-cell definitions
                foreach (CssBox row in AllRows)
                {
                    //Check for column width in table-cell definitions
                    for (int i = 0; i < _columnCount; i++)
                    {
                        if (float.IsNaN(ColumnWidths[i]) &&                    //Check if no width specified for column
                            i < row.Boxes.Count &&                             //And there's a box to check
                            row.Boxes[i].Display == CssConstants.TableCell)    //And the box is a table-cell
                        {
                            CssLength len = new CssLength(row.Boxes[i].Width); //Get specified width

                            if (len.Number > 0)                                //If some width specified
                            {
                                int   colspan = GetColSpan(row.Boxes[i]);
                                float flen    = 0f;
                                if (len.IsPercentage)//Get width as a percentage
                                {
                                    flen = CssValueParser.ParseNumber(row.Boxes[i].Width, availCellSpace);
                                }
                                else if (len.Unit == CssUnit.Pixels || len.Unit == CssUnit.None)
                                {
                                    flen = len.Number; //Get width as an absolute-pixel value
                                }
                                flen /= Convert.ToSingle(colspan);

                                for (int j = i; j < i + colspan; j++)
                                {
                                    ColumnWidths[j] = flen;
                                }
                            }
                        }
                    }
                }
                #endregion
            }

            #endregion

            #region Determine missing Column widths

            if (WidthSpecified) //If a width was specified,
            {
                //Assign NaNs equally with space left after gathering not-NaNs
                int   numberOfNans = 0;
                float occupedSpace = 0f;

                //Calculate number of NaNs and occuped space
                foreach (float t in ColumnWidths)
                {
                    if (float.IsNaN(t))
                    {
                        numberOfNans++;
                    }
                    else
                    {
                        occupedSpace += t;
                    }
                }

                //Determine width that will be assigned to un asigned widths
                float nanWidth = (availCellSpace - occupedSpace) / Convert.ToSingle(numberOfNans);

                for (int i = 0; i < ColumnWidths.Length; i++)
                {
                    if (float.IsNaN(ColumnWidths[i]))
                    {
                        ColumnWidths[i] = nanWidth;
                    }
                }
            }
            else
            {
                //Assign NaNs using full width
                float[] maxFullWidths = new float[ColumnWidths.Length];

                //Get the maximum full length of NaN boxes
                foreach (CssBox row in AllRows)
                {
                    for (int i = 0; i < row.Boxes.Count; i++)
                    {
                        int col = GetCellRealColumnIndex(row, row.Boxes[i]);

                        if (float.IsNaN(ColumnWidths[col]) &&
                            i < row.Boxes.Count &&
                            GetColSpan(row.Boxes[i]) == 1)
                        {
                            maxFullWidths[col] = Math.Max(maxFullWidths[col], row.Boxes[i].GetFullWidth(g));
                        }
                    }
                }

                for (int i = 0; i < ColumnWidths.Length; i++)
                {
                    if (float.IsNaN(ColumnWidths[i]))
                    {
                        ColumnWidths[i] = maxFullWidths[i];
                    }
                }
            }

            #endregion

            #region Reduce widths if necessary

            int curCol = 0;

            //While table width is larger than it should, and width is reductable
            while (GetWidthSum() > GetAvailableWidth() && CanReduceWidth())
            {
                while (!CanReduceWidth(curCol))
                {
                    curCol++;
                }

                ColumnWidths[curCol] -= 1f;

                curCol++;

                if (curCol >= ColumnWidths.Length)
                {
                    curCol = 0;
                }
            }

            #endregion

            #region Check for minimum sizes (increment widths if necessary)

            foreach (CssBox row in AllRows)
            {
                foreach (CssBox cell in row.Boxes)
                {
                    int colspan   = GetColSpan(cell);
                    int col       = GetCellRealColumnIndex(row, cell);
                    int affectcol = col + colspan - 1;

                    if (ColumnWidths[col] < ColumnMinWidths[col])
                    {
                        float diff = ColumnMinWidths[col] - ColumnWidths[col];
                        ColumnWidths[affectcol] = ColumnMinWidths[affectcol];

                        if (col < ColumnWidths.Length - 1)
                        {
                            ColumnWidths[col + 1] -= diff;
                        }
                    }
                }
            }

            #endregion

            #region Set table padding

            //Ensure there's no padding
            TableBox.PaddingLeft = TableBox.PaddingTop = TableBox.PaddingRight = TableBox.PaddingBottom = "0";

            #endregion

            #region Layout cells

            //Actually layout cells!
            float startx     = TableBox.ClientLeft + HorizontalSpacing;
            float starty     = TableBox.ClientTop + VerticalSpacing;
            float curx       = startx;
            float cury       = starty;
            float maxRight   = startx;
            float maxBottom  = 0f;
            int   currentrow = 0;

            for (int i = 0; i < AllRows.Count; i++)
            {
                var row = AllRows[i];
                curx   = startx;
                curCol = 0;

                for (int j = 0; j < row.Boxes.Count; j++)
                {
                    CssBox cell = row.Boxes[j];
                    if (curCol >= ColumnWidths.Length)
                    {
                        break;
                    }

                    int   rowspan     = GetRowSpan(cell);
                    var   columnIndex = GetCellRealColumnIndex(row, cell);
                    float width       = GetCellWidth(columnIndex, cell);
                    cell.Location = new PointF(curx, cury);
                    cell.Size     = new SizeF(width, 0f);
                    cell.MeasureBounds(g); //That will automatically set the bottom of the cell

                    //Alter max bottom only if row is cell's row + cell's rowspan - 1
                    CssSpacingBox sb = cell as CssSpacingBox;
                    if (sb != null)
                    {
                        if (sb.EndRow == currentrow)
                        {
                            maxBottom = Math.Max(maxBottom, sb.ExtendedBox.ActualBottom);
                        }
                    }
                    else if (rowspan == 1)
                    {
                        maxBottom = Math.Max(maxBottom, cell.ActualBottom);
                    }
                    maxRight = Math.Max(maxRight, cell.ActualRight);
                    curCol++;
                    curx = cell.ActualRight + HorizontalSpacing;
                }

                foreach (CssBox cell in row.Boxes)
                {
                    CssSpacingBox spacer = cell as CssSpacingBox;

                    if (spacer == null && GetRowSpan(cell) == 1)
                    {
                        cell.ActualBottom = maxBottom;
                        CssLayoutEngine.ApplyCellVerticalAlignment(g, cell);
                    }
                    else if (spacer != null && spacer.EndRow == currentrow)
                    {
                        spacer.ExtendedBox.ActualBottom = maxBottom;
                        CssLayoutEngine.ApplyCellVerticalAlignment(g, spacer.ExtendedBox);
                    }
                }

                cury = maxBottom + VerticalSpacing;
                currentrow++;
            }

            TableBox.ActualRight  = maxRight + HorizontalSpacing + TableBox.ActualBorderRightWidth;
            TableBox.ActualBottom = maxBottom + VerticalSpacing + TableBox.ActualBorderBottomWidth;

            #endregion
        }
示例#28
0
        /// <summary>
        /// Creates a new CssLength from a length specified on a CSS style sheet or fragment
        /// </summary>
        /// <param name="length">Length as specified in the Style Sheet or style fragment</param>
        public CssLength(string length)
        {
            _length       = length;
            _number       = 0f;
            _unit         = CssUnit.None;
            _isPercentage = false;

            //Return zero if no length specified, zero specified
            if (string.IsNullOrEmpty(length) || length == "0")
            {
                return;
            }

            //If percentage, use ParseNumber
            if (length.EndsWith("%"))
            {
                _number       = CssValueParser.ParseNumber(length, 1);
                _isPercentage = true;
                return;
            }

            //If no units, has error
            if (length.Length < 3)
            {
                double.TryParse(length, out _number);
                _hasError = true;
                return;
            }

            //Get units of the length
            string u = length.Substring(length.Length - 2, 2);

            //Number of the length
            string number = length.Substring(0, length.Length - 2);

            //TODO: Units behave different in paper and in screen!
            switch (u)
            {
            case CssConstants.Em:
                _unit       = CssUnit.Ems;
                _isRelative = true;
                break;

            case CssConstants.Ex:
                _unit       = CssUnit.Ex;
                _isRelative = true;
                break;

            case CssConstants.Px:
                _unit       = CssUnit.Pixels;
                _isRelative = true;
                break;

            case CssConstants.Mm:
                _unit = CssUnit.Milimeters;
                break;

            case CssConstants.Cm:
                _unit = CssUnit.Centimeters;
                break;

            case CssConstants.In:
                _unit = CssUnit.Inches;
                break;

            case CssConstants.Pt:
                _unit = CssUnit.Points;
                break;

            case CssConstants.Pc:
                _unit = CssUnit.Picas;
                break;

            default:
                _hasError = true;
                return;
            }

            if (!double.TryParse(number, NumberStyles.Number, NumberFormatInfo.InvariantInfo, out _number))
            {
                _hasError = true;
            }
        }
示例#29
0
        static void CreateSvgLinearGradient(SvgElement parentNode, HtmlElement elem)
        {
            //linear gradient definition

            SvgLinearGradient linearGradient = new SvgLinearGradient(elem);

            foreach (WebDom.DomAttribute attr in elem.GetAttributeIterForward())
            {
                WebDom.WellknownName wellknownName = (WebDom.WellknownName)attr.LocalNameIndex;
                switch (wellknownName)
                {
                case WellknownName.Svg_X1:
                {
                    linearGradient.X1 = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WellknownName.Svg_X2:
                {
                    linearGradient.X2 = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WellknownName.Svg_Y1:
                {
                    linearGradient.Y1 = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WellknownName.Svg_Y2:
                {
                    linearGradient.Y2 = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;
                }
            }
            //------------------------------------------------------------
            int j = elem.ChildrenCount;
            List <StopColorPoint> stopColorPoints = new List <StopColorPoint>(j);

            for (int i = 0; i < j; ++i)
            {
                HtmlElement node = elem.GetChildNode(i) as HtmlElement;
                if (node == null)
                {
                    continue;
                }
                switch (node.WellknownElementName)
                {
                case WellKnownDomNodeName.svg_stop:
                {
                    //stop point
                    StopColorPoint stopPoint = new StopColorPoint();
                    foreach (WebDom.DomAttribute attr in node.GetAttributeIterForward())
                    {
                        WebDom.WellknownName wellknownName = (WebDom.WellknownName)attr.LocalNameIndex;
                        switch (wellknownName)
                        {
                        case WellknownName.Svg_StopColor:
                        {
                            stopPoint.StopColor = CssValueParser.GetActualColor(attr.Value);
                        }
                        break;

                        case WellknownName.Svg_Offset:
                        {
                            stopPoint.Offset = UserMapUtil.ParseGenericLength(attr.Value);
                        }
                        break;
                        }
                    }
                    stopColorPoints.Add(stopPoint);
                }
                break;
                }
            }
        }
示例#30
0
        static void CreateSvgPath(SvgElement parentNode, HtmlElement elem)
        {
            SvgPathSpec spec    = new SvgPathSpec();
            SvgPath     svgPath = new SvgPath(spec, elem);

            parentNode.AddChild(svgPath);
            foreach (WebDom.DomAttribute attr in elem.GetAttributeIterForward())
            {
                WebDom.WellknownName wellknownName = (WebDom.WellknownName)attr.LocalNameIndex;
                switch (wellknownName)
                {
                case WebDom.WellknownName.Svg_X:
                {
                    spec.X = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Y:
                {
                    spec.Y = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WebDom.WellknownName.Width:
                {
                    spec.Width = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WebDom.WellknownName.Height:
                {
                    spec.Height = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Fill:
                {
                    spec.ActualColor = CssValueParser.GetActualColor(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Stroke:
                {
                    spec.StrokeColor = CssValueParser.GetActualColor(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Stroke_Width:
                {
                    spec.StrokeWidth = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Transform:
                {
                    //TODO: parse svg transform function
                }
                break;

                default:
                {
                    //other attrs
                    switch (attr.Name)
                    {
                    case "d":
                    {
                        //parse vertex commands
                        Svg.Pathing.SvgPathDataParser parser = new Svg.Pathing.SvgPathDataParser();
                        svgPath.Segments = parser.Parse(attr.Value.ToCharArray());
                    }
                    break;
                    }
                }
                break;
                }
            }
        }
示例#31
0
        static void CreateSvgImage(SvgElement parentNode, HtmlElement elem)
        {
            SvgImageSpec spec     = new SvgImageSpec();
            SvgImage     svgImage = new SvgImage(spec, elem);

            parentNode.AddChild(svgImage);
            foreach (WebDom.DomAttribute attr in elem.GetAttributeIterForward())
            {
                WebDom.WellknownName wellknownName = (WebDom.WellknownName)attr.LocalNameIndex;
                switch (wellknownName)
                {
                case WebDom.WellknownName.Svg_X:
                {
                    spec.X = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Y:
                {
                    spec.Y = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WebDom.WellknownName.Width:
                {
                    spec.Width = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WebDom.WellknownName.Height:
                {
                    spec.Height = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Fill:
                {
                    spec.ActualColor = CssValueParser.GetActualColor(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Stroke:
                {
                    spec.StrokeColor = CssValueParser.GetActualColor(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Stroke_Width:
                {
                    spec.StrokeWidth = UserMapUtil.ParseGenericLength(attr.Value);
                }
                break;

                case WebDom.WellknownName.Svg_Transform:
                {
                    //TODO: parse svg transform function
                }
                break;

                case WellknownName.Href:
                {
                    //image src***
                    spec.ImageSrc = attr.Value;
                }
                break;

                default:
                {
                }
                break;
                }
            }
        }