MeasureCharacterRanges() public method

public MeasureCharacterRanges ( string text, Font font, RectangleF layoutRect, StringFormat stringFormat ) : Region[]
text string
font Font
layoutRect RectangleF
stringFormat StringFormat
return Region[]
示例#1
0
        public DisplayCharacterRanges(System.Drawing.Graphics gr, System.Drawing.Font font, StringFormat format, string text)
        {
            _rectF = new RectangleF[text.Length];
            int   c       = 0;
            float xOffset = 0;

            for (int l = 0; l < text.Length; l += 32, c += 32)
            {
                string t = text.Substring(l, Math.Min(32, text.Length - l));

                CharacterRange[] ranges = new CharacterRange[t.Length];
                for (int i = 0; i < t.Length; i++)
                {
                    ranges[i] = new CharacterRange(i, 1);
                }

                format.SetMeasurableCharacterRanges(ranges);

                SizeF    size    = gr.MeasureString(t, font);
                Region[] regions = gr.MeasureCharacterRanges(t, font, new RectangleF(0, 0, size.Width, size.Height), format);

                for (int i = 0; i < regions.Length; i++)
                {
                    _rectF[c + i]    = regions[i].GetBounds(gr);
                    _rectF[c + i].X += xOffset;
                    regions[i].Dispose();
                }

                xOffset = _rectF[c + t.Length - 1].X + _rectF[c + t.Length - 1].Width;
            }
        }
        private RectangleF MeasureString(System.Drawing.Graphics graphics, string text, System.Drawing.Font font)
        {
            bool isEmpty = false;

            if (string.IsNullOrEmpty(text))
            {
                isEmpty = true;
                text    = " ";
            }

            var format    = CreateStringFormat(text);
            var rectangle = new RectangleF(0, 0, float.PositiveInfinity, float.PositiveInfinity);
            var regions   = graphics.MeasureCharacterRanges(text, font, rectangle, format);

            Debug.Assert(regions.Length == 1);

            rectangle = regions[0].GetBounds(graphics);

            if (isEmpty)
            {
                rectangle.Width = 0;
            }
            else
            {
                rectangle.Width += 1.0f;
            }

            return(rectangle);
        }
示例#3
0
 internal java.awt.geom.Rectangle2D GetStringBounds(String aString, System.Drawing.Graphics g)
 {
     // TODO (KR) Could replace with System.Windows.Forms.TextRenderer#MeasureText (to skip creating Graphics)
     //
     // From .NET Framework Class Library documentation for Graphics#MeasureString:
     //
     //    To obtain metrics suitable for adjacent strings in layout (for
     //    example, when implementing formatted text), use the
     //    MeasureCharacterRanges method or one of the MeasureString
     //    methods that takes a StringFormat, and pass GenericTypographic.
     //    Also, ensure the TextRenderingHint for the Graphics is
     //    AntiAlias.
     //
     // TODO (KR) Consider implementing with one of the Graphics#MeasureString methods that takes a StringFormat.
     // TODO (KR) Consider implementing with Graphics#MeasureCharacterRanges().
     if (aString.Length == 0)
     {
         SizeF size = g.MeasureString(aString, GetNetFont(), Int32.MaxValue, StringFormat.GenericTypographic);
         return(new java.awt.geom.Rectangle2D.Float(0, 0, size.Width, size.Height));
     }
     else
     {
         StringFormat format = new StringFormat(StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoWrap);
         format.Trimming = StringTrimming.None;
         format.SetMeasurableCharacterRanges(new CharacterRange[] { new CharacterRange(0, aString.Length) });
         Region[] regions = g.MeasureCharacterRanges(aString, GetNetFont(), new RectangleF(0, 0, int.MaxValue, int.MaxValue), format);
         SizeF    size    = regions[0].GetBounds(g).Size;
         regions[0].Dispose();
         return(new java.awt.geom.Rectangle2D.Float(0, -getAscent(), size.Width, size.Height));
     }
 }
示例#4
0
        private void drawFormattedText(string s, Font f, SolidBrush brush, RectangleF drawRect)
        {
            string s1, s2, s3;
            int    i, j, len, r;

            CharacterRange[] ranges        = new CharacterRange[5];
            StringFormat     stringFormat1 = new StringFormat();

            r   = 0;
            len = s.Length;
            i   = s.IndexOf('*');
            while (i != -1)
            {
                j = s.IndexOf('*', i + 1);
                CharacterRange range = new CharacterRange(i, j - i - 1);
                ranges[++r] = range;
                s1          = s.Substring(0, i);             // text before bold
                s2          = s.Substring(i + 1, j - i - 1); // just the bold text
                s3          = s.Substring(j + 1);            // text after the bold
                s           = s1 + s2 + s3;
                i           = s.IndexOf('*');
            }
            stringFormat1.SetMeasurableCharacterRanges(ranges);

            Region[] charRegion = graphics.MeasureCharacterRanges(s,
                                                                  f, drawRect, stringFormat1);

            graphics.DrawString(s, f, brush, drawRect);
            int k;

            for (k = 0; k < charRegion.Length; k++)
            {
                graphics.FillRegion(new SolidBrush(Color.FromArgb(50, Color.Fuchsia)), charRegion[k]);
            }
        }
示例#5
0
 public static int GetDisplayLength(Graphics g, string s, Font font, TextDrawingMode textDrawingMode)
 {
     if (string.IsNullOrEmpty(s))
         return 0;
     if (textDrawingMode == TextDrawingMode.GRAPHICS)
     {
         if (s.Contains("\t"))
             s = s.Replace("\t", "        ");
         ranges[0].Length = s.Length;
         //CharacterRange[] ranges = new CharacterRange[] { new CharacterRange(0, s.Length) };
         sf.SetMeasurableCharacterRanges(ranges);
         Region[] regions = g.MeasureCharacterRanges(s, font, layoutRect, sf);
         RectangleF rectF = regions[0].GetBounds(g);
         //return (int)rectF.Width;//プロポーショナルでなくても数ピクセルずれる
         return (int)((int)((rectF.Width - 1) / fontDisplaySize + 0.95f) * fontDisplaySize);
     }
     else if (textDrawingMode == TextDrawingMode.TEXTRENDERER)
     {
         Size size = TextRenderer.MeasureText(g, s, font, layoutSize, TextFormatFlags.NoPadding | TextFormatFlags.NoPrefix);
         //Size size = TextRenderer.MeasureText(g, s, StaticConfig.Font);
         return size.Width;
     }
     else// if (StaticConfig.TextDrawingMode == TextDrawingMode.WINAPI)
     {
         Size size = GDI.MeasureText(s, font);
         return size.Width;
     }
     //来るわけがない
     //else
     //    throw new ExeEE("描画モード不明");
 }
