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

📄 function.cc

📁 swf文件查看工具,能够看flash文件的格式
💻 CC
📖 第 1 页 / 共 3 页
字号:
PostScriptFunction::PostScriptFunction(PostScriptFunction *func) {  memcpy(this, func, sizeof(PostScriptFunction));  code = (PSObject *)gmallocn(codeSize, sizeof(PSObject));  memcpy(code, func->code, codeSize * sizeof(PSObject));  codeString = func->codeString->copy();}PostScriptFunction::~PostScriptFunction() {  gfree(code);  delete codeString;}void PostScriptFunction::transform(double *in, double *out) {  PSStack *stack;  int i;  stack = new PSStack();  for (i = 0; i < m; ++i) {    //~ may need to check for integers here    stack->pushReal(in[i]);  }  exec(stack, 0);  for (i = n - 1; i >= 0; --i) {    out[i] = stack->popNum();    if (out[i] < range[i][0]) {      out[i] = range[i][0];    } else if (out[i] > range[i][1]) {      out[i] = range[i][1];    }  }  // if (!stack->empty()) {  //   error(-1, "Extra values on stack at end of PostScript function");  // }  delete stack;}GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) {  GString *tok;  char *p;  GBool isReal;  int opPtr, elsePtr;  int a, b, mid, cmp;  while (1) {    if (!(tok = getToken(str))) {      error(-1, "Unexpected end of PostScript function stream");      return gFalse;    }    p = tok->getCString();    if (isdigit(*p) || *p == '.' || *p == '-') {      isReal = gFalse;      for (++p; *p; ++p) {	if (*p == '.') {	  isReal = gTrue;	  break;	}      }      resizeCode(*codePtr);      if (isReal) {	code[*codePtr].type = psReal;	code[*codePtr].real = atof(tok->getCString());      } else {	code[*codePtr].type = psInt;	code[*codePtr].intg = atoi(tok->getCString());      }      ++*codePtr;      delete tok;    } else if (!tok->cmp("{")) {      delete tok;      opPtr = *codePtr;      *codePtr += 3;      resizeCode(opPtr + 2);      if (!parseCode(str, codePtr)) {	return gFalse;      }      if (!(tok = getToken(str))) {	error(-1, "Unexpected end of PostScript function stream");	return gFalse;      }      if (!tok->cmp("{")) {	elsePtr = *codePtr;	if (!parseCode(str, codePtr)) {	  return gFalse;	}	delete tok;	if (!(tok = getToken(str))) {	  error(-1, "Unexpected end of PostScript function stream");	  return gFalse;	}      } else {	elsePtr = -1;      }      if (!tok->cmp("if")) {	if (elsePtr >= 0) {	  error(-1, "Got 'if' operator with two blocks in PostScript function");	  return gFalse;	}	code[opPtr].type = psOperator;	code[opPtr].op = psOpIf;	code[opPtr+2].type = psBlock;	code[opPtr+2].blk = *codePtr;      } else if (!tok->cmp("ifelse")) {	if (elsePtr < 0) {	  error(-1, "Got 'ifelse' operator with one blocks in PostScript function");	  return gFalse;	}	code[opPtr].type = psOperator;	code[opPtr].op = psOpIfelse;	code[opPtr+1].type = psBlock;	code[opPtr+1].blk = elsePtr;	code[opPtr+2].type = psBlock;	code[opPtr+2].blk = *codePtr;      } else {	error(-1, "Expected if/ifelse operator in PostScript function");	delete tok;	return gFalse;      }      delete tok;    } else if (!tok->cmp("}")) {      delete tok;      resizeCode(*codePtr);      code[*codePtr].type = psOperator;      code[*codePtr].op = psOpReturn;      ++*codePtr;      break;    } else {      a = -1;      b = nPSOps;      // invariant: psOpNames[a] < tok < psOpNames[b]      while (b - a > 1) {	mid = (a + b) / 2;	cmp = tok->cmp(psOpNames[mid]);	if (cmp > 0) {	  a = mid;	} else if (cmp < 0) {	  b = mid;	} else {	  a = b = mid;	}      }      if (cmp != 0) {	error(-1, "Unknown operator '%s' in PostScript function",	      tok->getCString());	delete tok;	return gFalse;      }      delete tok;      resizeCode(*codePtr);      code[*codePtr].type = psOperator;      code[*codePtr].op = (PSOp)a;      ++*codePtr;    }  }  return gTrue;}GString *PostScriptFunction::getToken(Stream *str) {  GString *s;  int c;  GBool comment;  s = new GString();  comment = gFalse;  while (1) {    if ((c = str->getChar()) == EOF) {      break;    }    codeString->append(c);    if (comment) {      if (c == '\x0a' || c == '\x0d') {	comment = gFalse;      }    } else if (c == '%') {      comment = gTrue;    } else if (!isspace(c)) {      break;    }  }  if (c == '{' || c == '}') {    s->append((char)c);  } else if (isdigit(c) || c == '.' || c == '-') {    while (1) {      s->append((char)c);      c = str->lookChar();      if (c == EOF || !(isdigit(c) || c == '.' || c == '-')) {	break;      }      str->getChar();      codeString->append(c);    }  } else {    while (1) {      s->append((char)c);      c = str->lookChar();      if (c == EOF || !isalnum(c)) {	break;      }      str->getChar();      codeString->append(c);    }  }  return s;}void PostScriptFunction::resizeCode(int newSize) {  if (newSize >= codeSize) {    codeSize += 64;    code = (PSObject *)greallocn(code, codeSize, sizeof(PSObject));  }}void PostScriptFunction::exec(PSStack *stack, int codePtr) {  int i1, i2;  double r1, r2;  GBool b1, b2;  while (1) {    switch (code[codePtr].type) {    case psInt:      stack->pushInt(code[codePtr++].intg);      break;    case psReal:      stack->pushReal(code[codePtr++].real);      break;    case psOperator:      switch (code[codePtr++].op) {      case psOpAbs:	if (stack->topIsInt()) {	  stack->pushInt(abs(stack->popInt()));	} else {	  stack->pushReal(fabs(stack->popNum()));	}	break;      case psOpAdd:	if (stack->topTwoAreInts()) {	  i2 = stack->popInt();	  i1 = stack->popInt();	  stack->pushInt(i1 + i2);	} else {	  r2 = stack->popNum();	  r1 = stack->popNum();	  stack->pushReal(r1 + r2);	}	break;      case psOpAnd:	if (stack->topTwoAreInts()) {	  i2 = stack->popInt();	  i1 = stack->popInt();	  stack->pushInt(i1 & i2);	} else {	  b2 = stack->popBool();	  b1 = stack->popBool();	  stack->pushBool(b1 && b2);	}	break;      case psOpAtan:	r2 = stack->popNum();	r1 = stack->popNum();	stack->pushReal(atan2(r1, r2));	break;      case psOpBitshift:	i2 = stack->popInt();	i1 = stack->popInt();	if (i2 > 0) {	  stack->pushInt(i1 << i2);	} else if (i2 < 0) {	  stack->pushInt((int)((Guint)i1 >> i2));	} else {	  stack->pushInt(i1);	}	break;      case psOpCeiling:	if (!stack->topIsInt()) {	  stack->pushReal(ceil(stack->popNum()));	}	break;      case psOpCopy:	stack->copy(stack->popInt());	break;      case psOpCos:	stack->pushReal(cos(stack->popNum()));	break;      case psOpCvi:	if (!stack->topIsInt()) {	  stack->pushInt((int)stack->popNum());	}	break;      case psOpCvr:	if (!stack->topIsReal()) {	  stack->pushReal(stack->popNum());	}	break;      case psOpDiv:	r2 = stack->popNum();	r1 = stack->popNum();	stack->pushReal(r1 / r2);	break;      case psOpDup:	stack->copy(1);	break;      case psOpEq:	if (stack->topTwoAreInts()) {	  i2 = stack->popInt();	  i1 = stack->popInt();	  stack->pushBool(i1 == i2);	} else if (stack->topTwoAreNums()) {	  r2 = stack->popNum();	  r1 = stack->popNum();	  stack->pushBool(r1 == r2);	} else {	  b2 = stack->popBool();	  b1 = stack->popBool();	  stack->pushBool(b1 == b2);	}	break;      case psOpExch:	stack->roll(2, 1);	break;      case psOpExp:	r2 = stack->popNum();	r1 = stack->popNum();	stack->pushReal(pow(r1, r2));	break;      case psOpFalse:	stack->pushBool(gFalse);	break;      case psOpFloor:	if (!stack->topIsInt()) {	  stack->pushReal(floor(stack->popNum()));	}	break;      case psOpGe:	if (stack->topTwoAreInts()) {	  i2 = stack->popInt();	  i1 = stack->popInt();	  stack->pushBool(i1 >= i2);	} else {	  r2 = stack->popNum();	  r1 = stack->popNum();	  stack->pushBool(r1 >= r2);	}	break;      case psOpGt:	if (stack->topTwoAreInts()) {	  i2 = stack->popInt();	  i1 = stack->popInt();	  stack->pushBool(i1 > i2);	} else {	  r2 = stack->popNum();	  r1 = stack->popNum();	  stack->pushBool(r1 > r2);	}	break;      case psOpIdiv:	i2 = stack->popInt();	i1 = stack->popInt();	stack->pushInt(i1 / i2);	break;      case psOpIndex:	stack->index(stack->popInt());	break;      case psOpLe:	if (stack->topTwoAreInts()) {	  i2 = stack->popInt();	  i1 = stack->popInt();	  stack->pushBool(i1 <= i2);	} else {	  r2 = stack->popNum();	  r1 = stack->popNum();	  stack->pushBool(r1 <= r2);	}	break;      case psOpLn:	stack->pushReal(log(stack->popNum()));	break;      case psOpLog:	stack->pushReal(log10(stack->popNum()));	break;      case psOpLt:	if (stack->topTwoAreInts()) {	  i2 = stack->popInt();	  i1 = stack->popInt();	  stack->pushBool(i1 < i2);	} else {	  r2 = stack->popNum();	  r1 = stack->popNum();	  stack->pushBool(r1 < r2);	}	break;      case psOpMod:	i2 = stack->popInt();	i1 = stack->popInt();	stack->pushInt(i1 % i2);	break;      case psOpMul:	if (stack->topTwoAreInts()) {	  i2 = stack->popInt();	  i1 = stack->popInt();	  //~ should check for out-of-range, and push a real instead	  stack->pushInt(i1 * i2);	} else {	  r2 = stack->popNum();	  r1 = stack->popNum();	  stack->pushReal(r1 * r2);	}	break;      case psOpNe:	if (stack->topTwoAreInts()) {	  i2 = stack->popInt();	  i1 = stack->popInt();	  stack->pushBool(i1 != i2);	} else if (stack->topTwoAreNums()) {	  r2 = stack->popNum();	  r1 = stack->popNum();	  stack->pushBool(r1 != r2);	} else {	  b2 = stack->popBool();	  b1 = stack->popBool();	  stack->pushBool(b1 != b2);	}	break;      case psOpNeg:	if (stack->topIsInt()) {	  stack->pushInt(-stack->popInt());	} else {	  stack->pushReal(-stack->popNum());	}	break;      case psOpNot:	if (stack->topIsInt()) {	  stack->pushInt(~stack->popInt());	} else {	  stack->pushBool(!stack->popBool());	}	break;      case psOpOr:	if (stack->topTwoAreInts()) {	  i2 = stack->popInt();	  i1 = stack->popInt();	  stack->pushInt(i1 | i2);	} else {	  b2 = stack->popBool();	  b1 = stack->popBool();	  stack->pushBool(b1 || b2);	}	break;      case psOpPop:	stack->pop();	break;      case psOpRoll:	i2 = stack->popInt();	i1 = stack->popInt();	stack->roll(i1, i2);	break;      case psOpRound:	if (!stack->topIsInt()) {	  r1 = stack->popNum();	  stack->pushReal((r1 >= 0) ? floor(r1 + 0.5) : ceil(r1 - 0.5));	}	break;      case psOpSin:	stack->pushReal(sin(stack->popNum()));	break;      case psOpSqrt:	stack->pushReal(sqrt(stack->popNum()));	break;      case psOpSub:	if (stack->topTwoAreInts()) {	  i2 = stack->popInt();	  i1 = stack->popInt();	  stack->pushInt(i1 - i2);	} else {	  r2 = stack->popNum();	  r1 = stack->popNum();	  stack->pushReal(r1 - r2);	}	break;      case psOpTrue:	stack->pushBool(gTrue);	break;      case psOpTruncate:	if (!stack->topIsInt()) {	  r1 = stack->popNum();	  stack->pushReal((r1 >= 0) ? floor(r1) : ceil(r1));	}	break;      case psOpXor:	if (stack->topTwoAreInts()) {	  i2 = stack->popInt();	  i1 = stack->popInt();	  stack->pushInt(i1 ^ i2);	} else {	  b2 = stack->popBool();	  b1 = stack->popBool();	  stack->pushBool(b1 ^ b2);	}	break;      case psOpIf:	b1 = stack->popBool();	if (b1) {	  exec(stack, codePtr + 2);	}	codePtr = code[codePtr + 1].blk;	break;      case psOpIfelse:	b1 = stack->popBool();	if (b1) {	  exec(stack, codePtr + 2);	} else {	  exec(stack, code[codePtr].blk);	}	codePtr = code[codePtr + 1].blk;	break;      case psOpReturn:	return;      }      break;    default:      error(-1, "Internal: bad object in PostScript function code");      break;    }  }}

⌨️ 快捷键说明

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