public bool GetGlyph(char ch, out SrGlyph glyph) { return(DefaultSize.GetGlyph(ch, out glyph)); }
private bool PopulateGlyphCache(uint ch, out Glyph glyph, Color?defaultColor) { var resolution = (uint)(BaseDPI * Font.DPIPercent / 100); var size = Font.GetFTSize(_SizePoints, resolution); uint index; if (ch == '\t') { index = Font.Face.GetCharIndex(' '); } else { index = Font.Face.GetCharIndex(ch); } if (index <= 0) { glyph = default(Glyph); return(false); } var flags = LoadFlags.Render; if (!Font.EnableBitmaps) { flags |= LoadFlags.NoBitmap; } if (!Font.Hinting) { flags |= LoadFlags.NoHinting; } if (Font.Monochrome) { flags |= LoadFlags.Monochrome; } else { flags |= LoadFlags.Color; } Font.Face.LoadGlyph( index, flags, Font.Monochrome ? LoadTarget.Mono : LoadTarget.Normal ); var sizeMetrics = size.Metrics; var ftgs = Font.Face.Glyph; var scaleX = sizeMetrics.ScaleX; var scaleY = sizeMetrics.ScaleY; var bitmap = ftgs.Bitmap; DynamicAtlas <Color> .Reservation texRegion = default(DynamicAtlas <Color> .Reservation); if ((bitmap.Width > 0) && (bitmap.Rows > 0)) { texRegion = Upload(bitmap); } var ascender = sizeMetrics.Ascender.ToSingle(); var glyphMetrics = ftgs.Metrics; var advance = glyphMetrics.HorizontalAdvance.ToSingle(); if (ch == '\t') { advance *= Font.TabSize; } var scaleFactor = 100f / Font.DPIPercent; var widthMetric = glyphMetrics.Width.ToSingle(); var bearingXMetric = glyphMetrics.HorizontalBearingX.ToSingle(); var rect = texRegion.Rectangle; glyph = new SrGlyph { Character = ch, Width = widthMetric, LeftSideBearing = bearingXMetric, RightSideBearing = ( advance - widthMetric - glyphMetrics.HorizontalBearingX.ToSingle() ), XOffset = ftgs.BitmapLeft - bearingXMetric - Font.GlyphMargin, YOffset = -ftgs.BitmapTop + ascender - Font.GlyphMargin + Font.VerticalOffset + VerticalOffset, RectInTexture = rect, // FIXME: This will become invalid if the extra spacing changes // FIXME: Scale the spacing appropriately based on ratios LineSpacing = sizeMetrics.Height.ToSingle() + ExtraLineSpacing, DefaultColor = defaultColor, Baseline = sizeMetrics.Ascender.ToSingle() }; if (texRegion.Atlas != null) { glyph.Texture = texRegion.Atlas; glyph.BoundsInTexture = texRegion.Atlas.BoundsFromRectangle(in rect); } // HACK if (ch <= 0xCFFF) { // Some fonts have weirdly-sized space characters if (char.IsWhiteSpace((char)ch)) { glyph.RightSideBearing = (float)Math.Round(glyph.RightSideBearing); } } if (ch < LowCacheSize) { LowCache[ch] = glyph; } Cache[ch] = glyph; return(true); }
public bool GetGlyph(char ch, out Glyph glyph) { if (IsDisposed) { glyph = default(Glyph); return(false); } if (Cache.TryGetValue(ch, out glyph)) { return(true); } if ((ch == '\r') || (ch == '\n') || (ch == '\0')) { return(false); } Font.Face.SetCharSize( 0, _SizePoints, (uint)(BaseDPI * Font.DPIPercent / 100), (uint)(BaseDPI * Font.DPIPercent / 100) ); uint index; if (ch == '\t') { index = Font.Face.GetCharIndex(' '); } else { index = Font.Face.GetCharIndex(ch); } if (index <= 0) { return(false); } var flags = LoadFlags.Color | LoadFlags.Render; if (!Font.EnableBitmaps) { flags |= LoadFlags.NoBitmap; } if (!Font.Hinting) { flags |= LoadFlags.NoHinting; } Font.Face.LoadGlyph( index, flags, LoadTarget.Normal ); var ftgs = Font.Face.Glyph; var scaleX = Font.Face.Size.Metrics.ScaleX; var scaleY = Font.Face.Size.Metrics.ScaleY; var bitmap = ftgs.Bitmap; DynamicAtlas <Color> .Reservation texRegion = default(DynamicAtlas <Color> .Reservation); if ((bitmap.Width > 0) && (bitmap.Rows > 0)) { texRegion = Upload(bitmap); } var ascender = Font.Face.Size.Metrics.Ascender.ToSingle(); var metrics = ftgs.Metrics; var advance = metrics.HorizontalAdvance.ToSingle(); if (ch == '\t') { advance *= Font.TabSize; } var scaleFactor = 100f / Font.DPIPercent; var widthMetric = metrics.Width.ToSingle(); var bearingXMetric = metrics.HorizontalBearingX.ToSingle(); glyph = new SrGlyph { Character = ch, Width = widthMetric, LeftSideBearing = bearingXMetric, RightSideBearing = ( advance - widthMetric - metrics.HorizontalBearingX.ToSingle() ), XOffset = ftgs.BitmapLeft - bearingXMetric - Font.GlyphMargin, YOffset = -ftgs.BitmapTop + ascender - Font.GlyphMargin, Texture = texRegion.Texture, BoundsInTexture = texRegion.Rectangle, LineSpacing = Font.Face.Size.Metrics.Height.ToSingle() }; // Some fonts have weirdly-sized space characters if (Char.IsWhiteSpace(ch)) { glyph.RightSideBearing = (float)Math.Round(glyph.RightSideBearing); } Cache[ch] = glyph; return(true); }