示例#6
0
		/// <summary>
		/// Updates the width of the word as it would be
		/// when drawn with the specified font in the specified graphics.
		/// </summary>
		public virtual void UpdateMeasures(Graphics graphics, Font font)
		{
			string word = _value;
			int rangePos = 0;
			int rangeLen = word.Length;

			if (IsWhitespace)
			{
				// Enclose the word in printable characters for
				// Graphics.MeasureText to work correctly.
				// Furthermore tabs are not measured, so replace
				// tabs with, say, 4 spaces
				word = "W" + word + "W";
				word = word.Replace("\t", "    ");
				rangePos = 1;
				rangeLen = word.Length - 2;
			}

			_sformat.SetMeasurableCharacterRanges(new CharacterRange[]
				{
					new CharacterRange(rangePos, rangeLen)
				});
			Region[] r = graphics.MeasureCharacterRanges(
				word, font, _srect, _sformat);
			RectangleF bounds = r[0].GetBounds(graphics);
			r[0].Dispose();

			_width = bounds.Width;
		}
示例#7
0
        private static RectangleF MeasureRectangle(System.Drawing.Graphics graphics, int fontSize, System.Drawing.Font font, string s)
        {
            var stringFormat = new StringFormat(StringFormatFlags.NoWrap);

            stringFormat.SetMeasurableCharacterRanges(new[] { new CharacterRange(0, 1) });
            var ranges = graphics.MeasureCharacterRanges(s, font, new RectangleF(0, 0, 10 * fontSize, 10 * fontSize), stringFormat);
            var rect   = ranges[0].GetBounds(graphics);

            return(rect);
        }
示例#8
0
文件: Util.cs 项目: cmrazek/ProbeNpp
        public static SizeF MeasureString(Graphics g, string str, Font font, Rectangle rect, StringFormat sf)
        {
            var sfTemp = sf.Clone() as StringFormat;
            var ranges = new CharacterRange[] { new CharacterRange(0, str.Length) };
            sfTemp.SetMeasurableCharacterRanges(ranges);

            var regions = g.MeasureCharacterRanges(str, font, rect, sfTemp);
            if (regions != null && regions.Length > 0) return regions[0].GetBounds(g).Size;
            return new SizeF();
        }
示例#9
0
 private static SizeF GetTextSize(string str, Graphics g, bool fTitle) {
     SizeF empty = SizeF.Empty;
     CharacterRange[] ranges = new CharacterRange[] { new CharacterRange(0, str.Length) };
     sfMeasure.SetMeasurableCharacterRanges(ranges);
     Region[] regionArray = g.MeasureCharacterRanges(str, fTitle ? font : fontSubText, rctMeasure, sfMeasure);
     using(regionArray[0]) {
         empty = regionArray[0].GetBounds(g).Size;
         empty.Width += 6f;
     }
     return empty;
 }
示例#10
0
        /// <summary>
        ///     Measures the Size of a Text.
        /// </summary>
        /// <param name="g">Graphics object used to draw the text</param>
        /// <param name="text">The text</param>
        /// <param name="font">Font used to draw the text</param>
        /// <returns></returns>
        public static SizeF measureText(Graphics g, string text, Font font)
        {
            if (text == null) return Size.Empty;
            StringFormat format = new StringFormat();
            RectangleF rect = new RectangleF(0, 0, 1000, 1000);
            CharacterRange[] ranges = { new CharacterRange(0, text.Length) };
            Region[] regions = new Region[1];

            format.SetMeasurableCharacterRanges(ranges);
            regions = g.MeasureCharacterRanges(text, font, rect, format);
            rect = regions[0].GetBounds(g);

            return new SizeF(rect.Right + 1f, rect.Bottom + 1f);
        }
示例#11
0
        private static int StringWidth(Graphics graphics, string text, Font font)
        {
            System.Drawing.StringFormat format = new System.Drawing.StringFormat();
            System.Drawing.RectangleF rect = new System.Drawing.RectangleF(0, 0, 1000, 1000);
            System.Drawing.CharacterRange[] ranges = { new System.Drawing.CharacterRange(0, text.Length) };
            System.Drawing.Region[] regions = new System.Drawing.Region[1];

            format.SetMeasurableCharacterRanges(ranges);

            regions = graphics.MeasureCharacterRanges(text, font, rect, format);
            rect = regions[0].GetBounds(graphics);

            return (int)(rect.Right + 1.0f);
        }
示例#12
0
 public static int MeasureCharWidth( Graphics graphics, char c, Font font)
 {
     if (c == ' ') c = '_';
     char[] ch = new char[1];
     ch[0] = c;
     string           str     = new string( ch );
     StringFormat     format  = new StringFormat( StringFormat.GenericTypographic );
     RectangleF       rect    = new RectangleF( 0, 0, 1000, 1000 );
     CharacterRange[] ranges  = { new CharacterRange( 0, str.Length ) };
     Region[]         regions = new Region[1];
     format.SetMeasurableCharacterRanges( ranges );
     regions = graphics.MeasureCharacterRanges( str, font, rect, format );
     rect    = regions[0].GetBounds( graphics );
     return (int)(rect.Right + 1.0f);
 }
示例#13
0
文件: TextUtil.cs 项目: NanQi/demo
 public static Size GetTextSize(Graphics graphics, string text, Font font, Size size)
 {
    if (text.Length == 0)
    {
       return Size.Empty;
    }
    StringFormat stringFormat = new StringFormat();
    stringFormat.FormatFlags = StringFormatFlags.FitBlackBox;
    RectangleF layoutRect = new RectangleF(0f, 0f, size.Width, size.Height);
    CharacterRange[] ranges = new CharacterRange[] {new CharacterRange(0, text.Length)};
    Region[] regionArray = new Region[1];
    stringFormat.SetMeasurableCharacterRanges(ranges);
    Rectangle rectangle =
       Rectangle.Round(graphics.MeasureCharacterRanges(text, font, layoutRect, stringFormat)[0].GetBounds(graphics));
    return new Size(rectangle.Width, rectangle.Height);
 }
