📄 type1.c
字号:
} oldvert = newvert; oldverthalf = newverthalf; oldhor = newhor; oldhorhalf = newhorhalf; return p;} /******************************************************//* Subroutines and statics for the Type1Char routines *//******************************************************/ static int strindex; /* index into PostScript string being interpreted */static DOUBLE currx, curry; /* accumulated x and y values for hints */ struct callstackentry { psobj *currstrP; /* current CharStringP */ int currindex; /* current strindex */ unsigned short currkey; /* current decryption key */ }; static DOUBLE Stack[MAXSTACK];static int Top;static struct callstackentry CallStack[MAXCALLSTACK];static int CallTop;static DOUBLE PSFakeStack[MAXPSFAKESTACK];static int PSFakeTop; static int ClearStack(){ Top = -1; return(0); } static int Push(Num) DOUBLE Num;{ if (++Top < MAXSTACK) Stack[Top] = Num; else Error0i("Push: Stack full\n"); return(0); } static int ClearCallStack(){ CallTop = -1; return(0);} static int PushCall(CurrStrP, CurrIndex, CurrKey) psobj *CurrStrP; int CurrIndex; unsigned short CurrKey;{ if (++CallTop < MAXCALLSTACK) { CallStack[CallTop].currstrP = CurrStrP; /* save CharString pointer */ CallStack[CallTop].currindex = CurrIndex; /* save CharString index */ CallStack[CallTop].currkey = CurrKey; /* save decryption key */ } else Error0i("PushCall: Stack full\n"); return(0);} static int PopCall(CurrStrPP, CurrIndexP, CurrKeyP) psobj **CurrStrPP; int *CurrIndexP; unsigned short *CurrKeyP;{ if (CallTop >= 0) { *CurrStrPP = CallStack[CallTop].currstrP; /* restore CharString pointer */ *CurrIndexP = CallStack[CallTop].currindex; /* restore CharString index */ *CurrKeyP = CallStack[CallTop--].currkey; /* restore decryption key */ } else Error0i("PopCall: Stack empty\n"); return(0);} static int ClearPSFakeStack(){ PSFakeTop = -1; return(0);} /* PSFakePush: Pushes a number onto the fake PostScript stack */static int PSFakePush(Num) DOUBLE Num;{ if (++PSFakeTop < MAXPSFAKESTACK) PSFakeStack[PSFakeTop] = Num; else Error0i("PSFakePush: Stack full\n"); return(0);} /* PSFakePop: Removes a number from the top of the fake PostScript stack */static DOUBLE PSFakePop (){ if (PSFakeTop >= 0) return(PSFakeStack[PSFakeTop--]); else Error0d("PSFakePop : Stack empty\n"); /*NOTREACHED*/} /***********************************************************************//* Center a stem on the pixel grid -- used by HStem3 and VStem3 *//***********************************************************************/static struct segment *CenterStem(edge1, edge2) DOUBLE edge1; DOUBLE edge2;{ int idealwidth, verticalondevice; DOUBLE leftx, lefty, rightx, righty, center, width; DOUBLE widthx, widthy; DOUBLE shift, shiftx, shifty; DOUBLE Xpixels, Ypixels; struct segment *p; p = Loc(CharSpace, edge1, 0.0); QueryLoc(p, IDENTITY, &leftx, &lefty); p = Join(p, Loc(CharSpace, edge2, 0.0)); QueryLoc(p, IDENTITY, &rightx, &righty); Destroy(p); widthx = FABS(rightx - leftx); widthy = FABS(righty - lefty); if (widthy <= EPS) { /* verticalondevice hint */ verticalondevice = TRUE; center = (rightx + leftx) / 2.0; width = widthx; } else if (widthx <= EPS) { /* horizontal hint */ verticalondevice = FALSE; center = (righty + lefty) / 2.0; width = widthy; } else { /* neither horizontal nor verticalondevice and not oblique */ return (NULL); } idealwidth = ROUND(width); if (idealwidth == 0) idealwidth = 1; if (ODD(idealwidth)) { /* is ideal width odd? */ /* center stem over pixel */ shift = FLOOR(center) + 0.5 - center; } else { /* align stem on pixel boundary */ shift = ROUND(center) - center; } if (verticalondevice) { shiftx = shift; shifty = 0.0; } else { shifty = shift; shiftx = 0.0; } p = Loc(IDENTITY, shiftx, shifty); QueryLoc(p, CharSpace, &Xpixels, &Ypixels); wsoffsetX = Xpixels; wsoffsetY = Ypixels; currx += wsoffsetX; curry += wsoffsetY; return (p);} /*----------------------------------------------------------------------- Decrypt - From Adobe Type 1 book page 63, with some modifications-----------------------------------------------------------------------*/#define KEY 4330 /* Initial key (seed) for CharStrings decryption */#define C1 52845 /* Multiplier for pseudo-random number generator */#define C2 22719 /* Constant for pseudo-random number generator */ static unsigned short r; /* Pseudo-random sequence of keys */ static unsigned char Decrypt(cipher)unsigned char cipher;{ unsigned char plain; plain = cipher ^ (r >> 8); r = (cipher + r) * C1 + C2; return plain;} /* Get the next byte from the codestring being interpreted */static int DoRead(CodeP) int *CodeP;{ if (strindex >= CharStringP->len) return(FALSE); /* end of string */ /* We handle the non-documented Adobe convention to use lenIV=-1 to suppress charstring encryption. */ if (blues->lenIV==-1) { *CodeP = (unsigned char) CharStringP->data.stringP[strindex++]; } else { *CodeP = Decrypt((unsigned char) CharStringP->data.stringP[strindex++]); } return(TRUE);} /* Strip blues->lenIV bytes from CharString and update encryption key *//* (the lenIV entry in the Private dictionary specifies the number of *//* random bytes at the beginning of each CharString; default is 4) */static void StartDecrypt(){ int Code; r = KEY; /* Initial key (seed) for CharStrings decryption */ for (strindex = 0; strindex < blues->lenIV;){ if (!DoRead(&Code)) /* Read a byte and update decryption key */ Error0v("StartDecrypt: Premature end of CharString\n"); } }#undef DecodeDebugstatic int Decode(Code) int Code;{ int Code1, Code2, Code3, Code4; if (Code <= 31){ /* Code is [0,31] */#ifdef DecodeDebug fprintf(stderr, "Decode: Code=%d -> Command\n", Code);#endif DoCommand(Code); } else if (Code <= 246){ /* Code is [32,246] */#ifdef DecodeDebug fprintf(stderr, "Decode: Code=%d -> number=%f\n", Code, (DOUBLE)(Code-139));#endif Push((DOUBLE)(Code - 139)); } else if (Code <= 250) { /* Code is [247,250] */ if (!DoRead(&Code2)) goto ended;#ifdef DecodeDebug fprintf(stderr, "Decode: Code=%d next Code=%d -> number=%f\n", Code, Code2, (DOUBLE)(((Code - 247) << 8) + Code2 + 108));#endif Push((DOUBLE)(((Code - 247) << 8) + Code2 + 108)); } else if (Code <= 254) { /* Code is [251,254] */ if (!DoRead(&Code2)) goto ended;#ifdef DecodeDebug fprintf(stderr, "Decode: Code=%d, next Code=%d -> number=%f\n", Code, Code2, (DOUBLE)( -((Code - 251) << 8) - Code2 - 108));#endif Push((DOUBLE)( -((Code - 251) << 8) - Code2 - 108)); } else { /* Code is 255 */ if (!DoRead(&Code1)) goto ended; if (!DoRead(&Code2)) goto ended; if (!DoRead(&Code3)) goto ended; if (!DoRead(&Code4)) goto ended;#ifdef DecodeDebug fprintf(stderr, "Decode: Code=255, Code1=%d, Code2=%d, Code3=%d, Code4=%d -> number=%f\n", Code1, Code2, Code3, Code4, (DOUBLE)((((((Code1<<8) + Code2)<<8) + Code3)<<8) + Code4));#endif Push((DOUBLE)((((((Code1<<8) + Code2)<<8) + Code3)<<8) + Code4)); } return(0); ended: Error0i("Decode: Premature end of Type 1 CharString");}#undef DoCommandDebug /* Interpret a command code */static int DoCommand(Code) int Code;{ switch(Code) { case HSTEM: /* |- y dy HSTEM |- */#ifdef DoCommandDebug printf("DoCommand: HStem\n");#endif /* Vertical range of a horizontal stem zone */ if (Top < 1) Error1i("DoCommand: Stack low (Code=%d)\n", Code); HStem(Stack[0], Stack[1]); ClearStack(); break; case VSTEM: /* |- x dx VSTEM |- */#ifdef DoCommandDebug printf("DoCommand: VStem\n");#endif /* Horizontal range of a vertical stem zone */ if (Top < 1) Error1i("DoCommand: Stack low (Code=%d)\n", Code); VStem(Stack[0], Stack[1]); ClearStack(); break; case VMOVETO: /* |- dy VMOVETO |- */#ifdef DoCommandDebug printf("DoCommand: VMoveto\n");#endif /* Vertical MOVETO, equivalent to 0 dy RMOVETO */ if (Top < 0) Error1i("DoCommand: Stack low (Code=%d)\n", Code); RMoveTo(0.0, Stack[0]); ClearStack(); break; case RLINETO: /* |- dx dy RLINETO |- */#ifdef DoCommandDebug printf("DoCommand: RLineto\n");#endif /* Like RLINETO in PostScript */ if (Top < 1) Error1i("DoCommand: Stack low (Code=%d)\n", Code); RLineTo(Stack[0], Stack[1]); ClearStack(); break; case HLINETO: /* |- dx HLINETO |- */#ifdef DoCommandDebug printf("DoCommand: HLineto\n");#endif /* Horizontal LINETO, equivalent to dx 0 RLINETO */ if (Top < 0) Error1i("DoCommand: Stack low (Code=%d)\n", Code); RLineTo(Stack[0], 0.0); ClearStack(); break; case VLINETO: /* |- dy VLINETO |- */#ifdef DoCommandDebug printf("DoCommand: VLineto\n");#endif /* Vertical LINETO, equivalent to 0 dy RLINETO */ if (Top < 0) Error1i("DoCommand: Stack low (Code=%d)\n", Code); RLineTo(0.0, Stack[0]); ClearStack(); break; case RRCURVETO:#ifdef DoCommandDebug printf("DoCommand: RRCurveto\n");#endif /* |- 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) Error1i("DoCommand: Stack low (Code=%d)\n", Code); RRCurveTo(Stack[0], Stack[1], Stack[2], Stack[3], Stack[4], Stack[5]); ClearStack(); break; case CLOSEPATH: /* - CLOSEPATH |- */#ifdef DoCommandDebug printf("DoCommand: ClosePath\n");#endif /* Closes a subpath without repositioning the */ /* current point */ DoClosePath(); ClearStack(); break; case CALLSUBR: /* subr# CALLSUBR - */#ifdef DoCommandDebug printf("DoCommand: CallSubr\n");#endif /* Calls a CharString subroutine with index */ /* subr# from the Subrs array */ if (Top < 0) Error1i("DoCommand: Stack low\n (Code=%d)", Code); CallSubr((int)Stack[Top--]); break; case RETURN: /* - RETURN - */#ifdef DoCommandDebug printf("DoCommand: Return\n");#endif /* Returns from a Subrs array CharString */ /* subroutine called with CALLSUBR */ Return(); break; case ESCAPE: /* ESCAPE to two-byte command code */#ifdef DoCommandDebug printf("DoCommand: Escape to 2 Byte Code (Code=%d)\n", Code);#endif if (!DoRead(&Code)) Error0i("DoCommand: ESCAPE is last byte\n"); Escape(Code); break; case HSBW: /* |- sbx wx HSBW |- */#ifdef DoCommandDebug printf("DoCommand: HSBW\n");#endif /* 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) Error1i("DoCommand: Stack low (Code=%d)\n", Code); Sbw(Stack[0], 0.0, Stack[1], 0.0); ClearStack(); break; case ENDCHAR: /* - ENDCHAR |- */#ifdef DoCommandDebug printf("DoCommand: EndChar\n");#endif /* Finishes a CharString outline */ EndChar();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -