Exemplo n.º 1
0
 public TextureFontFace(FontFace nOpenTypeFontFace, string xmlFontInfo, GlyphImage glyphImg)
 {
     //for msdf font
     //1 font atlas may support mutliple font size 
     atlasBuilder = new SimpleFontAtlasBuilder();
     fontAtlas = atlasBuilder.LoadFontInfo(xmlFontInfo);
     fontAtlas.TotalGlyph = glyphImg;
     this.nOpenTypeFontFace = nOpenTypeFontFace; 
 }
Exemplo n.º 2
0
        public ActualFont ResolveForTextureFont(RequestFont font)
        {
            //check if we have texture font fot this font 
            TextureFont t = TextureFont.GetCacheFontAsTextureFont(font);
            if (t != null)
            {
                return t;
            }
            //--------------------------------------------------------------------
            LateTextureFontInfo lateFontInfo;
            if (!textureBitmapInfos.TryGetValue(font.Name, out lateFontInfo))
            {
                //not found
                return null;
            }
            //check if we have create TextureFont
            TextureFontFace textureFontface = lateFontInfo.Fontface;
            if (textureFontface == null)
            {
                //load glyh image here
                GlyphImage glyphImage = null;
                using (var nativeImg = new PixelFarm.Drawing.Imaging.NativeImage(lateFontInfo.TextureBitmapFile))
                {
                    glyphImage = new GlyphImage(nativeImg.Width, nativeImg.Height);
                    var buffer = new int[nativeImg.Width * nativeImg.Height];
                    System.Runtime.InteropServices.Marshal.Copy(nativeImg.GetNativeImageHandle(), buffer, 0, buffer.Length);
                    glyphImage.SetImageBuffer(buffer, true);
                }

                InstalledFont installedFont = GLES2PlatformFontMx.GetInstalledFont(font.Name, InstalledFontStyle.Regular);
                FontFace nOpenTypeFontFace = NOpenTypeFontLoader.LoadFont(installedFont.FontPath,
                      GLES2PlatformFontMx.defaultLang,
                      GLES2PlatformFontMx.defaultHbDirection,
                      GLES2PlatformFontMx.defaultScriptCode);


                textureFontface = new TextureFontFace(nOpenTypeFontFace, lateFontInfo.FontMapFile, glyphImage);
                lateFontInfo.Fontface = textureFontface;
                return textureFontface.GetFontAtPointsSize(font.SizeInPoints);
            }
            if (textureFontface != null)
            {
                t = (TextureFont)(textureFontface.GetFontAtPointsSize(font.SizeInPoints));
                t.AssignToRequestFont(font);
                return t;
            }
            else
            {
                //
                //need to create font face
                //create fontface first

            }
            return null;
        }
        const double FT_RESIZE = 64; //essential to be floating point
        internal unsafe static GlyphImage BuildMsdfFontImage(FontGlyph fontGlyph)
        {
            IntPtr shape = MyFtLib.CreateShape();
            FT_Outline outline = (*(FT_Outline*)fontGlyph.glyphMatrix.outline);            //outline version
            //------------------------------
            int npoints = outline.n_points;
            List<PixelFarm.VectorMath.Vector2> points = new List<PixelFarm.VectorMath.Vector2>(npoints);
            int startContour = 0;
            int cpoint_index = 0;
            int todoContourCount = outline.n_contours;
            int controlPointCount = 0;
            while (todoContourCount > 0)
            {
                int nextContour = outline.contours[startContour] + 1;
                bool isFirstPoint = true;
                //---------------
                //create contour 

                IntPtr cnt = MyFtLib.ShapeAddBlankContour(shape);
                FtVec2 secondControlPoint = new FtVec2();
                FtVec2 thirdControlPoint = new FtVec2();
                bool justFromCurveMode = false;
                FtVec2 lastMoveTo = new FtVec2();
                FtVec2 lastPoint = new FtVec2();
                FtVec2 current_point = new Fonts.FtVec2();
                for (; cpoint_index < nextContour; ++cpoint_index)
                {
                    FT_Vector xvpoint = outline.points[cpoint_index];
                    current_point = new FtVec2(xvpoint.x / FT_RESIZE, xvpoint.y / FT_RESIZE);
                    //Console.WriteLine(xvpoint.x.ToString() + "," + xvpoint.y);
                    byte vtag = outline.tags[cpoint_index];
                    bool has_dropout = (((vtag >> 2) & 0x1) != 0);
                    int dropoutMode = vtag >> 3;
                    if ((vtag & 0x1) != 0)
                    {
                        if (justFromCurveMode)
                        {
                            switch (controlPointCount)
                            {
                                case 1:
                                    {
                                        MyFtLib.ContourAddQuadraticSegment(cnt,
                                           lastPoint.x, lastPoint.y,
                                           secondControlPoint.x, secondControlPoint.y,
                                           current_point.x, current_point.y);
                                        lastPoint = current_point;
                                    }
                                    break;
                                case 2:
                                    {
                                        MyFtLib.ContourAddCubicSegment(cnt,
                                            lastPoint.x, lastPoint.y,
                                            secondControlPoint.x, secondControlPoint.y,
                                            thirdControlPoint.x, thirdControlPoint.y,
                                            current_point.x, current_point.y);
                                        lastPoint = current_point;
                                    }
                                    break;
                                default:
                                    {
                                        throw new NotSupportedException();
                                    }
                            }
                            controlPointCount = 0;
                            justFromCurveMode = false;
                        }
                        else
                        {
                            //line mode
                            if (isFirstPoint)
                            {
                                isFirstPoint = false;
                                lastMoveTo = lastPoint = current_point;
                            }
                            else
                            {
                                MyFtLib.ContourAddLinearSegment(cnt,
                                    lastPoint.x, lastPoint.y,
                                    current_point.x, current_point.y);
                                lastPoint = current_point;
                            }
                        }
                    }
                    else
                    {
                        if (isFirstPoint)
                        {
                            isFirstPoint = false;
                            lastMoveTo = lastPoint = current_point;
                        }

                        switch (controlPointCount)
                        {
                            case 0:
                                {   //bit 1 set=> off curve, this is a control point
                                    //if this is a 2nd order or 3rd order control point
                                    if (((vtag >> 1) & 0x1) != 0)
                                    {
                                        ////printf("[%d] bzc3rd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                        thirdControlPoint = new FtVec2(current_point.x, current_point.y);
                                    }
                                    else
                                    {
                                        ////printf("[%d] bzc2nd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                        secondControlPoint = new FtVec2(current_point.x, current_point.y);
                                    }
                                }
                                break;
                            case 1:
                                {
                                    if (((vtag >> 1) & 0x1) != 0)
                                    {
                                        ////printf("[%d] bzc3rd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                        thirdControlPoint = new FtVec2(current_point.x, current_point.y);
                                    }
                                    else
                                    {
                                        //we already have prev second control point
                                        //so auto calculate line to 
                                        //between 2 point
                                        FtVec2 mid = GetMidPoint(secondControlPoint, current_point);
                                        MyFtLib.ContourAddQuadraticSegment(cnt,
                                            lastPoint.x, lastPoint.y,
                                            secondControlPoint.x, secondControlPoint.y,
                                            mid.x, mid.y);
                                        lastPoint = mid;
                                        //------------------------
                                        controlPointCount--;
                                        //------------------------
                                        //printf("[%d] bzc2nd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                        secondControlPoint = current_point;
                                    }
                                }
                                break;
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                        }

                        controlPointCount++;
                        justFromCurveMode = true;
                    }
                }
                //--------
                //close figure
                //if in curve mode
                if (justFromCurveMode)
                {
                    switch (controlPointCount)
                    {
                        case 0: break;
                        case 1:
                            {
                                MyFtLib.ContourAddQuadraticSegment(cnt,
                                          lastPoint.x, lastPoint.y,
                                          secondControlPoint.x, secondControlPoint.y,
                                          lastMoveTo.x, lastMoveTo.y);
                                lastPoint = current_point;
                            }
                            break;
                        case 2:
                            {
                                MyFtLib.ContourAddCubicSegment(cnt,
                                          lastPoint.x, lastPoint.y,
                                          secondControlPoint.x, secondControlPoint.y,
                                          thirdControlPoint.x, thirdControlPoint.y,
                                          lastMoveTo.x, lastMoveTo.y);
                                lastPoint = current_point;
                            }
                            break;
                        default:
                            { throw new NotSupportedException(); }
                    }
                    justFromCurveMode = false;
                    controlPointCount = 0;
                }
                else
                {
                    MyFtLib.ContourAddLinearSegment(cnt,
                                    current_point.x, current_point.y,
                                    lastMoveTo.x, lastMoveTo.y);
                    lastPoint = current_point;
                }

                //ps.CloseFigure();
                //--------                   
                startContour++;
                todoContourCount--;
            }
            //------------

            double s_left, s_bottom, s_right, s_top;
            MyFtLib.ShapeFindBounds(shape, out s_left, out s_bottom, out s_right, out s_top);
            RectangleF glyphBounds = new RectangleF((float)s_left, (float)s_top, (float)(s_right - s_left), (float)(s_top - s_bottom));
            //then create msdf texture
            if (!MyFtLib.ShapeValidate(shape))
            {
                throw new NotSupportedException();
            }
            MyFtLib.ShapeNormalize(shape);
            int borderXY = 0;
            int w = (int)Math.Ceiling(glyphBounds.Width) + (borderXY + borderXY);
            int h = (int)(Math.Ceiling(glyphBounds.Height)) + (borderXY + borderXY);
            if (w == 0)
            {
                w = 5;
                h = 5;
            }
            int[] outputBuffer = new int[w * h];
            GlyphImage glyphImage = new GlyphImage(w, h);
            glyphImage.BorderXY = borderXY;
            glyphImage.OriginalGlyphBounds = glyphBounds;
            unsafe
            {
                fixed (int* output_header = &outputBuffer[0])
                {
                    float dx = 0;
                    float dy = 0;
                    if (s_left < 0)
                    {
                        //make it positive
                        dx = (float)-s_left;
                    }
                    else if (s_left > 0)
                    {

                    }
                    if (s_bottom < 0)
                    {
                        //make it positive
                        dy = (float)-s_bottom;
                    }
                    else if (s_bottom > 0)
                    {

                    }
                    //this glyph image has border (for msdf to render correctly)
                    MyFtLib.MyFtGenerateMsdf(shape, w, h, 4, 1, dx + borderXY, dy + borderXY, -1, 3, output_header);
                    MyFtLib.DeleteUnmanagedObj(shape);
                }
                glyphImage.SetImageBuffer(outputBuffer, true);
            }
            return glyphImage;
        }
Exemplo n.º 4
0
        public GlyphImage BuildSingleImage()
        {
            //1. add to list 
            var glyphList = new List<GlyphData>(glyphs.Count);
            foreach (GlyphData glyphData in glyphs.Values)
            {
                //sort data
                glyphList.Add(glyphData);
            }
            //2. sort
            glyphList.Sort((a, b) =>
            {
                return a.glyphImage.Width.CompareTo(b.glyphImage.Width);
            });
            //3. layout

            int totalMaxLim = 800;
            int maxRowHeight = 0;
            int currentY = 0;
            int currentX = 0;
            for (int i = glyphList.Count - 1; i >= 0; --i)
            {
                GlyphData g = glyphList[i];
                if (g.glyphImage.Height > maxRowHeight)
                {
                    maxRowHeight = g.glyphImage.Height;
                }
                if (currentX + g.glyphImage.Width > totalMaxLim)
                {
                    //start new row
                    currentY += maxRowHeight;
                    currentX = 0;
                }
                //-------------------
                g.pxArea = new Rectangle(currentX, currentY, g.glyphImage.Width, g.glyphImage.Height);
                currentX += g.glyphImage.Width;
            }

            currentY += maxRowHeight;
            int imgH = currentY;



            //4. create array that can hold data
            int[] totalBuffer = new int[totalMaxLim * imgH];
            for (int i = glyphList.Count - 1; i >= 0; --i)
            {
                GlyphData g = glyphList[i];
                //copy data to totalBuffer
                GlyphImage img = g.glyphImage;
                CopyToDest(img.GetImageBuffer(), img.Width, img.Height, totalBuffer, g.pxArea.Left, g.pxArea.Top, totalMaxLim);
            }
            //------------------
            GlyphImage glyphImage = new Fonts.GlyphImage(totalMaxLim, imgH);
            glyphImage.SetImageBuffer(totalBuffer, true);
            return latestGenGlyphImage = glyphImage;
        }
Exemplo n.º 5
0
 public void AddGlyph(int codePoint, char c, FontGlyph fontGlyph, GlyphImage glyphImage)
 {
     glyphs[codePoint] = new GlyphData(codePoint, c, fontGlyph, glyphImage);
 }
Exemplo n.º 6
0
        public GlyphData(int codePoint, char c, FontGlyph fontGlyph, GlyphImage glyphImage)
        {
            this.codePoint = codePoint;
            this.character = c;
            this.fontGlyph = fontGlyph;
            this.glyphImage = glyphImage;

        }