Text Rendering using Type1 Font | C++

Rendering Text

In order to render text, the Rendering subsystem requires the implementation of Aspose.Font.Rendering.IGlyphOutlinePainter interface to draw glyph. This can be achieved using the following steps.

  1. Implement the IGlyphOutlinePainter methods by creating a class GlyphOutlinePainter which requires object of type System.Drawing.Drawing2D.GraphicsPath for graphic drawing objectives. The implementation is as illustrated below.

     1For complete examples and data files, please go to https://github.com/aspose-font/Aspose.Font-for-C
      2RenderingText::GlyphOutlinePainter::GlyphOutlinePainter(System::SharedPtr<System::Drawing::Drawing2D::GraphicsPath> path)
      3{
      4    _path = path;
      5}
      6
      7void RenderingText::GlyphOutlinePainter::MoveTo(System::SharedPtr<Aspose::Font::RenderingPath::MoveTo> moveTo)
      8{
      9    _path->CloseFigure();
     10    _currentPoint.set_X((float)moveTo->get_X());
     11    _currentPoint.set_Y((float)moveTo->get_Y());
     12}
     13
     14void RenderingText::GlyphOutlinePainter::LineTo(System::SharedPtr<Aspose::Font::RenderingPath::LineTo> lineTo)
     15{
     16    float x = (float)lineTo->get_X();
     17    float y = (float)lineTo->get_Y();
     18    _path->AddLine(_currentPoint.get_X(), _currentPoint.get_Y(), x, y);
     19    _currentPoint.set_X(x);
     20    _currentPoint.set_Y(y);
     21}
     22
     23void RenderingText::GlyphOutlinePainter::CurveTo(System::SharedPtr<Aspose::Font::RenderingPath::CurveTo> curveTo)
     24{
     25    float x3 = (float)curveTo->get_X3();
     26    float y3 = (float)curveTo->get_Y3();
     27    
     28    _path->AddBezier(_currentPoint.get_X(), _currentPoint.get_Y(), (float)curveTo->get_X1(), (float)curveTo->get_Y1(), (float)curveTo->get_X2(), (float)curveTo->get_Y2(), x3, y3);
     29    
     30    _currentPoint.set_X(x3);
     31    _currentPoint.set_Y(y3);
     32}
     33
     34void RenderingText::GlyphOutlinePainter::ClosePath()
     35{
     36    _path->CloseFigure();
     37}
     38
     39System::Object::shared_members_type Aspose::Font::Examples::WorkingWithType1Fonts::RenderingText::GlyphOutlinePainter::GetSharedMembers()
     40{
     41    auto result = System::Object::GetSharedMembers();
     42    
     43    result.Add("Aspose::Font::Examples::WorkingWithType1Fonts::RenderingText::GlyphOutlinePainter::_path", this->_path);
     44    result.Add("Aspose::Font::Examples::WorkingWithType1Fonts::RenderingText::GlyphOutlinePainter::_currentPoint", this->_currentPoint);
     45    
     46    return result;
     47}

  2. Create method DrawText() which draws specified text into System.Drawing.Bitmap object and saves resultant bitmap on Disc. This will include the following steps:

Auxillary steps for this strategy

