Beispiel #1
0
        /// <summary>
        /// Static constructor and initialization
        /// </summary>
        static CssBox()
        {
            #region Initialize _properties, _inheritables and _defaults Dictionaries
            
            _properties = new Dictionary<string, PropertyInfo>();
            _defaults = new Dictionary<string, string>();
            _inheritables = new List<PropertyInfo>();
            _cssproperties = new List<PropertyInfo>();

            PropertyInfo[] props = typeof(CssBox).GetProperties();
            for (int i = 0; i < props.Length; i++)
            {
                CssPropertyAttribute att = Attribute.GetCustomAttribute(props[i], typeof(CssPropertyAttribute)) as CssPropertyAttribute;

                if (att != null)
                {
                    _properties.Add(att.Name, props[i]);
                    _defaults.Add(att.Name, GetDefaultValue(props[i]));
                    _cssproperties.Add(props[i]);

                    CssPropertyInheritedAttribute inh = Attribute.GetCustomAttribute(props[i], typeof(CssPropertyInheritedAttribute)) as CssPropertyInheritedAttribute;

                    if (inh != null)
                    {
                        _inheritables.Add(props[i]);
                    }
                }
            } 
            #endregion

            Empty = new CssBox();
            
        }
Beispiel #2
0
        /// <summary>
        /// Parses a length. Lengths are followed by an unit identifier (e.g. 10px, 3.1em)
        /// </summary>
        /// <param name="length">Specified length</param>
        /// <param name="hundredPercent">Equivalent to 100 percent when length is percentage</param>
        /// <param name="box"></param>
        /// <param name="useParentsEm"></param>
        /// <param name="returnPoints">Allows the return float to be in points. If false, result will be pixels</param>
        /// <returns></returns>
        public static float ParseLength(string length, float hundredPercent, CssBox box, float emFactor, bool returnPoints)
        {
            //Return zero if no length specified, zero specified
            if (string.IsNullOrEmpty(length) || length == "0") return 0f;

            //If percentage, use ParseNumber
            if (length.EndsWith("%")) return ParseNumber(length, hundredPercent);

            //If no units, return zero
            if (length.Length < 3) return 0f;

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

            //Factor will depend on the unit
            float factor = 1f;

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

            //TODO: Units behave different in paper and in screen!
            switch (unit)
            {
                case CssConstants.Em:
                    factor = emFactor;
                    break;
                case CssConstants.Px:
                    factor = 1f;
                    break;
                case CssConstants.Mm:
                    factor = 3f; //3 pixels per millimeter
                    break;
                case CssConstants.Cm:
                    factor = 37f; //37 pixels per centimeter
                    break;
                case CssConstants.In:
                    factor = 96f; //96 pixels per inch
                    break;
                case CssConstants.Pt:
                    factor = 96f / 72f; // 1 point = 1/72 of inch

                    if (returnPoints)
                    {
                        return ParseNumber(number, hundredPercent);
                    }

                    break;
                case CssConstants.Pc:
                    factor = 96f / 72f * 12f; // 1 pica = 12 points
                    break;
                default:
                    factor = 0f;
                    break;
            }

            

            return factor * ParseNumber(number, hundredPercent);
        }
Beispiel #3
0
 /// <summary>
 /// Creates a new LineBox
 /// </summary>
 public CssLineBox(CssBox ownerBox)
 {
     _rects = new Dictionary<CssBox, RectangleF>();
     _relatedBoxes = new List<CssBox>();
     _words = new List<CssBoxWord>();
     _ownerBox = ownerBox;
     _ownerBox.LineBoxes.Add(this);
 }
Beispiel #4
0
            public SpacingBox(CssBox tableBox, ref CssBox extendedBox, int startRow)
                : base(tableBox, new HtmlTag("<none colspan=" + extendedBox.GetAttribute("colspan", "1") + ">"))
            {
                ExtendedBox = extendedBox;
                Display = CssConstants.None;

                _startRow = startRow;
                _endRow = startRow + int.Parse(extendedBox.GetAttribute("rowspan", "1")) - 1;
            }
