예제 #1
0
        // Compute outline for a single glyph
        // if flatten is true convert curve into a list of segments
        // out parameter advance is set to the default glyph advancement
        // if embold <> 0, embold the outline by the desired strength
        public Outline GetGlyphOutline(uint idx, out Outline.Point advance, bool flatten, float embold, int isteps)
        {
            // TODO: add outline caching ?


            // load glyph for c in face slot
            //int code = FT.FT_Load_Char(face_, (uint)c, FT.FT_LOAD_DEFAULT); // FT_LOAD_DEFAULT, FT_LOAD_NO_BITMAP, FT_LOAD_NO_SCALE ?

            int code = FT.FT_Load_Glyph(face_, idx, FT.FT_LOAD_DEFAULT);

            FT.CheckError(code);


            // Check that the glyph is in Outline format

            FT.FT_FaceRec facerec = FT.HandleToRecord <FT.FT_FaceRec>(face_);

            IntPtr slot = facerec.glyph;

            FT.FT_GlyphSlotRec slotrec = FT.HandleToRecord <FT.FT_GlyphSlotRec>(slot);

            if (slotrec.format != FT.GLYPH_FORMAT_OUTLINE)
            {
                throw new FTError(string.Format("Bad glyph format (0x{0:x4})", slotrec.format));
                //throw new FTError("Bad glyph format (" + slotrec.format + ")");
            }

            // Get glyph outline in gptr
            IntPtr gptr;

            code = FT.FT_Get_Glyph(slotrec, out gptr);
            FT.CheckError(code);


            // Embold outline
            if (embold != 0)
            {
                // Console.WriteLine("EMBOLD=" + embold);
                // IntPtr optr = FT.fthelper_glyph_get_outline_address(slot);
                FT.FT_Outline_Embolden(slotrec.outline, (int)(embold * 64 * 100)); // convert to 26.6 fractional format
            }

            // Decompose outline
            Outline outline = null;

            if (flatten)
            {
                outline = Outline.FlattenGlyph(slotrec, vectorScale_, isteps);
            }
            else
            {
                outline = Outline.DecomposeGlyph(slotrec, vectorScale_, isteps);
            }

            FT.FT_Done_Glyph(gptr);

            advance = new Outline.Point(slotrec.advance, vectorScale_);

            return(outline);
        }
예제 #2
0
        public unsafe UnityEngine.Texture2D RenderIntoTexture(char c)
        {
            int code;

            FT.FT_FaceRec facerec = FT.HandleToRecord <FT.FT_FaceRec>(face_);
            IntPtr        slot    = facerec.glyph;

            code = FT.FT_Load_Char(face_, c, FT.FT_LOAD_RENDER /*|FT.FT_LOAD_TARGET_NORMAL*/);
            if (code != 0)
            {
                return(null);
            }

            FT.FT_GlyphSlotRec   slotrec = FT.HandleToRecord <FT.FT_GlyphSlotRec>(slot);
            FTSharp.FT.FT_Bitmap ftbm    = slotrec.bitmap;

            UnityEngine.Texture2D texbuffer = new UnityEngine.Texture2D((int)ftbm.width, (int)ftbm.rows, UnityEngine.TextureFormat.ARGB32, false);
            if (((int)ftbm.pixel_mode) != 2)
            {
                UnityEngine.Debug.LogError("Unsupported bitmap depth :" + ((int)ftbm.pixel_mode).ToString());
                return(null);
            }
            //  FT_PIXEL_MODE_MONO,
            //FT_PIXEL_MODE_GRAY,

            UnityEngine.Color32 [] clrs = texbuffer.GetPixels32();
            int i = 0;



            // UNSAFE DOES NOT WORK IN THE WEB PLAYER !
            for (int y = 0; y < ftbm.rows; y++)
            {
                long  j  = (((ftbm.rows - (1 + y)) * ftbm.pitch));
                byte *bo = ((byte *)ftbm.buffer);
                for (int x = 0; x < ftbm.width; x++)
                {
                    clrs[i].a = clrs[i].r = clrs[i].g = clrs[i].b = (bo[j + x]);
                    i++;
                }
            }
            texbuffer.SetPixels32(clrs);
            texbuffer.Apply();
            return(texbuffer);
        }
