📄 type1.c
字号:
ClearStack(); ClearPSFakeStack(); ClearCallStack(); FinitStems(); InitStems(); for (;;) { if (!DoRead(&Code)) break; Decode(Code); if (errflag) return; } path = Join(mypath, path);} /* |- sbx sby wx wy SBW |- *//* Set the left sidebearing point to (sbx,sby), *//* set the character width vector to (wx,wy). */static Sbw(sbx, sby, wx, wy) double sbx, sby, wx, wy;{ IfTrace4((FontDebug), "SBW %f %f %f %f\n", &sbx, &sby, &wx, &wy); escapementX = wx; /* Character width vector */ escapementY = wy; /* Sidebearing values are sbx, sby args, plus accent offset from Seac(). */ sidebearingX = sbx + accentoffsetX; sidebearingY = sby + accentoffsetY; path = Join(path, Loc(CharSpace, sidebearingX, sidebearingY)); if (ProcessHints) {currx = sidebearingX; curry = sidebearingY;}} /* num1 num2 DIV quotient *//* Behaves like DIV in the PostScript language */static double Div(num1, num2) double num1, num2;{ IfTrace2((FontDebug), "Div %f %f\n", &num1, &num2); return(num1 / num2);} /* The following four subroutines (FlxProc, FlxProc1, FlxProc2, and HintReplace) are C versions of the OtherSubrs Programs, which were were published in the Adobe Type 1 Font Format book. The Flex outline fragment is described by c1: (x0, y0) = c3: (x0, yshrink(y0)) or (xshrink(x0), y0) " (x1, y1) = " (x1, yshrink(y1)) or (xshrink(x1), y1) " (x2, y2) - reference point c2: (x0, y0) = c4: (x0, yshrink(y0)) or (xshrink(x0), y0) " (x1, y1) = " (x1, yshrink(y1)) or (xshrink(x1), y1) " (x2, y2) = " (x2, y2), rightmost endpoint c3: (x0, y0) - control point, 1st Bezier curve " (x1, y1) - control point, -"- " (x2, y2) - end point, -"- c4: (x0, y0) - control point, 2nd Bezier curve " (x1, y1) - control point, -"- " (x2, y2) - end point, -"- ep: (epY, epX) - final endpoint (should be same as c4: (x2, y2)) idmin - minimum Flex height (1/100 pixel) at which to render curves*/ #define dtransform(dxusr,dyusr,dxdev,dydev) { \ register struct segment *point = Loc(CharSpace, dxusr, dyusr); \ QueryLoc(point, IDENTITY, dxdev, dydev); \ Destroy(point); \} #define itransform(xdev,ydev,xusr,yusr) { \ register struct segment *point = Loc(IDENTITY, xdev, ydev); \ QueryLoc(point, CharSpace, xusr, yusr); \ Destroy(point); \} #define transform(xusr,yusr,xdev,ydev) dtransform(xusr,yusr,xdev,ydev) #define PaintType (0) #define lineto(x,y) { \ struct segment *CurrentPoint; \ double CurrentX, CurrentY; \ CurrentPoint = Phantom(path); \ QueryLoc(CurrentPoint, CharSpace, &CurrentX, &CurrentY); \ Destroy(CurrentPoint); \ RLineTo(x - CurrentX, y - CurrentY); \} #define curveto(x0,y0,x1,y1,x2,y2) { \ struct segment *CurrentPoint; \ double CurrentX, CurrentY; \ CurrentPoint = Phantom(path); \ QueryLoc(CurrentPoint, CharSpace, &CurrentX, &CurrentY); \ Destroy(CurrentPoint); \ RRCurveTo(x0 - CurrentX, y0 - CurrentY, x1 - x0, y1 - y0, x2 - x1, y2 - y1); \} #define xshrink(x) ((x - c4x2) * shrink +c4x2)#define yshrink(y) ((y - c4y2) * shrink +c4y2) #define PickCoords(flag) \ if (flag) { /* Pick "shrunk" coordinates */ \ x0 = c1x0; y0 = c1y0; \ x1 = c1x1; y1 = c1y1; \ x2 = c1x2; y2 = c1y2; \ x3 = c2x0; y3 = c2y0; \ x4 = c2x1; y4 = c2y1; \ x5 = c2x2; y5 = c2y2; \ } else { /* Pick original coordinates */ \ x0 = c3x0; y0 = c3y0; \ x1 = c3x1; y1 = c3y1; \ x2 = c3x2; y2 = c3y2; \ x3 = c4x0; y3 = c4y0; \ x4 = c4x1; y4 = c4y1; \ x5 = c4x2; y5 = c4y2; \ } /* FlxProc() = OtherSubrs[0]; Main part of Flex *//* Calling sequence: 'idmin epX epY 3 0 callothersubr' *//* Computes Flex values, and renders the Flex path, *//* and returns (leaves) ending coordinates on stack */static void FlxProc(c1x2, c1y2, c3x0, c3y0, c3x1, c3y1, c3x2, c3y2, c4x0, c4y0, c4x1, c4y1, c4x2, c4y2, epY, epX, idmin) double c1x2, c1y2; double c3x0, c3y0, c3x1, c3y1, c3x2, c3y2; double c4x0, c4y0, c4x1, c4y1, c4x2, c4y2; double epX, epY; int idmin;{ double dmin; double c1x0, c1y0, c1x1, c1y1; double c2x0, c2y0, c2x1, c2y1, c2x2, c2y2; char yflag; double x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5; double cxx, cyx, cxy, cyy; /* Transformation matrix */ int flipXY; double x, y; double erosion = 1; /* Device parameter */ /* Erosion may have different value specified in 'internaldict' */ double shrink; double dX, dY; char erode; double eShift; double cx, cy; double ex, ey; Destroy(path); path = FlxOldPath; /* Restore previous path (stored in FlxProc1) */ if (ProcessHints) { dmin = ABS(idmin) / 100.0; /* Minimum Flex height in pixels */ c2x2 = c4x2; c2y2 = c4y2; /* Point c2 = c4 */ yflag = FABS(c1y2 - c3y2) > FABS(c1x2 - c3x2); /* Flex horizontal? */ QuerySpace(CharSpace, &cxx, &cyx, &cxy, &cyy); /* Transformation matrix */ if (FABS(cxx) < 0.00001 || FABS(cyy) < 0.00001) flipXY = -1; /* Char on side */ else if (FABS(cyx) < 0.00001 || FABS(cxy) < 0.00001) flipXY = 1; /* Char upright */ else flipXY = 0; /* Char at angle */ if (yflag) { /* Flex horizontal */ if (flipXY == 0 || c3y2 == c4y2) { /* Char at angle or Flex height = 0 */ PickCoords(FALSE); /* Pick original control points */ } else { shrink = FABS((c1y2 - c4y2) / (c3y2 - c4y2)); /* Slope */ c1x0 = c3x0; c1y0 = yshrink(c3y0); c1x1 = c3x1; c1y1 = yshrink(c3y1); c2x0 = c4x0; c2y0 = yshrink(c4y0); c2x1 = c4x1; c2y1 = yshrink(c4y1); dtransform(0.0, ROUND(c3y2-c1y2), &x, &y); /* Flex height in pixels */ dY = FABS((flipXY == 1) ? y : x); PickCoords(dY < dmin); /* If Flex small, pick 'shrunk' control points */ if (FABS(y2 - c1y2) > 0.001) { /* Flex 'non-zero'? */ transform(c1x2, c1y2, &x, &y); if (flipXY == 1) { cx = x; cy = y; } else { cx = y; cy = x; } dtransform(0.0, ROUND(y2-c1y2), &x, &y); dY = (flipXY == 1) ? y : x; if (ROUND(dY) != 0) dY = ROUND(dY); else dY = (dY < 0) ? -1 : 1; erode = PaintType != 2 && erosion >= 0.5; if (erode) cy -= 0.5; ey = cy + dY; ey = CEIL(ey) - ey + FLOOR(ey); if (erode) ey += 0.5; if (flipXY == 1) { itransform(cx, ey, &x, &y); } else { itransform(ey, cx, &x, &y); } eShift = y - y2; y1 += eShift; y2 += eShift; y3 += eShift; } } } else { /* Flex vertical */ if (flipXY == 0 || c3x2 == c4x2) { /* Char at angle or Flex height = 0 */ PickCoords(FALSE); /* Pick original control points */ } else { shrink = FABS((c1x2 - c4x2) / (c3x2 - c4x2)); /* Slope */ c1x0 = xshrink(c3x0); c1y0 = c3y0; c1x1 = xshrink(c3x1); c1y1 = c3y1; c2x0 = xshrink(c4x0); c2y0 = c4y0; c2x1 = xshrink(c4x1); c2y1 = c4y1; dtransform(ROUND(c3x2 - c1x2), 0.0, &x, &y); /* Flex height in pixels */ dX = FABS((flipXY == -1) ? y : x); PickCoords(dX < dmin); /* If Flex small, pick 'shrunk' control points */ if (FABS(x2 - c1x2) > 0.001) { transform(c1x2, c1y2, &x, &y); if (flipXY == -1) { cx = y; cy = x; } else { cx = x; cy = y; } dtransform(ROUND(x2-c1x2), 0.0, &x, &y); dX = (flipXY == -1) ? y : x; if (ROUND(dX) != 0) dX = ROUND(dX); else dX = (dX < 0) ? -1 : 1; erode = PaintType != 2 && erosion >= 0.5; if (erode) cx -= 0.5; ex = cx + dX; ex = CEIL(ex) - ex + FLOOR(ex); if (erode) ex += 0.5; if (flipXY == -1) { itransform(cy, ex, &x, &y); } else { itransform(ex, cy, &x, &y); } eShift = x - x2; x1 += eShift; x2 += eShift; x3 += eShift; } } } if (x2 == x5 || y2 == y5) { lineto(x5, y5); } else { curveto(x0, y0, x1, y1, x2, y2); curveto(x3, y3, x4, y4, x5, y5); } } else { /* ProcessHints is off */ PickCoords(FALSE); /* Pick original control points */ curveto(x0, y0, x1, y1, x2, y2); curveto(x3, y3, x4, y4, x5, y5); } PSFakePush(epY); PSFakePush(epX);} /* FlxProc1() = OtherSubrs[1]; Part of Flex *//* Calling sequence: '0 1 callothersubr' *//* Saves and clears path, then restores currentpoint */static void FlxProc1(){ struct segment *CurrentPoint; CurrentPoint = Phantom(path); FlxOldPath = path; path = CurrentPoint;} /* FlxProc2() = OtherSubrs[2]; Part of Flex *//* Calling sequence: '0 2 callothersubr' *//* Returns currentpoint on stack */static void FlxProc2(){ struct segment *CurrentPoint; double CurrentX, CurrentY; CurrentPoint = Phantom(path); QueryLoc(CurrentPoint, CharSpace, &CurrentX, &CurrentY); Destroy(CurrentPoint); /* Push CurrentPoint on fake PostScript stack */ PSFakePush(CurrentX); PSFakePush(CurrentY);} /* HintReplace() = OtherSubrs[3]; Hint Replacement *//* Calling sequence: 'subr# 1 3 callothersubr pop callsubr' *//* Reinitializes stem hint structure */static void HintReplace(){ /* Effectively retire the current stems, but keep them around for */ /* revhint use in case we are in a stem when we replace hints. */ currstartstem = numstems; /* 'subr#' is left on PostScript stack (for 'pop callsubr') */} /* arg1 ... argn n othersubr# CALLOTHERSUBR - *//* Make calls on the PostScript interpreter (or call equivalent C code) *//* NOTE: The n arguments have been pushed on the fake PostScript stack */static CallOtherSubr(othersubrno) int othersubrno;{ IfTrace1((FontDebug), "CallOtherSubr %d\n", othersubrno); switch(othersubrno) { case 0: /* OtherSubrs[0]; Main part of Flex */ if (PSFakeTop < 16) Error0("CallOtherSubr: PSFakeStack low"); ClearPSFakeStack(); FlxProc( PSFakeStack[0], PSFakeStack[1], PSFakeStack[2], PSFakeStack[3], PSFakeStack[4], PSFakeStack[5], PSFakeStack[6], PSFakeStack[7], PSFakeStack[8], PSFakeStack[9], PSFakeStack[10], PSFakeStack[11], PSFakeStack[12], PSFakeStack[13], PSFakeStack[14], PSFakeStack[15], (int) PSFakeStack[16] ); break; case 1: /* OtherSubrs[1]; Part of Flex */ FlxProc1(); break; case 2: /* OtherSubrs[2]; Part of Flex */ FlxProc2(); break; case 3: /* OtherSubrs[3]; Hint Replacement */ HintReplace(); break; default: { /* call OtherSubrs[4] or higher if PostScript is present */ } }} /* |- x y SETCURRENTPOINT |- *//* Sets the current point to (x,y) in absolute *//* character space coordinates without per- *//* forming a CharString MOVETO command */static SetCurrentPoint(x, y) double x, y;{ IfTrace2((FontDebug), "SetCurrentPoint %f %f\n", &x, &y); currx = x; curry = y;} /* The Type1Char routine for use by PostScript. *//************************************************/struct xobject *Type1Char(env, S, charstrP, subrsP, osubrsP, bluesP, modeP) char *env; struct XYspace *S; psobj *charstrP; psobj *subrsP; psobj *osubrsP; struct blues_struct *bluesP; /* FontID's ptr to the blues struct */ int *modeP;{ int Code; path = NULL; errflag = FALSE; /* Make parameters available to all Type1 routines */ Environment = env; CharSpace = S; /* used when creating path elements */ CharStringP = charstrP; SubrsP = subrsP; OtherSubrsP = osubrsP; ModeP = modeP; blues = bluesP; /* compute the alignment zones */ ComputeAlignmentZones(); StartDecrypt(); ClearStack(); ClearPSFakeStack(); ClearCallStack(); InitStems(); currx = curry = 0; escapementX = escapementY = 0; sidebearingX = sidebearingY = 0; accentoffsetX = accentoffsetY = 0; wsoffsetX = wsoffsetY = 0; /* No shift to preserve whitspace. */ wsset = 0; /* wsoffsetX,Y haven't been set yet. */ for (;;) { if (!DoRead(&Code)) break; Decode(Code); if (errflag) break; } FinitStems(); /* Clean up if an error has occurred */ if (errflag) { if (path != NULL) { Destroy(path); /* Reclaim storage */ path = NULL; /* Indicate that character could not be built */ } } return((struct xobject *) path);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -