PfRender(), PfRenderCx()

Render a string via a user callback function

Synopsis:

#include <photon/Pf.h>
int PfRender( void *ctx,
                 const char *font,
                 long adata,
                 long bdata,
                 const char *str,
                 int len,
                 int flags,
                 PhPoint_t const *pos,
                 PhRect_t const *clip,
                 void (*func) (
                    void *, const PhPoint_t *pos,
                    const FontRender *));

#include <font_api.h>
int PfRenderCx( struct _Pf_ctrl *context,
                void *ctx,
                const char *font,
                long adata,
                long bdata,
                const char *str,
                int len,
                int flags,
                PhPoint_t const *pos,
                PhRect_t const *clip,
                void (*func) (
                   void *, const PhPoint_t *pos,
                   const FontRender *));

Arguments:

context (PfRenderCx() only)
A pointer to the font context to use, returned by PfAttachCx() or PfAttachDllCx().
ctx
A context/data pointer that's passed to the user callback, func. This value must be nonzero; if you don't want to pass a context, set this argument to 1.
font
The base font, which you should create by calling PfGenerateFontName() or PfGenerateFontNameCx().
adata
The horizontal fractional point size, if you set PF_FRACTIONAL in the flags argument.
bdata
The vertical fractional point size, if you set PF_FRACTIONAL in the flags argument.
str
The string whose extent you want to calculate. The string is a UTF-8 multibyte one by default.
len
The length of the string, str, in bytes. If len is 0, the function uses strlen(str).
flags
Flags that affect the behavior of the function.

You can set up to one of the following to indicate the format of the string:

If you don't set either of the above, the function assumes that the string is composed of UTF-8 multibyte characters.

You can OR in:

pos
A pointer to a PhPoint_t structure that specifies the location at which to render the text.
clip
A pointer to a PhRect_t that specifies the clipping rectangle for the text. If clip is NULL, it's ignored. The font server performs coarse character clipping only.
func
A user callback function that's called to render the text. It's called with the desired pen location and the metrics of the bitmap. If the entire bitmap doesn't fit in the allocated memory, multiple calls to the font server and the user function can be made, advancing the pen as appropriate between calls.

Library:

PfRender()
ph
PfRenderCx()
font

Description:

These functions render the given string via a user callback function. The difference between PfRender() and PfRenderCx() is that PfRenderCx() lets you specify the font context to use.

When a request to construct the bitmap is sent to the font server, the string bitmap is returned, for efficiency, in the shared-memory area created through the initial call to PfAttach(), PfAttachCx() or PfAttachDllCx().

Normally, only the graphics drivers use these functions, but they may be useful for application programs that have to obtain text bitmap data directly.

The generic design of these routines allows future expansion.

The FontRender metrics structure contains at least the following members:

PhPoint_t size
The bounding size of the bitmap, in pixels.
PhPoint_t offset
The offset of the bitmap (the upper-left of the extent).
int width
The width of the bitmap.
short bpl
The number of bytes per line.
short bpp
The number of bits per pixel (1 for normal output, 4 for anti-aliased).
unsigned char *bmptr
A pointer to the bitmap data (stored row-wise).

Returns:

0
Success.
-1
An error occurred; errno is set.

Examples:

PfRenderCx():

/* Render alignment example.  Demonstrates how to achieve 8-bit,
 * 32-bit, and 64-bit aligned render maps if supported by the
 * particular font server.
 */
#include <font_api.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

static int check_32 = 0;
static int bad_32 = 0;
static int check_64 = 0;
static int bad_64 = 0;

static void func(void * ctx, const pf_point_t * pos, const FontRender * render)
{
  printf("NOTE: render callback.\n");

  if(check_32)
  {  int times = render->bpl / 4;
     int total = times * 4;

     if(total != render->bpl)
       bad_32 = 1;
  }

  if(check_64)
  {  int times = render->bpl / 8;
     int total = times * 8;

     if(total != render->bpl)
       bad_64 = 1;
  }
}

