Exemplo n.º 1
0
 public static SizeF MeasureText(this Graphics g,
                                 string text, Font font,
                                 TextHPosition hpos = TextHPosition.Left, TextVPosition vpos = TextVPosition.Top,
                                 float lineHeight   = 1.2F, float fontRatio = 1.0F)
 {
     return(g.BoundsText(text, font,
                         hpos, vpos,
                         lineHeight, fontRatio).Size);
 }
Exemplo n.º 2
0
 public static RectangleF BoundsText(this Graphics g,
                                     string text, Font font,
                                     TextHPosition hpos = TextHPosition.Left, TextVPosition vpos = TextVPosition.Top,
                                     float lineHeight   = 1.2F, float fontRatio = 1.0F)
 {
     return(g.BoundsText(text, font,
                         null,
                         new Rectangle(0, 0, 0, 0), hpos, vpos,
                         lineHeight, fontRatio));
 }
Exemplo n.º 3
0
        /// <summary>
        ///   属性指定テキストを描画する
        /// </summary>
        /// <param name="text">描画文字列の配列</param>
        /// <param name="attr">表示属性指定</param>
        /// <param name="rect">描画範囲</param>
        /// <returns>描画した領域</returns>
        public static Rectangle DrawText(this Graphics g,
                                         string[] text, MPAttribute attr,
                                         Rectangle rect,
                                         Control control = null)
        {
            if ((text == null) || (text.Length == 0) || (rect == null))
            {
                return(new Rectangle(0, 0, 0, 0));
            }
            Rectangle urect      = new Rectangle(0, 0, 0, 0);
            float     lineHeight = (float)rect.Height / (float)text.Length;
            Rectangle lineRect   = new Rectangle();

            for (int i = 0; i < text.Length; i++)
            {
                MPAttribute xattr = attr;
                string      xtext = text[i].Trim();
                Match       m     = pat_class.Match(xtext);
                if (m.Success)
                {
                    xattr = (MPAttribute)attr.GetClass(m.Groups[1].Value);
                    xtext = m.Groups[2].Value.Trim();
                }

                lineRect.X      = rect.X;
                lineRect.Width  = rect.Width;
                lineRect.Y      = rect.Y + (int)(lineHeight * i);
                lineRect.Height = rect.Y + (int)(lineHeight * (i + 1)) - lineRect.Y;

                Color         bgcolor       = Color.White;
                Color         color         = Color.Black;
                TextHPosition hpos          = TextHPosition.LeftShrink;
                TextVPosition vpos          = TextVPosition.Middle;
                float         outlineRatio  = 0F;
                Color         outlineColor  = ColorUtil.Invalid;
                float         lh            = 1F;
                Color         shadowColor   = ColorUtil.Invalid;
                float         shadowOffsetX = 0F;
                float         shadowOffsetY = 0F;
                float         fontRatio     = 1.0F;
                Font          refFont       = Control.DefaultFont;

                if (control != null)
                {
                    bgcolor = control.GetRealBackColor();
                    color   = control.ForeColor;
                    refFont = control.Font;
                    if (control is MPText)
                    {
                        MPText cc = control as MPText;
                        hpos          = cc.HPosition;
                        vpos          = cc.VPosition;
                        outlineRatio  = cc.OutlineRatio;
                        outlineColor  = cc.OutlineColor;
                        shadowColor   = cc.ShadowColor;
                        shadowOffsetX = cc.ShadowOffsetX;
                        shadowOffsetY = cc.ShadowOffsetY;
                    }
                }

                // 文字色は"textcolor", "color"の定義の順に探す。
                color = xattr.GetColor("textcolor", xattr.GetColor("color", color));
                if (color == ColorUtil.Auto)
                {
                    color = ColorUtil.GetBWColor(bgcolor);
                }
                xattr.FetchTextPosition(ref hpos, ref vpos);
                xattr.FetchTextStyle(ref outlineRatio, ref outlineColor, ref lh, ref shadowColor, ref shadowOffsetX, ref shadowOffsetY);
                if (outlineColor == ColorUtil.Auto)
                {
                    outlineColor = ColorUtil.GetBWColor(color);
                }
                Font  font         = xattr.GetFont(refFont);
                float outlineWidth = font.GetEmSize() * outlineRatio;
                Brush brush        = null;
                if (color.A > 0)
                {
                    brush = new SolidBrush(color);
                }
                Pen pen = null;
                if ((outlineColor.A > 0) && (outlineWidth > 0))
                {
                    pen = new Pen(outlineColor, outlineWidth);
                }
                Brush shadow = null;
                if (shadowColor.A > 0)
                {
                    shadow = new SolidBrush(shadowColor);
                }

                lineRect = g.DrawText(new string[] { xtext }, font,
                                      pen, brush,
                                      lineRect, hpos, TextVPosition.Middle,
                                      1F, fontRatio,
                                      shadow, shadowOffsetX, shadowOffsetY);
                if ((urect.Width == 0) || (urect.Height == 0))
                {
                    urect = lineRect;
                }
                else if ((lineRect.Width != 0) && (lineRect.Height != 0))
                {
                    urect = Rectangle.Union(urect, lineRect);
                }

                if (brush != null)
                {
                    brush.Dispose();
                }
                if (pen != null)
                {
                    pen.Dispose();
                }
                if (shadow != null)
                {
                    shadow.Dispose();
                }
            }
            return(urect);
        }
