/// <summary>Doesn't create the virtual if it doesn't exist.</summary> internal void GetVirtual(CssEvent e, int priority) { // Get the CS: ComputedStyle cs = e.SelectorTarget.computedStyle; VirtualElements virts = cs.RenderData.Virtuals; IRenderableNode node = null; if (virts != null) { // Get and apply: node = virts.Get(priority) as IRenderableNode; } // Update the target: e.SelectorTarget = (node == null) ? null : node.RenderData; }
/// <summary>Sets up this renderer so that it's ready to start packing child elements of /// a given element into lines.</summary> /// <param name="renderable">The parent render data whose children will be packed.</param> public LineBoxMeta BeginLines(RenderableData renderable, VirtualElements virts, LayoutBox box, bool autoWidth) { // Get CS: ComputedStyle cs = renderable.computedStyle; LineBoxMeta lineZone; InfiniText.FontFace face = box.FontFace; // Update line height: // Line height: Css.Value lineHeightValue = cs.LineHeightX; float cssLineHeight; if (lineHeightValue.IsType(typeof(Css.Keywords.Normal))) { // Get from the metrics font now: cssLineHeight = box.FontFace.BaselineToBaseline * box.FontSize; } else if ( lineHeightValue.Type != Css.ValueType.RelativeNumber && lineHeightValue.GetType() != typeof(Css.Units.DecimalUnit) ) { // E.g. line-height:14px, but not line-height:1. It's just as-is: cssLineHeight = lineHeightValue.GetRawDecimal(); } else { // Some multiple of the font size: cssLineHeight = lineHeightValue.GetRawDecimal() * box.FontSize; } // Check if it's a block context: if (box.DisplayMode == DisplayMode.Inline && LastBlockBox != null) { // Anything else uses the nearest parent block element as the max. lineZone = new InlineBoxMeta(LastBlockBox, TopOfStackSafe, box, renderable); // Put up the 'strut': lineZone.LineHeight = cssLineHeight; box.Baseline = box.FontSize * face.Descender; } else { lineZone = LastBlockBox = new BlockBoxMeta(TopOfStackSafe, box, renderable); lineZone.MaxX = box.InnerWidth; if (virts != null && virts.Has(ComputedStyle.VerticalScrollPriority)) { lineZone.MaxX -= 14; if (lineZone.MaxX < 0) { lineZone.MaxX = 0; } } bool left = (cs.DrawDirectionX == DirectionMode.RTL); lineZone.GoingLeftwards = left; // H-align: int hAlign = cs.HorizontalAlignX; if (hAlign == HorizontalAlignMode.Auto) { if (left) { hAlign = HorizontalAlignMode.Right; } else { hAlign = HorizontalAlignMode.Left; } } if (hAlign == HorizontalAlignMode.Left) { // Ok how it is (left by default). hAlign = 0; } lineZone.HorizontalAlign = hAlign; } // Apply whitespace mode: lineZone.WhiteSpace = cs.WhiteSpaceX; // Apply line height: lineZone.CssLineHeight = cssLineHeight; // Update vertical-align: Css.Value vAlign = cs.Resolve(Css.Properties.VerticalAlign.GlobalProperty); // Get the complete value: float vAlignValue = vAlign.GetDecimal(renderable, Css.Properties.VerticalAlign.GlobalProperty); // If it's a keyword.. if (vAlign is Css.CssKeyword) { // It's a mode: lineZone.VerticalAlign = (int)vAlignValue; lineZone.VerticalAlignOffset = 0f; } else { // It's a baseline offset: lineZone.VerticalAlign = VerticalAlignMode.Baseline; lineZone.VerticalAlignOffset = vAlignValue; } box.ContentWidth = 0; box.ContentHeight = 0; return(lineZone); }