freetype
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ft] Getting the charcode Value when the Glyph ID is known


From: Balraj Balakrishnan, Integra-PDY, IN
Subject: [ft] Getting the charcode Value when the Glyph ID is known
Date: Tue, 26 Apr 2011 10:55:09 +0000

Dear Team,

 

I am using freetype2 font engine to retrieve the glyph images, I manipulated the source code provided in the site (example2.cpp ) to my custom requirement .

It would be helpful if you guys can help me solve some of the concerns which I am facing:

1.  While using the FT_Get_First_Char and FT_Get_Next_Char to iterate the glyphs id’s one by one to retrieve all the glyphs present in the font file, it fails to get all the glyph id’s from the font file, some of the glyph id’s are gone missing. I tested the same using the ftDemo samples provided in the site (version details: ft2demos-2.4.4 Specific File: ftview.c), where in all the glyph id’s are properly extracted from the font file, I want to know the possible reason why this might be happening, or is there any mistake in the code which am probably doing to cause this problem?

 

Void WriteGlyphAsTGA(FT_Library &library,

                const std::string &fileName,

                wchar_t ch,

                FT_Face &face,

                int size,

                const Pixel32 &fontCol,

                const Pixel32 outlineCol,

                float outlineWidth)

{

    int i = 0;

    if (FT_Set_Char_Size(face, size << 6, size << 6, 90, 90) == 0)

    {

        char*  p;

        unsigned long code;

        FT_UInt glyph_index;

        // Load the glyph we are looking for.

        FT_UInt gindex;

        code = FT_Get_First_Char( face, &gindex );

        while( gindex != 0 )

        {

        std::cout<< "Glyph Index=" << gindex << "\n";

        if (FT_Load_Glyph(face, gindex, FT_LOAD_NO_BITMAP) == 0)

        {

        // Need an outline for this to work.

                if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)

                {

               // Render the basic glyph to a span list.

               Spans spans;

               RenderSpans(library, &face->glyph->outline, &spans);

 

               // Next we need the spans for the outline.

               Spans outlineSpans;

 

               // Set up a stroker.

               FT_Stroker stroker;

               FT_Stroker_New(library, &stroker);

               FT_Stroker_Set(stroker,

                       (int)(outlineWidth * 64),

                       FT_STROKER_LINECAP_ROUND,

                       FT_STROKER_LINEJOIN_ROUND,

                       0);

 

               FT_Glyph glyph;

               if (FT_Get_Glyph(face->glyph, &glyph) == 0)

               {

               FT_Glyph_StrokeBorder(&glyph, stroker, 0, 1);

               // Again, this needs to be an outline to work.

               if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)

               {

                       // Render the outline spans to the span list

                       FT_Outline *o =

                               &reinterpret_cast<FT_OutlineGlyph>(glyph)->outline;

                                RenderSpans(library, o, &outlineSpans);

               }

 

                 if ( FT_HAS_GLYPH_NAMES( face ) )

                       {

                               //std::cout << "Test1";

                              

                               char* format;

                               int    format_len, size;

                               const char*  header;

                               size = 256;

                               p=(char*)malloc(4*sizeof(char*));

                              

                               format = ", name = ";

                         format_len = strlen( format );

                         if ( size >= format_len + 2 )

                         {

                           if ( FT_Get_Glyph_Name( face, gindex, p, 256 ) )

       

                         }

                       }

 

 

          // Clean up afterwards.

          FT_Stroker_Done(stroker);

          FT_Done_Glyph(glyph);

 

          // Now we need to put it all together.

          if (!spans.empty())

          {

            // Figure out what the bounding rect is for both the span lists.

            Rect rect(spans.front().x,

                      spans.front().y,

                      spans.front().x,

                      spans.front().y);

            for (Spans::iterator s = spans.begin();

                 s != spans.end(); ++s)

            {

              rect.Include(Vec2(s->x, s->y));

              rect.Include(Vec2(s->x + s->width - 1, s->y));

            }

            for (Spans::iterator s = outlineSpans.begin();

                 s != outlineSpans.end(); ++s)

            {

              rect.Include(Vec2(s->x, s->y));

              rect.Include(Vec2(s->x + s->width - 1, s->y));

            }

 

#if 0

            // This is unused in this test but you would need this to draw

            // more than one glyph.

            float bearingX = face->glyph->metrics.horiBearingX >> 6;

            float bearingY = face->glyph->metrics.horiBearingY >> 6;

            float advance = face->glyph->advance.x >> 6;

#endif

 

            // Get some metrics of our image.

            int imgWidth = rect.Width(),

                imgHeight = rect.Height(),

                imgSize = imgWidth * imgHeight;

 

            // Allocate data for our image and clear it out to transparent.

            Pixel32 *pxl = new Pixel32[imgSize];

            memset(pxl, 255, sizeof(Pixel32) * imgSize);

 

            // Loop over the outline spans and just draw them into the

            // image.

            for (Spans::iterator s = outlineSpans.begin();

                 s != outlineSpans.end(); ++s)

              for (int w = 0; w < s->width; ++w)

                pxl[(int)((imgHeight - 1 - (s->y - rect.ymin)) * imgWidth

                          + s->x - rect.xmin + w)] =

                  Pixel32(outlineCol.r, outlineCol.g, outlineCol.b,

                          s->coverage);

                                             

 

            // Then loop over the regular glyph spans and blend them into

            // the image.

            for (Spans::iterator s = spans.begin();

                 s != spans.end(); ++s)

              for (int w = 0; w < s->width; ++w)

              {

                Pixel32 &dst =

                  pxl[(int)((imgHeight - 1 - (s->y - rect.ymin)) * imgWidth

                      + s->x - rect.xmin + w)];

                Pixel32 src = "" fontCol.g, fontCol.b,

                                      s->coverage);

                               dst.r = (int)(dst.r + ((src.r - dst.r) * src.a) / 255.0f);

                dst.g = (int)(dst.g + ((src.g - dst.g) * src.a) / 255.0f);

                dst.b = (int)(dst.b + ((src.b - dst.b) * src.a) / 255.0f);

                               dst.a = MIN(255, dst.a + src.a);

              }

 

            const std::string Fname = "D\\GLYPH_IMAGES\\" + itos(gindex) + "~" + p + ".tga";

              

            WriteTGA(Fname, pxl, imgWidth, imgHeight);

 

            delete [] pxl;

          }

        }

      }

          code = FT_Get_Next_Char( face, code, &gindex );

 

    }

        }

  }

}

 