Exemplo n.º 4
0
        /// <summary>
        ///   アウトラインテキストを描画するときの外枠を得る
        /// </summary>
        /// <param name="text">描画文字列の配列</param>
        /// <param name="attr">表示属性指定</param>
        /// <param name="rect">描画範囲</param>
        /// <returns>サイズ</returns>
        public static RectangleF BoundsText(this Graphics g,
                                            string[] text, MPAttribute attr,
                                            Rectangle rect,
                                            Control control = null)
        {
            if ((text == null) || (text.Length == 0) || (rect == null))
            {
                return(new RectangleF(0, 0, 0, 0));
            }
            RectangleF urect      = new RectangleF(0, 0, 0, 0);
            float      lineHeight = (float)rect.Height / (float)text.Length;
            Rectangle  lineRect   = new Rectangle();

            for (int i = 0; i < text.Length; i++)
            {
                MPAttribute xattr = attr;
                string      xtext = text[i].Trim();
                Match       m     = pat_class.Match(xtext);
                if (m.Success)
                {
                    xattr = (MPAttribute)attr.GetClass(m.Groups[1].Value);
                    xtext = m.Groups[2].Value.Trim();
                }

                lineRect.X      = rect.X;
                lineRect.Width  = rect.Width;
                lineRect.Y      = rect.Y + (int)(lineHeight * i);
                lineRect.Height = rect.Y + (int)(lineHeight * (i + 1)) - lineRect.Y;

                TextHPosition hpos          = TextHPosition.LeftShrink;
                TextVPosition vpos          = TextVPosition.Middle;
                float         outlineRatio  = 0F;
                Color         outlineColor  = ColorUtil.Invalid;
                float         lh            = 1F;
                Color         shadowColor   = ColorUtil.Invalid;
                float         shadowOffsetX = 0F;
                float         shadowOffsetY = 0F;
                float         fontRatio     = 1.0F;

                xattr.FetchTextPosition(ref hpos, ref vpos);
                xattr.FetchTextStyle(ref outlineRatio, ref outlineColor, ref lh, ref shadowColor, ref shadowOffsetX, ref shadowOffsetY);
                Font  font         = xattr.GetFont((control != null)?control.Font:Control.DefaultFont);
                float outlineWidth = font.GetEmSize() * outlineRatio;
                Pen   pen          = null;
                if ((outlineColor.A > 0) && (outlineWidth > 0))
                {
                    pen = new Pen(outlineColor, outlineWidth);
                }

                RectangleF xrect = g.BoundsText(new string[] { xtext }, font,
                                                pen,
                                                lineRect, hpos, TextVPosition.Middle,
                                                1F, fontRatio);
                if ((urect.Width == 0) || (urect.Height == 0))
                {
                    urect = xrect;
                }
                else if ((xrect.Width != 0) && (xrect.Height != 0))
                {
                    urect = RectangleF.Union(urect, xrect);
                }

                font.Dispose();
                if (pen != null)
                {
                    pen.Dispose();
                }
            }
            return(urect);
        }