int main(int argc, char const * argv[])
{  struct _Pf_ctrl * pf;

  fprintf(stderr, "POINT: PfRenderCx and bitmap alignment.\n");

  if((pf = PfAttachCx(NULL, 0)) != NULL)
  {  FontID * id;
     int skip = 0;

     if((id = PfFindFontCx(pf, "TextFont", 0L, 9)) != NULL)
     {  FontName tag;
        pf_point_t pos = { 0 , 0 };

        if((PfRenderCx(pf, pf, PfConvertFontIDCx(pf, id, tag), 0L, 0L, "TEST.",
                       0, 0, &pos, NULL, func)
           == -1) && (errno == EINVAL))
        {  if(setenv("PHFONTMEM", "32000", 1) == -1)
           {  fprintf(stderr, "NOTE: setenv failed to write to PHFONTMEM.\n");
              fprintf(stderr, "FAIL: PfRenderCx and bitmap alignment.\n");
           }
           else
           {  fprintf(stderr, "NOTE: render 8-bit aligned image.\n");

              PfDetachCx(pf);

              if((pf = PfAttachCx(NULL, -1)) != NULL)
              {  if(PfRenderCx(pf, pf, PfConvertFontIDCx(pf, id, tag), 0L, 0L,
                               "TEST.", 0, 0, &pos, NULL, func) == 0)
                 {  PfDetachCx(pf);

                    if((pf = PfAttachCx("/dev/phfont32", -1)) != NULL)
                    {  fprintf(stderr, "NOTE: render 32-bit aligned image.\n");
                       check_32 = 1;

                       if(PfRenderCx(pf, pf, PfConvertFontIDCx(pf, id, tag),
                                     0L, 0L, "TEST.", 0, 0, &pos, NULL,
                                     func) == 0)
                       {  if(bad_32)
                          {  fprintf(stderr,
                                "NOTE: PfRenderCx did not render a 32-bit \
aligned image.\n");
                             fprintf(stderr,
                                "FAIL: PfRenderCx and bitmap alignment.\n");
                          }
                          else
                          {  check_32 = 0;

                             PfDetachCx(pf);

                             if((pf = PfAttachCx("/dev/phfont64", -1)) != NULL)
                             {  fprintf(stderr,
                                   "NOTE: render 64-bit aligned image.\n");
                                check_64 = 1;

                                if(PfRenderCx(pf, pf, PfConvertFontIDCx(pf, id,
                                              tag), 0L, 0L, "TEST.", 0, 0,
                                              &pos, NULL, func) == 0)
                                {  if(bad_64)
                                   {  fprintf(stderr,
                                        "NOTE: PfRenderCx did not render a \
64-bit aligned image.\n");
                                      fprintf(stderr,
                                        "FAIL: PfRenderCx and bitmap alignment.\n");
                                   }
                                   else
                                     fprintf(stderr,
                                       "PASS: PfRenderCx and bitmap alignment.\n");
                                }
                                else
                                {  fprintf(stderr,
                                      "NOTE: PfRenderCx failed, errno %d.\n",
                                      errno);
                                   fprintf(stderr,
                                      "FAIL: PfRenderCx and bitmap alignment.\n");
                                }
                             }
                             else
                             {  fprintf(stderr,
                                  "UNRES: Unable to attach to fontserver, \
errno %d.\n", errno);
                                fprintf(stderr,
                                   "FAIL: PfRenderCx and bitmap alignment.\n");
                                skip = 1;
                             }
                          }
                       }
                       else
                       {  fprintf(stderr, "NOTE: PfRenderCx failed, errno %d.\n",
                                  errno);
                          fprintf(stderr,
                            "FAIL: PfRenderCx and bitmap alignment.\n");
                       }
                    }
                    else
                    {  fprintf(stderr,
                          "UNRES: Unable to attach to fontserver, errno %d.\n",
                          errno);
                       fprintf(stderr, "FAIL: PfRenderCx and bitmap alignment.\n");
                       skip = 1;
                    }
                 }
                 else
                 {  fprintf(stderr, "NOTE: PfRenderCx failed, errno %d.\n", errno);
                    fprintf(stderr, "FAIL: PfRenderCx and bitmap alignment.\n");
                 }
              }
              else
              {  fprintf(stderr, "UNRES: PfAttachCx failed, errno %d.\n", errno);
                 fprintf(stderr, "FAIL: PfRenderCx and bitmap alignment.\n");
              }
           }
        }
        else
        {  fprintf(stderr,
              "NOTE: PfRenderCx returned success with invalid render buffer.\n");
           fprintf(stderr, "FAIL: PfRenderCx and bitmap alignment.\n");
        }

        if(PfFreeFontCx(pf, id) == -1L)
        {  fprintf(stderr, "NOTE: PfFreeFontCx failed, errno %d.\n", errno);
        }
     }
     else
     {  fprintf(stderr, "NOTE: PfFindFontCx failed to create font id, errno %d.\n",
                errno);
        fprintf(stderr, "FAIL: PfRenderCx and bitmap alignment.\n");
     }

     if(!skip)
       PfDetachCx(pf);
  }
  else
  {  fprintf(stderr, "UNRES: Unable to attach to fontserver, errno %d.\n", errno);
     fprintf(stderr, "FAIL: PfRenderCx and bitmap alignment.\n");
  }

  return(0);
}

Classification:

Photon

PfRender()

Safety:
Interrupt handler No
Signal handler No
Thread No

PfRenderCx()

Safety:
Interrupt handler No
Signal handler No
Thread Yes

See also:

PfAttach(), PfAttachCx(), PfDetach(), PfDetachCx(), PfGenerateFontName(), PfGenerateFontNameCx(), PhPoint_t, PhRect_t