Back to index

tetex-bin  3.0
Defines | Functions | Variables
hints.c File Reference
#include "types.h"
#include "objects.h"
#include "spaces.h"
#include "paths.h"
#include "regions.h"
#include "hints.h"

Go to the source code of this file.

Defines

#define MAXLABEL   20
#define ODD(x)   (((int)(x)) & 01)
#define FPFLOOR(fp)   TOFRACTPEL((fp) >> FRACTBITS)
#define FPROUND(fp)   FPFLOOR((fp) + FPHALF)
#define ISTOP(flag)   ((flag)&0x20)
#define ISBOTTOM(flag)   ((flag)&0x10)
#define ISLEFT(flag)   ((flag)&0x08)
#define XofY(edge, y)   edge->xvalues[y - edge->ymin]
#define findXofY(edge, y)   ((y < edge->ymin || y >= edge->ymax) ? SearchXofY(edge, y) : XofY(edge, y))
#define ISBREAK(top, bot)   (top->ymax != bot->ymin)
#define BLACKABOVE   -1
#define BLACKBELOW   +1
#define NONE   0
#define IsValidPel(j)   (j!=MINPEL)
#define WeAreAtTop(e, i)   (ISTOP(e->flag) && e->ymin == i)
#define WeAreAtBottom(e, i)   (ISBOTTOM(e->flag) && e->ymax-1 == i)
#define WeAreInMiddle(e, i)   ((!ISTOP(e->flag) && !ISBOTTOM(e->flag))||(i < e->ymax-1 && i > e->ymin))
#define SAMESWATH(e1, e2)   (e1->ymin == e2->ymin)

Functions

void InitHints ()
void CloseHints (struct fractpoint *hintP)
static void ComputeHint (struct hintsegment *hP, fractpel currX, fractpel currY, struct fractpoint *hintP)
void ProcessHint (struct hintsegment *hP, fractpel currX, fractpel currY, struct fractpoint *hintP)
static pel SearchXofY (struct edgelist *edge, pel y)
static int ImpliedHorizontalLine (struct edgelist *e1, struct edgelist *e2, int y)
static void FixSubPaths (struct region *R)
static struct edgelistbefore ()
static void DumpSubPaths (struct edgelist *anchor)
static struct edgelistbefore (struct edgelist *e)
static void writeXofY (struct edgelist *e, int y, int x)
static void CollapseWhiteRun (struct edgelist *anchor, pel yblack, struct edgelist *left, struct edgelist *right, pel ywhite)
void ApplyContinuity (struct region *R)

Variables

struct {
int inuse
int computed
oldHint [MAXLABEL]

Define Documentation

#define BLACKABOVE   -1

Definition at line 415 of file hints.c.

#define BLACKBELOW   +1

Definition at line 416 of file hints.c.

#define findXofY (   edge,
  y 
)    ((y < edge->ymin || y >= edge->ymax) ? SearchXofY(edge, y) : XofY(edge, y))

Definition at line 354 of file hints.c.

#define FPFLOOR (   fp)    TOFRACTPEL((fp) >> FRACTBITS)

Definition at line 82 of file hints.c.

#define FPROUND (   fp)    FPFLOOR((fp) + FPHALF)

Definition at line 83 of file hints.c.

#define ISBOTTOM (   flag)    ((flag)&0x10)

Definition at line 331 of file hints.c.

#define ISBREAK (   top,
  bot 
)    (top->ymax != bot->ymin)

Definition at line 403 of file hints.c.

#define ISLEFT (   flag)    ((flag)&0x08)

Definition at line 336 of file hints.c.

#define ISTOP (   flag)    ((flag)&0x20)

Definition at line 330 of file hints.c.

#define IsValidPel (   j)    (j!=MINPEL)

Definition at line 701 of file hints.c.

#define MAXLABEL   20

Definition at line 74 of file hints.c.

#define NONE   0

Definition at line 417 of file hints.c.

#define ODD (   x)    (((int)(x)) & 01)

Definition at line 81 of file hints.c.