2.  In order to suppress the previous problem, I did a work around by putting a for loop to retrieve all the glyph id’s present in the range between 1 to 256, so far its working fine, but my concern with this is:

a.  Now that I am retrieving the glyph’s, how can I get the character code for each glyph ID?

b.  Can the glyph ID exceed the range of 1-255?

 

 

for(i = 1;i <= 256; i++)

       {

       gindex = i;

       if (FT_Load_Glyph(face, gindex, FT_LOAD_NO_BITMAP) == 0)

       {

      // Need an outline for this to work.

      if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)

      {       

        // Render the basic glyph to a span list.

        Spans spans;

        RenderSpans(library, &face->glyph->outline, &spans);

 

        // Next we need the spans for the outline.

        Spans outlineSpans;

 

        // Set up a stroker.

        FT_Stroker stroker;

        FT_Stroker_New(library, &stroker);

        FT_Stroker_Set(stroker,

                       (int)(outlineWidth * 64),

                       FT_STROKER_LINECAP_ROUND,

                       FT_STROKER_LINEJOIN_ROUND,

                       0);

 

        FT_Glyph glyph;

        if (FT_Get_Glyph(face->glyph, &glyph) == 0)

        {

          FT_Glyph_StrokeBorder(&glyph, stroker, 0, 1);

          // Again, this needs to be an outline to work.

          if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)

          {

            // Render the outline spans to the span list

            FT_Outline *o =

              &reinterpret_cast<FT_OutlineGlyph>(glyph)->outline;

            RenderSpans(library, o, &outlineSpans);

          }

 

                if ( FT_HAS_GLYPH_NAMES( face ) )

                     {

                           //std::cout << "Test1";

                          

                           char* format;

                           int    format_len, size;

                           const char*  header;

                           size = 256;

                           p=(char*)malloc(4*sizeof(char*));

                    

                           format = ", name = ";

                       format_len = strlen( format );

                       if ( size >= format_len + 2 )

                       {                         

                         if ( FT_Get_Glyph_Name( face, gindex, p, 256 ) )

                                  }

                     }              

          // Clean up afterwards.

          FT_Stroker_Done(stroker);

          FT_Done_Glyph(glyph);

 

          // Now we need to put it all together.

          if (!spans.empty())

          {

            // Figure out what the bounding rect is for both the span lists.

            Rect rect(spans.front().x,

                      spans.front().y,

                      spans.front().x,

                      spans.front().y);

            for (Spans::iterator s = spans.begin();

                 s != spans.end(); ++s)

            {

              rect.Include(Vec2(s->x, s->y));

              rect.Include(Vec2(s->x + s->width - 1, s->y));

            }

            for (Spans::iterator s = outlineSpans.begin();

                 s != outlineSpans.end(); ++s)

            {

              rect.Include(Vec2(s->x, s->y));

              rect.Include(Vec2(s->x + s->width - 1, s->y));

            }

 

#if 0

            // This is unused in this test but you would need this to draw

            // more than one glyph.

            float bearingX = face->glyph->metrics.horiBearingX >> 6;

            float bearingY = face->glyph->metrics.horiBearingY >> 6;

            float advance = face->glyph->advance.x >> 6;

#endif

 

            // Get some metrics of our image.

            int imgWidth = rect.Width(),

                imgHeight = rect.Height(),

                imgSize = imgWidth * imgHeight;

 

            // Allocate data for our image and clear it out to transparent.

            Pixel32 *pxl = new Pixel32[imgSize];

            memset(pxl, 255, sizeof(Pixel32) * imgSize);

 

            // Loop over the outline spans and just draw them into the

            // image.

            for (Spans::iterator s = outlineSpans.begin();

                 s != outlineSpans.end(); ++s)

              for (int w = 0; w < s->width; ++w)

                pxl[(int)((imgHeight - 1 - (s->y - rect.ymin)) * imgWidth

                          + s->x - rect.xmin + w)] =

                  Pixel32(outlineCol.r, outlineCol.g, outlineCol.b,

                          s->coverage);

                                        

 

            // Then loop over the regular glyph spans and blend them into

            // the image.

            for (Spans::iterator s = spans.begin();

                 s != spans.end(); ++s)

              for (int w = 0; w < s->width; ++w)

              {

                Pixel32 &dst =

                  pxl[(int)((imgHeight - 1 - (s->y - rect.ymin)) * imgWidth

                      + s->x - rect.xmin + w)];

                Pixel32 src = "" fontCol.g, fontCol.b,

                                      s->coverage);

                           dst.r = (int)(dst.r + ((src.r - dst.r) * src.a) / 255.0f);

                dst.g = (int)(dst.g + ((src.g - dst.g) * src.a) / 255.0f);

                dst.b = (int)(dst.b + ((src.b - dst.b) * src.a) / 255.0f);

                           dst.a = MIN(255, dst.a + src.a);

              }

 

           const std::string Fname = "D:\\GLYPH_IMAGES\\" + itos(gindex) + "~" + p + "~" + itos(code) + ".tga";

                    

            // Dump the image to disk.

            WriteTGA(Fname, pxl, imgWidth, imgHeight);

 

            delete [] pxl;

          }

        }

      }

    }

 

 

Note: Among the few font files which I tested with the above issue “TimesNewRoman.pfa” was one of them.

 

Regard’s

 

Amith Sai

 


Before printing this email, please make sure that it's necessary. 

Note: Effective immediately my email address has changed to address@hidden;  kindly update your address book to reflect this change.  Thank you.


This email and any accompanying attachments is for the sole use of the intended recipient(s) and may contain confidential and privileged information. Any unauthorized review, use, disclosure, distribution, or copying is strictly prohibited. If you are not the intended recipient of this communication or received the email by mistake, please notify the sender and destroy all copies. Integra Software Services Pvt Ltd. reserves the right, subject to applicable local law, to monitor and review the content of any electronic message or information sent to or from its company allotted employee email address/ID without informing the sender or recipient of the message.

Attachment: TimesNewRoman.pfa
Description: TimesNewRoman.pfa


reply via email to

[Prev in Thread] Current Thread [Next in Thread]