示例#14
0
        public static RectangleF MeasureDisplayStringWidth(Graphics graphics, string text, Font font)
        {
            var zFormat = new StringFormat
            {
                Alignment = StringAlignment.Near,
                LineAlignment = StringAlignment.Near,
            };
            var rect = new RectangleF(0, 0, 65536, 65536);
            CharacterRange[] ranges = { new CharacterRange(0, text.Length) };
            var regions = new Region[1];

            zFormat.SetMeasurableCharacterRanges(ranges);

            regions = graphics.MeasureCharacterRanges(text, font, rect, zFormat);
            rect = regions[0].GetBounds(graphics);

            return rect;
        }
示例#15
0
        public static Size GetTextSize(Graphics graphics, string text, Font font, Size size)
        {
            if(text.Length == 0) return Size.Empty;

            StringFormat format = new StringFormat();
            format.FormatFlags = StringFormatFlags.FitBlackBox; //MeasureTrailingSpaces;

            RectangleF layoutRect = new System.Drawing.RectangleF(0, 0, size.Width, size.Height);
            CharacterRange[] chRange = {new CharacterRange(0, text.Length)};
            Region[] regs = new Region[1];

            format.SetMeasurableCharacterRanges(chRange);

            regs = graphics.MeasureCharacterRanges(text, font, layoutRect, format);
            Rectangle rect = Rectangle.Round(regs[0].GetBounds(graphics));

            return new Size(rect.Width, rect.Height);
        }
 /// <summary>
 /// Measures the actual width of the text
 /// http://www.codeproject.com/KB/GDI-plus/measurestring.aspx
 /// </summary>
 public static Int32 MeasureDisplayStringWidth(Graphics graphics, String text, Font font)
 {
     try
     {
         StringFormat format = new StringFormat();
         RectangleF rect = new RectangleF(0, 0, 1000, 1000);
         CharacterRange[] ranges = { new CharacterRange(0, text.Length) };
         Region[] regions = new Region[1];
         format.SetMeasurableCharacterRanges(ranges);
         regions = graphics.MeasureCharacterRanges(text, font, rect, format);
         rect = regions[0].GetBounds(graphics);
         return (Int32)rect.Right;
     }
     catch (IndexOutOfRangeException)
     {
         return 0;
     }
 }
        //////////////////////////////////////////////////////////////////////////
        public static SizeF MeasureDisplayStringWidth(Graphics graphics, string text, Font font)
        {
            if (text == "") return new SizeF(0, 0);

            System.Drawing.StringFormat format = new System.Drawing.StringFormat();
            System.Drawing.RectangleF rect = new System.Drawing.RectangleF(0, 0, 1000, 1000);
            System.Drawing.CharacterRange[] ranges =
                                       { new System.Drawing.CharacterRange(0,
                                                               text.Length) };
            System.Drawing.Region[] regions = new System.Drawing.Region[1];

            format.SetMeasurableCharacterRanges(ranges);

            regions = graphics.MeasureCharacterRanges(text, font, rect, format);
            rect = regions[0].GetBounds(graphics);

            return new SizeF(rect.Right + 1.0f, rect.Bottom);
        }
示例#18
0
            public static Size MeasureString(Graphics graphics, string text, Font font, RectangleF bounds, StringFormat format)
            {
                var size = Size.Empty;

                using (format = new StringFormat(format))
                {
                    if (bounds.IsEmpty)
                    {
                        bounds = new RectangleF(0, 0, float.MaxValue, float.MaxValue);

                        // We need to clear RightToLeft and set StringAlignment.Near, otherwise we get an incorrect measurement.
                        format.FormatFlags &= ~StringFormatFlags.DirectionRightToLeft;
                        format.Alignment = StringAlignment.Near;
                        format.LineAlignment = StringAlignment.Near;
                    }

                    try
                    {
                        // Measure text
                        format.SetMeasurableCharacterRanges(new[] { new CharacterRange(0, text.Length) });
                        var regions = graphics.MeasureCharacterRanges(text, font, bounds, format);

                        // Need to use Right and Bottom to account for leadingi
                        var rect = regions[0].GetBounds(graphics);
                        size = new Size((int)Math.Ceiling(rect.Right), (int)Math.Ceiling(rect.Bottom));

                        // Remain compatible with Graphics.MeasureString
                        size.Height += 1;
                    }
                    catch (ExternalException ex)
                    {
                        // eat the exception when the text is too long.
                        if (ex.ErrorCode != NativeMethods.E_FAIL)
                        {
                            throw;
                        }

                        size = Size.Empty;
                    }
                }

                return size;
            }
示例#19
0
        //adapted from http://www.codeproject.com/KB/GDI-plus/measurestring.aspx
        public static SizeF MeasureDisplayStringWidth(System.Drawing.Graphics gCanvas, string sText, Font fntFont)
        {
            System.Drawing.StringFormat sfFormat = new System.Drawing.StringFormat();
            System.Drawing.RectangleF   rtRect   = new System.Drawing.RectangleF(0, 0,
                                                                                 1000, 1000);
            System.Drawing.CharacterRange[] craRanges = { new System.Drawing.CharacterRange(0, sText.Length) };
            System.Drawing.Region[]         raRegions = new System.Drawing.Region[1];

            sfFormat.SetMeasurableCharacterRanges(craRanges);

            raRegions = gCanvas.MeasureCharacterRanges(sText, fntFont, rtRect, sfFormat);
            rtRect    = raRegions[0].GetBounds(gCanvas);

            SizeF sfFinal = new SizeF();

            sfFinal.Width  = (rtRect.Right + 1.0f);
            sfFinal.Height = (rtRect.Bottom);

            return(sfFinal);
        }
        private Point GetCharSize(Graphics CurGraphics)
        {
            // DrawString doesn't actually print where you tell it to but instead consistently prints
            // with an offset. This is annoying when the other draw commands do not print with an offset
            // this method returns a point defining the offset so we can take it off the printstring command.

            CharacterRange[] characterRanges = {new CharacterRange(0, 1)};
            RectangleF layoutRect = new RectangleF(0, 0, 100, 100);
            StringFormat stringFormat = new StringFormat();
            stringFormat.SetMeasurableCharacterRanges(characterRanges);
            Region[] stringRegions = new Region[1];

            stringRegions = CurGraphics.MeasureCharacterRanges(
                "A",
                this.Font,
                layoutRect,
                stringFormat);

            RectangleF measureRect1 = stringRegions[0].GetBounds(CurGraphics);
            return new Point((Int32) (measureRect1.Width + 0.5), (Int32) (measureRect1.Height + 0.5));
        }
