Esempio n. 1
0
        public static void GenerateKerning(ref Texture_Font_T font)
        {
            Texture_Glyph_T prevglyph;
            Texture_Glyph_T glyph;
            uint            glyphindex;
            uint            previndex;
            FTVector26Dot6  kerning;

            for (int x = 1; x < font.Glyphs.Count; x++)
            {
                glyph      = font.Glyphs[x];
                glyphindex = face.GetCharIndex(glyph.Codepoint);
                glyph.Kerning.Clear();
                for (int y = 1; y < font.Glyphs.Count; y++)
                {
                    prevglyph = font.Glyphs[y];
                    previndex = face.GetCharIndex(prevglyph.Codepoint);
                    kerning   = face.GetKerning(previndex, glyphindex, KerningMode.Unfitted);
                    if (kerning.X)
                    {
                        Kerning_t k = new Kerning_t();
                        k.Codepoint = prevglyph.Codepoint;
                        k.Kerning   = kerning.X.ToSingle() / HRESF;
                        glyph.Kerning.Add(k);
                    }
                }
            }
        }
Esempio n. 2
0
        public static Texture_Font_T LoadFontFromFile(Texture_Atlas_T atlas, float fontsize, string filename)
        {
            Texture_Font_T font = new Texture_Font_T();

            font.Atlas    = atlas;
            font.Size     = fontsize;
            font.Filename = filename;
            if (FontInit(ref font) == false)
            {
                throw new Exception("error initialising Font");
            }
            return(font);
        }
Esempio n. 3
0
        public static Texture_Glyph_T GetGlyph(ref Texture_Font_T font, char codepoint)
        {
            Texture_Glyph_T glyph;

            if ((FindGlyph(ref font, codepoint, out glyph)))
            {
                return(glyph);
            }
            if (LoadGlyph(ref font, codepoint))
            {
                FindGlyph(ref font, codepoint, out glyph);
                return(glyph);
            }
            throw new Exception("Error retrieving the glyph!");
        }
Esempio n. 4
0
        public static bool FindGlyph(ref Texture_Font_T font, char codepoint, out Texture_Glyph_T Glyph)
        {
            Texture_Glyph_T glyph;
            int             uintcodepoint = char.ConvertToUtf32(codepoint.ToString(), 0);

            for (int i = 0; i < font.Glyphs.Count; i++)
            {
                glyph = font.Glyphs[i];
                if ((glyph.Codepoint == uintcodepoint) && ((int)uintcodepoint == -1) ||
                    ((glyph.RenderMode == font.Rendermode) && glyph.Outlinethickness == font.Outlinethickness))
                {
                    Glyph = glyph;
                    return(true);
                }
            }
            Glyph = new Texture_Glyph_T();
            return(false);
        }
Esempio n. 5
0
        public static bool LoadFace(ref Texture_Font_T font, ref Library library, ref Face face, float size)
        {
            library = new Library();
            if (library == null)
            {
                return(false);
            }
            face = new Face(library, font.Filename);
            if (face == null)
            {
                return(false);
            }
            face.SelectCharmap(Encoding.Unicode);
            face.SetCharSize(Fixed26Dot6.FromSingle(size), 0, DPI * HRES, HRES);
            FTMatrix matrix = new FTMatrix((int)(1.0 / HRES * 0x10000L), (int)(0.0 * 0x10000L), (int)(0.0 * 0x10000L), (int)(1.0 * 0x10000L));

            face.SetTransform(matrix);
            return(true);
        }
Esempio n. 6
0
        public static bool FontInit(ref Texture_Font_T font)
        {
            SizeMetrics sizemetrics = null;

            font.Glyphs             = new System.Collections.Generic.List <Texture_Glyph_T>();
            font.Height             = 0;
            font.Ascender           = 0;
            font.Descender          = 0;
            font.Outlinethickness   = 0.0f;
            font.Rendermode         = RenderMode.RENDER_NORMAL;
            font.Hinting            = 1;
            font.Kerning            = 1;
            font.Filtering          = 1;
            font.Lcd_filter_weights = new byte[5] {
                0x10, 0x40, 0x70, 0x40, 0x10
            };
            if (!LoadFace(ref font, ref library, ref face, font.Size))
            {
                return(false);
            }
            font.Underlineposition = face.UnderlinePosition / (HRESF * HRESF) * font.Size;
            font.Underlineposition = System.MathF.Round(font.Underlineposition);
            if (font.Underlineposition < -2.0)
            {
                font.Underlineposition = -2.0f;
            }
            font.Underlinethickness = face.UnderlineThickness / (HRESF * HRESF) * font.Size;
            font.Underlinethickness = System.MathF.Round(font.Underlinethickness);
            if (font.Underlinethickness < 1)
            {
                font.Underlinethickness = 1.0f;
            }
            sizemetrics    = face.Size.Metrics;
            font.Ascender  = sizemetrics.Ascender.ToSingle();
            font.Descender = sizemetrics.Descender.ToSingle();
            font.Height    = sizemetrics.Height.ToSingle();
            font.Linegap   = font.Height - font.Ascender + font.Descender;

            GetGlyph(ref font, '\0');
            return(true);
        }
