Files
Arquivotheca.SunOS-4.1.4/usr.lib/libpixrect/pr/pf_text.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

183 lines
4.0 KiB
C

#ifndef lint
static char sccsid[] = "@(#)pf_text.c 1.1 94/10/31 SMI";
#endif
/*
* Copyright 1986 by Sun Microsystems, Inc.
*/
/*
* Rasterop up a text string in a specified Pixfont.
*/
#include <sys/types.h>
#include <pixrect/pixrect.h>
#include <pixrect/pixfont.h>
struct pr_size pf_textbatch();
pf_text(prpos, op, pf, str)
struct pr_prpos prpos;
int op;
Pixfont *pf;
char *str;
{
register int rmdr = strlen((char *) str), len, errors = 0;
int prplen;
struct pr_size pr_size;
struct pr_prpos prp[81];
while (rmdr > 0) {
len = rmdr;
if (len > 80)
len = 80;
prplen = len;
rmdr -= len;
pr_size = pf_textbatch(prp, &prplen, pf, str);
errors |= prs_batchrop(prpos, op, prp, prplen);
str += len;
prpos.pos.x += pr_size.x;
prpos.pos.y += pr_size.y;
}
return errors;
}
struct pr_size
pf_textbatch(dst, lenp, pf, str)
register struct pr_prpos *dst;
int *lenp;
Pixfont *pf;
register char *str;
{
register int basex = 0, basey = 0;
register struct pixchar *pc;
struct pr_size pr_size;
register int len = *lenp;
pr_size.x = 0;
pr_size.y = 0;
/*
* Place each character. Basex and basey keep track
* of the base position change which resulted from the previous
* character.
*/
while (len > 0) {
if (*str == 0) {
*lenp -= len;
break;
}
len--;
pc = &pf->pf_char[(u_char) *str++];
if (pc->pc_pr) {
dst->pr = pc->pc_pr;
/*
* Character begins at its home location.
*/
dst->pos.x = basex + pc->pc_home.x;
dst->pos.y = basey + pc->pc_home.y;
dst++;
/*
* Next character must specify an offset to return
* to the baseline (- home terms) and account for
* the width of the character (advance terms).
*/
basex = pc->pc_adv.x - pc->pc_home.x;
basey = pc->pc_adv.y - pc->pc_home.y;
} else {
/*
* Skip character, but offset next by its advance.
*/
(*lenp)--;
basex += pc->pc_adv.x;
basey += pc->pc_adv.y;
}
/*
* Accumulate advances for caller.
*/
pr_size.x += pc->pc_adv.x;
pr_size.y += pc->pc_adv.y;
}
return (pr_size);
}
pf_textbound(bound, len, pf, str)
struct pr_subregion *bound;
register int len;
register Pixfont *pf;
register char *str;
/*
* bound is set to bounding box for str, with origin at left-most
* point on the baseline for the first character.
* bound->pos is top-left corner, bound->size.x is width,
* bound->size.y is height.
* bound->pr is not modified.
* NOTE: pf_textbound must duplicate what pf_text & pf_textbatch do!
*/
{
register int basex = 0, basey = 0;
register struct pixchar *pc;
int dstposx, dstposy;
bound->pos.x = bound->pos.y = 0;
bound->size.x = bound->size.y = 0;
/*
* Place each character. Basex and basey keep track of the base
* position which resulted from the previous character.
*/
while (len > 0) {
len--;
pc = &pf->pf_char[(u_char) *str++];
if (pc->pc_pr) {
/*
* Character begins at its home location.
*/
dstposx = basex + pc->pc_home.x;
dstposy = basey + pc->pc_home.y;
if (dstposx < bound->pos.x)
bound->pos.x = dstposx;
if (dstposy < bound->pos.y)
bound->pos.y = dstposy;
/*
* Character ends where pixrect does
*/
dstposx += pc->pc_pr->pr_width;
dstposy += pc->pc_pr->pr_height;
if (dstposx > bound->pos.x + bound->size.x)
bound->size.x = dstposx - bound->pos.x;
if (dstposy > bound->pos.y + bound->size.y)
bound->size.y = dstposy - bound->pos.y;
}
basex += pc->pc_adv.x;
basey += pc->pc_adv.y;
}
}
struct pr_size
pf_textwidth(len, pf, str)
int len;
register Pixfont *pf;
register char *str;
{
struct pr_size pr_size;
register struct pixchar *pc;
register int firstchar = 1;
u_char ch;
pr_size.x = 0;
pr_size.y = 0;
while (--len >= 0) {
ch = (u_char) *str++;
pc = &pf->pf_char[ch];
if (pc->pc_pr == 0)
pc = &pf->pf_char[' '];
if (firstchar) {
pr_size.y = (pc->pc_pr) ? pc->pc_pr->pr_height :
pf->pf_char['A'].pc_pr->pr_height;
firstchar = 0;
}
pr_size.x += pc->pc_adv.x;
pr_size.y += pc->pc_adv.y;
}
return (pr_size);
}