示例#21
0
 private static int getDrawLength(Graphics g, Font fnt, RectangleF rect, StringFormat sf, int maxLen)
 {
     CharacterRange[] ranges = new CharacterRange[] { new CharacterRange(0, 1) };
     float num = 1f;
     float width = 0f;
     int num3 = 2;
     string text = StrFunc.CreateInstance().MakeCycleStr(maxLen, "X");
     while ((num3 <= maxLen) && (width != num))
     {
         num = width;
         ranges[0].Length = num3;
         sf.SetMeasurableCharacterRanges(ranges);
         width = g.MeasureCharacterRanges(text, fnt, rect, sf)[0].GetBounds(g).Width;
         num3++;
     }
     if (num3 == maxLen)
     {
         return maxLen;
     }
     return (num3 - 1);
 }
示例#22
0
		/// <summary>
		/// Calculates the exact size of a string.
		/// Code taken from http://www.codeproject.com/KB/GDI-plus/measurestring.aspx
		/// </summary>
		/// <param name="graphics">The graphics object used to calculate the string's size.</param>
		/// <param name="font">The font which will be used to draw the string.</param>
		/// <param name="text">The actual string which will be drawn.</param>
		/// <returns>Returns the untransformed size of the string when being drawn.</returns>
		static public SizeF MeasureDisplayStringWidth(Graphics graphics, string text, Font font)
		{
			// set something to generate the minimum size
			bool minimum= false;
			if(text ==string.Empty)
			{
				minimum= true;
				text= " ";
			}

			System.Drawing.StringFormat format = new System.Drawing.StringFormat();
			System.Drawing.RectangleF rect = new System.Drawing.RectangleF(0, 0, 1000, 1000);
			System.Drawing.CharacterRange[] ranges = { new System.Drawing.CharacterRange(0, text.Length) };
			System.Drawing.Region[] regions = new System.Drawing.Region[1];

			format.SetMeasurableCharacterRanges(ranges);

			regions = graphics.MeasureCharacterRanges(text, font, rect, format);
			rect = regions[0].GetBounds(graphics);

			return minimum ? new SizeF(0.0f, rect.Height) : rect.Size;
		}
示例#23
0
        partial void MeasureCharacterRangeImp(string str, Font font, StringFormat format, CharacterRange range, ref RectangleF ret)
        {
            if (FixGdiPlusStringSize(ref str))
            {
                if (range.First >= str.Length)
                {
                    range.First  = str.Length - 1;
                    range.Length = 0;
                }
                else if (range.First + range.Length >= str.Length)
                {
                    range.Length = str.Length - range.First;
                }
            }
            format.format.SetMeasurableCharacterRanges(new SD.CharacterRange[] {
                new SD.CharacterRange(range.First, range.Length)
            });
            var regions = g.MeasureCharacterRanges(str, font.font, new SD.RectangleF(0, 0, 100500, 100000), format.format);
            var bounds  = regions[0].GetBounds(g);

            regions[0].Dispose();
            ret = bounds.ToRectangleF();
        }
示例#24
0
        public SizeF MeasureString(string text)
        {
            if (UseCompatibleTextRendering)
            {
                if (measureGraphics == null)
                {
                    measureGraphics = sd.Graphics.FromImage(new sd.Bitmap(1, 1));
                }

                sd.CharacterRange[] ranges = { new sd.CharacterRange(0, text.Length) };
                var stringFormat           = GraphicsHandler.DefaultStringFormat;
                lock (stringFormat)
                {
                    stringFormat.SetMeasurableCharacterRanges(ranges);
                    var regions = measureGraphics.MeasureCharacterRanges(text, Control, sd.RectangleF.Empty, stringFormat);
                    var rect    = regions[0].GetBounds(measureGraphics);
                    return(rect.Size.ToEto());
                }
            }

            var size = swf.TextRenderer.MeasureText(text, Control, sd.Size.Empty, GraphicsHandler.DefaultTextFormat);

            return(size.ToEto());
        }
示例#25
0
		Region [] Measure (Graphics gfx, RectangleF rect)
		{
			using (StringFormat format = StringFormat.GenericTypographic) {
				format.SetMeasurableCharacterRanges (ranges);

				using (Font font = new Font (FontFamily.GenericSerif, 11.0f)) {
					return gfx.MeasureCharacterRanges ("abc", font, rect, format);
				}
			}
		}
示例#26
0
		/// <summary>
		/// Draw the highlighted text using GDI+
		/// </summary>
		/// <param name="g"></param>
		/// <param name="r"></param>
		/// <param name="txt"></param>
		protected virtual void DrawGdiPlusTextHighlighting(Graphics g, Rectangle r, string txt) {
			// Find the substrings we want to highlight
			List<CharacterRange> ranges = new List<CharacterRange>(this.Filter.FindAllMatchedRanges(txt));

			if (ranges.Count == 0)
				return;

			using (StringFormat fmt = this.StringFormatForGdiPlus) {
				RectangleF rf = r;
				fmt.SetMeasurableCharacterRanges(ranges.ToArray());
				Region[] stringRegions = g.MeasureCharacterRanges(txt, this.Font, rf, fmt);

				foreach (Region region in stringRegions) {
					RectangleF bounds = region.GetBounds(g);
					this.DrawSubstringFrame(g, bounds.X - 1, bounds.Y - 1, bounds.Width + 2, bounds.Height);
				}
			}
		}
		private SizeF MeasureString(string s, StyleInfo si, Graphics g, out float descent)
		{
			Font drawFont=null;
			StringFormat drawFormat=null;
			SizeF ms = SizeF.Empty;
			descent = 0;				
			if (s == null || s.Length == 0)
				return ms;
			try
			{
				// STYLE
				System.Drawing.FontStyle fs = 0;
				if (si.FontStyle == FontStyleEnum.Italic)
					fs |= System.Drawing.FontStyle.Italic;

				// WEIGHT
				switch (si.FontWeight)
				{
					case FontWeightEnum.Bold:
					case FontWeightEnum.Bolder:
					case FontWeightEnum.W500:
					case FontWeightEnum.W600:
					case FontWeightEnum.W700:
					case FontWeightEnum.W800:
					case FontWeightEnum.W900:
						fs |= System.Drawing.FontStyle.Bold;
						break;
					default:
						break;
				}
				try
				{
					FontFamily ff = si.GetFontFamily();
					drawFont = new Font(ff, si.FontSize, fs);
					// following algorithm comes from the C# Font Metrics documentation
					float descentPixel = si.FontSize * ff.GetCellDescent(fs) / ff.GetEmHeight(fs);
					descent = RSize.PointsFromPixels(g, descentPixel);
				}
				catch
				{
					drawFont = new Font("Arial", si.FontSize, fs);	// usually because font not found
					descent = 0;
				}
				drawFormat = new StringFormat();
				drawFormat.Alignment = StringAlignment.Near;

				CharacterRange[] cr = {new CharacterRange(0, s.Length)};
				drawFormat.SetMeasurableCharacterRanges(cr);
				Region[] rs = new Region[1];
				rs = g.MeasureCharacterRanges(s, drawFont, new RectangleF(0,0,float.MaxValue,float.MaxValue),
					drawFormat);
				RectangleF mr = rs[0].GetBounds(g);

				ms.Height = RSize.PointsFromPixels(g, mr.Height);	// convert to points from pixels
				ms.Width = RSize.PointsFromPixels(g, mr.Width);		// convert to points from pixels
				return ms;
			}
			finally
			{
				if (drawFont != null)
					drawFont.Dispose();
				if (drawFormat != null)
					drawFont.Dispose();
			}
		}
