unsafe internal static void CopyGlyphBitmap(FontGlyph fontGlyph)
        {
            FT_Bitmap* ftBmp = (FT_Bitmap*)fontGlyph.glyphMatrix.bitmap;
            //image is 8 bits grayscale
            int h = ftBmp->rows;
            int w = ftBmp->width;
            int stride = ftBmp->pitch;
            int size = stride * h;
            //copy it to array  
            //bmp glyph is bottom up 
            //so .. invert it...

            byte[] buff = new byte[size];
            //------------------------------------------------
            byte* currentSrc = ftBmp->buffer;
            int srcpos = size;
            int targetpos = 0;
            for (int r = 1; r <= h; ++r)
            {
                srcpos -= stride;
                currentSrc = ftBmp->buffer + srcpos;
                for (int c = 0; c < stride; ++c)
                {
                    buff[targetpos] = *(currentSrc + c);
                    targetpos++;
                }
            }

            ////------------------------------------------------
            //IntPtr bmpPtr = (IntPtr)ftBmp->buffer;
            //Marshal.Copy((IntPtr)ftBmp->buffer, buff, 0, size);
            ////------------------------------------------------ 

            //------------------------------------------------
            fontGlyph.glyImgBuffer8 = buff;
            //convert to 32bpp
            //make gray value as alpha channel color value
            ActualImage actualImage = new ActualImage(w, h, Agg.PixelFormat.ARGB32);
            byte[] newBmp32Buffer = ActualImage.GetBuffer(actualImage);
            int src_p = 0;
            int target_p = 0;
            for (int r = 0; r < h; ++r)
            {
                for (int c = 0; c < w; ++c)
                {
                    byte srcColor = buff[src_p + c];
                    //expand to 4 channel
                    newBmp32Buffer[target_p] = 0;
                    newBmp32Buffer[target_p + 1] = 0;
                    newBmp32Buffer[target_p + 2] = 0;
                    newBmp32Buffer[target_p + 3] = srcColor; //A
                    target_p += 4;
                }
                src_p += stride;
            }
            fontGlyph.glyphImage32 = actualImage;
        }
Example #2
0
        public override FontGlyph GetGlyphByIndex(ushort glyphIndex)
        {
            //1.
            FontGlyph fontGlyph = new FontGlyph();

            fontGlyph.flattenVxs  = GetGlyphVxs(glyphIndex);
            fontGlyph.horiz_adv_x = _typeFace.GetHAdvanceWidthFromGlyphIndex(glyphIndex);

            return(fontGlyph);
        }
Example #3
0
        public void ReadSVG(string svgContent)
        {
            int    startIndex        = 0;
            String fontElementString = GetSubString(svgContent, "<font", ">", ref startIndex);

            fontId = GetStringValue(fontElementString, "id");
            GetIntValue(fontElementString, "horiz-adv-x", out horiz_adv_x);
            String fontFaceString = GetSubString(svgContent, "<font-face", "/>", ref startIndex);

            fontFamily = GetStringValue(fontFaceString, "font-family");
            GetIntValue(fontFaceString, "font-weight", out font_weight);
            font_stretch = GetStringValue(fontFaceString, "font-stretch");
            GetIntValue(fontFaceString, "units-per-em", out unitsPerEm);
            panose_1 = new Panos_1(GetStringValue(fontFaceString, "panose-1"));
            GetIntValue(fontFaceString, "ascent", out ascent);
            GetIntValue(fontFaceString, "descent", out descent);
            GetIntValue(fontFaceString, "x-height", out x_height);
            GetIntValue(fontFaceString, "cap-height", out cap_height);
            String bboxString = GetStringValue(fontFaceString, "bbox");

            String[] valuesString = bboxString.Split(' ');
            int.TryParse(valuesString[0], out boundingBox.Left);
            int.TryParse(valuesString[1], out boundingBox.Bottom);
            int.TryParse(valuesString[2], out boundingBox.Right);
            int.TryParse(valuesString[3], out boundingBox.Top);
            GetIntValue(fontFaceString, "underline-thickness", out underline_thickness);
            GetIntValue(fontFaceString, "underline-position", out underline_position);
            unicode_range = GetStringValue(fontFaceString, "unicode-range");
            String missingGlyphString = GetSubString(svgContent, "<missing-glyph", "/>", ref startIndex);

            missingGlyph = CreateGlyphFromSVGGlyphData(missingGlyphString);
            String nextGlyphString = GetSubString(svgContent, "<glyph", "/>", ref startIndex);

            while (nextGlyphString != null)
            {
                // get the data and put it in the glyph dictionary

                FontGlyph newGlyph = CreateGlyphFromSVGGlyphData(nextGlyphString);
                if (newGlyph.unicode > 0)
                {
                    originalGlyphs.Add(newGlyph.unicode, newGlyph);
                }

                nextGlyphString = GetSubString(svgContent, "<glyph", "/>", ref startIndex);
            }
        }
