private void RasterizeAcceleratorOverlay( UIOperationContext context, ref ImperativeRenderer labelRenderer, ref ImperativeRenderer targetRenderer, Control control, AbstractString label, bool showFocused = false, Control forControl = null ) { if (control == null) { return; } if (!showFocused && (control == Focused) && !label.IsNull && (label.Length > 0)) { return; } if (label.Length <= 0) { return; } var box = control.GetRect(); if ((box.Width <= 1) || (box.Height <= 1)) { return; } var decorator = Decorations.AcceleratorTarget; var settings = new Decorations.DecorationSettings { Box = box, ContentBox = box }; decorator.Rasterize(ref context, ref targetRenderer, settings); var outlinePadding = 1f; decorator = Decorations.AcceleratorLabel; Color?textColor = null; decorator.GetTextSettings(ref context, default(ControlStates), out Material material, ref textColor, out _); var layout = decorator.GlyphSource.LayoutString(label, buffer: AcceleratorOverlayBuffer); var textScale = 1f; if (layout.Size.X > (box.Width - decorator.Padding.X)) { textScale = Math.Max(0.25f, (box.Width - decorator.Padding.X) / layout.Size.X); } var scaledSize = layout.Size * textScale; var labelTraits = new DenseList <string> { "above" }; var labelPosition = box.Position - new Vector2(0, scaledSize.Y + decorator.Padding.Y + outlinePadding); if (labelPosition.Y <= 0) { labelTraits[0] = "inside"; labelPosition = box.Position; } labelPosition.X = Arithmetic.Clamp(labelPosition.X, 0, CanvasSize.X - scaledSize.X); labelPosition.Y = Math.Max(0, labelPosition.Y); var labelBox = new RectF( labelPosition, scaledSize + decorator.Padding.Size ); if (IsObstructedByAnyPreviousBox(ref labelBox, forControl)) { labelBox.Left = box.Extent.X - labelBox.Width; } if (IsObstructedByAnyPreviousBox(ref labelBox, forControl)) { labelTraits[0] = "below"; labelBox.Left = labelPosition.X; labelBox.Top = box.Extent.Y + 1; // FIXME: Why the +1? } while (IsObstructedByAnyPreviousBox(ref labelBox, forControl)) { labelTraits[0] = "stacked"; labelBox.Left = box.Left; labelBox.Width = box.Width; labelBox.Top = labelBox.Extent.Y + 0.5f; } // HACK var labelContentBox = new RectF( labelBox.Position + new Vector2(decorator.Padding.Left, decorator.Padding.Top), scaledSize ); settings = new Decorations.DecorationSettings { Box = labelBox, ContentBox = box, Traits = labelTraits }; decorator.Rasterize(ref context, ref labelRenderer, settings); labelRenderer.DrawMultiple(layout.DrawCalls, offset: labelContentBox.Position.Floor(), scale: new Vector2(textScale), layer: 1); RasterizedOverlayBoxes.Add(new RasterizedOverlayBox { Control = forControl, ControlBox = box, LabelBox = labelBox }); }