![]()  | 
![]()  | 
![]()  | 
![]()  | 
Get individual point information for a glyph outline
#include <photon/Pf.h>
long PfGetOutline( char const *pkucFont,
                   unsigned long ulSymbol,
                   PHFONT_METRICS *ptsMetrics,
                   PhPoint_t **pptsPoints,
                   int **ppiLoops );
#include <font_api.h>
long PfGetOutlineCx( struct _Pf_ctrl *context,
                     char const *pkucFont,
                     unsigned long ulSymbol,
                     PHFONT_METRICS *ptsMetrics,
                     PhPoint_t **pptsPoints,
                     int **ppiLoops );
int32_t Advance; // 16.16 format int32_t BearingX; // 16.16 format int32_t BearingY; // 16.16 format int32_t MaxX; // 16.16 format int32_t Height; // 1.1 format (pixel) int32_t Width; // 1.1 format (pixel)
These functions provide individual point information, in pixel coordinates, for a glyph outline. These points can be transformed in any way desired. In order to fill the resultant outlines, there are several possible routes:
![]()  | 
Your application must free the memory pointed to by pptsPoints and ppiLoops. | 
PfGetOutlineCx() is similar to PfGetOutline(), but lets you specify the font context.
The number of contours that make up the outline, or -1 if an error occurred (errno is set).
PfGetOutlineCx():
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <Ph.h>
#include <Pt.h>
int draw_canvas( PtWidget_t * ptsWidget, PhTile_t * ptsDamage );
#define DESC_FONT "PrimaSans BT"
int main(int argc, char *argv[])
{  PtArg_t args[4];
   PhPoint_t win_size, pos, dim;
   PtWidget_t * wnd, * raw;
   FontName font;
   PhRect_t extent;
   long lAscender = 0L;
   PtInit (NULL);
   //  set base pwndMain parms
   win_size.x = 400;
   win_size.y = 400;
   PtSetArg(&args[0],Pt_ARG_DIM, &win_size, 0);
   PtSetArg(&args[1],Pt_ARG_WINDOW_TITLE, (long)"Outline Test", 0);
   wnd = PtCreateWidget (PtWindow, Pt_NO_PARENT, 2, args);
   if(PfGenerateFontName(DESC_FONT, 0, 36, font) == NULL)
     return(Pt_CONTINUE);
   PfExtentText(&extent, NULL, font, "M", 0);
   lAscender = 200;
   pos.y = 0;
   pos.x = 0;
   dim.x = 400;
   dim.y = (lAscender + (-extent.ul.y));
   PtSetArg(&args[0], Pt_ARG_POS, &pos, 0);
   PtSetArg(&args[1], Pt_ARG_DIM, &dim, 0);
   PtSetArg(&args[2], Pt_ARG_RAW_DRAW_F, draw_canvas, 0L);
   PtSetArg(&args[3], Pt_ARG_POINTER, font, 0L);
   raw = PtCreateWidget(PtRaw, wnd, 4, args);
   PtRealizeWidget(wnd);
   PtMainLoop ();
   return(EXIT_SUCCESS);
}
long s_lAdvanceY = 0L;
int * loops;
int draw_canvas( PtWidget_t * widget, PhTile_t * damage )
{  PgColor_t old;
   pf_point_t * pnt = NULL;
   pf_metrics_t metrics;
   long contours = 0L;
   struct _Pf_ctrl * pf;
   PhRect_t rect;
   s_lAdvanceY = 0L;
   // find our canvas
   PtCalcCanvas(widget, &rect);
   PtSuperClassDraw( PtBasic, widget, damage );
   old = PgSetStrokeColor(Pg_BLACK);
   if((pf = PfAttachCx(NULL, 0)) != NULL)
   {  char const * pfont;
      PtGetResource(widget, Pt_ARG_POINTER, &pfont, 0L);
      if((contours = PfGetOutlineCx(pf, pfont, 'i', &metrics, &pnt, &loops)) == -1L)
        return(Pt_CONTINUE);
      else
      {  PhPoint_t pos;
         long ii;
         int offset = 0;
         pos.x = (-metrics.BearingX >> 16) + rect.ul.x;
         pos.y = (metrics.BearingY >> 16) + rect.ul.y;
         for(ii = 0L; ii < contours; ii++)
         {  PgDrawPolygon(pnt + offset, loops[ii], &pos, Pg_DRAW_STROKE);
            offset += loops[ii];
         }
         free(pnt);
         free(loops);
      }
      PfDetachCx(pf);
   }
   PgSetStrokeColor(old);
   return( Pt_CONTINUE );
}
PfGetOutline():
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <Ph.h>
#include <Pt.h>
int DrawOutline( PhPoint_t * pnt, long ContourCount,
                 PhRect_t * rect, long lAscender);
int fnDrawCanvas( PtWidget_t * ptsWidget,
                  PhTile_t * ptsDamage );