Example #4
0
        public FontGlyph GetGlyph(char c)
        {
            FontGlyph glyph;

            if (!cachedGlyphs.TryGetValue(c, out glyph))
            {
                //create font glyph for this font size
                var         originalGlyph  = fontface.GetGlyphForCharacter(c);
                VertexStore characterGlyph = new VertexStore();
                scaleTx.TransformToVxs(originalGlyph.originalVxs, characterGlyph);
                glyph             = new FontGlyph();
                glyph.horiz_adv_x = originalGlyph.horiz_adv_x;
                glyph.originalVxs = characterGlyph;
                //then flatten it

                glyph.flattenVxs = curveFlattner.MakeVxs(characterGlyph, new VertexStore());

                cachedGlyphs.Add(c, glyph);
            }
            return(glyph);
        }
Example #5
0
        public FontGlyph GetGlyphByIndex(uint glyphIndex)
        {
            FontGlyph glyph;

            //temp
            if (!cachedGlyphsByIndex.TryGetValue(glyphIndex, out glyph))
            {
                //create font glyph for this font size
                FontGlyph originalGlyph = fontface.GetGlyphByIndex((int)glyphIndex);

                VertexStore characterGlyph = new VertexStore();
                scaleTx.TransformToVxs(originalGlyph.originalVxs, characterGlyph);

                glyph             = new FontGlyph();
                glyph.originalVxs = characterGlyph;
                //then flatten it
                glyph.flattenVxs  = curveFlattner.MakeVxs(characterGlyph, new VertexStore());
                glyph.horiz_adv_x = originalGlyph.horiz_adv_x;
                cachedGlyphsByIndex.Add(glyphIndex, glyph);
            }
            return(glyph);
        }
Example #6
0
        FontGlyph CreateGlyphFromSVGGlyphData(string svgGlyphData)
        {
            FontGlyph newGlyph = new FontGlyph();

            if (!GetIntValue(svgGlyphData, "horiz-adv-x", out newGlyph.horiz_adv_x))
            {
                newGlyph.horiz_adv_x = horiz_adv_x;
            }

            newGlyph.glyphName = GetStringValue(svgGlyphData, "glyph-name");
            String unicodeString = GetStringValue(svgGlyphData, "unicode");

            if (unicodeString != null)
            {
                if (unicodeString.Length == 1)
                {
                    newGlyph.unicode = (int)unicodeString[0];
                }
                else
                {
                    if (unicodeString.Split(';').Length > 1 && unicodeString.Split(';')[1].Length > 0)
                    {
                        throw new NotImplementedException("We do not currently support glyphs longer than one character.  You need to wirite the seach so that it will find them if you want to support this");
                    }

                    if (int.TryParse(unicodeString, NumberStyles.Number, null, out newGlyph.unicode) == false)
                    {
                        // see if it is a unicode
                        String hexNumber = GetSubString(unicodeString, "&#x", ";");
                        int.TryParse(hexNumber, NumberStyles.HexNumber, null, out newGlyph.unicode);
                    }
                }
            }

            String dString = GetStringValue(svgGlyphData, "d");

            int        parseIndex = 0;
            int        polyStartVertexSourceIndex = 0;
            Vector2    lastXY   = new Vector2(0, 0);
            double     px       = 0;
            double     py       = 0;
            PathWriter gyphPath = new PathWriter();

            newGlyph.originalVxs = gyphPath.Vxs;
            if (dString == null || dString.Length == 0)
            {
                return(newGlyph);
            }

            while (parseIndex < dString.Length)
            {
                char command = dString[parseIndex];
                switch (command)
                {
                case 'M':
                {
                    parseIndex++;
                    // svg fonts are stored cw and agg expects its shapes to be ccw.  cw shapes are holes.
                    // so we store the position of the start of this polygon so we can flip it when we colse it.
                    polyStartVertexSourceIndex = gyphPath.Count;
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.MoveTo(px, py);
                }
                break;

                case 'v':
                {
                    parseIndex++;
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.VerticalLineToRel(py);
                }
                break;

                case 'V':
                {
                    parseIndex++;
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.VerticalLineTo(py);
                }
                break;

                case 'h':
                {
                    parseIndex++;
                    px = GetNextNumber(dString, ref parseIndex);
                    gyphPath.HorizontalLineToRel(px);
                }
                break;

                case 'H':
                {
                    parseIndex++;
                    px = GetNextNumber(dString, ref parseIndex);
                    gyphPath.HorizontalLineTo(px);
                }
                break;

                case 'l':
                {
                    parseIndex++;
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.LineToRel(px, py);
                }
                break;

                case 'L':
                {
                    parseIndex++;
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.LineTo(px, py);
                }
                break;

                case 'q':
                {
                    //Curve3
                    parseIndex++;
                    double p2x = GetNextNumber(dString, ref parseIndex);
                    double p2y = GetNextNumber(dString, ref parseIndex);
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.Curve3Rel(p2x, p2y, px, py);
                }
                break;

                case 'Q':
                {           //Curve3
                    parseIndex++;
                    double p2x = GetNextNumber(dString, ref parseIndex);
                    double p2y = GetNextNumber(dString, ref parseIndex);
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.Curve3(p2x, p2y, px, py);
                }
                break;

                case 't':
                {
                    //svg smooth curve3
                    parseIndex++;
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.SmoothCurve3Rel(px, py);
                }
                break;

                case 'T':
                {
                    parseIndex++;
                    px = GetNextNumber(dString, ref parseIndex);
                    py = GetNextNumber(dString, ref parseIndex);
                    gyphPath.SmoothCurve3(px, py);
                }
                break;

                case 'z':
                case 'Z':
                {
                    parseIndex++;
                    //curXY = lastXY; // value not used this is to remove an error.
                    //newGlyph.glyphData.ClosePathStorage();
                    gyphPath.CloseFigure();
                    // svg fonts are stored cw and agg expects its shapes to be ccw.  cw shapes are holes.
                    // We stored the position of the start of this polygon, no we flip it as we close it.
                    //newGlyph.glyphData.InvertPolygon(polyStartVertexSourceIndex);
                    // VertexHelper.InvertPolygon(gyphPath.Vxs, polyStartVertexSourceIndex);
                }
                break;

                case ' ':
                case '\n':     // some white space we need to skip
                case '\r':
                {
                    parseIndex++;
                }
                break;

                default:
                    throw new NotImplementedException("unrecognized d command '" + command + "'.");
                }
            }

            return(newGlyph);
        }