Exemplo n.º 5
0
        public void FetchTextPosition(ref TextHPosition hpos, ref TextVPosition vpos, string key = "")
        {
            bool   shrink = this.Get(key + "shrink", true);
            string val    = this.Get(key + "align");

            if (!String.IsNullOrEmpty(val))
            {
                switch (val.ToUpper())
                {
                case "LEFTTOP":
                case "TOPLEFT":
                case "TOP":
                    hpos = shrink?TextHPosition.LeftShrink:TextHPosition.Left;
                    vpos = TextVPosition.Top;
                    break;

                case "CENTERTOP":
                case "TOPCENTER":
                    hpos = shrink?TextHPosition.CenterShrink:TextHPosition.Center;
                    vpos = TextVPosition.Top;
                    break;

                case "RIGHTTOP":
                case "TOPRIGHT":
                    hpos = shrink?TextHPosition.RightShrink:TextHPosition.Right;
                    vpos = TextVPosition.Top;
                    break;

                case "LEFTFIT":
                case "FITLEFT":
                case "FIT":
                    hpos = shrink?TextHPosition.LeftShrink:TextHPosition.Left;
                    vpos = TextVPosition.Fit;
                    break;

                case "CENTERFIT":
                case "FITCENTER":
                    hpos = shrink?TextHPosition.CenterShrink:TextHPosition.Center;
                    vpos = TextVPosition.Fit;
                    break;

                case "RIGHTFIT":
                case "FITRIGHT":
                    hpos = shrink?TextHPosition.RightShrink:TextHPosition.Right;
                    vpos = TextVPosition.Fit;
                    break;

                case "LEFT":
                case "LEFTMIDDLE":
                case "MIDDLELEFT":
                case "MIDDLE":
                    hpos = shrink?TextHPosition.LeftShrink:TextHPosition.Left;
                    vpos = TextVPosition.Middle;
                    break;

                case "CENTER":
                case "CENTERMIDDLE":
                case "MIDDLECENTER":
                    hpos = shrink?TextHPosition.CenterShrink:TextHPosition.Center;
                    vpos = TextVPosition.Middle;
                    break;

                case "RIGHT":
                case "RIGHTMIDDLE":
                case "MIDDLERIGHT":
                    hpos = shrink?TextHPosition.RightShrink:TextHPosition.Right;
                    vpos = TextVPosition.Middle;
                    break;

                case "LEFTBOTTOM":
                case "BOTTOMLEFT":
                case "BOTTOM":
                    hpos = shrink?TextHPosition.LeftShrink:TextHPosition.Left;
                    vpos = TextVPosition.Bottom;
                    break;

                case "CENTERBOTTOM":
                case "BOTTOMCENTER":
                    hpos = shrink?TextHPosition.CenterShrink:TextHPosition.Center;
                    vpos = TextVPosition.Bottom;
                    break;

                case "RIGHTBOTTOM":
                case "BOTTOMRIGHT":
                    hpos = shrink?TextHPosition.RightShrink:TextHPosition.Right;
                    vpos = TextVPosition.Bottom;
                    break;
                }
            }
        }
