![]() |
![]() |
![]() |
![]() |
![]() |
This version of this document is no longer maintained. For the latest documentation, see http://www.qnx.com/developers/docs. |
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 |
PfAttachCx(), PfDetach(), PfDetachCx(), PfGlyph(), PfGlyphCx(), PfGenerateFontName(), PfGenerateFontNameCx(), PhPoint_t
Fonts chapter of the Photon Programmer's Guide
![]() |
![]() |
![]() |
![]() |