Example #7
0
 public override FontGlyph GetGlyphByIndex(uint glyphIndex)
 {
     //1.  
     FontGlyph fontGlyph = new FontGlyph();
     fontGlyph.flattenVxs = GetGlyphVxs(glyphIndex);
     fontGlyph.horiz_adv_x = typeFace.GetAdvanceWidthFromGlyphIndex((int)glyphIndex);
     return fontGlyph;
 }
 //---------------------------------------------------------------------------
 public static GlyphImage BuildMsdfFontImage(FontGlyph fontGlyph)
 {
     return(NativeFontGlyphBuilder.BuildMsdfFontImage((NativeFontGlyph)fontGlyph));
 }
Example #9
0
 void BuildOutlineGlyph(FontGlyph fontGlyph, int pxsize)
 {
     NativeFontGlyphBuilder.BuildGlyphOutline(fontGlyph);
     Agg.VertexStore vxs = new Agg.VertexStore();
     NativeFontGlyphBuilder.FlattenVxs(fontGlyph.originalVxs, vxs);
     fontGlyph.flattenVxs = vxs;
 }
Example #10
0
 void BuildBitmapGlyph(FontGlyph fontGlyph, int pxsize)
 {
     NativeFontGlyphBuilder.CopyGlyphBitmap(fontGlyph);
 }