Beispiel #5
0
        public CssTable(CssBox tableBox, Graphics g)
            :this()
        {
            if (!(tableBox.Display == CssConstants.Table || tableBox.Display == CssConstants.InlineTable))
                throw new ArgumentException("Box is not a table", "tableBox");

            _tableBox = tableBox;

            MeasureWords(tableBox, g);

            Analyze(g);
        }
        public CssAnonymousBlockBox(CssBox parent, CssBox insertBefore)
            : this(parent)
        {
            int index = parent.Boxes.IndexOf(insertBefore);

            if (index < 0)
            {
                throw new Exception("insertBefore box doesn't exist on parent");
            }
            parent.Boxes.Remove(this);
            parent.Boxes.Insert(index, this);
        }
Beispiel #7
0
        /// <summary>
        /// Creates line boxes for the specified blockbox
        /// </summary>
        /// <param name="g"></param>
        /// <param name="blockBox"></param>
        public static void CreateLineBoxes(Graphics g, CssBox blockBox)
        {

            blockBox.LineBoxes.Clear();

            float maxRight = blockBox.ActualRight - blockBox.ActualPaddingRight - blockBox.ActualBorderRightWidth;

            //Get the start x and y of the blockBox
            float startx = blockBox.Location.X + blockBox.ActualPaddingLeft - 0 + blockBox.ActualBorderLeftWidth; //TODO: Check for floats
            float starty = blockBox.Location.Y + blockBox.ActualPaddingTop - 0 + blockBox.ActualBorderTopWidth;
            float curx = startx + blockBox.ActualTextIndent;
            float cury = starty;

            //Reminds the maximum bottom reached
            float maxBottom = starty;

            //Extra amount of spacing that should be applied to lines when breaking them.
            float lineSpacing = 0f;

            //First line box
            CssLineBox line = new CssLineBox(blockBox);

            //Flow words and boxes
            FlowBox(g, blockBox, blockBox, maxRight, lineSpacing, startx,ref line, ref curx, ref cury, ref maxBottom);

            //Gets the rectangles foreach linebox
            foreach (CssLineBox linebox in blockBox.LineBoxes)
            {
                
                BubbleRectangles(blockBox, linebox);
                linebox.AssignRectanglesToBoxes();
                ApplyAlignment(g, linebox);
                if (blockBox.Direction == CssConstants.Rtl) ApplyRightToLeft(linebox);

                //linebox.DrawRectangles(g);
            }

            blockBox.ActualBottom = maxBottom + blockBox.ActualPaddingBottom + blockBox.ActualBorderBottomWidth;
        }
Beispiel #8
0
        /// <summary>
        /// Gets the cell column index checking its position and other cells colspans
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cell"></param>
        /// <returns></returns>
        private int GetCellRealColumnIndex(CssBox row, CssBox cell)
        {
            int i = 0;

            foreach (CssBox b in row.Boxes)
            {
                if (b.Equals(cell)) break;
                i += GetColSpan(b);
            }

            return i;
        }
Beispiel #9
0
        /// <summary>
        /// Gets the spanned width of a cell
        /// (With of all columns it spans minus one)
        /// </summary>
        /// <param name="row"></param>
        /// <param name="cell"></param>
        /// <param name="realcolindex"></param>
        /// <param name="colspan"></param>
        /// <returns></returns>
        private float GetSpannedMinWidth(CssBox row, CssBox cell, int realcolindex, int colspan)
        {
            float w = 0f;

            for (int i = realcolindex; i < row.Boxes.Count || i < realcolindex + colspan - 1; i++)
            {
                w += ColumnMinWidths[i];
            }

            return w;
        }