Esempio n. 7
0
        public static bool LoadGlyph(ref Texture_Font_T font, char codepoint)
        {
            int             i;
            int             x;
            int             y;
            Glyph           glyph;
            GlyphSlot       glyphSlot;
            FTBitmap        fTBitmap;
            uint            glyphindex;
            Texture_Glyph_T glyph_T;
            int             glyphtop  = 0;
            int             glyphleft = 0;
            Region          region;
            int             missed = 0;

            //check glyph has not already been loaded
            if (FindGlyph(ref font, codepoint, out glyph_T))
            {
                return(true);
            }
            // handle null codepoint
            if (codepoint == '\0')
            {
                region  = Atlas.Atlas.GetRegion(ref font.Atlas, 5, 5);
                glyph_T = InitGlyph();
                byte[] data = new byte[4 * 4 * 3] {
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0
                };
                if (region.X < 0)
                {
                    //throw new Exception("texture atlas is full!");
                    return(false);
                }
                Atlas.Atlas.SetRegion(ref font.Atlas, region.X, region.Y, 4, 4, data, 0);
                glyph_T.Codepoint = -1;
                glyph_T.S01       = (region.X + 2) / (float)font.Atlas.Width;
                glyph_T.T01       = (region.Y + 2) / (float)font.Atlas.Height;
                glyph_T.S11       = (region.X + 3) / (float)font.Atlas.Width;
                glyph_T.T11       = (region.Y + 3) / (float)font.Atlas.Height;
                font.Glyphs.Add(glyph_T);
                return(true);
            }
            LoadFlags  flags  = 0;
            LoadTarget target = 0;

            glyphindex = face.GetCharIndex((uint)char.ConvertToUtf32(codepoint.ToString(), 0));
            if (font.Rendermode != RenderMode.RENDER_NORMAL && font.Rendermode != RenderMode.RENDER_SIGNED_DISTANCE_FIELD)
            {
                flags |= LoadFlags.NoBitmap;
            }
            else
            {
                flags |= LoadFlags.Render;
            }
            if (!font.Hinting)
            {
                flags |= LoadFlags.NoHinting | LoadFlags.NoAutohint;
            }
            else
            {
                flags |= LoadFlags.ForceAutohint;
            }
            if (font.Atlas.Depth == 3)
            {
                library.SetLcdFilter(LcdFilter.Light);
                target |= LoadTarget.Lcd;
                if (font.Filtering)
                {
                    library.SetLcdFilterWeights(font.Lcd_filter_weights);
                }
            }
            else if (HRES == 1)
            {
                target |= LoadTarget.Light;
            }
            face.LoadGlyph(glyphindex, flags, target);
            if (font.Rendermode == RenderMode.RENDER_NORMAL || font.Rendermode == RenderMode.RENDER_SIGNED_DISTANCE_FIELD)
            {
                glyphSlot = face.Glyph;
                fTBitmap  = glyphSlot.Bitmap;
                glyphtop  = glyphSlot.BitmapTop;
                glyphleft = glyphSlot.BitmapLeft;
            }
            else
            {
                Stroker     stroker = new Stroker(library);
                BitmapGlyph bitmapGlyph;

                stroker.Set((int)(font.Outlinethickness * HRES), StrokerLineCap.Round, StrokerLineJoin.Round, 0);
                glyph = face.Glyph.GetGlyph();
                if (font.Rendermode == RenderMode.RENDER_OUTLINE_EDGE)
                {
                    glyph.Stroke(stroker, true);
                }
                else if (font.Rendermode == RenderMode.RENDER_OUTLINE_NEGATIVE)
                {
                    glyph.StrokeBorder(stroker, true, true);
                }
                else if (font.Rendermode == RenderMode.RENDER_OUTLINE_POSITIVE)
                {
                    glyph.StrokeBorder(stroker, false, true);
                }
                if (font.Atlas.Depth == 1)
                {
                    glyph.ToBitmap(SharpFont.RenderMode.Normal, new FTVector26Dot6(0, 0), true);
                }
                else
                {
                    glyph.ToBitmap(SharpFont.RenderMode.Lcd, new FTVector26Dot6(0, 0), true);
                }
                bitmapGlyph = glyph.ToBitmapGlyph();
                fTBitmap    = bitmapGlyph.Bitmap;
                glyphtop    = bitmapGlyph.Top;
                glyphleft   = bitmapGlyph.Left;

                stroker.Dispose();
            }
            Padding padding = new Padding(0, 1, 0, 1);

            if (font.Rendermode == RenderMode.RENDER_SIGNED_DISTANCE_FIELD)
            {
                padding.Top  = 1;
                padding.Left = 1;
            }
            if (font.Padding != 0)
            {
                padding.Left   += font.Padding;
                padding.Right  += font.Padding;
                padding.Top    += font.Padding;
                padding.Bottom += font.Padding;
            }
            int width  = (fTBitmap.Width / font.Atlas.Depth) + padding.Left + padding.Right;
            int height = fTBitmap.Rows + padding.Top + padding.Bottom;

            region = Atlas.Atlas.GetRegion(ref font.Atlas, width, height);
            if (region.X < 0)
            {
                //throw new exception("texture atlas full");
                return(false);
            }
            byte[] data = new byte[width * height * font.Atlas.Depth];
            data = fTBitmap.BufferData;
            if (font.Rendermode == RenderMode.RENDER_SIGNED_DISTANCE_FIELD)
            {
                // todo ? where is make distance map comming from
                throw new NotImplementedException();
            }
            Atlas.Atlas.SetRegion(ref font.Atlas, region.X, region.Y, width, height, data, width * font.Atlas.Depth);
            glyph_T                  = InitGlyph();
            glyph_T.Codepoint        = (uint)char.ConvertToUtf32(codepoint.ToString(), 0);
            glyph_T.Width            = (uint)width;
            glyph_T.Height           = (uint)height;
            glyph_T.RenderMode       = font.Rendermode;
            glyph_T.Outlinethickness = font.Outlinethickness;
            glyph_T.OffsetX          = glyphleft;
            glyph_T.OffsetY          = glyphtop;
            glyph_T.S01              = region.X / (float)font.Atlas.Width;
            glyph_T.T01              = region.Y / (float)font.Atlas.Height;
            glyph_T.S11              = (region.X + width) / (float)font.Atlas.Width;
            glyph_T.T11              = (region.Y + height) / (float)font.Atlas.Height;
            face.LoadGlyph(glyphindex, LoadFlags.Render | LoadFlags.NoHinting, target);
            glyphSlot        = face.Glyph;
            glyph_T.Advancex = glyphSlot.Advance.X.ToSingle();
            glyph_T.Advancey = glyphSlot.Advance.Y.ToSingle();
            font.Glyphs.Add(glyph_T);
            if (font.Rendermode != RenderMode.RENDER_NORMAL && font.Rendermode != RenderMode.RENDER_SIGNED_DISTANCE_FIELD)
            {
                glyph.Dispose();
            }
            GenerateKerning(ref font);
            return(true);
        }