示例#28
0
        /// <summary>
        /// Function to retrieve a character range for the specified character.
        /// </summary>
        /// <param name="character">The character to evaluate.</param>
        /// <param name="graphics">The graphics context to use.</param>
        /// <returns>The region for the character range.</returns>
        private RectangleF?GetCharacterRange(ref char character, System.Drawing.Graphics graphics)
        {
            Region[] characterRanges        = null;
            Region[] defaultCharacterRanges = null;

            try
            {
                // Try to get the character size.
                characterRanges = graphics.MeasureCharacterRanges(character.ToString(CultureInfo.CurrentCulture),
                                                                  _fontData.Font,
                                                                  new RectangleF(0, 0, _fontInfo.TextureWidth, _fontInfo.TextureHeight),
                                                                  _fontData.StringFormat);

                defaultCharacterRanges = graphics.MeasureCharacterRanges(_fontInfo.DefaultCharacter.ToString(CultureInfo.CurrentCulture),
                                                                         _fontData.Font,
                                                                         new RectangleF(0,
                                                                                        0,
                                                                                        _fontInfo.TextureWidth,
                                                                                        _fontInfo.TextureHeight),
                                                                         _fontData.StringFormat);

                // If the character doesn't exist, then return an empty value.
                switch (characterRanges.Length)
                {
                case 0 when(defaultCharacterRanges.Length == 0):
                    return(null);

                case 0 when(defaultCharacterRanges.Length > 0):
                    character       = _fontInfo.DefaultCharacter;
                    characterRanges = defaultCharacterRanges;
                    break;
                }

                // If we didn't get a size, but we have a default, then use that.

                RectangleF result = characterRanges[0].GetBounds(graphics);

                if ((result.Width >= 0.1f) || (result.Height >= 0.1f))
                {
                    return(result);
                }

                character       = _fontInfo.DefaultCharacter;
                characterRanges = defaultCharacterRanges;
                result          = characterRanges[0].GetBounds(graphics);
                characterRanges[0].Dispose();
                characterRanges = null;

                return(((result.Width < 0.1f) || (result.Height < 0.1f))
                    ? null
                    : (RectangleF?)result);
            }
            finally
            {
                if (characterRanges != null)
                {
                    foreach (Region region in characterRanges)
                    {
                        region.Dispose();
                    }
                }

                if (defaultCharacterRanges != null)
                {
                    foreach (Region region in defaultCharacterRanges)
                    {
                        region.Dispose();
                    }
                }
            }
        }
示例#29
0
 public Region[] Measure(Graphics g, Font f, string str, int x, int y, int xOffset, int yOffset, int cw, int index, int length)
 {
     if (this.m_Ranges == null)
     {
         this.m_Ranges = new CharacterRange[1];
     }
     this.m_Ranges[0].First = index;
     this.m_Ranges[0].Length = length;
     this.m_StringFormat.SetMeasurableCharacterRanges(this.m_Ranges);
     this.m_TempRectF.X = x;
     this.m_TempRectF.Y = y;
     this.m_TempRectF.Width = cw;
     this.m_TempRectF.Height = this.m_LineHeight;
     return g.MeasureCharacterRanges(str, f, this.m_TempRectF, this.m_StringFormat);
 }
示例#30
0
        private SizeF MeasureString(string s, Graphics g, Font drawFont, StringFormat drawFormat)
        {
            if (s == null || s.Length == 0)
                return SizeF.Empty;

            CharacterRange[] cr = {new CharacterRange(0, s.Length)};
            drawFormat.SetMeasurableCharacterRanges(cr);
            Region[] rs = new Region[1];
            rs = g.MeasureCharacterRanges(s, drawFont, new RectangleF(0,0,float.MaxValue,float.MaxValue),
                drawFormat);
            RectangleF mr = rs[0].GetBounds(g);

            return new SizeF(mr.Width, mr.Height);
        }
示例#31
0
        internal static pTexture CreateText(string text, float size, Vector2 restrictBounds, Color color, ShadowType shadow, bool bold, bool italic, bool underline, TextAlignment alignment, bool forceAa, out Vector2 measured, out RectangleF[] characterRegions, Color background, Color border, int borderWidth, bool measureOnly, bool getCharacterRegions, FontFace fontFace, Vector4 cornerBounds, Vector2 padding, pTexture lastTexture = null, int startIndex = 0, int length = -1)
        {
            characterRegions = null;
            if (text == null)
            {
                measured = Vector2.Zero;
                return(null);
            }

            if (ConfigManager.dDisableTextRendering)
            {
                measured = new Vector2(text.Length * size, size);
                return(null);
            }

#if DEBUG
            if (!text.Contains(@"NativeText"))
            {
                int  limit_per_second = osu.GameModes.Play.Player.Playing ? 5 : 58;
                bool newSecond        = GameBase.Time / 1000 != currentSecond;

                drawCount++;
                if (drawCount == limit_per_second)
                {
                    Debug.Print(@"NativeText: High number of text refreshes per second.");
                }

                if (newSecond)
                {
                    currentSecond = GameBase.Time / 1000;
                    drawCount     = 0;
                }
            }
#endif

            //This lock ensures we are only using the shared GDI+ object (FromHwnd) in one place at a time.
            lock (createTextLock)
            {
                try
                {
                    using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromHwnd(IntPtr.Zero))
                        using (StringFormat sf = new StringFormat())
                        {
                            if (dpiRatio == 0)
                            {
                                dpiRatio = 96 / graphics.DpiX;
                            }

                            size *= dpiRatio;

                            GameBase.PerformanceMonitor.ReportCount(CounterType.NativeText);

                            graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

                            SizeF measuredSize;

                            string face = GetFontFace(fontFace);

                            if (face.StartsWith(@"Aller"))
                            {
                                //if we are using the default osu! font, allow specific language overrides based on simple detection.
                                string fontFaceOverride = getLanguageSpeicificFont(text);
                                if (fontFaceOverride != null)
                                {
                                    face = fontFaceOverride;
                                }
                            }

                            if (startIndex != 0 || length > 0)
                            {
                                text = text.Substring(startIndex, length);
                            }
                            else if (length == -1)
                            {
                                length = text.Length;
                            }


                            if (size < 20 && face.EndsWith(@" Light"))
                            {
                                face = face.Replace(@" Light", string.Empty);
                            }

                            FontStyle fs = FontStyle.Regular;
                            if (bold)
                            {
                                if (face.EndsWith(@" Light"))
                                {
                                    face = face.Replace(@" Light", string.Empty);
                                }
                                fs |= FontStyle.Bold;
                            }

                            if (italic)
                            {
                                fs |= FontStyle.Italic;
                            }

                            if (underline)
                            {
                                fs |= FontStyle.Underline;
                            }

                            switch (alignment)
                            {
                            case TextAlignment.Left:
                            case TextAlignment.LeftFixed:
                                sf.Alignment = StringAlignment.Near;
                                break;

                            case TextAlignment.Centre:
                                sf.Alignment = StringAlignment.Center;
                                break;

                            case TextAlignment.Right:
                                sf.Alignment = StringAlignment.Far;
                                break;
                            }

                            if (!OsuMain.IsWine && face.StartsWith(@"Aller"))
                            {
                                for (char c = '0'; c <= '9'; c++)
                                {
                                    text = text.Replace(c, (char)(c + (0xf83c - '0')));
                                }
                            }

                            Font f = GetFont(face, size * ScaleModifier, fs);
                            if (ScaleModifier != 1)
                            {
                                restrictBounds *= ScaleModifier;
                            }

                            try
                            {
                                if (text.Length == 0)
                                {
                                    text = " ";
                                }
                                measuredSize = restrictBounds != Vector2.Zero
                                                ? graphics.MeasureString(text, f, new SizeF(restrictBounds.X, restrictBounds.Y), sf)
                                                : graphics.MeasureString(text, f);
                            }
                            catch (InvalidOperationException)
                            {
                                measured = Vector2.Zero;
                                return(null);
                            }

                            int width  = (int)(measuredSize.Width + 1);
                            int height = (int)(measuredSize.Height + 1);

                            if (restrictBounds.Y != 0)
                            {
                                height = (int)restrictBounds.Y;
                            }

                            if (restrictBounds.X != 0 && (alignment != TextAlignment.Left || background.A > 0))
                            {
                                width = (int)restrictBounds.X;
                            }

                            if (padding != Vector2.Zero && restrictBounds == Vector2.Zero)
                            {
                                width  += (int)(padding.X * 2);
                                height += (int)(padding.Y * 2);
                            }

                            measured = new Vector2(width, height);
                            float offset = Math.Max(0.5f, Math.Min(1f, (size * ScaleModifier) / 14));

                            if (getCharacterRegions)
                            {
                                characterRegions = new RectangleF[text.Length];

                                // SetMeasurableCharacterRanges only accepts a maximum of 32 intervals to be queried, so we as the library user are
                                // forced to split the string into 32 character long chunks and perform MeasureCharacterRanges on each.
                                int numIntervals = (text.Length / 32) + 1;
                                for (int i = 0; i < numIntervals; ++i)
                                {
                                    int offsetIndex = i * 32;
                                    int end         = Math.Min(text.Length - offsetIndex, 32);

                                    CharacterRange[] characterRanges = new CharacterRange[end];
                                    for (int j = 0; j < end; ++j)
                                    {
                                        characterRanges[j] = new CharacterRange(j + offsetIndex, 1);
                                    }

                                    sf.SetMeasurableCharacterRanges(characterRanges);
                                    Region[] regions = graphics.MeasureCharacterRanges(
                                        text,
                                        f,
                                        new RectangleF(
                                            padding.X,
                                            padding.Y,
                                            restrictBounds.X == 0 ? Single.PositiveInfinity : restrictBounds.X,
                                            restrictBounds.Y == 0 ? Single.PositiveInfinity : restrictBounds.Y),
                                        sf);

                                    for (int j = 0; j < end; ++j)
                                    {
                                        Region region = regions[j] as Region;
                                        characterRegions[j + offsetIndex] = region.GetBounds(graphics);
                                    }
                                }
                            }

                            if (measureOnly)
                            {
                                int startSpace = 0;
                                int endSpace   = 0;

                                int i = 0;
                                while (i < text.Length && text[i++] == ' ')
                                {
                                    startSpace++;
                                }
                                int j = text.Length - 1;
                                while (j >= i && text[j--] == ' ')
                                {
                                    endSpace++;
                                }
                                if (startSpace == text.Length)
                                {
                                    endSpace += startSpace;
                                }

                                measured = new Vector2(width + (endSpace * 5.145f * size / 12), height);
                                return(null);
                            }

                            using (Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppArgb))
                                using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(b))
                                {
                                    //Quality settings
                                    g.TextRenderingHint = graphics.TextRenderingHint;
                                    g.SmoothingMode     = SmoothingMode.HighQuality;
                                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;

                                    if (background.A > 0)
                                    {
                                        if (cornerBounds != Vector4.Zero)
                                        {
                                            fillRoundedRectangle(g, new Rectangle(0, 0, width, height), new SolidBrush(OsuMathHelper.CConvert(background)), cornerBounds);

                                            if (borderWidth > 0)
                                            {
                                                drawRoundedRectangle(g,
                                                                     new Rectangle(0, 0, width - (int)Math.Ceiling(borderWidth / 2f), height - (int)Math.Ceiling(borderWidth / 2f)),
                                                                     new Pen(OsuMathHelper.CConvert(border), borderWidth),
                                                                     cornerBounds);
                                            }
                                        }
                                        else
                                        {
                                            g.Clear(OsuMathHelper.CConvert(background));
                                            if (borderWidth > 0)
                                            {
                                                g.DrawRectangle(new Pen(OsuMathHelper.CConvert(border), borderWidth),
                                                                new Rectangle(borderWidth / 2, borderWidth / 2, width - borderWidth, height - borderWidth));
                                            }
                                        }
                                    }
                                    else
                                    {
                                        g.Clear(System.Drawing.Color.FromArgb(1, color.R, color.G, color.B));
                                    }


                                    using (Brush brush = new SolidBrush(OsuMathHelper.CConvert(color)))
                                    {
                                        if (restrictBounds != Vector2.Zero)
                                        {
                                            restrictBounds.X -= padding.X * 2;
                                            restrictBounds.Y -= padding.Y * 2;

                                            switch (shadow)
                                            {
                                            case ShadowType.Normal:
                                                g.DrawString(text, f, shadowBrush, new RectangleF(padding.X - offset, offset + padding.Y, restrictBounds.X, restrictBounds.Y), sf);
                                                g.DrawString(text, f, shadowBrush, new RectangleF(padding.X + offset, offset + padding.Y, restrictBounds.X, restrictBounds.Y), sf);
                                                break;

                                            case ShadowType.Border:
                                                Brush borderBrush = greyBrush;
                                                if (background.A == 0 && borderWidth == 1 && border.A > 0)
                                                {
                                                    borderBrush = new SolidBrush(OsuMathHelper.CConvert(border));
                                                }

                                                g.DrawString(text, f, borderBrush, new RectangleF(padding.X + offset, padding.Y + offset, restrictBounds.X, restrictBounds.Y), sf);
                                                g.DrawString(text, f, borderBrush, new RectangleF(padding.X + offset, padding.Y - offset, restrictBounds.X, restrictBounds.Y), sf);
                                                g.DrawString(text, f, borderBrush, new RectangleF(padding.X - offset, padding.Y + offset, restrictBounds.X, restrictBounds.Y), sf);
                                                g.DrawString(text, f, borderBrush, new RectangleF(padding.X - offset, padding.Y - offset, restrictBounds.X, restrictBounds.Y), sf);
                                                break;
                                            }

                                            g.DrawString(text, f, brush, new RectangleF(padding.X, padding.Y, restrictBounds.X, restrictBounds.Y), sf);
                                        }
                                        else
                                        {
                                            switch (shadow)
                                            {
                                            case ShadowType.Normal:
                                                g.DrawString(text, f, shadowBrush, padding.X - offset, padding.Y + offset);
                                                g.DrawString(text, f, shadowBrush, padding.X + offset, padding.Y + offset);
                                                break;

                                            case ShadowType.Border:
                                                Brush borderBrush = greyBrush;
                                                if (background.A == 0 && borderWidth == 1 && border.A > 0)
                                                {
                                                    borderBrush = new SolidBrush(OsuMathHelper.CConvert(border));
                                                }

                                                g.DrawString(text, f, borderBrush, padding.X + offset, padding.Y + offset);
                                                g.DrawString(text, f, borderBrush, padding.X - offset, padding.Y + offset);
                                                g.DrawString(text, f, borderBrush, padding.X + offset, padding.Y - offset);
                                                g.DrawString(text, f, borderBrush, padding.X - offset, padding.Y - offset);
                                                break;
                                            }

                                            g.DrawString(text, f, brush, padding.X, padding.Y);
                                        }
                                    }

                                    //if (lastTexture == null || lastTexture.isDisposed)
                                    {
                                        lastTexture            = pTexture.FromBitmap(b);
                                        lastTexture.Disposable = true;
                                    }

                                    /*else
                                     * {
                                     *  lastTexture.Width = b.Width;
                                     *  lastTexture.Height = b.Height;
                                     *  lastTexture.SetData(b);
                                     * }*/

                                    return(lastTexture);
                                }
                        }
                }
                catch (Exception e)
                {
                    measured = Vector2.Zero;
                    return(null);
                }
            }
        }
示例#32
0
		/// <summary>
		/// Get the smallest encompassing Region for the supplied string, Font and Graphics context.
		/// </summary>
		/// <param name="g">Graphics context object to measure string on.</param>
		/// <param name="str">String to measure.</param>
		/// <param name="fnt">Font to use for string.</param>
		/// <returns>Smallest Region encompassing the supplied string.</returns>
		public static Region GetGraphicalStringRegion(Graphics g, string str, Font fnt)
		{
			StringFormat format = new StringFormat();
			RectangleF rect = new RectangleF(0, 0, 1000, 1000);
			CharacterRange[] ranges = {new CharacterRange(0, str.Length)};
			Region[] regions = new Region[1];

			format.SetMeasurableCharacterRanges(ranges);

			regions = g.MeasureCharacterRanges(str, fnt, rect, format);

			return regions[0];
		}
示例#33
0
		/// <summary>
		/// Get the smallest encompassing Region of the supplied string using the supplied Font, Rectangle and StringFormat on the supplied Graphics context.
		/// </summary>
		/// <param name="g">Graphics context object to measure string on.</param>
		/// <param name="str">String to measure.</param>
		/// <param name="fnt">Font to use for string.</param>
		/// <param name="rct">Rectangle to measure string in.</param>
		/// <param name="strfmt">StringFormat to use when measuring the string.</param>
		/// <returns>Smallest Region encompassing the Text of the Control supplied using the StringFormat supplied.</returns>
		public static Region GetStringFormattedStringRegion(Graphics g, string str, Font fnt, Rectangle rct, StringFormat strfmt)
		{
			RectangleF rctF = new RectangleF(rct.X, rct.Y, rct.Width, rct.Height);
			CharacterRange[] ranges = {new CharacterRange(0, str.Length)};
			Region[] regions = new Region[1];

			strfmt.SetMeasurableCharacterRanges(ranges);

			regions = g.MeasureCharacterRanges(str, fnt, rctF, strfmt);

			return regions[0];
		}
        // "http://stackoverflow.com/questions/2116216#2116475"
        private static double GetTextWidth(Graphics g, Font f, string text)
        {
            StringFormat format = new StringFormat(StringFormat.GenericDefault);
            RectangleF rect = new RectangleF(0, 0, 1000, 1000);
            CharacterRange[] ranges = { new CharacterRange(0, text.Length) };

            format.SetMeasurableCharacterRanges(ranges);
            format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;

            Region[] regions = g.MeasureCharacterRanges(text, f, rect, format);
            rect = regions[0].GetBounds(g);

            return rect.Right;
        }
示例#35
0
        static private int MeasureDisplayStringWidthExact(Graphics graphics, string text,
                                            Font font)
        {
            var ranges = new[] { new CharacterRange(0, text.Length) };
            var format = new StringFormat();
            format.SetMeasurableCharacterRanges(ranges);

            var rect = new RectangleF(0, 0, 1000, 1000);

            var regions = graphics.MeasureCharacterRanges(text, font, rect, format);
            rect = regions[0].GetBounds(graphics);

            return (int)(rect.Right + 1.0f);
        }