Implementation of DrawText method is as shown below.

 1For complete examples and data files, please go to https://github.com/aspose-font/Aspose.Font-for-C
  2void RenderingText::DrawText(System::String text, System::SharedPtr<IFont> font, double fontSize, System::SharedPtr<System::Drawing::Brush> backgroundBrush, System::SharedPtr<System::Drawing::Brush> textBrush, System::String outFile)
  3{
  4    //Get glyph identifiers for every symbol in text line
  5    System::ArrayPtr<System::SharedPtr<GlyphId>> gids = System::MakeArray<System::SharedPtr<Aspose::Font::Glyphs::GlyphId>>(text.get_Length());
  6    for (int32_t i = 0; i < text.get_Length(); i++)
  7    {
  8        gids[i] = font->get_Encoding()->DecodeToGid(text[i]);
  9    }
 10    // set common drawing settings
 11    double dpi = 300;
 12    
 13    double resolutionCorrection = dpi / 72;
 14    // 72 is font's internal dpi
 15    // prepare output bitmap
 16    System::SharedPtr<System::Drawing::Bitmap> outBitmap = System::MakeObject<System::Drawing::Bitmap>(960, 720);
 17    outBitmap->SetResolution((float)dpi, (float)dpi);
 18    System::SharedPtr<System::Drawing::Graphics> outGraphics = System::Drawing::Graphics::FromImage(outBitmap);
 19    outGraphics->FillRectangle(backgroundBrush, 0, 0, outBitmap->get_Width(), outBitmap->get_Height());
 20    outGraphics->set_SmoothingMode(System::Drawing::Drawing2D::SmoothingMode::HighQuality);
 21    //declare coordinate variables and previous gid
 22    System::SharedPtr<GlyphId> previousGid;
 23    double glyphXCoordinate = 0;
 24    double glyphYCoordinate = fontSize * resolutionCorrection;
 25    //loop which paints every glyph in gids
 26    
 27    {
 28        for (System::SharedPtr<GlyphId> gid : gids)
 29        {
 30            // if the font contains the gid
 31            if (gid != nullptr)
 32            {
 33                System::SharedPtr<Glyph> glyph = font->get_GlyphAccessor()->GetGlyphById(gid);
 34                if (glyph == nullptr)
 35                {
 36                    continue;
 37                }
 38                
 39                // path that accepts drawing instructions
 40                System::SharedPtr<System::Drawing::Drawing2D::GraphicsPath> path = System::MakeObject<System::Drawing::Drawing2D::GraphicsPath>();
 41                
 42                // Create IGlyphOutlinePainter implementation
 43                System::SharedPtr<RenderingText::GlyphOutlinePainter> outlinePainter = System::MakeObject<RenderingText::GlyphOutlinePainter>(path);
 44                
 45                // Create the renderer
 46                System::SharedPtr<Aspose::Font::Renderers::IGlyphRenderer> renderer = System::MakeObject<Aspose::Font::Renderers::GlyphOutlineRenderer>(outlinePainter);
 47                
 48                // get common glyph properties
 49                double kerning = 0;
 50                
 51                // get kerning value
 52                if (previousGid != nullptr)
 53                {
 54                    kerning = (font->get_Metrics()->GetKerningValue(previousGid, gid) / glyph->get_SourceResolution()) * fontSize * resolutionCorrection;
 55                    kerning += FontWidthToImageWith(font->get_Metrics()->GetGlyphWidth(previousGid), glyph->get_SourceResolution(), fontSize);
 56                }
 57                
 58                // glyph positioning - increase glyph X coordinate according to kerning distance
 59                glyphXCoordinate += kerning;
 60                
 61                // Glyph placement matrix
 62                System::SharedPtr<TransformationMatrix> glyphMatrix = System::MakeObject<TransformationMatrix>(System::MakeArray<double>({fontSize * resolutionCorrection, 0, 0, -fontSize * resolutionCorrection, glyphXCoordinate, glyphYCoordinate}));
 63                
 64                // render current glyph
 65                renderer->RenderGlyph(font, gid, glyphMatrix);
 66                // fill the path
 67                path->set_FillMode(System::Drawing::Drawing2D::FillMode::Winding);
 68                outGraphics->FillPath(textBrush, path);
 69            }
 70            //set current gid as previous to get correct kerning for next glyph
 71            previousGid = gid;
 72        }
 73        
 74    }
 75    //Save results
 76    outBitmap->Save(outFile);
 77}

  1. create utility method to calculate font width to image width as shown in the code sample below
    1For complete examples and data files, please go to https://github.com/aspose-font/Aspose.Font-for-C
      2double RenderingText::FontWidthToImageWith(double width, int32_t fontSourceResulution, double fontSize, double dpi /* = 300*/)
      3{
      4    double resolutionCorrection = dpi / 72;
      5    // 72 is font's internal dpi
      6    return (width / fontSourceResulution) * fontSize * resolutionCorrection;
      7}

Calling the Rendering Text functionality

To use the above implmentations, the following sample code can be executed from the Main method of a console based application.

 1For complete examples and data files, please go to https://github.com/aspose-font/Aspose.Font-for-C
 2System::String fileName = dataDir + u"courier.pfb";
 3//Font file name with full path
 4    
 5System::SharedPtr<FontDefinition> fd = System::MakeObject<FontDefinition>(Aspose::Font::FontType::Type1, System::MakeObject<FontFileDefinition>(u"pfb", System::MakeObject<FileSystemStreamSource>(fileName)));
 6System::SharedPtr<Type1Font> font = System::DynamicCast_noexcept<Aspose::Font::Type1::Type1Font>(Aspose::Font::Font::Open(fd));
 7    
 8    
 9DrawText(u"Hello world", font, 14, System::Drawing::Brushes::get_White(), System::Drawing::Brushes::get_Black(), dataDir + u"hello1_type1_out.jpg");
10DrawText(u"Hello world", font, 14, System::Drawing::Brushes::get_Yellow(), System::Drawing::Brushes::get_Red(), dataDir + u"hello2_type1_out.jpg");

Subscribe to Aspose Product Updates

Get monthly newsletters & offers directly delivered to your mailbox.