Exemplo n.º 6
0
        private static GraphicsPath makeTextPath(string[] text, Font font,
                                                 Rectangle rect, TextHPosition hpos, TextVPosition vpos,
                                                 float lineHeight, float fontRatio, float emSize)
        {
            // 各行のテキストパスを得る
            GraphicsPath[] pp = new GraphicsPath[text.Length];
            using (Matrix m = new Matrix()) {
                if (fontRatio != 1F)
                {
                    m.Scale(fontRatio, 1F);
                }
                for (int i = 0; i < text.Length; i++)
                {
                    pp[i] = new GraphicsPath();
                    pp[i].AddString(text[i], font.FontFamily, (int)font.Style, emSize, new PointF(0F, 0F), StringFormat.GenericDefault);
                    if (fontRatio != 1F)
                    {
                        pp[i].Transform(m);
                    }
                }
            }
            // 全体の描画幅、高さを得る
            float ww = 0F;

            for (int i = 0; i < pp.Length; i++)
            {
                RectangleF r = pp[i].GetBounds();
                if (ww < r.Width)
                {
                    ww = r.Width;
                }
            }
            if ((hpos == TextHPosition.LeftShrink) || (hpos == TextHPosition.CenterShrink) || (hpos == TextHPosition.RightShrink))
            {
                if (ww > rect.Width)
                {
                    ww = rect.Width;
                }
            }
            float hh, hhstep;

            switch (vpos)
            {
            case TextVPosition.Fit:
                hh = rect.Height;
                if ((text.Length == 1) || (hh < emSize))
                {
                    hhstep = 0;
                }
                else
                {
                    hhstep = (hh - emSize) / (float)(text.Length - 1);
                }
                break;

            case TextVPosition.Proportional:
                hh     = rect.Height;
                hhstep = (float)rect.Height / (float)text.Length;
                break;

            default:
                hh     = emSize + (emSize * lineHeight) * (float)(text.Length - 1);
                hhstep = emSize * lineHeight;
                break;
            }
            // テキストパスを一つにまとめる
            GraphicsPath p = new GraphicsPath();

            for (int i = 0; i < pp.Length; i++)
            {
                RectangleF bb = pp[i].GetBounds();
                if ((bb.Width > 0) && (bb.Height > 0)) // 空パスをAddPathするとエラーになるらしい
                {
                    float xoff = -bb.X;
                    float xmag = 1F;
                    switch (hpos)
                    {
                    case TextHPosition.Left:
                        //xoff += 0F;
                        //xmag = 1F;
                        break;

                    case TextHPosition.Center:
                        xoff += ((float)rect.Width - bb.Width) / 2F;
                        //xmag = 1F;
                        break;

                    case TextHPosition.Right:
                        xoff += (float)rect.Width - bb.Width - 1F;
                        //xmag = 1F;
                        break;

                    case TextHPosition.LeftShrink:
                        if (ww < bb.Width)
                        {
                            //xoff += 0F;
                            if (bb.Width == 0)
                            {
                                xmag = 1F;
                            }
                            else
                            {
                                xmag = (float)rect.Width / (bb.Width + 1F);
                            }
                        }
                        else
                        {
                            //xoff += 0F;
                            xmag = 1F;
                        }
                        break;

                    case TextHPosition.CenterShrink:
                        if (ww < bb.Width)
                        {
                            //xoff += 0F;
                            if (bb.Width == 0)
                            {
                                xmag = 1F;
                            }
                            else
                            {
                                xmag = (float)rect.Width / (bb.Width + 1F);
                            }
                        }
                        else
                        {
                            xoff += ((float)rect.Width - bb.Width) / 2F;
                            xmag  = 1F;
                        }
                        break;

                    case TextHPosition.RightShrink:
                        if (ww < bb.Width)
                        {
                            //xoff += 0F;
                            if (bb.Width == 0)
                            {
                                xmag = 1F;
                            }
                            else
                            {
                                xmag = (float)rect.Width / (bb.Width + 1F);
                            }
                        }
                        else
                        {
                            xoff += (float)rect.Width - bb.Width - 1F;
                            xmag  = 1F;
                        }
                        break;
                    }
                    float yoff = hhstep * (float)i - bb.Y;
                    if (hhstep <= 0)
                    {
                        yoff += ((float)rect.Height - emSize) / 2F;
                    }
                    float ymag = 1F;
                    switch (vpos)
                    {
                    case TextVPosition.Top:
                        // yoff += 0F;
                        break;

                    case TextVPosition.Middle:
                        yoff += ((float)rect.Height - hh) / 2F;
                        break;

                    case TextVPosition.Bottom:
                        yoff += (float)rect.Height - hh;
                        break;

                    case TextVPosition.Fit:
                        // yoff += 0F;
                        break;

                    case TextVPosition.Proportional:
                        yoff = hhstep * (float)i + (hhstep - bb.Height) / 2F - bb.Y;
                        break;
                    }
                    if ((xoff != 0F) || (yoff != 0F))
                    {
                        using (Matrix m = new Matrix()) {
                            m.Translate(xoff, yoff);
                            pp[i].Transform(m);
                        }
                    }
                    if ((xmag != 1F) || (ymag != 1F))
                    {
                        using (Matrix m = new Matrix()) {
                            m.Scale(xmag, ymag);
                            pp[i].Transform(m);
                        }
                    }
                    p.AddPath(pp[i], false);
                }
                pp[i].Dispose();
            }
            return(p);
        }
