1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
#include "sys-defines.h"
#include "plot.h"
#include "extern.h"
#include "h_stick.h"
#define GOOD_PRINTABLE_ASCII(c) ((c >= 0x20) && (c <= 0x7E))
#define MIN_TERMINATOR 0x21
#define MAX_TERMINATOR 0xfe
/* forward references */
static unsigned char _label_terminator __P((const unsigned char *s));
double
#ifdef _HAVE_PROTOS
_h_falabel_pcl (const unsigned char *s, int h_just)
#else
_h_falabel_pcl (s, h_just)
const unsigned char *s;
int h_just; /* horizontal justification: JUST_LEFT, CENTER, or RIGHT */
#endif
{
int master_font_index, typeface;
double theta, costheta, sintheta;
double width;
unsigned char *t;
unsigned char terminator;
bool stick_font = false;
if (*s == (unsigned char)'\0')
return 0.0;
if (h_just != JUST_LEFT)
{
_plotter->warning ("ignoring request to use non-default justification for a label");
return 0.0;
}
/* label rotation angle in radians, in user frame */
theta = M_PI * _plotter->drawstate->text_rotation / 180.0;
sintheta = sin (theta);
costheta = cos (theta);
/* width of the string in user units */
/* N.B. we don't re-encode Stick font (see below), since it's monospaced */
width = _plotter->flabelwidth_pcl (s);
/* compute index of font in master table of PCL fonts, in g_fontdb.h */
master_font_index =
(_pcl_typeface_info[_plotter->drawstate->typeface_index].fonts)[_plotter->drawstate->font_index];
typeface = _pcl_font_info[master_font_index].pcl_typeface;
stick_font = (typeface == HPGL2_STICK);
if (stick_font)
/* font is a HP-GL/2 Stick font, which uses HP's Roman-8 encoding, so
re-encode ISO-Latin-1 as Roman-8 */
{
unsigned const char *sptr = s;
unsigned char *tptr;
t = (unsigned char *)_plot_xmalloc (strlen ((const char *)s) + 1);
tptr = t;
while (*sptr)
{
if (*sptr < 0x80)
*tptr++ = *sptr++;
else
*tptr++ = _iso_to_roman8[(*sptr++) - 0x80];
}
*tptr = '\0';
/* shift rightward to compensate for the fact that characters in
fixed-width Stick fonts are off-center, positioned in the left
2/3 of the cell */
_plotter->drawstate->pos.x +=
costheta * _plotter->drawstate->font_size / 6.0;
_plotter->drawstate->pos.y +=
sintheta * _plotter->drawstate->font_size / 6.0;
}
else
t = (unsigned char *)s;
/* sync font and pen position */
_plotter->set_font();
_plotter->set_position();
/* draw label */
terminator = _label_terminator (t);
if (t == (unsigned char)0)
_plotter->warning ("label contains too many distinct characters to be drawn");
else
{
if (terminator != _plotter->label_terminator)
{
/* output instruction, update */
sprintf (_plotter->outbuf.current, "DT%c;", (char)terminator);
_update_buffer (&_plotter->outbuf);
_plotter->label_terminator = terminator;
}
sprintf (_plotter->outbuf.current, "LB%s%c;",
t, _plotter->label_terminator);
_update_buffer (&_plotter->outbuf);
/* where is the plotter pen now located?? we don't know, exactly */
_plotter->position_is_unknown = true;
}
if (stick_font)
{
free (t);
/* undo above horizontal shift */
_plotter->drawstate->pos.x -=
costheta * _plotter->drawstate->font_size / 6.0;
_plotter->drawstate->pos.y -=
sintheta * _plotter->drawstate->font_size / 6.0;
}
/* reposition after drawing label */
_plotter->drawstate->pos.x += costheta * width;
_plotter->drawstate->pos.y += sintheta * width;
return width;
}
static unsigned char
#ifdef _HAVE_PROTOS
_label_terminator (const unsigned char *s)
#else
_label_terminator (s)
const unsigned char *s; /* label we'll be rendering */
#endif
{
unsigned char i;
for (i = MIN_TERMINATOR; i <= MAX_TERMINATOR; i++)
{
const unsigned char *sptr;
bool suitable;
sptr = s;
suitable = true;
while (*sptr)
if (*sptr++ == i)
{
suitable = false;
break; /* unsuitable */
}
if (suitable)
return i;
}
/* label contains every possible character, won't be able to render it */
return (unsigned char)0;
}
|