private void RenderSelection(EditText editText, UIRenderingContext context, int start, int length, Color color, out float offsetTextStart, out float offsetAlignment, out float selectionSize) { // calculate the size of the text region by removing padding var textRegionSize = new Vector2(editText.ActualWidth - editText.Padding.Left - editText.Padding.Right, editText.ActualHeight - editText.Padding.Top - editText.Padding.Bottom); var font = editText.Font; // determine the image to draw in background of the edit text var fontScale = editText.LayoutingContext.RealVirtualResolutionRatio; var provider = editText.IsSelectionActive ? editText.ActiveImage : editText.MouseOverState == MouseOverState.MouseOverElement ? editText.MouseOverImage : editText.InactiveImage; var image = provider?.GetSprite(); var fontSize = new Vector2(fontScale.Y * editText.ActualTextSize); offsetTextStart = font.MeasureString(editText.TextToDisplay, ref fontSize, start).X; selectionSize = font.MeasureString(editText.TextToDisplay, ref fontSize, start + length).X - offsetTextStart; var lineSpacing = font.GetTotalLineSpacing(editText.ActualTextSize); if (font.FontType == SpriteFontType.Dynamic) { offsetTextStart /= fontScale.X; selectionSize /= fontScale.X; } var scaleRatio = editText.ActualTextSize / font.Size; if (font.FontType == SpriteFontType.SDF) { offsetTextStart *= scaleRatio; selectionSize *= scaleRatio; lineSpacing *= editText.ActualTextSize / font.Size; } offsetAlignment = -textRegionSize.X / 2f; if (editText.TextAlignment != TextAlignment.Left) { var textWidth = font.MeasureString(editText.TextToDisplay, ref fontSize).X; if (font.FontType == SpriteFontType.Dynamic) { textWidth /= fontScale.X; } if (font.FontType == SpriteFontType.SDF) { textWidth *= scaleRatio; } offsetAlignment = editText.TextAlignment == TextAlignment.Center ? -textWidth / 2 : -textRegionSize.X / 2f + (textRegionSize.X - textWidth); } var selectionWorldMatrix = editText.WorldMatrixInternal; selectionWorldMatrix.M41 += offsetTextStart + selectionSize / 2 + offsetAlignment; var selectionScaleVector = new Vector3(selectionSize, editText.LineCount * lineSpacing, 0); Batch.DrawRectangle(ref selectionWorldMatrix, ref selectionScaleVector, ref color, context.DepthBias + 1); }
public override void RenderColor(UIElement element, UIRenderingContext context) { base.RenderColor(element, context); var editText = (EditText)element; if (editText.Font == null) { return; } // determine the image to draw in background of the edit text var fontScale = element.LayoutingContext.RealVirtualResolutionRatio; var color = editText.RenderOpacity * Color.White; var provider = editText.IsSelectionActive ? editText.ActiveImage : editText.MouseOverState == MouseOverState.MouseOverElement ? editText.MouseOverImage : editText.InactiveImage; var image = provider?.GetSprite(); if (image?.Texture != null) { Batch.DrawImage(image.Texture, ref editText.WorldMatrixInternal, ref image.RegionInternal, ref editText.RenderSizeInternal, ref image.BordersInternal, ref color, context.DepthBias, image.Orientation); } // calculate the size of the text region by removing padding var textRegionSize = new Vector2(editText.ActualWidth - editText.Padding.Left - editText.Padding.Right, editText.ActualHeight - editText.Padding.Top - editText.Padding.Bottom); var font = editText.Font; var caretColor = editText.RenderOpacity * editText.CaretColor; var offsetTextStart = 0f; var offsetAlignment = 0f; var selectionSize = 0f; // Draw the composition selection if (editText.Composition.Length > 0) { var imeSelectionColor = editText.RenderOpacity * editText.IMESelectionColor; RenderSelection(editText, context, editText.SelectionStart, editText.Composition.Length, imeSelectionColor, out offsetTextStart, out offsetAlignment, out selectionSize); } // Draw the regular selection else if (editText.IsSelectionActive) { var selectionColor = editText.RenderOpacity * editText.SelectionColor; RenderSelection(editText, context, editText.SelectionStart, editText.SelectionLength, selectionColor, out offsetTextStart, out offsetAlignment, out selectionSize); } // create the text draw command var drawCommand = new SpriteFont.InternalUIDrawCommand { Color = editText.RenderOpacity * editText.TextColor, DepthBias = context.DepthBias + 2, RealVirtualResolutionRatio = fontScale, RequestedFontSize = editText.ActualTextSize, Batch = Batch, SnapText = context.ShouldSnapText && !editText.DoNotSnapText, Matrix = editText.WorldMatrixInternal, Alignment = editText.TextAlignment, TextBoxSize = textRegionSize }; if (editText.Font.FontType == SpriteFontType.SDF) { Batch.End(); Batch.BeginCustom(context.GraphicsContext, 1); } // Draw the text Batch.DrawString(font, editText.TextToDisplay, ref drawCommand); if (editText.Font.FontType == SpriteFontType.SDF) { Batch.End(); Batch.BeginCustom(context.GraphicsContext, 0); } // Draw the cursor if (editText.IsCaretVisible) { var lineSpacing = editText.Font.GetTotalLineSpacing(editText.ActualTextSize); if (editText.Font.FontType == SpriteFontType.SDF) { lineSpacing *= editText.ActualTextSize / font.Size; } var sizeCaret = editText.CaretWidth / fontScale.X; var caretWorldMatrix = element.WorldMatrixInternal; caretWorldMatrix.M41 += offsetTextStart + offsetAlignment + (editText.CaretPosition > editText.SelectionStart? selectionSize: 0); var caretScaleVector = new Vector3(sizeCaret, editText.LineCount * lineSpacing, 0); Batch.DrawRectangle(ref caretWorldMatrix, ref caretScaleVector, ref caretColor, context.DepthBias + 3); } }
public static Mesh ToStrideMesh(GraphicsDevice graphicsDevice, SimpleMesh g3Mesh, Vector3 offset, float scaling = 1f) { if (g3Mesh is null || g3Mesh.VertexCount == 0) { return(null); } var vertexDeclaration = GetVertexDeclaration(g3Mesh); var vertices = new byte[g3Mesh.VertexCount * vertexDeclaration.VertexStride]; var boundingBox = BoundingBox.Empty; BoundingSphere boundingSphere; unsafe { fixed(byte *ptr = vertices) { byte *current = ptr; for (int i = 0; i < g3Mesh.VertexCount; i++) { var vi = g3Mesh.GetVertexAll(i); var p = (new Vector3((float)vi.v.x, (float)vi.v.y, (float)vi.v.z) + offset) * scaling; BoundingBox.Merge(ref boundingBox, ref p, out boundingBox); Unsafe.Write(current, p); current += sizeof(Vector3); if (vi.bHaveN) { Unsafe.Write(current, vi.n); current += sizeof(Vector3); } if (vi.bHaveUV) { Unsafe.Write(current, vi.uv); current += sizeof(Vector2); } if (vi.bHaveC) { Unsafe.Write(current, new Color(vi.c.x, vi.c.y, vi.c.z)); current += sizeof(Color); } } BoundingSphere.FromPoints((IntPtr)ptr, 0, g3Mesh.VertexCount, vertexDeclaration.VertexStride, out boundingSphere); } } var vertexBuffer = Buffer.New(graphicsDevice, vertices, vertexDeclaration.VertexStride, BufferFlags.VertexBuffer); var indexBuffer = Buffer.Index.New(graphicsDevice, g3Mesh.Triangles.Reverse().ToArray()); return(new Mesh() { Draw = new MeshDraw() { VertexBuffers = new VertexBufferBinding[] { new VertexBufferBinding(vertexBuffer, vertexDeclaration, g3Mesh.VertexCount) }, IndexBuffer = new IndexBufferBinding(indexBuffer, is32Bit: true, g3Mesh.Triangles.Length), DrawCount = g3Mesh.Triangles.Length, PrimitiveType = PrimitiveType.TriangleList }, BoundingBox = boundingBox, BoundingSphere = boundingSphere }); }
public static Mesh ToStrideMesh(GraphicsDevice graphicsDevice, DMesh3 g3Mesh, Vector3 offset, float scaling = 1f) { if (g3Mesh is null) { return(null); } return(ToStrideMesh(graphicsDevice, new SimpleMesh(g3Mesh), offset, scaling)); }