Exemplo n.º 7
0
 public static RectangleF BoundsText(this Graphics g,
                                     string text, Font font,
                                     Rectangle rect, TextHPosition hpos = TextHPosition.Left, TextVPosition vpos = TextVPosition.Top,
                                     float lineHeight = 1.2F, float fontRatio = 1.0F)
 {
     if (String.IsNullOrEmpty(text))
     {
         return(new RectangleF(0, 0, 0, 0));
     }
     return(g.BoundsText(text.Split("\n".ToCharArray()), font,
                         null,
                         rect, hpos, vpos,
                         lineHeight, fontRatio));
 }
Exemplo n.º 8
0
        /// <summary>
        ///   アウトラインテキストを描画するときの外枠を得る
        /// </summary>
        /// <param name="text">描画文字列の配列</param>
        /// <param name="font">使用フォント</param>
        /// <param name="outline">アウトラインを描画するペン。nullのときはアウトライン描画なし</param>
        /// <param name="rect">描画範囲</param>
        /// <param name="hpos">水平描画位置</param>
        /// <param name="vpos">垂直描画位置</param>
        /// <param name="lineHeight">行間隔(行上端から次の行の上端までの間隔)フォント高さの倍数で指定する</param>
        /// <param name="fontRatio">文字の縦横比</param>
        /// <returns>BoundRectangle</returns>
        public static RectangleF BoundsText(this Graphics g,
                                            string[] text, Font font,
                                            Pen outline,
                                            Rectangle rect, TextHPosition hpos = TextHPosition.Left, TextVPosition vpos = TextVPosition.Top,
                                            float lineHeight = 1.2F, float fontRatio = 1.0F)
        {
            if ((text == null) || (text.Length == 0) || (rect == null))
            {
                return(new RectangleF(0, 0, 0, 0));
            }
            float emSize = font.GetEmSize();

            using (GraphicsPath p = makeTextPath(text, font, rect, hpos, vpos, lineHeight, fontRatio, emSize)) {
                if (outline == null)
                {
                    return(p.GetBounds());
                }
                else
                {
                    using (Matrix m = new Matrix()) {
                        return(RectangleF.Inflate(p.GetBounds(), outline.Width / 2F, outline.Width / 2F));
                    }
                }
            }
        }
