📄 type1.c
字号:
ended: Error0("Decode: Premature end of Type 1 CharString");} /* Interpret a command code */static DoCommand(Code) int Code;{ switch(Code) { case HSTEM: /* |- y dy HSTEM |- */ /* Vertical range of a horizontal stem zone */ if (Top < 1) Error0("DoCommand: Stack low\n"); HStem(Stack[0], Stack[1]); ClearStack(); break; case VSTEM: /* |- x dx VSTEM |- */ /* Horizontal range of a vertical stem zone */ if (Top < 1) Error0("DoCommand: Stack low\n"); VStem(Stack[0], Stack[1]); ClearStack(); break; case VMOVETO: /* |- dy VMOVETO |- */ /* Vertical MOVETO, equivalent to 0 dy RMOVETO */ if (Top < 0) Error0("DoCommand: Stack low\n"); RMoveTo(0.0, Stack[0]); ClearStack(); break; case RLINETO: /* |- dx dy RLINETO |- */ /* Like RLINETO in PostScript */ if (Top < 1) Error0("DoCommand: Stack low\n"); RLineTo(Stack[0], Stack[1]); ClearStack(); break; case HLINETO: /* |- dx HLINETO |- */ /* Horizontal LINETO, equivalent to dx 0 RLINETO */ if (Top < 0) Error0("DoCommand: Stack low\n"); RLineTo(Stack[0], 0.0); ClearStack(); break; case VLINETO: /* |- dy VLINETO |- */ /* Vertical LINETO, equivalent to 0 dy RLINETO */ if (Top < 0) Error0("DoCommand: Stack low\n"); RLineTo(0.0, Stack[0]); ClearStack(); break; case RRCURVETO: /* |- dx1 dy1 dx2 dy2 dx3 dy3 RRCURVETO |- */ /* Relative RCURVETO, equivalent to dx1 dy1 */ /* (dx1+dx2) (dy1+dy2) (dx1+dx2+dx3) */ /* (dy1+dy2+dy3) RCURVETO in PostScript */ if (Top < 5) Error0("DoCommand: Stack low\n"); RRCurveTo(Stack[0], Stack[1], Stack[2], Stack[3], Stack[4], Stack[5]); ClearStack(); break; case CLOSEPATH: /* - CLOSEPATH |- */ /* Closes a subpath without repositioning the */ /* current point */ DoClosePath(); ClearStack(); break; case CALLSUBR: /* subr# CALLSUBR - */ /* Calls a CharString subroutine with index */ /* subr# from the Subrs array */ if (Top < 0) Error0("DoCommand: Stack low\n"); CallSubr((int)Stack[Top--]); break; case RETURN: /* - RETURN - */ /* Returns from a Subrs array CharString */ /* subroutine called with CALLSUBR */ Return(); break; case ESCAPE: /* ESCAPE to two-byte command code */ if (!DoRead(&Code)) Error0("DoCommand: ESCAPE is last byte\n"); Escape(Code); break; case HSBW: /* |- sbx wx HSBW |- */ /* Set the left sidebearing point to (sbx,0), */ /* set the character width vector to (wx,0). */ /* Equivalent to sbx 0 wx 0 SBW. Space */ /* character should have sbx = 0 */ if (Top < 1) Error0("DoCommand: Stack low\n"); Sbw(Stack[0], 0.0, Stack[1], 0.0); ClearStack(); break; case ENDCHAR: /* - ENDCHAR |- */ /* Finishes a CharString outline */ EndChar(); ClearStack(); break; case RMOVETO: /* |- dx dy RMOVETO |- */ /* Behaves like RMOVETO in PostScript */ if (Top < 1) Error0("DoCommand: Stack low\n"); RMoveTo(Stack[0], Stack[1]); ClearStack(); break; case HMOVETO: /* |- dx HMOVETO |- */ /* Horizontal MOVETO. Equivalent to dx 0 RMOVETO */ if (Top < 0) Error0("DoCommand: Stack low\n"); RMoveTo(Stack[0], 0.0); ClearStack(); break; case VHCURVETO: /* |- dy1 dx2 dy2 dx3 VHCURVETO |- */ /* Vertical-Horizontal CURVETO, equivalent to */ /* 0 dy1 dx2 dy2 dx3 0 RRCURVETO */ if (Top < 3) Error0("DoCommand: Stack low\n"); RRCurveTo(0.0, Stack[0], Stack[1], Stack[2], Stack[3], 0.0); ClearStack(); break; case HVCURVETO: /* |- dx1 dx2 dy2 dy3 HVCURVETO |- */ /* Horizontal-Vertical CURVETO, equivalent to */ /* dx1 0 dx2 dy2 0 dy3 RRCURVETO */ if (Top < 3) Error0("DoCommand: Stack low\n"); RRCurveTo(Stack[0], 0.0, Stack[1], Stack[2], 0.0, Stack[3]); ClearStack(); break; default: /* Unassigned command code */ ClearStack(); Error1("DoCommand: Unassigned code %d\n", Code); }} static Escape(Code) int Code;{ int i, Num; struct segment *p; switch(Code) { case DOTSECTION: /* - DOTSECTION |- */ /* Brackets an outline section for the dots in */ /* letters such as "i", "j", and "!". */ DotSection(); ClearStack(); break; case VSTEM3: /* |- x0 dx0 x1 dx1 x2 dx2 VSTEM3 |- */ /* Declares the horizontal ranges of three */ /* vertical stem zones between x0 and x0+dx0, */ /* x1 and x1+dx1, and x2 and x2+dx2. */ if (Top < 5) Error0("DoCommand: Stack low\n"); if (!wsset && ProcessHints) { /* Shift the whole character so that the middle stem is centered. */ p = CenterStem(Stack[2] + sidebearingX, Stack[3]); path = Join(path, p); wsset = 1; } VStem(Stack[0], Stack[1]); VStem(Stack[2], Stack[3]); VStem(Stack[4], Stack[5]); ClearStack(); break; case HSTEM3: /* |- y0 dy0 y1 dy1 y2 dy2 HSTEM3 |- */ /* Declares the vertical ranges of three hori- */ /* zontal stem zones between y0 and y0+dy0, */ /* y1 and y1+dy1, and y2 and y2+dy2. */ if (Top < 5) Error0("DoCommand: Stack low\n"); HStem(Stack[0], Stack[1]); HStem(Stack[2], Stack[3]); HStem(Stack[4], Stack[5]); ClearStack(); break; case SEAC: /* |- asb adx ady bchar achar SEAC |- */ /* Standard Encoding Accented Character. */ if (Top < 4) Error0("DoCommand: Stack low\n"); Seac(Stack[0], Stack[1], Stack[2], (unsigned char) Stack[3], (unsigned char) Stack[4]); ClearStack(); break; case SBW: /* |- sbx sby wx wy SBW |- */ /* Set the left sidebearing point to (sbx,sby), */ /* set the character width vector to (wx,wy). */ if (Top < 3) Error0("DoCommand: Stack low\n"); Sbw(Stack[0], Stack[1], Stack[2], Stack[3]); ClearStack(); break; case DIV: /* num1 num2 DIV quotient */ /* Behaves like DIV in the PostScript language */ if (Top < 1) Error0("DoCommand: Stack low\n"); Stack[Top-1] = Div(Stack[Top-1], Stack[Top]); Top--; break; case CALLOTHERSUBR: /* arg1 ... argn n othersubr# CALLOTHERSUBR - */ /* Make calls on the PostScript interpreter */ if (Top < 1) Error0("DoCommand: Stack low\n"); Num = Stack[Top-1]; if (Top < Num+1) Error0("DoCommand: Stack low\n"); for (i = 0; i < Num; i++) PSFakePush(Stack[Top - i - 2]); Top -= Num + 2; CallOtherSubr((int)Stack[Top + Num + 2]); break; case POP: /* - POP number */ /* Removes a number from the top of the */ /* PostScript interpreter stack and pushes it */ /* onto the Type 1 BuildChar operand stack */ Push(PSFakePop()); break; case SETCURRENTPOINT: /* |- x y SETCURRENTPOINT |- */ /* Sets the current point to (x,y) in absolute */ /* character space coordinates without per- */ /* forming a CharString MOVETO command */ if (Top < 1) Error0("DoCommand: Stack low\n"); SetCurrentPoint(Stack[0], Stack[1]); ClearStack(); break; default: /* Unassigned escape code command */ ClearStack(); Error1("Escape: Unassigned code %d\n", Code); }} /* |- y dy HSTEM |- *//* Declares the vertical range of a horizontal stem zone *//* between coordinates y and y + dy *//* y is relative to the left sidebearing point */static HStem(y, dy) double y, dy;{ IfTrace2((FontDebug), "Hstem %f %f\n", &y, &dy); if (ProcessHints) { if (numstems >= MAXSTEMS) Error0("HStem: Too many hints\n"); if (dy < 0.0) {y += dy; dy = -dy;} stems[numstems].vertical = FALSE; stems[numstems].x = 0.0; stems[numstems].y = sidebearingY + y + wsoffsetY; stems[numstems].dx = 0.0; stems[numstems].dy = dy; ComputeStem(numstems); numstems++; }} /* |- x dx VSTEM |- *//* Declares the horizontal range of a vertical stem zone *//* between coordinates x and x + dx *//* x is relative to the left sidebearing point */static VStem(x, dx) double x, dx;{ IfTrace2((FontDebug), "Vstem %f %f\n", &x, &dx); if (ProcessHints) { if (numstems >= MAXSTEMS) Error0("VStem: Too many hints\n"); if (dx < 0.0) {x += dx; dx = -dx;} stems[numstems].vertical = TRUE; stems[numstems].x = sidebearingX + x + wsoffsetX; stems[numstems].y = 0.0; stems[numstems].dx = dx; stems[numstems].dy = 0.0; ComputeStem(numstems); numstems++; }} /* |- dx dy RLINETO |- *//* Behaves like RLINETO in PostScript */static RLineTo(dx, dy) double dx, dy;{ struct segment *B; IfTrace2((FontDebug), "RLineTo %f %f\n", &dx, &dy); B = Loc(CharSpace, dx, dy); if (ProcessHints) { currx += dx; curry += dy; /* B = Join(B, FindStems(currx, curry)); */ B = Join(B, FindStems(currx, curry, dx, dy)); } path = Join(path, Line(B));} /* |- dx1 dy1 dx2 dy2 dx3 dy3 RRCURVETO |- *//* Relative RCURVETO, equivalent to dx1 dy1 *//* (dx1+dx2) (dy1+dy2) (dx1+dx2+dx3) *//* (dy1+dy2+dy3) RCURVETO in PostScript */static RRCurveTo(dx1, dy1, dx2, dy2, dx3, dy3) double dx1, dy1, dx2, dy2, dx3, dy3;{ struct segment *B, *C, *D; IfTrace4((FontDebug), "RRCurveTo %f %f %f %f ", &dx1, &dy1, &dx2, &dy2); IfTrace2((FontDebug), "%f %f\n", &dx3, &dy3); B = Loc(CharSpace, dx1, dy1); C = Loc(CharSpace, dx2, dy2); D = Loc(CharSpace, dx3, dy3); if (ProcessHints) { /* For a Bezier curve, we apply the full hint value to the Bezier C point (and thereby D point). */ currx += dx1 + dx2 + dx3; curry += dy1 + dy2 + dy3; /* C = Join(C, FindStems(currx, curry)); */ C = Join(C, FindStems(currx, curry, dx3, dy3)); } /* Since XIMAGER is not completely relative, */ /* we need to add up the delta values */ C = Join(C, Dup(B)); D = Join(D, Dup(C)); path = Join(path, Bezier(B, C, D));} /* - CLOSEPATH |- *//* Closes a subpath WITHOUT repositioning the *//* current point */static DoClosePath(){ struct segment *CurrentPoint; IfTrace0((FontDebug), "DoClosePath\n"); CurrentPoint = Phantom(path); path = ClosePath(path); path = Join(Snap(path), CurrentPoint);} /* subr# CALLSUBR - *//* Calls a CharString subroutine with index *//* subr# from the Subrs array */static CallSubr(subrno) int subrno;{ IfTrace1((FontDebug), "CallSubr %d\n", subrno); if ((subrno < 0) || (subrno >= SubrsP->len)) Error0("CallSubr: subrno out of range\n"); PushCall(CharStringP, strindex, r); CharStringP = &SubrsP->data.arrayP[subrno]; StartDecrypt();} /* - RETURN - *//* Returns from a Subrs array CharString *//* subroutine called with CALLSUBR */static Return(){ IfTrace0((FontDebug), "Return\n"); PopCall(&CharStringP, &strindex, &r);} /* - ENDCHAR |- *//* Finishes a CharString outline *//* Executes SETCHACHEDEVICE using a bounding box *//* it computes directly from the character outline *//* and using the width information acquired from a previous *//* HSBW or SBW. It then calls a special version of FILL *//* or STROKE depending on the value of PaintType in the *//* font dictionary */static EndChar(){ IfTrace0((FontDebug), "EndChar\n"); /* There is no need to compute and set bounding box for the cache, since XIMAGER does that on the fly. */ /* Perform a Closepath just in case the command was left out */ path = ClosePath(path); /* Set character width */ path = Join(Snap(path), Loc(CharSpace, escapementX, escapementY)); } /* |- dx dy RMOVETO |- *//* Behaves like RMOVETO in PostScript */static RMoveTo(dx,dy) double dx,dy;{ struct segment *B; IfTrace2((FontDebug), "RMoveTo %f %f\n", &dx, &dy); B = Loc(CharSpace, dx, dy); if (ProcessHints) { currx += dx; curry += dy; /* B = Join(B, FindStems(currx, curry)); */ B = Join(B, FindStems(currx, curry, 0.0, 0.0)); } path = Join(path, B);} /* - DOTSECTION |- *//* Brackets an outline section for the dots in *//* letters such as "i", "j", and "!". */static DotSection(){ IfTrace0((FontDebug), "DotSection\n"); InDotSection = !InDotSection;} /* |- asb adx ady bchar achar SEAC |- *//* Standard Encoding Accented Character. */static Seac(asb, adx, ady, bchar, achar) double asb, adx, ady; unsigned char bchar, achar;{ int Code; struct segment *mypath; IfTrace4((FontDebug), "SEAC %f %f %f %d ", &asb, &adx, &ady, bchar); IfTrace1((FontDebug), "%d\n", achar); /* Move adx - asb, ady over and up from base char's sbpoint. */ /* (We use adx - asb to counteract the accents sb shift.) */ /* The variables accentoffsetX/Y modify sidebearingX/Y in Sbw(). */ /* Note that these incorporate the base character's sidebearing shift by */ /* using the current sidebearingX, Y values. */ accentoffsetX = sidebearingX + adx - asb; accentoffsetY = sidebearingY + ady; /* Set path = NULL to avoid complaints from Sbw(). */ path = NULL; /* Go find the CharString for the accent's code via an upcall */ CharStringP = GetType1CharString(Environment, achar); StartDecrypt(); ClearStack(); ClearPSFakeStack(); ClearCallStack(); for (;;) { if (!DoRead(&Code)) break; Decode(Code); if (errflag) return; } /* Copy snapped path to mypath and set path to NULL as above. */ mypath = Snap(path); path = NULL; /* We must reset these to null now. */ accentoffsetX = accentoffsetY = 0; /* go find the CharString for the base char's code via an upcall */ CharStringP = GetType1CharString(Environment, bchar); StartDecrypt();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -