/// <summary> /// Get glyph's size by graphics.MeasureString(). /// Then shrink glyph's size. /// xoffset now means offset in a single glyph's bitmap. /// </summary> /// <param name="fontBitmap"></param> /// <param name="charSet"></param> /// <param name="singleCharWidth"></param> /// <param name="singleCharHeight"></param> private static void PrepareInitialGlyphDict(FontBitmap fontBitmap, string charSet, out int singleCharWidth, out int singleCharHeight) { // Get glyph's size by graphics.MeasureString(). { int maxWidth = 0, maxHeight = 0; float fontSize = fontBitmap.GlyphFont.Size; using (var bitmap = new Bitmap(1, 1, PixelFormat.Format24bppRgb)) { using (Graphics graphics = Graphics.FromImage(bitmap)) { foreach (char c in charSet) { SizeF size = graphics.MeasureString(c.ToString(), fontBitmap.GlyphFont); var info = new GlyphInfo(0, 0, (int)size.Width, (int)size.Height); fontBitmap.GlyphInfoDictionary.Add(c, info); if (maxWidth < (int)size.Width) { maxWidth = (int)size.Width; } if (maxHeight < (int)size.Height) { maxHeight = (int)size.Height; } } } } singleCharWidth = maxWidth; singleCharHeight = maxHeight; } // shrink glyph's size. // xoffset now means offset in a single glyph's bitmap. { using (var bitmap = new Bitmap(singleCharWidth, singleCharHeight)) { using (var graphics = Graphics.FromImage(bitmap)) { Color clearColor = Color.FromArgb(0, 0, 0, 0); foreach (KeyValuePair<char, GlyphInfo> item in fontBitmap.GlyphInfoDictionary) { if (item.Key == ' ' || item.Key == '\t' || item.Key == '\r' || item.Key == '\n') { continue; } graphics.Clear(clearColor); graphics.DrawString(item.Key.ToString(), fontBitmap.GlyphFont, Brushes.White, 0, 0); BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); RetargetGlyphRectangleInwards(data, item.Value); bitmap.UnlockBits(data); } } } } }
/// <summary> /// shrink glyph's width to fit in exactly. /// </summary> /// <param name="bitmapData"></param> /// <param name="glyph"></param> private static void RetargetGlyphRectangleInwards(BitmapData bitmapData, GlyphInfo glyph) { int startX, endX; { bool done = false; for (startX = glyph.xoffset; startX < bitmapData.Width; startX++) { for (int j = glyph.yoffset; j < glyph.yoffset + glyph.height; j++) { if (!IsEmptyPixel(bitmapData, startX, j)) { done = true; break; } } if (done) { break; } } } { bool done = false; for (endX = glyph.xoffset + glyph.width - 1; endX >= 0; endX--) { for (int j = glyph.yoffset; j < glyph.yoffset + glyph.height; j++) { if (!IsEmptyPixel(bitmapData, endX, j)) { done = true; break; } } if (done) { break; } } } if (endX < startX) { //startX = endX = glyph.xoffset; glyph.width = 0; } else { glyph.xoffset = startX; glyph.width = endX - startX + 1; } }
/// <summary> /// /// </summary> /// <param name="characters"></param> /// <param name="result"></param> /// <returns></returns> public bool GetGlyphInfo(string characters, out GlyphInfo result) { return(this.dictionary.TryGetValue(characters, out result)); }
/// <summary> /// /// </summary> /// <param name="character"></param> /// <param name="result"></param> /// <returns></returns> public bool GetGlyphInfo(char character, out GlyphInfo result) { return(this.dictionary.TryGetValue(character.ToString(), out result)); }