Exemplo n.º 9
0
        /// <summary>
        ///   アウトラインテキストを描画する
        /// </summary>
        /// <param name="text">描画文字列の配列</param>
        /// <param name="font">使用フォント</param>
        /// <param name="outline">アウトラインを描画するペン。nullのときはアウトライン描画なし</param>
        /// <param name="fill">文字の描画色。nullのときは塗りつぶしなし</param>
        /// <param name="rect">描画範囲</param>
        /// <param name="hpos">水平描画位置</param>
        /// <param name="vpos">垂直描画位置</param>
        /// <param name="lineHeight">行間隔(行上端から次の行の上端までの間隔)フォント高さの倍数で指定する</param>
        /// <param name="fontRatio">文字の縦横比</param>
        /// <param name="shadow">影描画ブラシ。nullのときは影描画なし</param>
        /// <param name="shadowOffsetX">影描画時のXオフセット。未指定の場合フォント高さの10%</param>
        /// <param name="shadowOffsetY">影描画時のYオフセット。未指定の場合フォント高さの10%</param>
        /// <param name="shadowWidth">影描画時の太さ。未指定の場合shadowOffsetXとshadowOffsetYの二乗平均</param>
        /// <returns>描画した領域</returns>
        public static Rectangle DrawText(this Graphics g,
                                         string[] text, Font font,
                                         Pen outline, Brush fill,
                                         Rectangle rect, TextHPosition hpos = TextHPosition.Left, TextVPosition vpos = TextVPosition.Top,
                                         float lineHeight = 1.2F, float fontRatio     = 1.0F,
                                         Brush shadow     = null, float shadowOffsetX = float.MaxValue, float shadowOffsetY = float.MaxValue, float shadowWidth = float.MaxValue)
        {
            if ((text == null) || (text.Length == 0) || (rect == null))
            {
                return(new Rectangle(0, 0, 0, 0));
            }
            float        emSize = font.GetEmSize();
            GraphicsPath p      = makeTextPath(text, font, rect, hpos, vpos, lineHeight, fontRatio, emSize);

            using (Matrix m = new Matrix()) {
                m.Translate((float)rect.X, (float)rect.Y);
                p.Transform(m);
            }

            // 影描画
            if (shadow != null)
            {
                using (GraphicsPath sp = (GraphicsPath)p.Clone()) {
                    if (shadowOffsetX == float.MaxValue)
                    {
                        shadowOffsetX = emSize / 10F;
                    }
                    if (shadowOffsetY == float.MaxValue)
                    {
                        shadowOffsetY = shadowOffsetX;
                    }
                    using (Matrix m = new Matrix()) {
                        m.Translate(shadowOffsetX, shadowOffsetY);
                        sp.Transform(m);
                    }
                    if (shadowWidth == float.MaxValue)
                    {
                        shadowWidth = (float)Math.Sqrt(shadowOffsetX * shadowOffsetX + shadowOffsetY * shadowOffsetY);
                    }
                    using (Pen pen = new Pen(Color.Black, shadowWidth)) {
                        sp.Widen(pen);
                    }
                    g.FillPath(shadow, sp);
                }
            }

            // 文字描画
            if (outline != null)
            {
                g.DrawPath(outline, p);
            }
            if (fill != null)
            {
                g.FillPath(fill, p);
            }

            // 描画した領域
            Rectangle ret;

            if (outline == null)
            {
                ret = Rectangle.Ceiling(p.GetBounds());
            }
            else
            {
                ret = Rectangle.Ceiling(RectangleF.Inflate(p.GetBounds(), outline.Width / 2F, outline.Width / 2F));
            }

            p.Dispose();
            return(ret);
        }
Exemplo n.º 10
0
 public static Rectangle DrawText(this Graphics g,
                                  string text, Font font,
                                  Brush fill,
                                  Point loc, TextHPosition hpos = TextHPosition.Left, TextVPosition vpos = TextVPosition.Top,
                                  float lineHeight = 1.2F, float fontRatio     = 1.0F,
                                  Brush shadow     = null, float shadowOffsetX = float.MaxValue, float shadowOffsetY = float.MaxValue, float shadowWidth = float.MaxValue)
 {
     if (String.IsNullOrEmpty(text))
     {
         return(new Rectangle(0, 0, 0, 0));
     }
     return(g.DrawText(text.Split("\n".ToCharArray()), font,
                       null, fill,
                       new Rectangle(loc.X, loc.Y, 0, 0), hpos, vpos,
                       lineHeight, fontRatio,
                       shadow, shadowOffsetX, shadowOffsetY, shadowWidth));
 }
Exemplo n.º 11
0
 public static Rectangle DrawText(this Graphics g,
                                  string[] text, Font font,
                                  Brush fill,
                                  Point loc, TextHPosition hpos = TextHPosition.Left, TextVPosition vpos = TextVPosition.Top,
                                  float lineHeight = 1.2F, float fontRatio     = 1.0F,
                                  Brush shadow     = null, float shadowOffsetX = float.MaxValue, float shadowOffsetY = float.MaxValue, float shadowWidth = float.MaxValue)
 {
     return(g.DrawText(text, font,
                       null, fill,
                       new Rectangle(loc.X, loc.Y, 0, 0), hpos, vpos,
                       lineHeight, fontRatio,
                       shadow, shadowOffsetX, shadowOffsetY, shadowWidth));
 }