Get individual point information for a glyph outline
long PfGetOutline( char const *pkucFont,
unsigned long ulSymbol,
PHFONT_METRICS *ptsMetrics,
PhPoint_t **pptsPoints,
int **ppiLoops );
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)
ph
PfGetOutline() provides individual point information, in pixel coordinates, for a glyph outline. These points can be transformed in an 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).
#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 "Prima Sans 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);
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 |
PfAttach(), PfDetach(), PfGlyph(), PfGenerateFontName(), PhPoint_t
Fonts chapter of the Photon Programmer's Guide