⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 type1.c

📁 source code: Covert TXT to PDF
💻 C
📖 第 1 页 / 共 5 页
字号:
{  int i;   for (i = 0; i < numstems; i++) {    Destroy(stems[i].lbhint);    Destroy(stems[i].lbrevhint);    Destroy(stems[i].rthint);    Destroy(stems[i].rtrevhint);  }  return(0);  } /*******************************************************************//* Compute the dislocation that a stemhint should cause for points *//* inside the stem.                                                *//*******************************************************************/static int ComputeStem(stemno)int stemno;{  int verticalondevice, idealwidth;  DOUBLE stemstart, stemwidth;  struct segment *p;  int i;  DOUBLE stembottom, stemtop, flatposition;  DOUBLE Xpixels, Ypixels;  DOUBLE unitpixels, onepixel;  int suppressovershoot, enforceovershoot;  DOUBLE stemshift, flatpospixels, overshoot;  DOUBLE widthdiff; /* Number of character space units to adjust width */  DOUBLE lbhintvalue, rthintvalue;  DOUBLE cxx, cyx, cxy, cyy; /* Transformation matrix */  int rotated; /* TRUE if character is on the side, FALSE if upright */   /************************************************/  /* DETERMINE ORIENTATION OF CHARACTER ON DEVICE */  /************************************************/   QuerySpace(CharSpace, &cxx, &cyx, &cxy, &cyy); /* Transformation matrix */   if (FABS(cxx) < 0.00001 || FABS(cyy) < 0.00001)    rotated = TRUE; /* Char is on side (90 or 270 degrees), possibly oblique. */  else if (FABS(cyx) < 0.00001 || FABS(cxy) < 0.00001)    rotated = FALSE; /* Char is upright (0 or 180 degrees), possibly oblique. */  else {    stems[stemno].lbhint = NULL; /* Char is at non-axial angle, ignore hints. */    stems[stemno].lbrevhint = NULL;    stems[stemno].rthint = NULL;    stems[stemno].rtrevhint = NULL;    return(0);  }   /* Determine orientation of stem */   if (stems[stemno].vertical) {    verticalondevice = !rotated;    stemstart = stems[stemno].x;    stemwidth = stems[stemno].dx;  } else {    verticalondevice = rotated;    stemstart = stems[stemno].y;    stemwidth = stems[stemno].dy;  }   /* Determine how many pixels (non-negative) correspond to 1 character space     unit (unitpixels), and how many character space units (non-negative)     correspond to one pixel (onepixel). */   if (stems[stemno].vertical)    p = ILoc(CharSpace, 1, 0);  else    p = ILoc(CharSpace, 0, 1);  QueryLoc(p, IDENTITY, &Xpixels, &Ypixels);  Destroy(p);  if (verticalondevice)    unitpixels = FABS(Xpixels);  else    unitpixels = FABS(Ypixels);   onepixel = 1.0 / unitpixels;   /**********************/  /* ADJUST STEM WIDTHS */  /**********************/   widthdiff = 0.0;   /* Find standard stem with smallest width difference from this stem */  if (stems[stemno].vertical) { /* vertical stem */    if (blues->StdVW != 0)      /* there is an entry for StdVW */      widthdiff = blues->StdVW - stemwidth;    for (i = 0; i < blues->numStemSnapV; ++i) { /* now look at StemSnapV */      if (FABS(blues->StemSnapV[i] - stemwidth) < FABS(widthdiff))        /* this standard width is the best match so far for this stem */        widthdiff = blues->StemSnapV[i] - stemwidth;    }  } else {                      /* horizontal stem */    if (blues->StdHW != 0)      /* there is an entry for StdHW */      widthdiff = blues->StdHW - stemwidth;    for (i = 0; i < blues->numStemSnapH; ++i) { /* now look at StemSnapH */      if (FABS(blues->StemSnapH[i] - stemwidth) < FABS(widthdiff))        /* this standard width is the best match so far for this stem */        widthdiff = blues->StemSnapH[i] - stemwidth;    }  }   /* Only expand or contract stems if they differ by less than 1 pixel from     the closest standard width, otherwise make the width difference = 0. */  if (FABS(widthdiff) > onepixel)    widthdiff = 0.0;   /* Expand or contract stem to the nearest integral number of pixels. */  idealwidth = ROUND((stemwidth + widthdiff) * unitpixels);  /* Ensure that all stems are at least one pixel wide. */  if (idealwidth == 0)    idealwidth = 1;  /* Apply ForceBold to vertical stems. */  if (blues->ForceBold && stems[stemno].vertical &&      ((T1_Type1OperatorFlags & T1_IGNORE_FORCEBOLD)==0))    /* Force this vertical stem to be at least DEFAULTBOLDSTEMWIDTH wide. */    if (idealwidth < DEFAULTBOLDSTEMWIDTH)      idealwidth = DEFAULTBOLDSTEMWIDTH;  /* Now compute the number of character space units necessary */  widthdiff = idealwidth * onepixel - stemwidth;  /*********************************************************************/  /* ALIGNMENT ZONES AND OVERSHOOT SUPPRESSION - HORIZONTAL STEMS ONLY */  /*********************************************************************/   stemshift = 0.0;   if (!stems[stemno].vertical) {     /* Get bottom and top boundaries of the stem. */    stembottom = stemstart;    stemtop = stemstart + stemwidth;     /* Find out if this stem intersects an alignment zone (the BlueFuzz  */    /* entry in the Private dictionary specifies the number of character */    /* units to extend (in both directions) the effect of an alignment   */    /* zone on a horizontal stem.  The default value of BlueFuzz is 1.   */    for (i = 0; i < numalignmentzones; ++i) {      if (alignmentzones[i].topzone) {        if (stemtop >= alignmentzones[i].bottomy &&            stemtop <= alignmentzones[i].topy + blues->BlueFuzz) {          break; /* We found a top-zone */        }      } else {        if (stembottom <= alignmentzones[i].topy &&            stembottom >= alignmentzones[i].bottomy - blues->BlueFuzz) {          break; /* We found a bottom-zone */        }      }    }     if (i < numalignmentzones) { /* We found an intersecting zone (number i). */      suppressovershoot = FALSE;      enforceovershoot = FALSE;       /* When 1 character space unit is rendered smaller than BlueScale         device units (pixels), we must SUPPRESS overshoots.  Otherwise,         if the top (or bottom) of this stem is more than BlueShift character         space units away from the flat position, we must ENFORCE overshoot. */            if (unitpixels < blues->BlueScale){        suppressovershoot = TRUE;      }      else{        if (alignmentzones[i].topzone){          if (stemtop >= alignmentzones[i].bottomy + blues->BlueShift){            enforceovershoot = TRUE;	  }        else          if (stembottom <= alignmentzones[i].topy - blues->BlueShift){            enforceovershoot = TRUE;	  }	}      }                  /*************************************************/      /* ALIGN THE FLAT POSITION OF THE ALIGNMENT ZONE */      /*************************************************/       /* Compute the position of the alignment zone's flat position in         device space and the amount of shift needed to align it on a         pixel boundary. Move all stems this amount. */       if (alignmentzones[i].topzone)        flatposition = alignmentzones[i].bottomy;      else        flatposition = alignmentzones[i].topy;       /* Find the flat position in pixels */      flatpospixels = flatposition * unitpixels;       /* Find the stem shift necessary to align the flat         position on a pixel boundary, and use this shift for all stems */      stemshift = (ROUND(flatpospixels) - flatpospixels) * onepixel;       /************************************************/      /* HANDLE OVERSHOOT ENFORCEMENT AND SUPPRESSION */      /************************************************/       /* Compute overshoot amount (non-negative) */      if (alignmentzones[i].topzone)        overshoot = stemtop - flatposition;      else        overshoot = flatposition - stembottom;       if (overshoot > 0.0) {        /* ENFORCE overshoot by shifting the entire stem (if necessary) so that           it falls at least one pixel beyond the flat position. */         if (enforceovershoot){          if (overshoot < onepixel){            if (alignmentzones[i].topzone)              stemshift += onepixel - overshoot;            else              stemshift -= onepixel - overshoot;	  }	}	         /* SUPPRESS overshoot by aligning the stem to the alignment zone's           flat position. */         if (suppressovershoot){          if (alignmentzones[i].topzone)            stemshift -= overshoot;          else            stemshift += overshoot;	}      }       /************************************************************/      /* COMPUTE HINT VALUES FOR EACH SIDE OF THE HORIZONTAL STEM */      /************************************************************/       /* If the stem was aligned by a topzone, we expand or contract the stem         only at the bottom - since the stem top was aligned by the zone.         If the stem was aligned by a bottomzone, we expand or contract the stem         only at the top - since the stem bottom was aligned by the zone. */      if (alignmentzones[i].topzone) {        lbhintvalue = stemshift - widthdiff; /* bottom */        rthintvalue = stemshift;             /* top    */      } else {        lbhintvalue = stemshift;             /* bottom */        rthintvalue = stemshift + widthdiff; /* top    */      }      stems[stemno].lbhint    = (struct segment *)Permanent(Loc(CharSpace, 0.0,  lbhintvalue));      stems[stemno].lbrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -lbhintvalue));      stems[stemno].rthint    = (struct segment *)Permanent(Loc(CharSpace, 0.0,  rthintvalue));      stems[stemno].rtrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -rthintvalue));       return(0);     } /* endif (i < numalignmentzones) */     /* We didn't find any alignment zones intersecting this stem, so       proceed with normal stem alignment below. */   } /* endif (!stems[stemno].vertical) */   /* Align stem with pixel boundaries on device */  stemstart = stemstart - widthdiff / 2;  stemshift = ROUND(stemstart * unitpixels) * onepixel - stemstart;   /* Adjust the boundaries of the stem */  lbhintvalue = stemshift - widthdiff / 2; /* left  or bottom */  rthintvalue = stemshift + widthdiff / 2; /* right or top    */   if (stems[stemno].vertical) {    stems[stemno].lbhint    = (struct segment *)Permanent(Loc(CharSpace,  lbhintvalue, 0.0));    stems[stemno].lbrevhint = (struct segment *)Permanent(Loc(CharSpace, -lbhintvalue, 0.0));    stems[stemno].rthint    = (struct segment *)Permanent(Loc(CharSpace,  rthintvalue, 0.0));    stems[stemno].rtrevhint = (struct segment *)Permanent(Loc(CharSpace, -rthintvalue, 0.0));  } else {    stems[stemno].lbhint    = (struct segment *)Permanent(Loc(CharSpace, 0.0,  lbhintvalue));    stems[stemno].lbrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -lbhintvalue));    stems[stemno].rthint    = (struct segment *)Permanent(Loc(CharSpace, 0.0,  rthintvalue));    stems[stemno].rtrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -rthintvalue));  }  return(0);  } #define LEFT   1#define RIGHT  2#define BOTTOM 3#define TOP    4 /*********************************************************************//* Adjust a point using the given stem hint.  Use the left/bottom    *//* hint value or the right/top hint value depending on where the     *//* point lies in the stem.                                           *//*********************************************************************/static struct segment *Applyhint(p, stemnumber, half)struct segment *p;int stemnumber, half;{  if (half == LEFT || half == BOTTOM)    return Join(p, stems[stemnumber].lbhint); /* left  or bottom hint */  else    return Join(p, stems[stemnumber].rthint); /* right or top    hint */} /*********************************************************************//* Adjust a point using the given reverse hint.  Use the left/bottom *//* hint value or the right/top hint value depending on where the     *//* point lies in the stem.                                           *//*********************************************************************/static struct segment *Applyrevhint(p, stemnumber, half)struct segment *p;int stemnumber, half;{  if (half == LEFT || half == BOTTOM)    return Join(p, stems[stemnumber].lbrevhint); /* left  or bottom hint */  else    return Join(p, stems[stemnumber].rtrevhint); /* right or top    hint */} /***********************************************************************//* Find the vertical and horizontal stems that the current point       *//* (x, y) may be involved in.  At most one horizontal and one vertical *//* stem can apply to a single point, since there are no overlaps       *//* allowed.                                                            *//*   The actual hintvalue is returned as a location.                   *//* Hints are ignored inside a DotSection.                              *//***********************************************************************/static struct segment *FindStems(x, y, dx, dy)DOUBLE x, y, dx, dy;{  int i;  int newvert, newhor;  struct segment *p;  int newhorhalf, newverthalf;   if (InDotSection) return(NULL);   newvert = newhor = -1;  newhorhalf = newverthalf = -1;   for (i = currstartstem; i < numstems; i++) {    if (stems[i].vertical) { /* VSTEM hint */      if ((x >= stems[i].x - EPS) &&          (x <= stems[i].x+stems[i].dx + EPS)) {        newvert = i;        if (dy != 0.0) {          if (dy < 0) newverthalf = LEFT;          else        newverthalf = RIGHT;        } else {          if (x < stems[i].x+stems[i].dx / 2) newverthalf = LEFT;          else                                newverthalf = RIGHT;        }      }    } else {                 /* HSTEM hint */      if ((y >= stems[i].y - EPS) &&          (y <= stems[i].y+stems[i].dy + EPS)) {        newhor = i;        if (dx != 0.0) {          if (dx < 0) newhorhalf = TOP;          else        newhorhalf = BOTTOM;        } else {          if (y < stems[i].y+stems[i].dy / 2) newhorhalf = BOTTOM;          else                                newhorhalf = TOP;        }      }    }  }   p = NULL;   if (newvert == -1 && oldvert == -1) ; /* Outside of any hints */  else if (newvert == oldvert &&    newverthalf == oldverthalf); /* No hint change */  else if (oldvert == -1) { /* New vertical hint in effect */    p = Applyhint(p, newvert, newverthalf);  } else if (newvert == -1) { /* Old vertical hint no longer in effect */    p = Applyrevhint(p, oldvert, oldverthalf);  } else { /* New vertical hint in effect, old hint no longer in effect */    p = Applyrevhint(p, oldvert, oldverthalf);    p = Applyhint(p, newvert, newverthalf);  }   if (newhor == -1 && oldhor == -1) ; /* Outside of any hints */  else if (newhor == oldhor &&    newhorhalf == oldhorhalf) ; /* No hint change */  else if (oldhor == -1) { /* New horizontal hint in effect */    p = Applyhint(p, newhor, newhorhalf);  } else if (newhor == -1) { /* Old horizontal hint no longer in effect */    p = Applyrevhint(p, oldhor, oldhorhalf);  }  else { /* New horizontal hint in effect, old hint no longer in effect */    p = Applyrevhint(p, oldhor, oldhorhalf);    p = Applyhint(p, newhor, newhorhalf);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -