protected virtual void DrawTextCenter(
            Graphics g, string text, Font font, Rectangle rect, Color color
            )
        {
            if (Root.Canvas.UseGdiPlus)
            {
                using (var brush = new SolidBrush(color)) {
                    var fmt = (StringFormat)StringFormat.GenericTypographic.Clone();
                    fmt.Alignment     = StringAlignment.Center;
                    fmt.LineAlignment = StringAlignment.Center;
                    fmt.FormatFlags   =
                        StringFormatFlags.NoWrap |
                        StringFormatFlags.NoClip;
                    g.DrawString(text, font, brush, rect, fmt);
                }
            }
            else
            {
                //TextRenderer.DrawText(g, text, font, rect, color, GetBulletFormatFlags());

                using (var f = (Font)font.Clone())
                    using (var renderer = new Gdi32TextRenderer(g, f)) {
                        renderer.BkMode = BkMode.TRANSPARENT;
                        //renderer.TextAlignMode = TextAlignModes.TA_CENTER | TextAlignModes.TA_TOP;
                        renderer.TextColor = color;

                        var size   = renderer.MeasureText(text);
                        var left   = rect.Left + (rect.Width - size.Width) / 2 + 1;
                        var top    = rect.Top + (rect.Height - size.Height) / 2 + 1;
                        var width  = size.Width;
                        var height = size.Height;

                        var r = new Rectangle(
                            left + Root.Canvas.AutoScrollPosition.X - Root.Left,
                            top + Root.Canvas.AutoScrollPosition.Y - Root.Top,
                            width,
                            height
                            );

                        renderer.DrawText(text, r);
                    }
            }
        }
        // ------------------------------
        // protected
        // ------------------------------
        // --- text ---
        protected virtual void DrawText(
            Graphics g, string text, Font font, Rectangle rect, Color color
            )
        {
            if (Root.Canvas.UseGdiPlus)
            {
                using (var brush = new SolidBrush(color)) {
                    var fmt = new StringFormat(StringFormat.GenericTypographic);
                    fmt.FormatFlags =
                        StringFormatFlags.NoWrap |
                        StringFormatFlags.NoClip;
                    g.DrawString(text, font, brush, rect.Location, fmt);
                }
            }
            else
            {
                using (var f = (Font)font.Clone())
                    using (var renderer = new Gdi32TextRenderer(g, f)) {
                        renderer.BkMode = BkMode.TRANSPARENT;
                        //renderer.TextAlignMode = TextAlignModes.TA_LEFT | TextAlignModes.TA_TOP;
                        renderer.TextColor = color;
                        var r = new Rectangle(
                            rect.Left + Root.Canvas.AutoScrollPosition.X - Root.Left,
                            rect.Top + Root.Canvas.AutoScrollPosition.Y - Root.Top,
                            rect.Width,
                            rect.Height
                            );
                        renderer.DrawText(text, r);
                    }
            }

            // for debug
            //Console.WriteLine("DrawText: " + text);
            //var trace = new System.Diagnostics.StackTrace();
            //for (int StackLoop = 0; StackLoop < trace.FrameCount; ++StackLoop) {
            //    var frame = trace.GetFrame(StackLoop);
            //    var method = frame.GetMethod();
            //    Console.WriteLine(method.ToString());
            //}
            //Console.WriteLine("---");
        }