Exemplo n.º 1
0
        internal Size MeasureText(GUIState state, string text)
        {
            var measureContext = TextMeshUtil.GetTextContext(text, new Size(4096, 4096), this, state);
            var actualSize     = measureContext.Measure();

            return(actualSize);
        }
Exemplo n.º 2
0
        private static void MoveCaretCallBack(InputTextContext textBox)
        {
            var g = Form.current.uiContext;

            var          rect        = textBox.Rect;
            var          style       = GUIStyle.Basic;
            ITextContext textContext = TextMeshUtil.GetTextContext(textBox.Text, rect.Size, style, GUIState.Normal);

            var  contentRect      = style.GetContentRect(rect);
            var  mousePos         = Mouse.Instance.Position;
            var  offsetOfTextRect = contentRect.TopLeft;
            uint caretIndex;
            bool isInside;

            caretIndex = textContext.XyToIndex(
                (float)(mousePos.X - offsetOfTextRect.X),
                (float)(mousePos.Y - offsetOfTextRect.Y), out isInside);
            textBox.SelectIndex = textBox.CaretIndex = caretIndex;
        }
Exemplo n.º 3
0
        public static void DrawTextBox(Rect rect, int id, string text, InputTextContext context, GUIState state)
        {
            GUIContext    g      = Form.current.uiContext;
            WindowManager w      = g.WindowManager;
            Window        window = w.CurrentWindow;

            var d     = window.DrawList;
            var style = GUIStyle.Basic;
            // draw text, selection and caret
            var contentRect = style.GetContentRect(rect);

            d.PushClipRect(contentRect, true);
            if (g.ActiveId == id)
            {
                //Calculate positions and sizes
                var   textContext = TextMeshUtil.GetTextContext(context.Text, rect.Size, style, GUIState.Normal);
                var   offsetOfTextRect = contentRect.TopLeft;
                float pointX, pointY;
                float caretHeight;
                textContext.IndexToXY(context.CaretIndex, false, out pointX, out pointY, out caretHeight);
                var caretTopPoint    = new Point(pointX, pointY);
                var caretBottomPoint = new Point(pointX, pointY + caretHeight);
                caretTopPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                caretBottomPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);

                byte caretAlpha = context.CaretAlpha;

                // Check if the caret is outside the rect. If so, move the text so the caret is always shown. FIXME this should be done in TextBoxBehaviour
                var caretX = caretTopPoint.X;
                if (caretX < contentRect.X || caretX > contentRect.Right)
                {
                    var offsetX = -(caretX - contentRect.Width - rect.X);
                    contentRect.Offset(offsetX, 0);
                    caretTopPoint.Offset(offsetX, 0);
                    caretBottomPoint.Offset(offsetX, 0);
                }

                //Draw text
                d.DrawText(contentRect, context.Text, style, GUIState.Normal);

                //Draw selection rect

                /*
                 * Note: Design
                 *
                 *  left bound            right bound
                 *     ↓                        ↓
                 *     |      A-----------------+
                 *     |      |CONTENT_CONTENT_C| => Line 1 => rect1
                 *     +------B                 |
                 *     |ONTENT_CONTENT_CONTENT_C| => Line 2 (represents inner lines) => rect2
                 *     |                 C------+
                 *     |ONTENT_CONTENT_CO| => Line 3 => rect3
                 *     +-----------------D
                 *
                 * left bound = l
                 * right bound = r
                 */
                if (context.SelectIndex != context.CaretIndex)
                {
                    float selectPointX, selectPointY;
                    textContext.IndexToXY(context.SelectIndex, false, out selectPointX, out selectPointY, out float dummyHeight);
                    var selectTopPoint    = new Point(selectPointX, selectPointY);
                    var selectBottomPoint = new Point(selectPointX, selectPointY + caretHeight);
                    selectTopPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                    selectBottomPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                    var delta = Math.Abs(selectTopPoint.Y - caretTopPoint.Y);
                    if (delta < caretHeight) // single line
                    {
                        var selectionRect = new Rect(
                            new Point(pointX, pointY),
                            new Point(selectPointX, selectPointY + caretHeight));
                        selectionRect.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                        d.AddRectFilled(selectionRect.Min, selectionRect.Max, Color.Argb(100, 10, 102, 214));
                    }
                    else//mutiple line
                    {
                        var l = contentRect.Left;
                        var r = contentRect.Right;

                        Point A;
                        Point B;
                        Point C;
                        Point D;

                        if (selectTopPoint.Y > caretTopPoint.Y)
                        {
                            A = caretTopPoint;
                            B = caretBottomPoint;
                            C = selectTopPoint;
                            D = selectBottomPoint;
                        }
                        else
                        {
                            A = selectTopPoint;
                            B = selectBottomPoint;
                            C = caretTopPoint;
                            D = caretBottomPoint;
                        }


                        // Line 1
                        var rect1 = new Rect(A, r - A.X, caretHeight);
                        d.AddRectFilled(rect1, Color.Argb(100, 10, 102, 214), 12);
                        d.AddRect(rect1.Min, rect1.Max, Color.White, 12, 15, 2);

                        // Line 2
                        var rect2 = new Rect(new Point(l, B.Y), new Point(r, C.Y));
                        if (rect2.Height > 0.5 * caretHeight)//TODO There should more a more reasonable way to detect this: If it only has two lines, we don't draw the inner rectangle.
                        {
                            d.AddRectFilled(rect2, Color.Argb(100, 10, 102, 214), 12);
                            d.AddRect(rect2.Min, rect2.Max, Color.White, 12, 15, 2);
                        }

                        // Line 3
                        var rect3 = new Rect(new Point(l, C.Y), D);
                        d.AddRectFilled(rect3, Color.Argb(100, 10, 102, 214), 12);
                        d.AddRect(rect3.Min, rect3.Max, Color.White, 12, 15, 2);
                    }
                }

                //Draw caret
                d.PathMoveTo(caretTopPoint);
                d.PathLineTo(caretBottomPoint);
                d.PathStroke(Color.Argb(caretAlpha, 0, 0, 0), false, 2);
            }
            else
            {
                d.DrawText(contentRect, text, style, GUIState.Normal);
            }
            d.PopClipRect();

            // draw the box
            {
                d.AddRect(rect.Min, rect.Max, style.GetBorderColor(state));
            }
        }