예제 #3
0
        // Compute the Bounding box of a single glyph
        public BBox Measure(char c, out Outline.Point advance)
        {
            // load glyph for c in face slot
            int code = FT.FT_Load_Char(face_, (uint)c, (int)(FT.FT_LOAD_DEFAULT | (1 << 3))); // FT_LOAD_DEFAULT, FT_LOAD_NO_BITMAP, FT_LOAD_NO_SCALE ?

            FT.CheckError(code);


            // Check that the glyph is in Outline format

            FT.FT_FaceRec facerec = FT.HandleToRecord <FT.FT_FaceRec>(face_);

            IntPtr slot = facerec.glyph;

            FT.FT_GlyphSlotRec slotrec = FT.HandleToRecord <FT.FT_GlyphSlotRec>(slot);

            if (slotrec.format != FT.GLYPH_FORMAT_OUTLINE)
            {
                throw new FTError("Bad glyph format (" + slotrec.format + ")");
            }


            // get glyph in gptr
            IntPtr gptr;

            code = FT.FT_Get_Glyph(slotrec, out gptr);
            FT.CheckError(code);

            FT.FT_BBox ft_bbox;
            FT.FT_Glyph_Get_CBox(gptr, 0, out ft_bbox);

            FT.FT_Done_Glyph(gptr);

            BBox bbox = new BBox(ft_bbox, vectorScale_);

            advance = new Outline.Point(slotrec.advance, vectorScale_);

            return(bbox);
        }
예제 #4
0
        float vectorScale_; // (point_size * resolution)/ (72 * face->units_per_em)


        public Font(string path, float height, uint dpi)
        {
            lib  = FTLibrary.Instance;
            dpi_ = dpi;

            int code = FT.FT_New_Face(lib.Handle, path, 0, out face_);

            FT.CheckError(code);

            FT.FT_FaceRec facerec = FT.HandleToRecord <FT.FT_FaceRec>(face_);

            familyName_ = facerec.family_name;
            styleName_  = facerec.style_name;

            face_has_kerning_  = ((facerec.face_flags & FT.FT_FACE_FLAG_KERNING) != 0);
            face_units_per_EM_ = facerec.units_per_EM;
            face_height_       = facerec.height;

            //Console.WriteLine("new FONT = unit-per-em=" + face_units_per_EM_);
            //setCharSize(pointsize);

            setCharHeight(height);
        }
예제 #5
0
        public void RenderText(string text, DrawBitmapF drawBitmap, int penx, int peny)
        {
            int code;

            FT.FT_FaceRec facerec = FT.HandleToRecord <FT.FT_FaceRec>(face_);
            IntPtr        slot    = facerec.glyph;

            foreach (char c in text)
            {
                code = FT.FT_Load_Char(face_, c, FT.FT_LOAD_RENDER /*|FT.FT_LOAD_TARGET_NORMAL*/);
                if (code != 0)
                {
                    continue;
                }

                FT.FT_GlyphSlotRec slotrec = FT.HandleToRecord <FT.FT_GlyphSlotRec>(slot);
                //Bitmap bitmap = new Bitmap(slotrec.bitmap);

                //                drawBitmap(bitmap, penx + slotrec.bitmap_left, peny + slotrec.bitmap_top);
                //drawBitmap(bitmap, penx + slotrec.bitmap_left, peny - slotrec.bitmap_top);
                drawBitmap(slotrec.bitmap, penx + slotrec.bitmap_left, peny - slotrec.bitmap_top);
                penx += (slotrec.advance.x >> 6);
            }
        }