//============================================================= /// <summary> /// recalculate margin /// </summary> /// <param name="margin">marin side</param> /// <param name="cbWidth">width of containging block</param> /// <returns></returns> float RecalculateMargin(CssLength margin, float cbWidth) { //www.w3.org/TR/CSS2/box.html#margin-properties if (margin.IsAuto) { return(0); } return(CssValueParser.ConvertToPx(margin, cbWidth, this)); }
/// <summary> /// recalculate padding /// </summary> /// <param name="padding"></param> /// <param name="cbWidth"></param> /// <returns></returns> float RecalculatePadding(CssLength padding, float cbWidth) { //www.w3.org/TR/CSS2/box.html#padding-properties if (padding.IsAuto) { return(0); } return(CssValueParser.ConvertToPx(padding, cbWidth, this)); }
internal float MeasureWhiteSpace(CssBox box) { //depends on Font of this box float w = this.SampleIFonts.MeasureWhitespace(box.ActualFont); if (!(box.WordSpacing.IsEmpty || box.WordSpacing.IsNormalWordSpacing)) { w += CssValueParser.ConvertToPxWithFontAdjust(box.WordSpacing, 0, box); } return(w); }
public void ReEvaluateFont(ITextService iFonts, float parentFontSize) { RequestFont fontInfo = this._myspec.GetFont(parentFontSize); this._resolvedFont = fontInfo; if (_myspec.WordSpacing.IsNormalWordSpacing) { this._actualWordSpacing = iFonts.MeasureWhitespace(_resolvedFont); } else { this._actualWordSpacing = iFonts.MeasureWhitespace(_resolvedFont) + CssValueParser.ConvertToPx(_myspec.WordSpacing, 1, this); } }
public void ReEvaluateFont(IFonts iFonts, float parentFontSize) { FontInfo fontInfo = this._myspec.GetFontInfo(iFonts, parentFontSize); this._actualFont = fontInfo.ResolvedFont; this._actualLineHeight = fontInfo.LineHeight; this._actualEmHeight = fontInfo.LineHeight; if (_myspec.WordSpacing.IsNormalWordSpacing) { this._actualWordSpacing = iFonts.MeasureWhitespace(_actualFont); } else { this._actualWordSpacing = iFonts.MeasureWhitespace(_actualFont) + CssValueParser.ConvertToPx(_myspec.WordSpacing, 1, this); } }
/// <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 PerformContentLayout(LayoutVisitor lay) { if (this.CssDisplay == Css.CssDisplay.None) { return; } var prevSibling = lay.LatestSiblingBox; var myContainingBlock = lay.LatestContainingBlock; if (this.NeedComputedValueEvaluation) { this.ReEvaluateComputedValues(lay.SampleIFonts, myContainingBlock); } float localLeft = myContainingBlock.GetClientLeft() + this.ActualMarginLeft; float localTop = 0; if (prevSibling == null) { if (this.ParentBox != null) { localTop = myContainingBlock.GetClientTop(); } } else { localTop = prevSibling.LocalVisualBottom;// +prevSibling.ActualBorderBottomWidth; } float maringTopCollapse = UpdateMarginTopCollapse(prevSibling); if (maringTopCollapse < 0.1) { maringTopCollapse = this.GetEmHeight() * 1.1f; } localTop += maringTopCollapse; this.SetLocation(localLeft, localTop); this.SetHeightToZero(); //width at 100% (or auto) float minwidth = CalculateMinimumWidth(lay.EpisodeId); float width = myContainingBlock.VisualWidth - myContainingBlock.ActualPaddingLeft - myContainingBlock.ActualPaddingRight - myContainingBlock.ActualBorderLeftWidth - myContainingBlock.ActualBorderRightWidth - ActualMarginLeft - ActualMarginRight - ActualBorderLeftWidth - ActualBorderRightWidth; //Check width if not auto if (!this.Width.IsEmptyOrAuto) { width = CssValueParser.ConvertToPx(Width, width, this); } if (width < minwidth || width >= CssBoxConstConfig.TABLE_MAX_WIDTH) { width = minwidth; } float height = ExpectedHeight; if (height < 1) { height = this.VisualHeight + ActualBorderTopWidth + ActualBorderBottomWidth; } if (height < 1) { height = 2; } if (height <= 2 && ActualBorderTopWidth < 1 && ActualBorderBottomWidth < 1) { DirectSetBorderWidth(CssSide.Top, 1); DirectSetBorderWidth(CssSide.Bottom, 1); } this.SetVisualSize(width, height); this.SetVisualHeight(ActualPaddingTop + ActualPaddingBottom + height); }
/// <summary> /// evaluate computed value /// </summary> internal void ReEvaluateComputedValues(ITextService iFonts, CssBox containingBlock) { //depend on parent //1. fonts if (this.ParentBox != null) { ReEvaluateFont(iFonts, this.ParentBox.ResolvedFont.SizeInPixels); //2. actual word spacing //this._actualWordSpacing = this.NoEms(this.InitSpec.LineHeight); //3. font size //len = len.ConvertEmToPoints(parentBox.ActualFont.SizeInPoints); } else { ReEvaluateFont(iFonts, containingBlock.ResolvedFont.SizeInPixels); //this._actualFont = this.Spec.GetFont(containingBlock.Spec); } //----------------------------------------------------------------------- float cbWidth = containingBlock.VisualWidth; int tmpBoxCompactFlags = this._boxCompactFlags; this._boxCompactFlags |= BoxFlags.LAY_EVAL_COMPUTE_VALUES; //www.w3.org/TR/CSS2/box.html#margin-properties //w3c: margin applies to all elements except elements table display type //other than table-caption,table and inline table var cssDisplay = this.CssDisplay; BoxSpec spec = _myspec; switch (cssDisplay) { case CssDisplay.None: { return; } case CssDisplay.TableCell: case CssDisplay.TableColumn: case CssDisplay.TableColumnGroup: case CssDisplay.TableFooterGroup: case CssDisplay.TableHeaderGroup: case CssDisplay.TableRow: case CssDisplay.TableRowGroup: { //no margin } break; default: { //if (this.__aa_dbugId == 5) //{ // int a = spec.__aa_dbugId; //} this._actualMarginLeft = RecalculateMargin(spec.MarginLeft, cbWidth); this._actualMarginTop = RecalculateMargin(spec.MarginTop, cbWidth); this._actualMarginRight = RecalculateMargin(spec.MarginRight, cbWidth); this._actualMarginBottom = RecalculateMargin(spec.MarginBottom, cbWidth); } break; } //www.w3.org/TR/CSS2/box.html#padding-properties switch (cssDisplay) { case CssDisplay.TableRowGroup: case CssDisplay.TableHeaderGroup: case CssDisplay.TableFooterGroup: case CssDisplay.TableRow: case CssDisplay.TableColumnGroup: case CssDisplay.TableColumn: { //no padding } break; default: { //----------------------------------------------------------------------- //padding this._actualPaddingLeft = RecalculatePadding(spec.PaddingLeft, cbWidth); this._actualPaddingTop = RecalculatePadding(spec.PaddingTop, cbWidth); this._actualPaddingRight = RecalculatePadding(spec.PaddingRight, cbWidth); this._actualPaddingBottom = RecalculatePadding(spec.PaddingBottom, cbWidth); } break; } //----------------------------------------------------------------------- //borders float a1, a2, a3, a4; this._actualBorderLeftWidth = a1 = (spec.BorderLeftStyle == CssBorderStyle.None) ? 0 : CssValueParser.GetActualBorderWidth(spec.BorderLeftWidth, this); this._actualBorderTopWidth = a2 = (spec.BorderTopStyle == CssBorderStyle.None) ? 0 : CssValueParser.GetActualBorderWidth(spec.BorderTopWidth, this); this._actualBorderRightWidth = a3 = (spec.BorderRightStyle == CssBorderStyle.None) ? 0 : CssValueParser.GetActualBorderWidth(spec.BorderRightWidth, this); this._actualBorderBottomWidth = a4 = (spec.BorderBottomStyle == CssBorderStyle.None) ? 0 : CssValueParser.GetActualBorderWidth(spec.BorderBottomWidth, this); //--------------------------------------------------------------------------- this._borderLeftVisible = a1 > 0 && spec.BorderLeftStyle >= CssBorderStyle.Visible; this._borderTopVisible = a2 > 0 && spec.BorderTopStyle >= CssBorderStyle.Visible; this._borderRightVisible = a3 > 0 && spec.BorderRightStyle >= CssBorderStyle.Visible; this._borderBottomVisble = a4 > 0 && spec.BorderBottomStyle >= CssBorderStyle.Visible; //extension *** if (a1 + a2 + a3 + a4 > 0) { //css 2.1 border can't be nagative values tmpBoxCompactFlags |= BoxFlags.HAS_SOME_VISIBLE_BORDER; } else { tmpBoxCompactFlags &= ~BoxFlags.HAS_SOME_VISIBLE_BORDER; } //--------------------------------------------------------------------------- this._actualCornerNE = a1 = CssValueParser.ConvertToPx(spec.CornerNERadius, 0, this); this._actualCornerNW = a2 = CssValueParser.ConvertToPx(spec.CornerNWRadius, 0, this); this._actualCornerSE = a3 = CssValueParser.ConvertToPx(spec.CornerSERadius, 0, this); this._actualCornerSW = a4 = CssValueParser.ConvertToPx(spec.CornerSWRadius, 0, this); if ((a1 + a2 + a3 + a4) > 0) { //evaluate tmpBoxCompactFlags |= BoxFlags.HAS_ROUND_CORNER; } else { tmpBoxCompactFlags &= ~BoxFlags.HAS_ROUND_CORNER; } //--------------------------------------------------------------------------- //evaluate bg if (BackgroundGradient != Color.Transparent || RenderUtils.IsColorVisible(ActualBackgroundColor)) { tmpBoxCompactFlags |= BoxFlags.HAS_VISIBLE_BG; } else { tmpBoxCompactFlags &= ~BoxFlags.HAS_VISIBLE_BG; } if (spec.WordSpacing.IsNormalWordSpacing) { this._actualWordSpacing = iFonts.MeasureWhitespace(_resolvedFont); } else { this._actualWordSpacing = iFonts.MeasureWhitespace(_resolvedFont) + CssValueParser.ConvertToPx(spec.WordSpacing, 1, this); } //---------------------------------------------- this._boxCompactFlags = tmpBoxCompactFlags; //---------------------------------------------- //text indent this._actualTextIndent = CssValueParser.ConvertToPx(spec.TextIndent, containingBlock.VisualWidth, this); this._actualBorderSpacingHorizontal = spec.BorderSpacingHorizontal.Number; this._actualBorderSpacingVertical = spec.BorderSpacingVertical.Number; //----------------------- //this._actualLineHeight = 0.9f * CssValueParser.ConvertToPx(LineHeight, this.GetEmHeight(), this); //expected width expected height //this._expectedWidth = CssValueParser.ParseLength(Width, cbWidth, this); //this._expectedHight = CssValueParser.ParseLength(Height, containingBlock.SizeHeight, this); ////---------------------------------------------- //www.w3.org/TR/CSS2/visudet.html#line-height //line height, //percent value of line height : // is refer to font size of the element itself //if (this.LineHeight.Number > 0) //{ // _actualLineHeight = .9f * CssValueParser.ConvertToPx(LineHeight, this.GetEmHeight(), this); //} //else //{ // _actualLineHeight = .9f * (this.GetEmHeight()); //} if (this._myspec.HasBoxShadow) { //temp fix here //TODO: review move shadow to external decoration object/box if (decorator == null) { decorator = new CssBoxDecorator(); } decorator.HBoxShadowOffset = (int)CssValueParser.ConvertToPx(spec.BoxShadowHOffset, 0, this); decorator.VBoxShadowOffset = (int)CssValueParser.ConvertToPx(spec.BoxShadowVOffset, 0, this); decorator.Color = spec.BoxShadowColor; } else { this.decorator = null; } }