public CssVerticalCellSpacingBox(CssBox extendedBox, int startRow) : base(specForVCell, extendedBox.RootGfx) { _extendedBox = extendedBox; this.SetRowSpanAndColSpan(1, 1); _endRow = startRow + extendedBox.RowSpan - 1; }
/// <summary> /// Init. /// </summary> /// <param name="owner">the CSS box owner of the word</param> /// <param name="text">the word chars </param> /// <param name="hasSpaceBefore">was there a whitespace before the word chars (before trim)</param> /// <param name="hasSpaceAfter">was there a whitespace after the word chars (before trim)</param> public CssRectWord(CssBox owner, string text, bool hasSpaceBefore, bool hasSpaceAfter) : base(owner) { _text = text; _hasSpaceBefore = hasSpaceBefore; _hasSpaceAfter = hasSpaceAfter; }
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); }
/// <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 var unit = length.Substring(length.Length - 2, 2); //Factor will depend on the unit var factor = 1f; //Number of the length var 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)); }
internal void SetPrincipalBox(CssBox box) { this.principalBox = box; this.SkipPrincipalBoxEvalulation = true; }
/// <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); }
/// <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); }
/// <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); }
/// <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; }
public CssAnonymousBlockBox(CssBox parent) : base(parent) { Display = CssConstants.Block; }
/// <summary> /// Cascades to the TD's the border spacified in the TABLE tag. /// </summary> /// <param name="table"></param> /// <param name="border"></param> private void ApplyTableBorder(CssBox table, string border) { foreach (CssBox box in table.Boxes) { foreach (CssBox cell in box.Boxes) { cell.BorderWidth = TranslateLength(border); } } }
/// <summary> /// Split bad box that has inline and block boxes into two parts, the left - before the block box /// and right - after the block box. /// </summary> /// <param name="parentBox">the parent box that has the problem</param> /// <param name="badBox">the box to split into different boxes</param> /// <param name="leftBlock">the left block box that is created for the split</param> private static void CorrectBlockSplitBadBox(CssBox parentBox, CssBox badBox, CssBox leftBlock) { CssBox leftbox = null; while (badBox.Boxes[0].IsInline && ContainsInlinesOnlyDeep(badBox.Boxes[0])) { if (leftbox == null) { // if there is no elements in the left box there is no reason to keep it leftbox = CssBox.CreateBox(leftBlock, badBox.HtmlTag); leftbox.InheritStyle(badBox, true); } badBox.Boxes[0].ParentBox = leftbox; } var splitBox = badBox.Boxes[0]; if (!ContainsInlinesOnlyDeep(splitBox)) { CorrectBlockSplitBadBox(parentBox, splitBox, leftBlock); splitBox.ParentBox = null; } else { splitBox.ParentBox = parentBox; } if (badBox.Boxes.Count > 0) { CssBox rightBox; if (splitBox.ParentBox != null || parentBox.Boxes.Count < 3) { rightBox = CssBox.CreateBox(parentBox, badBox.HtmlTag); rightBox.InheritStyle(badBox, true); if (parentBox.Boxes.Count > 2) { rightBox.SetBeforeBox(parentBox.Boxes[1]); } if (splitBox.ParentBox != null) { splitBox.SetBeforeBox(rightBox); } } else { rightBox = parentBox.Boxes[2]; } rightBox.SetAllBoxes(badBox); } else if (splitBox.ParentBox != null && parentBox.Boxes.Count > 1) { splitBox.SetBeforeBox(parentBox.Boxes[1]); if (splitBox.HtmlTag != null && splitBox.HtmlTag.Name == "br" && (leftbox != null || leftBlock.Boxes.Count > 1)) { splitBox.Display = CssConstants.Inline; } } }
internal void TranslateAttributes(CssBox box) { string t = TagName.ToUpper(); foreach (string att in Attributes.Keys) { string value = Attributes[att]; switch (att) { case HtmlConstants.Align: if (value == HtmlConstants.Left || value == HtmlConstants.Center || value == HtmlConstants.Right || value == HtmlConstants.Justify) box.TextAlign = value; else box.VerticalAlign = value; break; case HtmlConstants.Background: box.BackgroundImage = value; break; case HtmlConstants.Bgcolor: box.BackgroundColor = value; break; case HtmlConstants.Border: box.BorderWidth = TranslateLength(value); if (t == HtmlConstants.Table) { ApplyTableBorder(box, value); } else { box.BorderStyle = CssConstants.Solid; } break; case HtmlConstants.Bordercolor: box.BorderColor = value; break; case HtmlConstants.Cellspacing: box.BorderSpacing = TranslateLength(value); break; case HtmlConstants.Cellpadding: ApplyTablePadding(box, value); break; case HtmlConstants.Color: box.Color = value; break; case HtmlConstants.Dir: box.Direction = value; break; case HtmlConstants.Face: box.FontFamily = value; break; case HtmlConstants.Height: box.Height = TranslateLength(value); break; case HtmlConstants.Hspace: box.MarginRight = box.MarginLeft = TranslateLength(value); break; case HtmlConstants.Nowrap: box.WhiteSpace = CssConstants.Nowrap; break; case HtmlConstants.Size: if (t == HtmlConstants.Hr) box.Height = TranslateLength(value); break; case HtmlConstants.Valign: box.VerticalAlign = value; break; case HtmlConstants.Vspace: box.MarginTop = box.MarginBottom = TranslateLength(value); break; case HtmlConstants.Width: box.Width = TranslateLength(value); break; } } }
/// <summary> /// /// </summary> /// <param name="tag"></param> /// <param name="box"></param> private void TranslateAttributes(HtmlTag tag, CssBox box) { if (tag.HasAttributes()) { foreach (string att in tag.Attributes.Keys) { string value = tag.Attributes[att]; switch (att) { case HtmlConstants.Align: if (value == HtmlConstants.Left || value == HtmlConstants.Center || value == HtmlConstants.Right || value == HtmlConstants.Justify) { box.TextAlign = value.ToLower(); } else { box.VerticalAlign = value.ToLower(); } break; case HtmlConstants.Background: box.BackgroundImage = value.ToLower(); break; case HtmlConstants.Bgcolor: box.BackgroundColor = value.ToLower(); break; case HtmlConstants.Border: if (!string.IsNullOrEmpty(value) && value != "0") { box.BorderLeftStyle = box.BorderTopStyle = box.BorderRightStyle = box.BorderBottomStyle = CssConstants.Solid; } box.BorderLeftWidth = box.BorderTopWidth = box.BorderRightWidth = box.BorderBottomWidth = TranslateLength(value); if (tag.Name == HtmlConstants.Table) { if (value != "0") { ApplyTableBorder(box, "1px"); } } else { box.BorderTopStyle = box.BorderLeftStyle = box.BorderRightStyle = box.BorderBottomStyle = CssConstants.Solid; } break; case HtmlConstants.Bordercolor: box.BorderLeftColor = box.BorderTopColor = box.BorderRightColor = box.BorderBottomColor = value.ToLower(); break; case HtmlConstants.Cellspacing: box.BorderSpacing = TranslateLength(value); break; case HtmlConstants.Cellpadding: ApplyTablePadding(box, value); break; case HtmlConstants.Color: box.Color = value.ToLower(); break; case HtmlConstants.Dir: box.Direction = value.ToLower(); break; case HtmlConstants.Face: box.FontFamily = _cssParser.ParseFontFamily(value); break; case HtmlConstants.Height: box.Height = TranslateLength(value); break; case HtmlConstants.Hspace: box.MarginRight = box.MarginLeft = TranslateLength(value); break; case HtmlConstants.Nowrap: box.WhiteSpace = CssConstants.NoWrap; break; case HtmlConstants.Size: if (tag.Name.Equals(HtmlConstants.Hr, StringComparison.OrdinalIgnoreCase)) { box.Height = TranslateLength(value); } else if (tag.Name.Equals(HtmlConstants.Font, StringComparison.OrdinalIgnoreCase)) { box.FontSize = value; } break; case HtmlConstants.Valign: box.VerticalAlign = value.ToLower(); break; case HtmlConstants.Vspace: box.MarginTop = box.MarginBottom = TranslateLength(value); break; case HtmlConstants.Width: box.Width = TranslateLength(value); break; default: Console.WriteLine("123"); break; } } } }
/// <summary> /// Split bad box that has inline and block boxes into two parts, the left - before the block box /// and right - after the block box. /// </summary> /// <param name="parentBox">the parent box that has the problem</param> /// <param name="badBox">the box to split into different boxes</param> /// <param name="leftBlock">the left block box that is created for the split</param> private static void CorrectBlockSplitBadBox(CssBox parentBox, CssBox badBox, CssBox leftBlock) { CssBox leftbox = CssBox.CreateBox(leftBlock, badBox.HtmlTag); leftbox.InheritStyle(badBox, true); bool hadLeft = false; while (badBox.Boxes[0].IsInline && ContainsInlinesOnlyDeep(badBox.Boxes[0])) { hadLeft = true; badBox.Boxes[0].ParentBox = leftbox; } CssBox splitBox = badBox.Boxes[0]; if (!ContainsInlinesOnlyDeep(splitBox)) { CorrectBlockSplitBadBox(parentBox, splitBox, leftBlock); splitBox.ParentBox = null; } else { splitBox.ParentBox = parentBox; } if (badBox.Boxes.Count > 0) { CssBox rightBox; if (splitBox.ParentBox != null || parentBox.Boxes.Count < 3) { rightBox = CssBox.CreateBox(parentBox, badBox.HtmlTag); rightBox.InheritStyle(badBox, true); if (parentBox.Boxes.Count > 2) { rightBox.SetBeforeBox(parentBox.Boxes[1]); } if (splitBox.ParentBox != null) { splitBox.SetBeforeBox(rightBox); } } else { rightBox = parentBox.Boxes[2]; } while (badBox.Boxes.Count > 0) { badBox.Boxes[0].ParentBox = rightBox; } } else if (splitBox.ParentBox != null && parentBox.Boxes.Count > 1) { splitBox.SetBeforeBox(parentBox.Boxes[1]); if (splitBox.HtmlTag != null && splitBox.HtmlTag.Name == "br" && (hadLeft || leftBlock.Boxes.Count > 1)) { splitBox.Display = CssConstants.Inline; } } }
public override void CustomRecomputedValue(CssBox containingBlock) { var ibox = CssBox.UnsafeGetController(this) as IBoxElement; if (ibox != null) { //todo: user minimum font height of the IBoxElement int w = (int)this.VisualWidth; int h = Math.Max((int)this.VisualHeight, ibox.MinHeight); ibox.ChangeElementSize(w, h); this.SetVisualSize(w, h); } else { //TODO: review this this.SetVisualSize(100, 20); } }
/// <summary> /// Makes a border path for rounded borders.<br/> /// To support rounded dotted/dashed borders we need to use arc in the border path.<br/> /// Return null if the border is not rounded.<br/> /// </summary> /// <param name="g">the device to draw into</param> /// <param name="border">Desired border</param> /// <param name="b">Box which the border corresponds</param> /// <param name="r">the rectangle the border is enclosing</param> /// <returns>Beveled border path, null if there is no rounded corners</returns> private static RGraphicsPath GetRoundedBorderPath(RGraphics g, Border border, CssBox b, RRect r) { RGraphicsPath path = null; switch (border) { case Border.Top: if (b.ActualCornerNw > 0 || b.ActualCornerNe > 0) { path = g.GetGraphicsPath(); path.Start(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2 + b.ActualCornerNw); if (b.ActualCornerNw > 0) { path.ArcTo(r.Left + b.ActualBorderLeftWidth / 2 + b.ActualCornerNw, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNw, RGraphicsPath.Corner.TopLeft); } path.LineTo(r.Right - b.ActualBorderRightWidth / 2 - b.ActualCornerNe, r.Top + b.ActualBorderTopWidth / 2); if (b.ActualCornerNe > 0) { path.ArcTo(r.Right - b.ActualBorderRightWidth / 2, r.Top + b.ActualBorderTopWidth / 2 + b.ActualCornerNe, b.ActualCornerNe, RGraphicsPath.Corner.TopRight); } } break; case Border.Bottom: if (b.ActualCornerSw > 0 || b.ActualCornerSe > 0) { path = g.GetGraphicsPath(); path.Start(r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2 - b.ActualCornerSe); if (b.ActualCornerSe > 0) { path.ArcTo(r.Right - b.ActualBorderRightWidth / 2 - b.ActualCornerSe, r.Bottom - b.ActualBorderBottomWidth / 2, b.ActualCornerSe, RGraphicsPath.Corner.BottomRight); } path.LineTo(r.Left + b.ActualBorderLeftWidth / 2 + b.ActualCornerSw, r.Bottom - b.ActualBorderBottomWidth / 2); if (b.ActualCornerSw > 0) { path.ArcTo(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2 - b.ActualCornerSw, b.ActualCornerSw, RGraphicsPath.Corner.BottomLeft); } } break; case Border.Right: if (b.ActualCornerNe > 0 || b.ActualCornerSe > 0) { path = g.GetGraphicsPath(); bool noTop = b.BorderTopStyle == CssConstants.None || b.BorderTopStyle == CssConstants.Hidden; bool noBottom = b.BorderBottomStyle == CssConstants.None || b.BorderBottomStyle == CssConstants.Hidden; path.Start(r.Right - b.ActualBorderRightWidth / 2 - (noTop ? b.ActualCornerNe : 0), r.Top + b.ActualBorderTopWidth / 2 + (noTop ? 0 : b.ActualCornerNe)); if (b.ActualCornerNe > 0 && noTop) { path.ArcTo(r.Right - b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2 + b.ActualCornerNe, b.ActualCornerNe, RGraphicsPath.Corner.TopRight); } path.LineTo(r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2 - b.ActualCornerSe); if (b.ActualCornerSe > 0 && noBottom) { path.ArcTo(r.Right - b.ActualBorderRightWidth / 2 - b.ActualCornerSe, r.Bottom - b.ActualBorderBottomWidth / 2, b.ActualCornerSe, RGraphicsPath.Corner.BottomRight); } } break; case Border.Left: if (b.ActualCornerNw > 0 || b.ActualCornerSw > 0) { path = g.GetGraphicsPath(); bool noTop = b.BorderTopStyle == CssConstants.None || b.BorderTopStyle == CssConstants.Hidden; bool noBottom = b.BorderBottomStyle == CssConstants.None || b.BorderBottomStyle == CssConstants.Hidden; path.Start(r.Left + b.ActualBorderLeftWidth / 2 + (noBottom ? b.ActualCornerSw : 0), r.Bottom - b.ActualBorderBottomWidth / 2 - (noBottom ? 0 : b.ActualCornerSw)); if (b.ActualCornerSw > 0 && noBottom) { path.ArcTo(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2 - b.ActualCornerSw, b.ActualCornerSw, RGraphicsPath.Corner.BottomLeft); } path.LineTo(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2 + b.ActualCornerNw); if (b.ActualCornerNw > 0 && noTop) { path.ArcTo(r.Left + b.ActualBorderLeftWidth / 2 + b.ActualCornerNw, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNw, RGraphicsPath.Corner.TopLeft); } } break; } return(path); }
public CssAnonymousSpaceBlockBox(CssBox parent) : base(parent) { Display = CssConstants.None; }
/// <summary> /// Creates a new BoxWord which represents an image /// </summary> /// <param name="owner">the CSS box owner of the word</param> public CssRectImage(CssBox owner) : base(owner) { }
public CssAnonymousSpaceBlockBox(CssBox parent, CssBox insertBefore) : base(parent, insertBefore) { Display = CssConstants.None; }
/// <summary> /// Init. /// </summary> /// <param name="parent">the parent box of this box</param> /// <param name="tag">the html tag data of this box</param> public CssBoxImage(CssBox parent, HtmlTag tag) : base(parent, tag) { _imageWord = new CssRectImage(this); Words.Add(_imageWord); }
/// <summary> /// Select all the words that are between <paramref name="selectionStart"/> word and <paramref name="selectionEnd"/> word in the DOM hierarchy.<br/> /// </summary> /// <param name="root">the root of the DOM sub-tree the selection is in</param> /// <param name="selectionStart">selection start word limit</param> /// <param name="selectionEnd">selection end word limit</param> private void SelectWordsInRange(CssBox root, CssRect selectionStart, CssRect selectionEnd) { bool inSelection = false; SelectWordsInRange(root, selectionStart, selectionEnd, ref inSelection); }
/// <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); }
/// <summary> /// Show context menu clicked on given rectangle. /// </summary> /// <param name="parent">the parent control to show the context menu on</param> /// <param name="rect">the rectangle that was clicked to show context menu</param> /// <param name="link">the link that was clicked to show context menu on</param> public void ShowContextMenu(RControl parent, CssRect rect, CssBox link) { try { DisposeContextMenu(); _parentControl = parent; _currentRect = rect; _currentLink = link; _contextMenu = _htmlContainer.Adapter.GetContextMenu(); // Give client a chance to customise the menu _htmlContainer.HandleContextMenuInvoked(_contextMenu); if (_contextMenu.ItemsCount > 0) { _contextMenu.AddDivider(); } if (rect != null) { bool isVideo = false; if (link != null) { isVideo = link is CssBoxFrame && ((CssBoxFrame)link).IsVideo; var linkExist = !string.IsNullOrEmpty(link.HrefLink); _contextMenu.AddItem(isVideo ? _openVideo : _openLink, linkExist, OnOpenLinkClick); if (_htmlContainer.IsSelectionEnabled) { _contextMenu.AddItem(isVideo ? _copyVideoUrl : _copyLink, linkExist, OnCopyLinkClick); } _contextMenu.AddDivider(); } if (rect.IsImage && !isVideo) { _contextMenu.AddItem(_saveImage, rect.Image != null, OnSaveImageClick); if (_htmlContainer.IsSelectionEnabled) { _contextMenu.AddItem(_copyImageLink, !string.IsNullOrEmpty(_currentRect.OwnerBox.GetAttribute("src")), OnCopyImageLinkClick); _contextMenu.AddItem(_copyImage, rect.Image != null, OnCopyImageClick); } _contextMenu.AddDivider(); } if (_htmlContainer.IsSelectionEnabled) { _contextMenu.AddItem(_copy, rect.Selected, OnCopyClick); } } if (_htmlContainer.IsSelectionEnabled) { _contextMenu.AddItem(_selectAll, true, OnSelectAllClick); } if (_contextMenu.ItemsCount > 0) { _contextMenu.RemoveLastDivider(); _contextMenu.Show(parent, parent.MouseLocation); } } catch (Exception ex) { _htmlContainer.ReportError(HtmlRenderErrorType.ContextMenu, "Failed to show context menu", ex); } }
/// <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)); }
/// <summary> /// Set CSS box property value by the CSS name.<br/> /// Used as a mapping between CSS property and the class property. /// </summary> /// <param name="cssBox">the CSS box to set it's property value</param> /// <param name="propName">the name of the CSS property</param> /// <param name="value">the value to set</param> public static void SetPropertyValue(CssBox cssBox, string propName, string value) { switch (propName) { case "border-bottom-width": cssBox.BorderBottomWidth = value; break; case "border-left-width": cssBox.BorderLeftWidth = value; break; case "border-right-width": cssBox.BorderRightWidth = value; break; case "border-top-width": cssBox.BorderTopWidth = value; break; case "border-width": cssBox.BorderWidth = value; break; case "border-bottom-style": cssBox.BorderBottomStyle = value; break; case "border-left-style": cssBox.BorderLeftStyle = value; break; case "border-right-style": cssBox.BorderRightStyle = value; break; case "border-style": cssBox.BorderStyle = value; break; case "border-top-style": cssBox.BorderTopStyle = value; break; case "border-color": cssBox.BorderColor = value; break; case "border-bottom-color": cssBox.BorderBottomColor = value; break; case "border-left-color": cssBox.BorderLeftColor = value; break; case "border-right-color": cssBox.BorderRightColor = value; break; case "border-top-color": cssBox.BorderTopColor = value; break; case "border": cssBox.Border = value; break; case "border-bottom": cssBox.BorderBottom = value; break; case "border-left": cssBox.BorderLeft = value; break; case "border-right": cssBox.BorderRight = value; break; case "border-top": cssBox.BorderTop = value; break; case "border-spacing": cssBox.BorderSpacing = value; break; case "border-collapse": cssBox.BorderCollapse = value; break; case "corner-radius": cssBox.CornerRadius = value; break; case "corner-nw-radius": cssBox.CornerNWRadius = value; break; case "corner-ne-radius": cssBox.CornerNERadius = value; break; case "corner-se-radius": cssBox.CornerSERadius = value; break; case "corner-sw-radius": cssBox.CornerSWRadius = value; break; case "margin": cssBox.Margin = value; break; case "margin-bottom": cssBox.MarginBottom = value; break; case "margin-left": cssBox.MarginLeft = value; break; case "margin-right": cssBox.MarginRight = value; break; case "margin-top": cssBox.MarginTop = value; break; case "padding": cssBox.Padding = value; break; case "padding-bottom": cssBox.PaddingBottom = value; break; case "padding-left": cssBox.PaddingLeft = value; break; case "padding-right": cssBox.PaddingRight = value; break; case "padding-top": cssBox.PaddingTop = value; break; case "left": cssBox.Left = value; break; case "top": cssBox.Top = value; break; case "width": cssBox.Width = value; break; case "height": cssBox.Height = value; break; case "background-color": cssBox.BackgroundColor = value; break; case "background-image": cssBox.BackgroundImage = value; break; case "background-repeat": cssBox.BackgroundRepeat = value; break; case "background-gradient": cssBox.BackgroundGradient = value; break; case "background-gradient-angle": cssBox.BackgroundGradientAngle = value; break; case "color": cssBox.Color = value; break; case "display": cssBox.Display = value; break; case "direction": cssBox.Direction = value; break; case "empty-cells": cssBox.EmptyCells = value; break; case "float": cssBox.Float = value; break; case "position": cssBox.Position = value; break; case "line-height": cssBox.LineHeight = value; break; case "vertical-align": cssBox.VerticalAlign = value; break; case "text-indent": cssBox.TextIndent = value; break; case "text-align": cssBox.TextAlign = value; break; case "text-decoration": cssBox.TextDecoration = value; break; case "white-space": cssBox.WhiteSpace = value; break; case "word-spacing": cssBox.WordSpacing = value; break; case "font": cssBox.Font = value; break; case "font-family": cssBox.FontFamily = value; break; case "font-size": cssBox.FontSize = value; break; case "font-style": cssBox.FontStyle = value; break; case "font-variant": cssBox.FontVariant = value; break; case "font-weight": cssBox.FontWeight = value; break; case "list-style": cssBox.ListStyle = value; break; case "list-style-position": cssBox.ListStylePosition = value; break; case "list-style-image": cssBox.ListStyleImage = value; break; case "list-style-type": cssBox.ListStyleType = value; break; } }
/// <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> /// <returns></returns> public static float ParseLength(string length, float hundredPercent, CssBox box) { return(ParseLength(length, hundredPercent, box, box.GetEmHeight(), false)); }
LayoutFarm.HtmlBoxes.CssBox CreateInputBox(DomElement domE, LayoutFarm.HtmlBoxes.CssBox parentBox, BoxSpec spec, LayoutFarm.RootGraphic rootgfx, HtmlHost host) { var typeAttr = domE.FindAttribute("type"); if (typeAttr != null) { switch (typeAttr.Value) { case "text": { // user can specific width of textbox //var textbox = new LayoutFarm.CustomWidgets.TextBox(100, 17, false); var textbox = new LayoutFarm.CustomWidgets.TextBoxContainer(100, 20, false); var wrapperBox = CreateWrapper( textbox, textbox.GetPrimaryRenderElement(rootgfx), spec, true); //place holder support var placeHolderAttr = domE.FindAttribute("placeholder"); if (placeHolderAttr != null) { textbox.PlaceHolderText = placeHolderAttr.Value; } parentBox.AppendChild(wrapperBox); return(wrapperBox); } case "button": { //use subdom? technique //todo: review the technique here var button = new HtmlWidgets.Button(60, 30); var ihtmlElement = domE as LayoutFarm.WebDom.IHtmlElement; if (ihtmlElement != null) { button.Text = ihtmlElement.innerHTML; } else { button.Text = ""; } button.Text = "testButton"; DomElement buttonDom = button.GetPresentationDomNode((HtmlDocument)domE.OwnerDocument); CssBox buttonCssBox = host.CreateBox2(parentBox, (WebDom.Impl.HtmlElement)buttonDom, true); // CreateCssBox(buttonDom, parentBox, spec, host); //var ui = button.GetPrimaryUIElement(this.myHost); //var wrapperBox = CreateWrapper( // button, // ui.GetPrimaryRenderElement(rootgfx), // spec, true); //parentBox.AppendChild(wrapperBox); //return wrapperBox; parentBox.AppendChild(buttonCssBox); return(buttonCssBox); } case "textbox": { var textbox = new LayoutFarm.CustomWidgets.TextBox(100, 17, false); CssBox wrapperBox = CreateWrapper( textbox, textbox.GetPrimaryRenderElement(rootgfx), spec, true); parentBox.AppendChild(wrapperBox); return(wrapperBox); } case "radio": { //tempfix -> just copy the Button code, //TODO: review here, use proper radio button var box = new LayoutFarm.CustomWidgets.SimpleBox(20, 20); CssBox wrapperBox = CreateWrapper( box, box.GetPrimaryRenderElement(rootgfx), spec, true); parentBox.AppendChild(wrapperBox); return(wrapperBox); } break; } } return(null); }
/// <summary> /// Get css link href at the given x,y location. /// </summary> /// <param name="location">the location to find the link at</param> /// <returns>css link href if exists or null</returns> public string GetLinkAt(Point location) { CssBox link = DomUtils.GetLinkBox(_root, OffsetByScroll(location)); return(link != null ? link.HrefLink : null); }
/// <summary> /// Recursively flows the content of the box using the inline model /// </summary> /// <param name="g">Device Info</param> /// <param name="blockbox">Blockbox that contains the text flow</param> /// <param name="box">Current box to flow its content</param> /// <param name="maxright">Maximum reached right</param> /// <param name="linespacing">Space to use between rows of text</param> /// <param name="startx">x starting coordinate for when breaking lines of text</param> /// <param name="line">Current linebox being used</param> /// <param name="curx">Current x coordinate that will be the left of the next word</param> /// <param name="cury">Current y coordinate that will be the top of the next word</param> /// <param name="maxbottom">Maximum bottom reached so far</param> private static void FlowBox(Graphics g, CssBox blockbox, CssBox box, float maxright, float linespacing, float startx, ref CssLineBox line, ref float curx, ref float cury, ref float maxbottom) { box.FirstHostingLineBox = line; foreach (CssBox b in box.Boxes) { float leftspacing = b.ActualMarginLeft + b.ActualBorderLeftWidth + b.ActualPaddingLeft; float rightspacing = b.ActualMarginRight + b.ActualBorderRightWidth + b.ActualPaddingRight; float topspacing = b.ActualBorderTopWidth + b.ActualPaddingTop; float bottomspacing = b.ActualBorderBottomWidth + b.ActualPaddingTop; b.RectanglesReset(); b.MeasureWordsSize(g); curx += leftspacing; if (b.Words.Count > 0) { #region Flow words foreach (CssBoxWord word in b.Words) { //curx += word.SpacesBeforeWidth; if ((b.WhiteSpace != CssConstants.Nowrap && curx + word.Width + rightspacing > maxright) || word.IsLineBreak) { #region Break line curx = startx; cury = maxbottom + linespacing; line = new CssLineBox(blockbox); if (word.IsImage || word.Equals(b.FirstWord)) { curx += leftspacing; } #endregion } line.ReportExistanceOf(word); word.Left = curx; // -word.LastMeasureOffset.X + 1; word.Top = cury; // - word.LastMeasureOffset.Y; curx = word.Right; // +word.SpacesAfterWidth; maxbottom = Math.Max(maxbottom, word.Bottom); //+ (word.IsImage ? topspacing + bottomspacing : 0)); _lastTreatedWord = word; } #endregion } else { FlowBox(g, blockbox, b, maxright, linespacing, startx, ref line, ref curx, ref cury, ref maxbottom); } curx += rightspacing; } box.LastHostingLineBox = line; }
//------------------------------------------- internal virtual CssBox GetPrincipalBox(CssBox parentCssBox, HtmlHost host) { //this method is called when HasCustomPrincipalBoxGenerator = true throw new NotImplementedException(); }
/// <summary> /// Init. /// </summary> /// <param name="owner">the CSS box owner of the word</param> protected CssRect(CssBox owner) { _ownerBox = owner; }
/// <summary> /// Draw simple border. /// </summary> /// <param name="border">Desired border</param> /// <param name="g">the device to draw to</param> /// <param name="box">Box which the border corresponds</param> /// <param name="brush">the brush to use</param> /// <param name="rectangle">the bounding rectangle to draw in</param> /// <returns>Beveled border path, null if there is no rounded corners</returns> public static void DrawBorder(Border border, RGraphics g, CssBox box, RBrush brush, RRect rectangle) { SetInOutsetRectanglePoints(border, box, rectangle, true, true); g.DrawPolygon(brush, _borderPts); }
/// <summary> /// Get CSS box property value by the CSS name.<br/> /// Used as a mapping between CSS property and the class property. /// </summary> /// <param name="cssBox">the CSS box to get it's property value</param> /// <param name="propName">the name of the CSS property</param> /// <returns>the value of the property, null if no such property exists</returns> public static string GetPropertyValue(CssBox cssBox, string propName) { switch (propName) { case "border-bottom-width": return(cssBox.BorderBottomWidth); case "border-left-width": return(cssBox.BorderLeftWidth); case "border-right-width": return(cssBox.BorderRightWidth); case "border-top-width": return(cssBox.BorderTopWidth); case "border-bottom-style": return(cssBox.BorderBottomStyle); case "border-left-style": return(cssBox.BorderLeftStyle); case "border-right-style": return(cssBox.BorderRightStyle); case "border-top-style": return(cssBox.BorderTopStyle); case "border-bottom-color": return(cssBox.BorderBottomColor); case "border-left-color": return(cssBox.BorderLeftColor); case "border-right-color": return(cssBox.BorderRightColor); case "border-top-color": return(cssBox.BorderTopColor); case "border-spacing": return(cssBox.BorderSpacing); case "border-collapse": return(cssBox.BorderCollapse); case "corner-radius": return(cssBox.CornerRadius); case "corner-nw-radius": return(cssBox.CornerNwRadius); case "corner-ne-radius": return(cssBox.CornerNeRadius); case "corner-se-radius": return(cssBox.CornerSeRadius); case "corner-sw-radius": return(cssBox.CornerSwRadius); case "margin-bottom": return(cssBox.MarginBottom); case "margin-left": return(cssBox.MarginLeft); case "margin-right": return(cssBox.MarginRight); case "margin-top": return(cssBox.MarginTop); case "padding-bottom": return(cssBox.PaddingBottom); case "padding-left": return(cssBox.PaddingLeft); case "padding-right": return(cssBox.PaddingRight); case "padding-top": return(cssBox.PaddingTop); case "page-break-inside": return(cssBox.PageBreakInside); case "left": return(cssBox.Left); case "top": return(cssBox.Top); case "width": return(cssBox.Width); case "max-width": return(cssBox.MaxWidth); case "height": return(cssBox.Height); case "background-color": return(cssBox.BackgroundColor); case "background-image": return(cssBox.BackgroundImage); case "background-position": return(cssBox.BackgroundPosition); case "background-repeat": return(cssBox.BackgroundRepeat); case "background-gradient": return(cssBox.BackgroundGradient); case "background-gradient-angle": return(cssBox.BackgroundGradientAngle); case "content": return(cssBox.Content); case "color": return(cssBox.Color); case "display": return(cssBox.Display); case "direction": return(cssBox.Direction); case "empty-cells": return(cssBox.EmptyCells); case "float": return(cssBox.Float); case "position": return(cssBox.Position); case "line-height": return(cssBox.LineHeight); case "vertical-align": return(cssBox.VerticalAlign); case "text-indent": return(cssBox.TextIndent); case "text-align": return(cssBox.TextAlign); case "text-decoration": return(cssBox.TextDecoration); case "white-space": return(cssBox.WhiteSpace); case "word-break": return(cssBox.WordBreak); case "visibility": return(cssBox.Visibility); case "word-spacing": return(cssBox.WordSpacing); case "font-family": return(cssBox.FontFamily); case "font-size": return(cssBox.FontSize); case "font-style": return(cssBox.FontStyle); case "font-variant": return(cssBox.FontVariant); case "font-weight": return(cssBox.FontWeight); case "list-style": return(cssBox.ListStyle); case "list-style-position": return(cssBox.ListStylePosition); case "list-style-image": return(cssBox.ListStyleImage); case "list-style-type": return(cssBox.ListStyleType); case "overflow": return(cssBox.Overflow); } return(null); }
public CssBlockRun(CssBox contentBlockBox) : base(CssRunKind.BlockRun) { this.contentBlockBox = contentBlockBox; }
/// <summary> /// Cascades to the TD's the border spacified in the TABLE tag. /// </summary> /// <param name="table"></param> /// <param name="border"></param> private void ApplyTablePadding(CssBox table, string padding) { foreach (CssBox box in table.Boxes) { foreach (CssBox cell in box.Boxes) { cell.Padding = TranslateLength(padding); } } }
public static StyleManager Padding( this StyleManager style, CssBox<CssLengthValue> value ) { return style; }
/// <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.HasAttributes()) { 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 = ((CssBoxImage)box).Image; 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.ParseCssBlock(box.HtmlTag.Name, box.HtmlTag.TryGetAttribute("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(); }
/// <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; }
public CssAnonymousSpaceBox(CssBox parentBox) : base(parentBox) { }
/// <summary> /// Inherits inheritable values from specified box. /// </summary> /// <param name="everything">Set to true to inherit all CSS properties instead of only the ineritables</param> /// <param name="p">Box to inherit the properties</param> protected void InheritStyle(CssBox p, bool everything) { if (p != null) { _borderSpacing = p._borderSpacing; _borderCollapse = p._borderCollapse; _color = p._color; _emptyCells = p._emptyCells; _whiteSpace = p._whiteSpace; _visibility = p._visibility; _textIndent = p._textIndent; _textAlign = p._textAlign; _verticalAlign = p._verticalAlign; _fontFamily = p._fontFamily; _fontSize = p._fontSize; _fontStyle = p._fontStyle; _fontVariant = p._fontVariant; _fontWeight = p._fontWeight; _listStyleImage = p._listStyleImage; _listStylePosition = p._listStylePosition; _listStyleType = p._listStyleType; _listStyle = p._listStyle; _lineHeight = p._lineHeight; _wordBreak = p.WordBreak; _direction = p._direction; if (everything) { _backgroundColor = p._backgroundColor; _backgroundGradient = p._backgroundGradient; _backgroundGradientAngle = p._backgroundGradientAngle; _backgroundImage = p._backgroundImage; _backgroundPosition = p._backgroundPosition; _backgroundRepeat = p._backgroundRepeat; _borderTopWidth = p._borderTopWidth; _borderRightWidth = p._borderRightWidth; _borderBottomWidth = p._borderBottomWidth; _borderLeftWidth = p._borderLeftWidth; _borderTopColor = p._borderTopColor; _borderRightColor = p._borderRightColor; _borderBottomColor = p._borderBottomColor; _borderLeftColor = p._borderLeftColor; _borderTopStyle = p._borderTopStyle; _borderRightStyle = p._borderRightStyle; _borderBottomStyle = p._borderBottomStyle; _borderLeftStyle = p._borderLeftStyle; _bottom = p._bottom; _cornerNwRadius = p._cornerNwRadius; _cornerNeRadius = p._cornerNeRadius; _cornerSeRadius = p._cornerSeRadius; _cornerSwRadius = p._cornerSwRadius; _cornerRadius = p._cornerRadius; _display = p._display; _float = p._float; _height = p._height; _marginBottom = p._marginBottom; _marginLeft = p._marginLeft; _marginRight = p._marginRight; _marginTop = p._marginTop; _left = p._left; _lineHeight = p._lineHeight; _overflow = p._overflow; _paddingLeft = p._paddingLeft; _paddingBottom = p._paddingBottom; _paddingRight = p._paddingRight; _paddingTop = p._paddingTop; _right = p._right; _textDecoration = p._textDecoration; _top = p._top; _position = p._position; _width = p._width; _maxWidth = p._maxWidth; _wordSpacing = p._wordSpacing; } } }
/// <summary> /// Init. /// </summary> /// <param name="parent">the parent box of this box</param> /// <param name="tag">the html tag data of this box</param> public CssBoxHr(CssBox parent, HtmlTag tag) : base(parent, tag) { Display = CssConstants.Block; }
static void SetBackgroundPosition(this CssBox box, WebDom.CssCodeValueExpression value) { //TODO: implement background position from combination value throw new NotSupportedException(); }
/// <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; }