PtWidget_t * pwndMain = NULL, * pobjRaw = NULL;
PhRect_t rect;
#define DESC_FONT "PrimaSans BT"
PhRect_t tsExtent;
FontName szFont;
long lAscender = 0;
int bDrawLine = 0;
int main(int argc, char *argv[])
{   PtArg_t args[4];
    PhPoint_t win_size, pntPOS, pntDIM;
    PtInit (NULL);
    if(argc > 1)
      bDrawLine = 1;
    //  set base pwndMain parms
    win_size.x = 400;
    win_size.y = 400;
    PtSetArg(&args[0],Pt_ARG_DIM, &win_size, 0);
    // window title = name  of program
    PtSetArg(&args[1],Pt_ARG_WINDOW_TITLE,
             (long)"Outline Test", 0);
    pwndMain = PtCreateWidget (PtWindow, Pt_NO_PARENT,
                               2, args);
    if(PfGenerateFontName(DESC_FONT, 0, 36,
                          szFont) == NULL)
      return(Pt_CONTINUE);
    PfExtentText(&tsExtent, NULL, szFont, "M", 0);
    lAscender = 200;
    pntPOS.y = 0;
    pntPOS.x = 0;
    pntDIM.x = 400;
    pntDIM.y = (lAscender + (-tsExtent.ul.y));
    PtSetArg(&args[0], Pt_ARG_POS, &pntPOS, 0);
    PtSetArg(&args[1], Pt_ARG_DIM, &pntDIM, 0);
    PtSetArg(&args[2], Pt_ARG_RAW_DRAW_F,
             fnDrawCanvas, 0L);
    pobjRaw = PtCreateWidget(PtRaw, pwndMain,
                             3, args);
    PtRealizeWidget(pwndMain);
    PtMainLoop ();
    return(EXIT_SUCCESS);
}
long s_lAdvanceX = 0L;
long s_lAdvanceY = 0L;
int * loops;
int fnDrawCanvas( PtWidget_t * ptsWidget,
                  PhTile_t * ptsDamage )
{   PgColor_t old;
    PhPoint_t * pnt = NULL;
    PHFONT_METRICS tsMetrics;
    long lNumContours = 0L;
    s_lAdvanceY = 0L;
    s_lAdvanceX = 0L;
    // find our canvas
    PtCalcCanvas(pobjRaw, &rect);
    PtSuperClassDraw( PtBasic, ptsWidget, ptsDamage );
    old = PgSetStrokeColor(Pg_BLACK);
    if((lNumContours =
           PfGetOutline(szFont, 'i', &tsMetrics,
                        &pnt, &loops)) == -1L)
      return(Pt_CONTINUE);
    if(tsMetrics.BearingX < 0)
      s_lAdvanceX += (-tsMetrics.BearingX +
                      0xFFFFL) >> 16;
    DrawOutline(pnt, lNumContours, &rect,
                lAscender);
    free(pnt);
    free(loops);
    s_lAdvanceX += (tsMetrics.Advance +
                    0xFFFFL) >> 16;
    if((lNumContours =
           PfGetOutline(szFont, 'o', &tsMetrics,
                        &pnt, &loops)) == -1L)
      return(Pt_CONTINUE);
    DrawOutline(pnt, lNumContours, &rect,
                lAscender);
    free(pnt);
    free(loops);
    s_lAdvanceX += (tsMetrics.Advance +
                    0xFFFFL) >> 16;
    if((lNumContours =
           PfGetOutline(szFont, 'u', &tsMetrics,
                        &pnt, &loops)) == -1L)
      return(Pt_CONTINUE);
    DrawOutline(pnt, lNumContours, &rect,
                lAscender);
    free(pnt);
    free(loops);
    s_lAdvanceX += (tsMetrics.Advance +
                    0xFFFFL) >> 16;
    if((lNumContours =
           PfGetOutline(szFont, 0x5EB3, &tsMetrics,
                        &pnt, &loops)) == -1L)
    {  printf("return failed\n");
       return(Pt_CONTINUE);
    }
    DrawOutline(pnt, lNumContours, &rect,
                lAscender);
    free(pnt);
    free(loops);
    s_lAdvanceX += (tsMetrics.Advance +
                    0xFFFFL) >> 16;
    if((lNumContours =
           PfGetOutline(szFont, 'A', &tsMetrics,
                        &pnt, &loops)) == -1L)
    {  printf("return failed\n");
       return(Pt_CONTINUE);
    }
    DrawOutline(pnt, lNumContours, &rect,
                lAscender);
    free(pnt);
    free(loops);
    PgSetStrokeColor(old);
    return( Pt_CONTINUE );
}
int DrawOutline( PhPoint_t * pnt, long ContourCount,
                 PhRect_t * rect, long lAscender)
{  unsigned long ul2 = 1L, ul1 = 0L;
   long ii = 0L, jj = 0L;
   PhPoint_t pos = { s_lAdvanceX + rect->ul.x,
                    (rect->lr.y - lAscender) };
   int offset = 0;
   PgColor_t old = PgSetFillColor(Pg_BLACK);
   for(ii = 0L; ii < ContourCount; ii++)
   {
      if(!bDrawLine)
      {  printf("PgDrawPolygon()\n");
         PgDrawPolygon(pnt + offset, loops[ii],
                       &pos, Pg_DRAW_STROKE);
         offset += loops[ii];
      }
      else if(bDrawLine)
           {  printf("PgDrawLine()\n");
              for(jj = 0; jj < loops[ii] - 1; jj++)
              {
                 PgDrawILine(pos.x + pnt[ul1].x,
                             pos.y + pnt[ul1].y,
                             pos.x + pnt[ul2].x,
                             pos.y + pnt[ul2].y);
                 ul1++, ul2++;
              }
              ul1++, ul2++;
           }
   }
   PgSetFillColor(old);
   return(0);
}
Photon
| Safety: | |
|---|---|
| Interrupt handler | No | 
| Signal handler | No | 
| Thread | No | 
| Safety: | |
|---|---|
| Interrupt handler | No | 
| Signal handler | No | 
| Thread | Yes | 
PfAttachCx(), PfDetach(), PfDetachCx(), PfGlyph(), PfGlyphCx(), PfGenerateFontName(), PfGenerateFontNameCx(), PhPoint_t
Fonts chapter of the Photon Programmer's Guide
![]()  | 
![]()  | 
![]()  | 
![]()  |