コード例 #1
0
ファイル: FTFont.cs プロジェクト: sq/Libraries
            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);
            }