Beispiel #10
0
        /// <summary>
        /// Analyzes the Table and assigns values to this CssTable object.
        /// To be called from the constructor
        /// </summary>
        private void Analyze(Graphics g)
        {
            float availSpace = GetAvailableWidth();
            float availCellSpace = float.NaN; //Will be set later

            #region Assign box kinds
            foreach (CssBox b in TableBox.Boxes)
            {
                b.RemoveAnonymousSpaces();
                switch (b.Display)
                {
                    case CssConstants.TableCaption:
                        _caption = b;
                        break;
                    case CssConstants.TableColumn:
                        for (int i = 0; i < GetSpan(b); i++)
                        {
                            Columns.Add(CreateColumn(b));
                        }
                        break;
                    case CssConstants.TableColumnGroup:
                        if (b.Boxes.Count == 0)
                        {
                            int gspan = GetSpan(b);
                            for (int i = 0; i < gspan; i++)
                            {
                                Columns.Add(CreateColumn(b));
                            }
                        }
                        else
                        {
                            foreach (CssBox bb in b.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(b);
                        else
                            _footerBox = b;
                        break;
                    case CssConstants.TableHeaderGroup:
                        if (HeaderBox != null)
                            BodyRows.Add(b);
                        else
                            _headerBox = b;
                        break;
                    case CssConstants.TableRow:
                        BodyRows.Add(b);
                        break;
                    case CssConstants.TableRowGroup:
                        foreach (CssBox bb in b.Boxes)
                            if (b.Display == CssConstants.TableRow)
                                BodyRows.Add(b);
                        break;
                    default:
                        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)
                {
                    row.RemoveAnonymousSpaces();
                    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 SpacingBox(TableBox, ref cell, currow));
                                    break;
                                }
                                colcount++;
                                realcol -= GetColSpan(rows[i].Boxes[j]) - 1;
                            }

                        } // End for (int i = currow + 1; i < currow + rowspan; i++)
                        curcol++;
                    } /// End foreach (Box cell in row.Boxes)
                    currow++;
                } /// End foreach (Box row in rows)

                TableBox.TableFixed = true;

            } /// End if (!TableBox.TableFixed)

            #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;

            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] = CssValue.ParseNumber(Columns[i].Width, availCellSpace);
                        }
                        else if (len.Unit == CssLength.CssUnit.Pixels || len.Unit == CssLength.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 = CssValue.ParseNumber(row.Boxes[i].Width, availCellSpace);
                                }
                                else if (len.Unit == CssLength.CssUnit.Pixels || len.Unit == CssLength.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
                for (int i = 0; i < ColumnWidths.Length; i++)
                    if (float.IsNaN(ColumnWidths[i]))
                        numberOfNans++;
                    else
                        occupedSpace += ColumnWidths[i];

                //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;
            float reduceAmount = 1f;

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

                ColumnWidths[curCol] -= reduceAmount;

                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

            TableBox.Padding = "0"; //Ensure there's no padding

            #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;

            foreach (CssBox row in AllRows)
            {
                if (row is CssAnonymousSpaceBlockBox || row is CssAnonymousSpaceBox) continue;

                curx = startx;
                curCol = 0;

                foreach (CssBox cell in row.Boxes)
                {
                    if (curCol >= ColumnWidths.Length) break;

                    int rowspan = GetRowSpan(cell);
                    float width = GetCellWidth(GetCellRealColumnIndex(row, cell), 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
                    SpacingBox sb = cell as SpacingBox;
                    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)
                {
                    SpacingBox spacer = cell as SpacingBox;

                    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
        }
Beispiel #11
0
        /// <summary>
        /// Applies style to all boxes in the tree
        /// </summary>
        private void CascadeStyles(CssBox startBox)
        {
            bool someBlock = false;

            foreach (CssBox b in startBox.Boxes)
            {
                b.InheritStyle();

                if (b.HtmlTag != null)
                {
                    //Check if tag name matches with a defined class
                    if (MediaBlocks["all"].ContainsKey(b.HtmlTag.TagName))
                    {
                        MediaBlocks["all"][b.HtmlTag.TagName].AssignTo(b);
                    }

                    //Check if class="" attribute matches with a defined style
                    if (b.HtmlTag.HasAttribute("class") &&
                        MediaBlocks["all"].ContainsKey("." + b.HtmlTag.Attributes["class"]))
                    {
                        MediaBlocks["all"]["." + b.HtmlTag.Attributes["class"]].AssignTo(b);
                    }
                    
                    b.HtmlTag.TranslateAttributes(b);

                    //Check for the style="" attribute
                    if (b.HtmlTag.HasAttribute("style"))
                    {
                        CssBlock block = new CssBlock(b.HtmlTag.Attributes["style"]);
                        block.AssignTo(b);
                    }

                    //Check for the <style> tag
                    if (b.HtmlTag.TagName.Equals("style", StringComparison.CurrentCultureIgnoreCase) &&
                        b.Boxes.Count == 1)
                    {
                        FeedStyleSheet(b.Boxes[0].Text);
                    } 

                    //Check for the <link rel=stylesheet> tag
                    if (b.HtmlTag.TagName.Equals("link", StringComparison.CurrentCultureIgnoreCase) &&
                        b.GetAttribute("rel", string.Empty).Equals("stylesheet", StringComparison.CurrentCultureIgnoreCase))
                    {
                        FeedStyleSheet(CssValue.GetStyleSheet(b.GetAttribute("href", string.Empty)));
                    }
                }

                CascadeStyles(b);
            }

            if (someBlock)
            {
                foreach (CssBox box in startBox.Boxes)
                {
                    box.Display = CssConstants.Block;
                }
            }
            
        }
Beispiel #12
0
        /// <summary>
        /// Scans the boxes (non-deeply) of the box, and returns groups of contiguous inline boxes.
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        private List<List<CssBox>> BlockCorrection_GetInlineGroups(CssBox box)
        {
            List<List<CssBox>> result = new List<List<CssBox>>();
            List<CssBox> current = null;

            //Scan boxes
            for (int i = 0; i < box.Boxes.Count; i++)
            {
                CssBox b = box.Boxes[i];

                //If inline, add it to the current group
                if (b.Display == CssConstants.Inline)
                {
                    if (current == null)
                    {
                        current = new List<CssBox>();
                        result.Add(current);
                    }
                    current.Add(b);
                }
                else
                {
                    current = null;
                }
            }


            //If last list contains nothing, erase it
            if (result.Count > 0 && result[result.Count - 1].Count == 0)
            {
                result.RemoveAt(result.Count - 1);
            }

            return result;
        }
Beispiel #13
0
        /// <summary>
        /// Recursively measures words inside the box
        /// </summary>
        /// <param name="b"></param>
        /// <param name="g"></param>
        private void MeasureWords(CssBox b, Graphics g)
        {
            if (b == null) return;

            foreach (CssBox bb in b.Boxes)
            {
                bb.MeasureWordsSize(g);
                MeasureWords(bb, g);
            }
        }
Beispiel #14
0
        /// <summary>
        /// Gets the rowspan of the specified box
        /// </summary>
        /// <param name="b"></param>
        private int GetRowSpan(CssBox b)
        {
            string att = b.GetAttribute("rowspan", "1");
            int rowspan;

            if (!int.TryParse(att, out rowspan))
            {
                return 1;
            }

            return rowspan;
        }
Beispiel #15
0
 /// <summary>
 /// Rounds the specified point
 /// </summary>
 /// <param name="p"></param>
 /// <param name="b"></param>
 /// <returns></returns>
 private static PointF RoundP(PointF p, CssBox b)
 {
     //HACK: Don't round if in printing mode
     //return Point.Round(p);
     return p;
 }
Beispiel #16
0
        /// <summary>
        /// Creates the corner to place with the borders
        /// </summary>
        /// <param name="outer"></param>
        /// <param name="inner"></param>
        /// <param name="startAngle"></param>
        /// <param name="sweepAngle"></param>
        /// <returns></returns>
        private static GraphicsPath CreateCorner(CssBox b, RectangleF r, int cornerIndex)
        {
            GraphicsPath corner = new GraphicsPath();

            RectangleF outer = RectangleF.Empty;
            RectangleF inner = RectangleF.Empty;
            float start1 = 0;
            float start2 = 0;

            switch (cornerIndex)
            {
                case 1:
                    outer = new RectangleF(r.Left, r.Top, b.ActualCornerNW, b.ActualCornerNW);
                    inner = RectangleF.FromLTRB(outer.Left + b.ActualBorderLeftWidth, outer.Top + b.ActualBorderTopWidth, outer.Right, outer.Bottom);
                    start1 = 180;
                    start2 = 270;
                    break;
                case 2:
                    outer = new RectangleF(r.Right - b.ActualCornerNE, r.Top, b.ActualCornerNE, b.ActualCornerNE);
                    inner = RectangleF.FromLTRB(outer.Left, outer.Top + b.ActualBorderTopWidth, outer.Right - b.ActualBorderRightWidth, outer.Bottom);
                    outer.X -= outer.Width;
                    inner.X -= inner.Width;
                    start1 = -90;
                    start2 = 0;
                    break;
                case 3:
                    outer = RectangleF.FromLTRB(r.Right - b.ActualCornerSE, r.Bottom - b.ActualCornerSE, r.Right, r.Bottom);
                    inner = new RectangleF(outer.Left, outer.Top, outer.Width - b.ActualBorderRightWidth, outer.Height - b.ActualBorderBottomWidth);
                    outer.X -= outer.Width;
                    outer.Y -= outer.Height;
                    inner.X -= inner.Width;
                    inner.Y -= inner.Height;
                    start1 = 0;
                    start2 = 90;
                    break;
                case 4:
                    outer = new RectangleF(r.Left, r.Bottom - b.ActualCornerSW, b.ActualCornerSW, b.ActualCornerSW);
                    inner = RectangleF.FromLTRB( r.Left + b.ActualBorderLeftWidth , outer.Top , outer.Right, outer.Bottom - b.ActualBorderBottomWidth);
                    start1 = 90;
                    start2 = 180;
                    outer.Y -= outer.Height;
                    inner.Y -= inner.Height;
                    break;
            }

            if (outer.Width <= 0f) outer.Width = 1f;
            if (outer.Height <= 0f) outer.Height = 1f;
            if (inner.Width <= 0f) inner.Width = 1f;
            if (inner.Height <= 0f) inner.Height = 1f;


            outer.Width *= 2; outer.Height *= 2;
            inner.Width *= 2; inner.Height *= 2;

            outer = RoundR(outer, b); inner = RoundR(inner, b);

            corner.AddArc(outer, start1, 90);
            corner.AddArc(inner, start2, -90);

            corner.CloseFigure();

            return corner;
        }
 public CssAnonymousSpaceBlockBox(CssBox parent, CssBox insertBefore)
     : base(parent, insertBefore)
 { Display = CssConstants.None; }
 public CssAnonymousSpaceBlockBox(CssBox parent)
     : base(parent)
 { Display = CssConstants.None; }
 public CssAnonymousBlockBox(CssBox parent)
     : base(parent)
 {
     Display = CssConstants.Block;
 }
Beispiel #20
0
        /// <summary>
        /// Gets the cells width, taking colspan and being in the specified column
        /// </summary>
        /// <param name="column"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        private float GetCellWidth(int column, CssBox b)
        {
            float colspan = Convert.ToSingle(GetColSpan(b));
            float sum = 0f;

            for (int i = column; i < column + colspan; i++)
            {
                if (column >= ColumnWidths.Length) break;
                if (ColumnWidths.Length <= i) break;
                sum += ColumnWidths[i]; 
            }

            sum += (colspan - 1) * HorizontalSpacing;

            return sum; ;// -b.ActualBorderLeftWidth - b.ActualBorderRightWidth - b.ActualPaddingRight - b.ActualPaddingLeft;
        }
Beispiel #21
0
        /// <summary>
        /// Gets the colspan of the specified box
        /// </summary>
        /// <param name="b"></param>
        private int GetColSpan(CssBox b)
        {
            string att = b.GetAttribute("colspan", "1");
            int colspan;

            if (!int.TryParse(att, out colspan))
            {
                return 1;
            }

            return colspan;
        }
Beispiel #22
0
        /// <summary>
        /// Gets the span attribute of the tag of the specified box
        /// </summary>
        /// <param name="b"></param>
        private int GetSpan(CssBox b)
        {
            float f = CssValue.ParseNumber(b.GetAttribute("span"), 1);

            return Math.Max(1, Convert.ToInt32(f));
        }
Beispiel #23
0
        /// <summary>
        /// Recursively measures the specified box
        /// </summary>
        /// <param name="b"></param>
        /// <param name="g"></param>
        private void Measure(CssBox b, Graphics g)
        {
            if (b == null) return;

            foreach (CssBox bb in b.Boxes)
            {
                bb.MeasureBounds(g);
                Measure(bb, g);
            }
        }
Beispiel #24
0
 internal CssBoxWord(CssBox owner)
 {
     _ownerBox = owner;
     _word = string.Empty;
 }
Beispiel #25
0
 /// <summary>
 /// Rounds the specified rectangle
 /// </summary>
 /// <param name="p"></param>
 /// <param name="b"></param>
 /// <returns></returns>
 private static RectangleF RoundR(RectangleF r, CssBox b)
 {
     //HACK: Don't round if in printing mode
     return Rectangle.Round(r);
 }
Beispiel #26
0
        /// <summary>
        /// Makes block boxes be among only block boxes. 
        /// Inline boxes should live in a pool of Inline boxes only.
        /// </summary>
        /// <param name="startBox"></param>
        private void BlockCorrection(CssBox startBox)
        {
            bool inlinesonly = startBox.ContainsInlinesOnly();

            if (!inlinesonly)
            {

                List<List<CssBox>> inlinegroups = BlockCorrection_GetInlineGroups(startBox);

                foreach (List<CssBox> group in inlinegroups)
                {
                    if (group.Count == 0) continue;

                    if (group.Count == 1 && group[0] is CssAnonymousSpaceBox)
                    {
                        CssAnonymousSpaceBlockBox sbox = new CssAnonymousSpaceBlockBox(startBox, group[0]);

                        group[0].ParentBox = sbox;
                    }
                    else
                    {
                        CssAnonymousBlockBox newbox = new CssAnonymousBlockBox(startBox, group[0]);

                        foreach (CssBox inline in group)
                        {
                            inline.ParentBox = newbox;
                        }
                    }
                }
            }

            foreach (CssBox b in startBox.Boxes)
            {
                BlockCorrection(b);
            }
        }
Beispiel #27
0
 /// <summary>
 /// Creates the column with the specified width
 /// </summary>
 /// <param name="width"></param>
 /// <returns></returns>
 private CssBox CreateColumn(CssBox modelBox)
 {
     return modelBox;
     //Box b = new Box(null, new HtmlTag(string.Format("<COL style=\"width:{0}\" >", width)));
     //b.Width = width;
     //return b;
 }
Beispiel #28
0
        /// <summary>
        /// Makes a border path
        /// </summary>
        /// <param name="border">Desired border</param>
        /// <param name="b">Box wich the border corresponds</param>
        /// <param name="isLineStart">Specifies if the border is for a starting line (no bevel on left)</param>
        /// <param name="isLineEnd">Specifies if the border is for an ending line (no bevel on right)</param>
        /// <returns>Beveled border path</returns>
        public static GraphicsPath GetBorderPath(Border border, CssBox b, RectangleF r, bool isLineStart, bool isLineEnd)
        {
            PointF[] pts = new PointF[4];
            float bwidth = 0;
            GraphicsPath corner = null;

            switch (border)
            {
                case Border.Top:
                    bwidth = b.ActualBorderTopWidth;
                    pts[0] = RoundP(new PointF(r.Left + b.ActualCornerNW, r.Top), b);
                    pts[1] = RoundP(new PointF(r.Right - b.ActualCornerNE, r.Top), b);
                    pts[2] = RoundP(new PointF(r.Right - b.ActualCornerNE, r.Top + bwidth), b);
                    pts[3] = RoundP(new PointF(r.Left + b.ActualCornerNW, r.Top + bwidth), b);

                    if (isLineEnd && b.ActualCornerNE == 0f) pts[2].X -= b.ActualBorderRightWidth;
                    if (isLineStart && b.ActualCornerNW == 0f) pts[3].X += b.ActualBorderLeftWidth;

                    if (b.ActualCornerNW > 0f) corner = CreateCorner(b, r, 1);
                    
                    break;
                case Border.Right:
                    bwidth = b.ActualBorderRightWidth;
                    pts[0] = RoundP(new PointF(r.Right - bwidth, r.Top + b.ActualCornerNE), b);
                    pts[1] = RoundP(new PointF(r.Right, r.Top + b.ActualCornerNE), b);
                    pts[2] = RoundP(new PointF(r.Right, r.Bottom - b.ActualCornerSE), b);
                    pts[3] = RoundP(new PointF(r.Right - bwidth, r.Bottom - b.ActualCornerSE), b);
                    
                   
                    if (b.ActualCornerNE == 0f) pts[0].Y += b.ActualBorderTopWidth;
                    if (b.ActualCornerSE == 0f) pts[3].Y -= b.ActualBorderBottomWidth; 
                    if (b.ActualCornerNE > 0f) corner = CreateCorner(b, r, 2);
                    break;
                case Border.Bottom:
                    bwidth = b.ActualBorderBottomWidth;
                    pts[0] = RoundP(new PointF(r.Left + b.ActualCornerSW, r.Bottom - bwidth), b);
                    pts[1] = RoundP(new PointF(r.Right - b.ActualCornerSE, r.Bottom - bwidth), b);
                    pts[2] = RoundP(new PointF(r.Right - b.ActualCornerSE, r.Bottom), b);
                    pts[3] = RoundP(new PointF(r.Left + b.ActualCornerSW, r.Bottom), b);

                    if (isLineStart && b.ActualCornerSW == 0f) pts[0].X += b.ActualBorderLeftWidth;
                    if (isLineEnd && b.ActualCornerSE == 0f) pts[1].X -= b.ActualBorderRightWidth;

                    if (b.ActualCornerSE > 0f) corner = CreateCorner(b, r, 3);
                    break;
                case Border.Left:
                    bwidth = b.ActualBorderLeftWidth;
                    pts[0] = RoundP(new PointF(r.Left, r.Top + b.ActualCornerNW), b);
                    pts[1] = RoundP(new PointF(r.Left + bwidth, r.Top + b.ActualCornerNW), b);
                    pts[2] = RoundP(new PointF(r.Left + bwidth, r.Bottom - b.ActualCornerSW), b);
                    pts[3] = RoundP(new PointF(r.Left, r.Bottom - b.ActualCornerSW), b);

                    if (b.ActualCornerNW == 0f) pts[1].Y += b.ActualBorderTopWidth;
                    if (b.ActualCornerSW == 0f) pts[2].Y -= b.ActualBorderBottomWidth;

                    if (b.ActualCornerSW > 0f) corner = CreateCorner(b, r, 4);
                    break;
            }

            GraphicsPath path = new GraphicsPath(pts, new byte[] { (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line, (byte)PathPointType.Line });

            if (corner != null)
            {
                path.AddPath(corner, true);
            }

            return path;
        }
Beispiel #29
0
 /// <summary>
 /// Creates a new BoxWord which represents an image
 /// </summary>
 /// <param name="owner"></param>
 /// <param name="image"></param>
 public CssBoxWord(CssBox owner, Image image)
     : this(owner)
 {
     Image = image;
 }
Beispiel #30
0
        /// <summary>
        /// Asigns the style on this block o the specified box
        /// </summary>
        /// <param name="b"></param>
        public void AssignTo(CssBox b)
        {
            foreach (PropertyInfo prop in PropertyValues.Keys)
            {
                string value = PropertyValues[prop];

                if (value == CssConstants.Inherit && b.ParentBox != null)
                {
                    value = Convert.ToString(prop.GetValue(b.ParentBox, null));
                }

                prop.SetValue(b, value, null);
            }
        }