#define SAMESWATH (   e1,
  e2 
)    (e1->ymin == e2->ymin)

Definition at line 734 of file hints.c.

#define WeAreAtBottom (   e,
  i 
)    (ISBOTTOM(e->flag) && e->ymax-1 == i)

Definition at line 727 of file hints.c.

#define WeAreAtTop (   e,
  i 
)    (ISTOP(e->flag) && e->ymin == i)

Definition at line 726 of file hints.c.

#define WeAreInMiddle (   e,
  i 
)    ((!ISTOP(e->flag) && !ISBOTTOM(e->flag))||(i < e->ymax-1 && i > e->ymin))

Definition at line 728 of file hints.c.

#define XofY (   edge,
  y 
)    edge->xvalues[y - edge->ymin]

Definition at line 345 of file hints.c.


Function Documentation

void ApplyContinuity ( struct region R)

Definition at line 817 of file hints.c.

{
 struct edgelist *left;
 struct edgelist *right;
 struct edgelist *edge,*e2;
 pel rightXabove,rightXbelow,leftXabove,leftXbelow;
 pel leftX,rightX;
 int i;
 LONG newcenter,abovecenter,belowcenter;
 
 FixSubPaths(R);
 if (RegionDebug >= 3)
        DumpSubPaths(R->anchor);
 left = R->anchor;
/* loop through and do all of the easy checking. ( no tops or bottoms) */
 while(VALIDEDGE(left))
 {
  right = left->link;
  for(i=left->ymin;i<left->ymax;++i)
  {
   leftX       = findXofY(left,i);
   rightX      = findXofY(right,i);
   leftXbelow  = findXofY(left,i+1);
   rightXbelow = findXofY(right,i+1);
   if(rightX <= leftX)
   {
/* then, we have a break in a near vertical line */
     leftXabove  = findXofY(left,i-1);
     rightXabove = findXofY(right,i-1);
     if( IsValidPel(leftXabove) && IsValidPel(rightXabove) )
     {
      abovecenter = leftXabove + rightXabove;
     }
     else
     {
      abovecenter = leftX + rightX;
     }
     if( IsValidPel(leftXbelow) && IsValidPel(rightXbelow) )
     {
      belowcenter = leftXbelow + rightXbelow;
     }
     else
     {
      belowcenter = leftX + rightX;
     }
     newcenter = abovecenter + belowcenter;
     if( newcenter > 4*leftX )
     {
      rightX = rightX + 1;
     }
     else if( newcenter < 4*leftX)
     {
      leftX = leftX - 1;
     }
     else
     {
      rightX = rightX + 1;
     }
     writeXofY(right,i,rightX);
     writeXofY(left,i,leftX);
     if(rightX > R->xmax) {R->xmax = rightX;}
     if(leftX < R->xmin) {R->xmin = leftX;}
   }
   if( !WeAreAtBottom(left,i) && (leftXbelow>=rightX))
   {
/* then we have a break in a near horizontal line in the middle */
    writeXofY(right,i,leftXbelow);
   }
   if( !WeAreAtBottom(right,i) && (leftX >=rightXbelow))
   {
/* then we have a break in a near horizontal line in the middle */
    writeXofY(left,i,rightXbelow);
   }
  }
  left = right->link;
 }
/*
There may be "implied horizontal lines" between edges that have
implications for continuity.  This loop looks for white runs that
have implied horizontal lines on the top or bottom, and calls
CollapseWhiteRuns to check and fix any continuity problems from
them.
*/
      for (edge = R->anchor; VALIDEDGE(edge); edge = edge->link) {
              if ((!ISTOP(edge->flag) && !ISBOTTOM(edge->flag)) || ISLEFT(edge->flag))
                      continue;  /* at some future date we may want left edge logic here too */
              for (e2 = edge->link; VALIDEDGE(e2) && SAMESWATH(edge,e2); e2 = e2->link) {
                      if (ISTOP(e2->flag) && ISTOP(edge->flag)
                          && NONE != ImpliedHorizontalLine(edge,e2,edge->ymin)) {
                              if (ISLEFT(e2->flag))
                                      CollapseWhiteRun(R->anchor, edge->ymin-1,
                                                       edge, e2, edge->ymin);
                      }
                      if (ISBOTTOM(e2->flag) && ISBOTTOM(edge->flag)
                          && NONE != ImpliedHorizontalLine(edge,e2, edge->ymax)) {
                              if (ISLEFT(e2->flag))
                                      CollapseWhiteRun(R->anchor, edge->ymax,
                                                       edge, e2, edge->ymax-1);
                      }
              }
      }
}

