/// <summary>Resets all values in the renderer. Called before each layout.</summary> public void Reset() { Depth = 0f; MaxDepth = 0f; ViewportBackground = true; BatchDepth = RenderQueue; PositionedAncestors.Clear(); TransformedAncestors.Clear(); FlowRootAncestors.Clear(); ColorOverlay = Color.white; FontAliasingTop = InfiniText.Fonts.OutlineLocation + InfiniText.Fonts.Aliasing; FontAliasingBottom = InfiniText.Fonts.OutlineLocation - InfiniText.Fonts.Aliasing; BoxStack.Clear(); LastBlockBox = null; ResetBoundary(); DepthUsed = false; CurrentBatch = null; CurrentShaderSet = ShaderSet.Standard; FirstInformer = null; FirstLetter = null; FirstLine = null; if (Counters != null) { Counters.Clear(); } // Reapply screen viewport as the root one: Viewport = ScreenViewport; // Clean input grid: InputGrid.Clean(Viewport.Width, Viewport.Height); if (InWorldUI == null) { // This is the main UI renderer. // Clear the root node: Node = null; } }
/// <summary>Lets the renderer know that the given parent element has finished /// packing all of its kids. This allows alignment to occur next.</summary> /// <param name="renderable">The element that is done packing.</param> public void EndLines(LineBoxMeta lineZone, ComputedStyle computed, LayoutBox box) { // Pop the box: BoxStack.Pop(); // Complete the last line: lineZone.CompleteLine(LineBreakMode.NoBreak | LineBreakMode.Last); // If inline-block or float, clear: if (box.DisplayMode == DisplayMode.InlineBlock || box.FloatMode != FloatMode.None) { // Must clear: lineZone.ClearFloat(FloatMode.Both); lineZone.PenY += lineZone.ClearY_; lineZone.ClearY_ = 0f; } // block, inline-block if (lineZone is BlockBoxMeta) { bool heightChange = false; if (box.InnerHeight == -1f) { heightChange = true; box.InnerHeight = lineZone.PenY; // Clip height now: box.InnerHeight = computed.ClipHeight(box.DisplayMode, box.InnerHeight); } box.ContentHeight = lineZone.PenY; box.ContentWidth = lineZone.LargestLineWidth; // If it's inline then we set the line width. if (box.InnerWidth == -1f) { box.InnerWidth = lineZone.LargestLineWidth; // Apply valid width/height: box.SetDimensions(false, false); } else if (heightChange) { // Apply valid width/height: box.SetDimensions(false, false); } bool inFlow = (box.PositionMode & PositionMode.InFlow) != 0; // Update position of the top-of-stack pen: LineBoxMeta tos = TopOfStackSafe; if (tos == null) { LastBlockBox = null; } else { if (inFlow) { // Advance the pen: tos.AdvancePen(box); } // Restore previous block: LastBlockBox = tos as BlockBoxMeta; if (LastBlockBox == null) { // Rare - block inside inline. LastBlockBox = (tos as InlineBoxMeta).HostBlock; } } } }
/// <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); }