示例#36
0
        public float[] GetCharacterXPositions( Graphics g, string str )
        {
            // Setup the StringFormat with proper CharacterRange references.
            StringFormat testFormat = new StringFormat();
            CharacterRange[] ranges = new CharacterRange[ str.Length ];
            for ( int i=0; i < str.Length; i++ )
                ranges[i] = new CharacterRange( i, 1 );

            testFormat.SetMeasurableCharacterRanges( ranges );

            // Measure into Regions
            Region[] regions = g.MeasureCharacterRanges( str, _font, new Rectangle( 0, 0, 1000, 1000 ), testFormat );

            // Convert Regions to Rects, then X coords.
            float[] xCoords = regions.Select( region => region.GetBounds( g ).X ).ToArray();
            return xCoords;
        }
示例#37
0
        /// <summary>
        /// Measures the location of words within a string;  limited by .Net 1.1 to 32 words
        ///     MEASUREMAX is a constant that defines that limit
        /// </summary>
        /// <param name="s"></param>
        /// <param name="g"></param>
        /// <param name="drawFont"></param>
        /// <param name="drawFormat"></param>
        /// <param name="cra"></param>
        /// <returns></returns>
        private WordStartFinish[] MeasureString32(string s, Graphics g, Font drawFont, StringFormat drawFormat, CharacterRange[] cra)
        {
            if (s == null || s.Length == 0)
                return null;

            drawFormat.SetMeasurableCharacterRanges(cra);
            Region[] rs = new Region[cra.Length];
            rs = g.MeasureCharacterRanges(s, drawFont, new RectangleF(0, 0, float.MaxValue, float.MaxValue),
                drawFormat);
            WordStartFinish[] sz = new WordStartFinish[cra.Length];
            int isz = 0;
            foreach (Region r in rs)
            {
                RectangleF mr = r.GetBounds(g);
                sz[isz].start = RSize.PointsFromPixels(g, mr.Left);
                sz[isz].end = RSize.PointsFromPixels(g, mr.Right);
                isz++;
            }
            return sz;
        }
示例#38
0
 public int MeasureDisplayStringWidth(Graphics graphics, string text, Font font)
 {
     text = text.ToUpper();
     System.Drawing.StringFormat format = new StringFormat(StringFormat.GenericTypographic);
     System.Drawing.RectangleF rect = new System.Drawing.RectangleF(0, 0, 1000, 1000);
     System.Drawing.CharacterRange[] ranges = { new System.Drawing.CharacterRange(0, text.Length) }; 
     System.Drawing.Region[] regions = new System.Drawing.Region[1];
     format.SetMeasurableCharacterRanges(ranges); 
     regions = graphics.MeasureCharacterRanges(text, font, rect, format);
     rect = regions[0].GetBounds(graphics);
     
     return (int)(rect.Right + 1.0f);
     
 }
示例#39
0
        private void HighlightString(Graphics g, PageText dtext, RectangleF r, Font f, StringFormat sf)
        {
            if (_HighlightText == null || _HighlightText.Length == 0)
                return;         // nothing to highlight
            bool bhighlightItem = dtext == _HighlightItem ||
                    (_HighlightItem != null && dtext.HtmlParent == _HighlightItem);
            if (!(_HighlightAll || bhighlightItem))
                return;         // not highlighting all and not on current highlight item

            string hlt = _HighlightCaseSensitive ? _HighlightText : _HighlightText.ToLower();
            string text = _HighlightCaseSensitive ? dtext.Text : dtext.Text.ToLower();

            if (text.IndexOf(hlt) < 0)
                return;         // string not in text

            StringFormat sf2 = null;
            try
            {
                // Create a CharacterRange array with the highlight location and length
                // Handle multiple occurences of text
                List<CharacterRange> rangel = new List<CharacterRange>();
                int loc = text.IndexOf(hlt);
                int hlen = hlt.Length;
                int len = text.Length;
                while (loc >= 0)
                {
                    rangel.Add(new CharacterRange(loc, hlen));
                    if (loc + hlen < len)  // out of range of text
                        loc = text.IndexOf(hlt, loc + hlen);
                    else
                        loc = -1;
                }

                if (rangel.Count <= 0)      // we should have gotten one; but
                    return;

                CharacterRange[] ranges = rangel.ToArray();

                // Construct a new StringFormat object.
                sf2 = sf.Clone() as StringFormat;

                // Set the ranges on the StringFormat object.
                sf2.SetMeasurableCharacterRanges(ranges);

                // Get the Regions to highlight by calling the
                // MeasureCharacterRanges method.
                if (r.Width <= 0 || r.Height <= 0)
                {
                    SizeF ts = g.MeasureString(dtext.Text, f);
                    r.Height = ts.Height;
                    r.Width = ts.Width;
                }
                Region[] charRegion = g.MeasureCharacterRanges(dtext.Text, f, r, sf2);

                // Fill in the region using a semi-transparent color to highlight
                foreach (Region rg in charRegion)
                {
                    Color hl = bhighlightItem ? _HighlightItemColor : _HighlightAllColor;
                    g.FillRegion(new SolidBrush(Color.FromArgb(50, hl)), rg);
                }
            }
            catch { }   // if highlighting fails we don't care; need to continue
            finally
            {
                if (sf2 != null)
                    sf2.Dispose();
            }
        }
		public Region[] MeasureStringLine(Graphics g, string text, CharacterRange[] measureRanges, Font font, Rectangle textRect, StringAlignment align = StringAlignment.Near, StringAlignment lineAlign = StringAlignment.Center)
		{
			// Expand text rect, because DrawString stops too soon
			textRect.Width += DrawStringWidthAdd;
			textRect.Height = Math.Max(textRect.Height, font.Height);

			// Assume manual ellipsis
			textRect.Width -= 5;
			StringFormat nameLabelFormat = StringFormat.GenericDefault;
			nameLabelFormat.Alignment = align;
			nameLabelFormat.LineAlignment = lineAlign;
			nameLabelFormat.Trimming = StringTrimming.Character;
			nameLabelFormat.FormatFlags |= StringFormatFlags.NoWrap | StringFormatFlags.MeasureTrailingSpaces;
			nameLabelFormat.SetMeasurableCharacterRanges(measureRanges);

			return g.MeasureCharacterRanges(text, font, textRect, nameLabelFormat);
		}