Exemplo n.º 4
0
        public static void DrawTextBox(Node node, int id, string text, InputTextContext context, GUIState state)
        {
            GUIContext g = Form.current.uiContext;

            Rect rect  = node.Rect;
            var  d     = node.RenderOpen();
            var  style = node.RuleSet;
            // draw text, selection and caret
            var contentRect = node.ContentRect;

            // clip text rendering to content-box
            //d.PushClip(contentRect);
            if (g.ActiveId == id)
            {
                //Calculate positions and sizes
                var   textContext = TextMeshUtil.GetTextContext(context.Text, rect.Size, style, GUIState.Normal);
                var   offsetOfTextRect = contentRect.TopLeft;
                float pointX, pointY;
                float caretHeight;
                textContext.IndexToXY(context.CaretIndex, false, out pointX, out pointY, out caretHeight);
                var caretTopPoint    = new Point(pointX, pointY);
                var caretBottomPoint = new Point(pointX, pointY + caretHeight);
                caretTopPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                caretBottomPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);

                byte caretAlpha = context.CaretAlpha;

                // Check if the caret is outside the rect. If so, move the text so the caret is always shown. FIXME this should be done in TextBoxBehaviour
                var caretX = caretTopPoint.X;
                if (caretX < contentRect.X || caretX > contentRect.Right)
                {
                    var offsetX = -(caretX - contentRect.Width - rect.X);
                    contentRect.Offset(offsetX, 0);
                    caretTopPoint.Offset(offsetX, 0);
                    caretBottomPoint.Offset(offsetX, 0);
                }

                //Draw text
                d.DrawText(style, context.Text, contentRect);

                //Draw selection rect

                /*
                 * Note: Design
                 *
                 *  left bound            right bound
                 *     ↓                        ↓
                 *     |      A-----------------+
                 *     |      |CONTENT_CONTENT_C| => Line 1 => rect1
                 *     +------B                 |
                 *     |ONTENT_CONTENT_CONTENT_C| => Line 2 (represents inner lines) => rect2
                 *     |                 C------+
                 *     |ONTENT_CONTENT_CO| => Line 3 => rect3
                 *     +-----------------D
                 *
                 * left bound = l
                 * right bound = r
                 */
                if (context.SelectIndex != context.CaretIndex)
                {
                    float selectPointX, selectPointY;
                    textContext.IndexToXY(context.SelectIndex, false, out selectPointX, out selectPointY, out float dummyHeight);
                    var selectTopPoint    = new Point(selectPointX, selectPointY);
                    var selectBottomPoint = new Point(selectPointX, selectPointY + caretHeight);
                    selectTopPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                    selectBottomPoint.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                    var delta = Math.Abs(selectTopPoint.Y - caretTopPoint.Y);
                    if (delta < caretHeight) // single line
                    {
                        var selectionRect = new Rect(
                            new Point(pointX, pointY),
                            new Point(selectPointX, selectPointY + caretHeight));
                        selectionRect.Offset(offsetOfTextRect.X, offsetOfTextRect.Y);
                        d.DrawRectangle(new Brush(Color.Argb(100, 10, 102, 214)), null, selectionRect);
                    }
                    else//multiple lines
                    {
                        var l = contentRect.Left;
                        var r = contentRect.Right;

                        Point A;
                        Point B;
                        Point C;
                        Point D;

                        if (selectTopPoint.Y > caretTopPoint.Y)
                        {
                            A = caretTopPoint;
                            B = caretBottomPoint;
                            C = selectTopPoint;
                            D = selectBottomPoint;
                        }
                        else
                        {
                            A = selectTopPoint;
                            B = selectBottomPoint;
                            C = caretTopPoint;
                            D = caretBottomPoint;
                        }


                        // Line 1
                        var rect1 = new Rect(A, r - A.X, caretHeight);
                        d.DrawRectangle(new Brush(Color.Argb(100, 10, 102, 214)), null, rect1);
                        d.DrawRectangle(null, new Pen(Color.White, 2), rect1);

                        // Line 2
                        var rect2 = new Rect(new Point(l, B.Y), new Point(r, C.Y));
                        if (rect2.Height > 0.5 * caretHeight)//TODO There should more a more reasonable way to detect this: If it only has two lines, we don't draw the inner rectangle.
                        {
                            d.DrawRectangle(new Brush(Color.Argb(100, 10, 102, 214)), null, rect2);
                            d.DrawRectangle(null, new Pen(Color.White, 2), rect2);
                        }

                        // Line 3
                        var rect3 = new Rect(new Point(l, C.Y), D);
                        d.DrawRectangle(new Brush(Color.Argb(100, 10, 102, 214)), null, rect3);
                        d.DrawRectangle(null, new Pen(Color.White, 2), rect3);
                    }
                }

                //Draw caret
                d.DrawLine(new Pen(Color.Argb(caretAlpha, 0, 0, 0), 2), caretTopPoint, caretBottomPoint);
            }
            else
            {
                d.DrawText(style, text, contentRect);
            }
            //d.Pop();
            d.Close();
        }
Exemplo n.º 5
0
        /// <summary>
        /// Append a text mesh to this drawlist
        /// </summary>
        public void AddText(Rect rect, string text, GUIStyle style, GUIState state)
        {
            if (GetCurrentClipRect().IsEmpty)
            {
                return;
            }

            AddTextDrawCommand();

            var textMesh            = this.TextMesh;
            var oldIndexBufferCount = textMesh.IndexBuffer.Count;

            string fontFamily = style.FontFamily;
            double fontSize   = style.FontSize;
            Color  fontColor  = style.FontColor;

            // get offset and scale from text layout
            var scale        = OSImplentation.TypographyTextContext.GetScale(fontFamily, fontSize);
            var textContext  = TextMeshUtil.GetTextContext(text, rect.Size, style, state) as OSImplentation.TypographyTextContext;
            var glyphOffsets = textContext.GlyphOffsets;

            int index = -1;

            // get glyph data from typeface
            FontStyle  fontStyle  = style.FontStyle;
            FontWeight fontWeight = style.FontWeight;

            foreach (var character in text)
            {
                index++;
                if (char.IsWhiteSpace(character))
                {
                    continue;
                }
                var glyphData = GlyphCache.Default.GetGlyph(character, fontFamily, fontStyle, fontWeight);
                if (glyphData == null)
                {
                    Typography.OpenFont.Glyph glyph = OSImplentation.TypographyTextContext.LookUpGlyph(fontFamily, character);
                    var polygons       = new List <List <Point> >();
                    var bezierSegments = new List <(Point, Point, Point)>();
                    Typography.OpenFont.GlyphLoader.Read(glyph, out polygons, out bezierSegments);
                    GlyphCache.Default.AddGlyph(character, fontFamily, fontStyle, fontWeight, polygons, bezierSegments);
                    glyphData = GlyphCache.Default.GetGlyph(character, fontFamily, fontStyle, fontWeight);
                    Debug.Assert(glyphData != null);
                }

                // append to drawlist
                Vector glyphOffset    = glyphOffsets[index];
                var    positionOffset = (Vector)rect.TopLeft;
                this.TextMesh.Append(positionOffset, glyphData, glyphOffset, scale, fontColor, false);
            }

            var newIndexBufferCount = textMesh.IndexBuffer.Count;

            // Update command
            var command = textMesh.Commands[textMesh.Commands.Count - 1];

            command.ElemCount += newIndexBufferCount - oldIndexBufferCount;
            textMesh.Commands[textMesh.Commands.Count - 1] = command;

            // TODO refactor this
        }