Here is the call graph for this function:

static struct edgelist* before ( ) [static, read]
static struct edgelist* before ( struct edgelist e) [static, read]

Definition at line 679 of file hints.c.

{
       struct edgelist *r;
       for (r = e->subpath; r->subpath != e; r = r->subpath) { ; }
       return(r);
}
void CloseHints ( struct fractpoint hintP)

Definition at line 100 of file hints.c.

{
  int i;
 
  for (i = 0; i < MAXLABEL; i++)
    {
    if (oldHint[i].inuse)
      {
      hintP->x -= oldHint[i].hint.x;
      hintP->y -= oldHint[i].hint.y;
 
      oldHint[i].inuse = FALSE;
 
      IfTrace3((HintDebug > 1),"  Hint %d was open, hint=(%dl,%dl)\n",
                i, hintP->x, hintP->y);
      }
    }
}
static void CollapseWhiteRun ( struct edgelist anchor,
pel  yblack,
struct edgelist left,
struct edgelist right,
pel  ywhite 
) [static]

Definition at line 746 of file hints.c.

{
       struct edgelist *edge;
       struct edgelist *swathstart = anchor;
       register pel x;
 
       if (XofY(left, ywhite) >= XofY(right, ywhite))
               return;
/*
Find the swath with 'yblack'.  If we don't find it, completely collapse
the white run and return:
*/
       while (VALIDEDGE(swathstart)) {
               if (yblack < swathstart->ymin)  {
                      writeXofY(left, ywhite, XofY(right, ywhite));
                      return;
               }
               if (yblack < swathstart->ymax) break;
               swathstart = swathstart->link->link;
       }
       if(!VALIDEDGE(swathstart)) {
               writeXofY(left, ywhite, XofY(right, ywhite));
               return;
       }
/*
Now we are in the swath that contains 'y', the reference line above
or below that we are trying to maintain continuity with.  If black
in this line begins in the middle of our white run, we must collapse
the white run from the left to that point.  If black ends in the
middle of our white run, we must collapse the white run from the right
to that point.
*/
       for (edge = swathstart; VALIDEDGE(edge); edge = edge->link) {
 
               if (!SAMESWATH(swathstart,edge))
                       break;
               if( XofY(edge, yblack) > XofY(left, ywhite)) {
                       if (ISLEFT(edge->flag)) {
                                x = XofY(edge, yblack);
                                if (XofY(right, ywhite) < x)
                                       x = XofY(right, ywhite);
                                writeXofY(left, ywhite, x);
                       }
                       else {
                                x = XofY(edge, yblack);
                                while (edge->link != NULL && SAMESWATH(edge, edge->link)
                                       && x >= XofY(edge->link, yblack) ) {
                                       edge = edge->link->link;
                                       x = XofY(edge, yblack);
                                }
                                if (x < XofY(right, ywhite))
                                       writeXofY(right, ywhite, x);
                                return;
                       }
               }
       }
       writeXofY(left, ywhite, XofY(right, ywhite));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ComputeHint ( struct hintsegment hP,
fractpel  currX,
fractpel  currY,
struct fractpoint hintP 
) [static]

Definition at line 124 of file hints.c.

{
  fractpel currRef = 0, currWidth = 0;
  int idealWidth;
  fractpel hintValue = 0;
  char orientation;
 
/*
By construction, width is never zero.  Therefore we can use the
width value to determine if the hint has been rotated by a
multiple of 90 degrees.
*/
 
  if (hP->width.y == 0)
    {
    orientation = 'v';  /* vertical */
    IfTrace0((HintDebug > 0),"  vertical hint\n");
    }
  else if (hP->width.x == 0)
    {
    orientation = 'h';  /* horizontal */
    IfTrace0((HintDebug > 0),"  horizontal hint\n");
    }
  else
    {
    IfTrace0((HintDebug > 0),"  hint not vertical or horizontal\n");
    hintP->x = hintP->y = 0;
    return;
    }
 
  /* Compute currRef and currWidth with a unit of 1 pel */
  if (orientation == 'v')      /* vertical */
    {
    currRef = hP->ref.x + currX;
    currWidth = ABS(hP->width.x);
    }
  else if (orientation == 'h') /* horizontal */
    {
    currRef = hP->ref.y + currY;
    currWidth = ABS(hP->width.y);
    }
  else                             /* error */
    {
    t1_abort("ComputeHint: invalid orientation");
    }
 
  IfTrace4((HintDebug > 1),
    "  currX=%dl, currY=%dl, currRef=%dl, currWidth=%dl\n",
    currX, currY,
    currRef, currWidth);
 
  if ((hP->hinttype == 'b')      /* Bar or stem */
    || (hP->hinttype == 's'))    /* Serif */
    {
    idealWidth = NEARESTPEL(currWidth);
    if (idealWidth == 0) idealWidth = 1;
    if (ODD(idealWidth))         /* Is ideal width odd? */
      {
      /* center "ref" over pel */
      hintValue = FPFLOOR(currRef) + FPHALF - currRef;
      }
    else
      {
      /* align "ref" on pel boundary */
      hintValue = FPROUND(currRef) - currRef;
      }
    if (HintDebug > 2) {
          IfTrace1(TRUE,"  idealWidth=%d, ", idealWidth);
      }
    }
  else if (hP->hinttype == 'c')  /* Curve extrema */
    {
    /* align "ref" on pel boundary */
    hintValue = FPROUND(currRef) - currRef;
    }
  else                           /* error */
    {
    t1_abort("ComputeHint: invalid hinttype");
    }
 
  IfTrace1((HintDebug > 1),"  hintValue=%dl", hintValue);
 
  if (orientation == 'v')      /* vertical */
    {
    hintP->x = hintValue;
    hintP->y = 0;
    }
  else if (orientation == 'h') /* horizontal */
    {
    hintP->x = 0;
    hintP->y = hintValue;
    }
  else                             /* error */
    {
    t1_abort("ComputeHint: invalid orientation");
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void DumpSubPaths ( struct edgelist anchor) [static]

Definition at line 635 of file hints.c.

{
 
       register struct edgelist *edge,*e,*e2;
       pel y;
 
       for (edge = anchor; VALIDEDGE(edge); edge = edge->link) {
               if (ISPERMANENT(edge->flag))
                       continue;
               IfTrace0(TRUE, "BEGIN Subpath\n");
               for (e2 = edge; !ISPERMANENT(e2->flag);) {
                       if (ISDOWN(e2->flag)) {
                               IfTrace1(TRUE, ". Downgoing edge's top at %p\n", e2);
                               for (e = e2;; e = e->subpath) {
                                       IfTrace4(TRUE, ". . [%5d] %5d    @ %p[%x]\n",
                                                e->ymin, *e->xvalues, e, e->flag);
                                       for (y=e->ymin+1; y < e->ymax; y++)
                                               IfTrace2(TRUE, ". . [%5d] %5d     \"\n", y, e->xvalues[y-e->ymin]);
                                       e->flag |= ISPERMANENT(ON);
                                       if (ISBREAK(e, e->subpath))
                                               break;
                               }
                       }
                       else {
                               IfTrace1(TRUE, ". Upgoing edge's top at %p\n", e2);
                               for (e = e2; !ISBREAK(e, e->subpath); e = e->subpath) { ; }
                               for (;; e=before(e)) {
                                       IfTrace4(TRUE, ". . [%5d] %5d    @ %p[%x]\n",
                                                e->ymax-1, e->xvalues[e->ymax-1-e->ymin], e, e->flag);
                                       for (y=e->ymax-2; y >= e->ymin; y--)
                                               IfTrace2(TRUE, ". . [%5d] %5d      \"\n", y, e->xvalues[y-e->ymin]);
                                       e->flag |= ISPERMANENT(ON);
                                       if (e == e2)
                                               break;
                               }
                       }
                       do {
                               e2 = before(e2);
                       } while (!ISBREAK(before(e2), e2));
               }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void FixSubPaths ( struct region R) [static]

Definition at line 490 of file hints.c.

{
       register struct edgelist *e;     /* fast loop variable                */
       register struct edgelist *edge;  /* current edge in region            */
       register struct edgelist *next;  /* next in subpath after 'edge'      */
       register struct edgelist *break1;  /* first break after 'next'        */
       register struct edgelist *break2 = NULL;  /* last break before 'edge'        */
       register struct edgelist *prev;    /* previous edge for fixing links  */
       int left = TRUE;
 
       for (edge = R->anchor; edge != NULL; edge = edge->link) {
 
               if (left)
                       edge->flag |= ISLEFT(ON);
               left = !left;
 
               next = edge->subpath;
 
               if (!ISBREAK(edge, next))
                       continue;
               if (edge->ymax < next->ymin)
                       t1_abort("disjoint subpath?");
/*
'edge' now contains an edgelist at the bottom of an edge, and 'next'
contains the next subsequent edgelist in the subpath, which must be at
the top.  We refer to this a "break" in the subpath.
*/
               next->flag |= ISTOP(ON);
               edge->flag |= ISBOTTOM(ON);
 
               if (ISDOWN(edge->flag) != ISDOWN(next->flag))
                       continue;
/*
We are now in the unusual case; both edges are going in the same
direction so this must be a "false break" due to the way that the user
created the path.  We'll have to fix it.
*/
               for (break1 = next; !ISBREAK(break1, break1->subpath); break1 = break1->subpath) { ; }
 
               for (e = break1->subpath; e != edge; e = e->subpath)
                       if (ISBREAK(e, e->subpath))
                               break2 = e;
/*
Now we've set up 'break1' and 'break2'.  I've found the following
diagram invaluable.  'break1' is the first break after 'next'.  'break2'
is the LAST break before 'edge'.
&drawing.
         next
        +------+     +---->+------+
   +--->|    >-----+ |     |    >-----+
   |    |      |   | |     |      |   |
   | +-------------+ |  +-------------+
   | |  |break1|     |  |  |      |
   | +->|    >-------+  +->|    >-----+
   |    |      |           |      |   |
   |    |      |        +-------------+
   |    +------+        |  |      |
   | +----------------+ |  |      |
   | |  +------+      | +->|    >-----+
   | +->|    >-----+  |    |      |   |
   |    |      |   |  | +-------------+
   | +-------------+  | |  |      |
   | |  |edge  |      | |  |break2|
   | +->|    >-----+  | +->|    >-----+
   |    |      |   |  |    |      |   |
   |    |      |   |  |    |      |   |
   |    |      |   |  |    |      |   |
   |    +------+   |  |    +------+   |
   |               |  |               |
   +---------------+  +---------------+
 
&edrawing.
We want to fix this situation by having 'edge' point to where 'break1'
now points, and having 'break1' point to where 'break2' now points.
Finally, 'break2' should point to 'next'.  Also, we observe that
'break1' can't be a bottom, and is also not a top unless it is the same
as 'next':
*/
               edge->subpath = break1->subpath;
 
               break1->subpath = break2->subpath;
               if (ISBREAK(break1, break1->subpath))
                       t1_abort("unable to fix subpath break?");
 
               break2->subpath = next;
 
               break1->flag &= ~ISBOTTOM(ON);
               if (break1 != next)
                       break1->flag &= ~ISTOP(ON);
       }
/*
This region might contain "ambiguous" edges; edges exactly equal to
edge->link.  Due to the random dynamics of where they get sorted into
the list, they can yield false crossings, where the edges appear
to cross.  This confuses our continuity logic no end.  Since we can
swap them without changing the region, we do.
*/
       for (edge = R->anchor, prev = NULL; VALIDEDGE(edge); prev = edge, edge = prev->link) {
 
               if (! ISAMBIGUOUS(edge->flag))
                       continue;
 
               next = edge->subpath;
 
               while (ISAMBIGUOUS(next->flag) && next != edge)
                       next = next->subpath;
/*
We've finally found a non-ambiguous edge; we make sure it is left/right
compatible with 'edge':
*/
               if ( (ISLEFT(edge->flag) == ISLEFT(next->flag) && ISDOWN(edge->flag) == ISDOWN(next->flag) )
                    || (ISLEFT(edge->flag) != ISLEFT(next->flag) && ISDOWN(edge->flag) != ISDOWN(next->flag) ) )
                       continue;
 
/*
Incompatible, we will swap 'edge' and the following edge in the list.
You may think that there must be a next edge in this swath.  So did I.
No!  If there is a totally ambiguous inner loop, for example, we could
get all the way to the outside without resolving ambiguity.
*/
               next = edge->link;  /* note new meaning of 'next' */
               if (next == NULL || edge->ymin != next->ymin)
                       continue;
               if (prev == NULL)
                       R->anchor = next;
               else
                       prev->link = next;
               edge->link = next->link;
               next->link = edge;
               edge->flag ^= ISLEFT(ON);
               edge->flag &= ~ISAMBIGUOUS(ON);
               next->flag ^= ISLEFT(ON);
               next->flag &= ~ISAMBIGUOUS(ON);
               edge = next;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ImpliedHorizontalLine ( struct edgelist e1,
struct edgelist e2,
int  y 
) [static]

Definition at line 419 of file hints.c.

{
       register struct edgelist *e3,*e4;
 
       if (ISDOWN(e1->flag) == ISDOWN(e2->flag))
               return(NONE);  /* can't be consecutive unless different directions */
/*
Now we check for consecutiveness:  Can we get from 'e1' to 'e2' with
only one intervening break?  Can we get from 'e2' to 'e1' with only one
intervening break?  'e3' will be as far as we can get after 'e1'; 'e4'
will be has far as we can get after 'e2':
*/
       for (e3 = e1; !ISBREAK(e3, e3->subpath); e3 = e3->subpath) { ; }
       for (e3 = e3->subpath; e3 != e2; e3 = e3->subpath)
               if (ISBREAK(e3, e3->subpath))
                       break;
 
       for (e4 = e2; !ISBREAK(e4, e4->subpath); e4 = e4->subpath) { ; }
       for (e4 = e4->subpath; e4 != e1; e4 = e4->subpath)
               if (ISBREAK(e4, e4->subpath))
                       break;
/*
If the edges are mutually consecutive, we must have horizontal lines
both top and bottom:
*/
       if (e3 == e2 && e4 == e1)
               return(TRUE);
/*
If the edges are not consecutive either way, no horizontal lines are
possible:
*/
       if (e3 != e2 && e4 != e1)
               return(NONE);
/*
Now let's swap 'e1' and 'e2' if necessary to enforce the rule that 'e2'
follows 'e1'.  Remember that subpath chains go in the opposite direction
from the way the subpaths were built; this led to the simplest way
do build them.
*/
       if (e4 != e1) {
               e2 = e1;
               e1 = e3;  /* remember e3 == e2, this just swaps 'e1' and 'e2' */
       }
/*
Now we have everything to return the answer:
*/
       if (ISTOP(e1->flag) && y == e1->ymin)
               return(ISDOWN(e2->flag));
       else if (ISBOTTOM(e1->flag) && y == e1->ymax)
               return(!ISDOWN(e2->flag));
       else
               t1_abort("ImpliedHorizontalLine:  why ask?");
       /*NOTREACHED*/
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 85 of file hints.c.

{
  int i;
 
  for (i = 0; i < MAXLABEL; i++)
    {
    oldHint[i].inuse    = FALSE;
    oldHint[i].computed = FALSE;
    }
}
void ProcessHint ( struct hintsegment hP,
fractpel  currX,
fractpel  currY,
struct fractpoint hintP 
)

Definition at line 229 of file hints.c.

{
  struct fractpoint thisHint;
 
  IfTrace4((HintDebug > 1),"  ref=(%dl,%dl), width=(%dl,%dl)",
      hP->ref.x, hP->ref.y,
      hP->width.x, hP->width.y);
  IfTrace4((HintDebug > 1),", %c %c %c %c",
      hP->orientation, hP->hinttype,
      hP->adjusttype, hP->direction);
  IfTrace1((HintDebug > 1),", label=%d\n", hP->label);
 
  if ((hP->adjusttype == 'm')      /* Move */
    || (hP->adjusttype == 'a'))    /* Adjust */
    {
    /* Look up hint in oldHint table */
    if ((hP->label >= 0) && (hP->label < MAXLABEL))
      {
      if (oldHint[hP->label].computed)
        /* Use old hint value if already computed */
        {
        thisHint.x = oldHint[hP->label].hint.x;
        thisHint.y = oldHint[hP->label].hint.y;
        oldHint[hP->label].inuse    = TRUE;
        }
      else
        /* Compute new value for hint and store it for future use */
        {
        ComputeHint(hP, currX, currY, &thisHint);
 
        oldHint[hP->label].hint.x = thisHint.x;
        oldHint[hP->label].hint.y = thisHint.y;
        oldHint[hP->label].inuse    = TRUE;
        oldHint[hP->label].computed = TRUE;
        }
      }
    else                             /* error */
      {
      t1_abort("ProcessHint: invalid label");
      }
    }
  else if (hP->adjusttype == 'r')  /* Reverse */
    {
    /* Use the inverse of the existing hint value to reverse hint */
    if ((hP->label >= 0) && (hP->label < MAXLABEL))
      {
      if (oldHint[hP->label].inuse)
        {
        thisHint.x = -oldHint[hP->label].hint.x;
        thisHint.y = -oldHint[hP->label].hint.y;
        oldHint[hP->label].inuse = FALSE;
        }
      else                           /* error */
        {
        t1_abort("ProcessHint: label is not in use");
        }
      }
    else                           /* error */
      {
      t1_abort("ProcessHint: invalid label");
      }
 
    }
  else                           /* error */
    {
    t1_abort("ProcessHint: invalid adjusttype");
    }
  IfTrace3((HintDebug > 1),"  label=%d, thisHint=(%dl,%dl)\n",
    hP->label, thisHint.x, thisHint.y);
 
  hintP->x += thisHint.x;
  hintP->y += thisHint.y;
 
  IfTrace2((HintDebug > 1),"  hint=(%dl,%dl)\n",
    hintP->x, hintP->y);
}

Here is the call graph for this function:

static pel SearchXofY ( struct edgelist edge,
pel  y 
) [static]

Definition at line 366 of file hints.c.

{
       register struct edgelist *e;  /* loop variable                        */
 
       if (y < edge->ymin) {
               if (ISTOP(edge->flag))
                       return(MINPEL);
               for (e = edge->subpath; e->subpath != edge; e = e->subpath) { ; }
               if (e->ymax == edge->ymin)
                        return(XofY(e, y));
       }
       else if (y >= edge->ymax) {
               if (ISBOTTOM(edge->flag))
                       return(MINPEL);
               e = edge->subpath;
               if (e->ymin == edge->ymax)
                         return(XofY(e, y));
       }
       else
               return(XofY(edge, y));
 
       t1_abort("bad subpath chain");

       /*NOTREACHED*/
       return MINPEL;
}

Here is the call graph for this function:

static void writeXofY ( struct edgelist e,
int  y,
int  x 
) [static]

Definition at line 712 of file hints.c.

{
       if (e->xmin > x)  e->xmin = x;
       if (e->xmax < x)  e->xmax = x;
       e->xvalues[y - e->ymin] = x;
}

Here is the caller graph for this function:


Variable Documentation

struct { ... } oldHint[MAXLABEL] [static]