Example #11
0
 internal FontGlyph ReloadGlyphFromChar(char unicodeChar, int pixelSize)
 {
     if (currentFacePixelSize != pixelSize)
     {
         currentFacePixelSize = pixelSize;
         NativeMyFontsLib.MyFtSetPixelSizes(this.ftFaceHandle, pixelSize);
     }
     //-------------------------------------------------- 
     var fontGlyph = new FontGlyph();
     NativeMyFontsLib.MyFtLoadChar(ftFaceHandle, unicodeChar, out fontGlyph.glyphMatrix);
     BuildOutlineGlyph(fontGlyph, pixelSize);
     return fontGlyph;
 }
        unsafe internal static void BuildGlyphOutline(FontGlyph fontGlyph)
        {
            FT_Outline outline = (*(FT_Outline*)fontGlyph.glyphMatrix.outline);
            //outline version
            //------------------------------
            int npoints = outline.n_points;

            int startContour = 0;
            int cpoint_index = 0;
            int todoContourCount = outline.n_contours;
            PixelFarm.Agg.VertexSource.PathWriter ps = new Agg.VertexSource.PathWriter();
            fontGlyph.originalVxs = ps.Vxs;
            int controlPointCount = 0;
            while (todoContourCount > 0)
            {
                int nextContour = outline.contours[startContour] + 1;
                bool isFirstPoint = true;
                FtVec2 secondControlPoint = new FtVec2();
                FtVec2 thirdControlPoint = new FtVec2();
                bool justFromCurveMode = false;
                //FT_Vector vpoint = new FT_Vector();
                for (; cpoint_index < nextContour; ++cpoint_index)
                {
                    FT_Vector vpoint = outline.points[cpoint_index];
                    byte vtag = outline.tags[cpoint_index];
                    bool has_dropout = (((vtag >> 2) & 0x1) != 0);
                    int dropoutMode = vtag >> 3;

                    Console.WriteLine(vpoint.ToString() + " " + vtag);

                    if ((vtag & 0x1) != 0)
                    {
                        //on curve
                        if (justFromCurveMode)
                        {
                            switch (controlPointCount)
                            {
                                case 1:
                                    {
                                        ps.Curve3(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                            vpoint.x / FT_RESIZE, vpoint.y / FT_RESIZE);
                                    }
                                    break;
                                case 2:
                                    {
                                        ps.Curve4(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                           thirdControlPoint.x / FT_RESIZE, thirdControlPoint.y / FT_RESIZE,
                                           vpoint.x / FT_RESIZE, vpoint.y / FT_RESIZE);
                                    }
                                    break;
                                default:
                                    {
                                        throw new NotSupportedException();
                                    }
                            }
                            controlPointCount = 0;
                            justFromCurveMode = false;
                        }
                        else
                        {
                            if (isFirstPoint)
                            {
                                isFirstPoint = false;
                                ps.MoveTo(vpoint.x / FT_RESIZE, vpoint.y / FT_RESIZE);
                            }
                            else
                            {
                                ps.LineTo(vpoint.x / FT_RESIZE, vpoint.y / FT_RESIZE);
                            }

                            if (has_dropout)
                            {
                                //printf("[%d] on,dropoutMode=%d: %d,y:%d \n", mm, dropoutMode, vpoint.x, vpoint.y);
                            }
                            else
                            {
                                //printf("[%d] on,x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                            }
                        }
                    }
                    else
                    {
                        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(vpoint);
                                    }
                                    else
                                    {
                                        //printf("[%d] bzc2nd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                        secondControlPoint = new FtVec2(vpoint);
                                    }
                                }
                                break;
                            case 1:
                                {
                                    if (((vtag >> 1) & 0x1) != 0)
                                    {
                                        //printf("[%d] bzc3rd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                        thirdControlPoint = new FtVec2(vpoint);
                                    }
                                    else
                                    {
                                        //we already have prev second control point
                                        //so auto calculate line to 
                                        //between 2 point
                                        FtVec2 mid = GetMidPoint(secondControlPoint, vpoint);
                                        //----------
                                        //generate curve3
                                        ps.Curve3(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                            mid.x / FT_RESIZE, mid.y / FT_RESIZE);
                                        //------------------------
                                        controlPointCount--;
                                        //------------------------
                                        //printf("[%d] bzc2nd,  x: %d,y:%d \n", mm, vpoint.x, vpoint.y);
                                        secondControlPoint = new FtVec2(vpoint);
                                    }
                                }
                                break;
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                                break;
                        }

                        controlPointCount++;
                        justFromCurveMode = true;
                    }
                }
                //--------
                //close figure
                //if in curve mode
                if (justFromCurveMode)
                {
                    switch (controlPointCount)
                    {
                        case 0: break;
                        case 1:
                            {
                                ps.Curve3(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                    ps.LastMoveX, ps.LastMoveY);
                            }
                            break;
                        case 2:
                            {
                                ps.Curve4(secondControlPoint.x / FT_RESIZE, secondControlPoint.y / FT_RESIZE,
                                   thirdControlPoint.x / FT_RESIZE, thirdControlPoint.y / FT_RESIZE,
                                   ps.LastMoveX, ps.LastMoveY);
                            }
                            break;
                        default:
                            { throw new NotSupportedException(); }
                    }
                    justFromCurveMode = false;
                    controlPointCount = 0;
                }
                ps.CloseFigure();
                //--------                   
                startContour++;
                todoContourCount--;
            }
        }
 //---------------------------------------------------------------------------
 public static GlyphImage BuildMsdfFontImage(FontGlyph fontGlyph)
 {
     return NativeFontGlyphBuilder.BuildMsdfFontImage(fontGlyph);
 }
        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;
        }
Example #15
0
 public void AddGlyph(int codePoint, char c, FontGlyph fontGlyph, GlyphImage glyphImage)
 {
     glyphs[codePoint] = new GlyphData(codePoint, c, fontGlyph, glyphImage);
 }
Example #16
0
        public GlyphData(int codePoint, char c, FontGlyph fontGlyph, GlyphImage glyphImage)
        {
            this.codePoint = codePoint;
            this.character = c;
            this.fontGlyph = fontGlyph;
            this.glyphImage = glyphImage;

        }