📄 set_spcs.c
字号:
* sp_globals.pixrnd rounding for pixels * sp_globals.mprnd rounding for sub-pixels * sp_globals.onepix 1 pixel in shifted pixel units * sp_globals.pixfix mask to eliminate fractional bits of shifted pixels * sp_globals.depth_adj curve splitting depth adjustment * Returns FALSE if specs are out of range */{fix31 mult; /* Successive multiplier values */ufix32 num; /* Numerator of largest multiplier value */ufix32 numcopy; /* Copy of numerator */ufix32 denom; /* Denominator of largest multiplier value */ufix32 denomcopy; /* Copy of denominator */ufix32 pix_max; /* Maximum pixel rounding error */fix31 xmult; /* Coefficient of X oru value in transformation */fix31 ymult; /* Coefficient of Y oru value in transformation */fix31 offset; /* Constant in transformation */fix15 i; /* Loop counter */fix15 x, y; /* Successive corners of bounding box in ORUs */fix31 pixval; /* Successive pixel values multiplied by orus per em */fix15 xx, yy; /* Bounding box corner that produces max pixel value *//* Determine numerator and denominator of largest multiplier value */mult = sp_globals.pspecs->xxmult >> 16;if (mult < 0) mult = -mult;num = mult;mult = sp_globals.pspecs->xymult >> 16;if (mult < 0) mult = -mult;if (mult > num) num = mult;mult = sp_globals.pspecs->yxmult >> 16;if (mult < 0) mult = -mult;if (mult > num) num = mult;mult = sp_globals.pspecs->yymult >> 16;if (mult < 0) mult = -mult;if (mult > num) num = mult;num++; /* Max absolute pixels per em (rounded up) */denom = (ufix32)sp_globals.orus_per_em;/* Set curve splitting depth adjustment to accomodate largest multiplier value */sp_globals.depth_adj = 0; /* 0 = 0.5 pel, 1 = 0.13 pel, 2 = 0.04 pel accuracy */denomcopy = denom;/* The following two occurances of a strange method of shifting twice by 1 are intentional and should not be changed to a single shift by 2. It prevents MicroSoft C 5.1 from generating functions calls to do the shift. Worse, using the REENTRANT_ALLOC option in conjunction with the /AC compiler option, the function appears to be called incorrectly, causing depth_adj to always be set to -7, causing very angular characters. */while ((num > denomcopy) && (sp_globals.depth_adj < 5)) /* > 1, 4, 16, ... pixels per oru? */ { denomcopy <<= 1; denomcopy <<= 1; sp_globals.depth_adj++; /* Add 1, 2, 3, ... to depth adjustment */ }numcopy = num << 2;while ((numcopy <= denom) && (sp_globals.depth_adj > -4)) /* <= 1/4, 1/16, 1/64 pix per oru? */ { numcopy <<= 1; numcopy <<= 1; sp_globals.depth_adj--; /* Subtract 1, 2, 3, ... from depth adjustment */ }SHOW(sp_globals.depth_adj);/* Set multiplier shift to accomodate largest multiplier value */sp_globals.multshift = 14; numcopy = num;while (numcopy >= denom) /* More than 1, 2, 4, ... pix per oru? */ { numcopy >>= 1; sp_globals.multshift--; /* sp_globals.multshift is 13, 12, 11, ... */ }sp_globals.multrnd = ((fix31)1 << sp_globals.multshift) >> 1;SHOW(sp_globals.multshift);pix_max = (ufix32)( 0xffff & read_word_u(sp_globals.hdr2_org + FH_PIXMX));num = 0;xmult = ((sp_globals.pspecs->xxmult >> 16) + 1) >> 1;ymult = ((sp_globals.pspecs->xymult >> 16) + 1) >> 1;offset = ((sp_globals.pspecs->xoffset >> 16) + 1) >> 1;for (i = 0; i < 8; i++) { if (i == 4) { xmult = ((sp_globals.pspecs->yxmult >> 16) + 1) >> 1; ymult = ((sp_globals.pspecs->yymult >> 16) + 1) >> 1; offset = ((sp_globals.pspecs->yoffset >> 16) + 1) >> 1; } x = (i & BIT1)? xmin: xmax; y = (i & BIT0)? ymin: ymax; pixval = (fix31)x * xmult + (fix31)y * ymult + offset * denom; if (pixval < 0) pixval = -pixval; if (pixval > num) { num = pixval; xx = x; yy = y; } }if (xx < 0) xx = -xx;if (yy < 0) yy = -yy;num += xx + yy + ((pix_max + 2) * denom); /* Allow (with 2:1 safety margin) for 1 pixel rounding errors in */ /* xmult, ymult and offset values, pix_max pixel expansion */ /* due to intelligent scaling, and */ /* 1 pixel rounding of overall character position */denom = denom << 14; /* Note num is in units of half pixels times orus per em */sp_globals.pixshift = -1;while ((num <= denom) && (sp_globals.pixshift < 8)) /* Max pixels <= 32768, 16384, 8192, ... pixels? */ { num <<= 1; sp_globals.pixshift++; /* sp_globals.pixshift = 0, 1, 2, ... */ }if (sp_globals.pixshift < 0) return FALSE;SHOW(sp_globals.pixshift);sp_globals.poshift = 16 - sp_globals.pixshift;sp_globals.onepix = (fix15)1 << sp_globals.pixshift;sp_globals.pixrnd = sp_globals.onepix >> 1;sp_globals.pixfix = ~0 << sp_globals.pixshift;sp_globals.mpshift = sp_globals.multshift - sp_globals.pixshift;if (sp_globals.mpshift < 0) return FALSE;sp_globals.mprnd = ((fix31)1 << sp_globals.mpshift) >> 1;return TRUE;}#ifdef oldFUNCTION void sp_setup_tcb(ptcb)#elsestatic FUNCTION void sp_setup_tcb(ptcb)#endifGDECLtcb_t GLOBALFAR *ptcb; /* Pointer to transformation control bloxk *//* * Convert transformation coeffs to internal form */{ptcb->xxmult = sp_setup_mult(sp_globals.pspecs->xxmult);ptcb->xymult = sp_setup_mult(sp_globals.pspecs->xymult);ptcb->xoffset = sp_setup_offset(sp_globals.pspecs->xoffset);ptcb->yxmult = sp_setup_mult(sp_globals.pspecs->yxmult);ptcb->yymult = sp_setup_mult(sp_globals.pspecs->yymult);ptcb->yoffset = sp_setup_offset(sp_globals.pspecs->yoffset);SHOW(ptcb->xxmult);SHOW(ptcb->xymult);SHOW(ptcb->xoffset);SHOW(ptcb->yxmult);SHOW(ptcb->yymult);SHOW(ptcb->yoffset);type_tcb(ptcb); /* Classify transformation type */}FUNCTION static fix15 sp_setup_mult(input_mult)GDECLfix31 input_mult; /* Multiplier in input format *//* * Called by sp_setup_tcb() to convert multiplier in transformation * matrix from external to internal form. */{fix15 imshift; /* Right shift to internal format */fix31 imdenom; /* Divisor to internal format */fix31 imrnd; /* Rounding for division operation */imshift = 15 - sp_globals.multshift;imdenom = (fix31)sp_globals.orus_per_em << imshift;imrnd = imdenom >> 1;input_mult >>= 1;if (input_mult >= 0) return (fix15)((input_mult + imrnd) / imdenom);else return -(fix15)((-input_mult + imrnd) / imdenom);}FUNCTION static fix31 sp_setup_offset(input_offset)GDECLfix31 input_offset; /* Multiplier in input format *//* * Called by sp_setup_tcb() to convert offset in transformation * matrix from external to internal form. */{fix15 imshift; /* Right shift to internal format */fix31 imrnd; /* Rounding for right shift operation */imshift = 15 - sp_globals.multshift;imrnd = ((fix31)1 << imshift) >> 1;return (((input_offset >> 1) + imrnd) >> imshift) + sp_globals.mprnd;}FUNCTION void type_tcb(ptcb)GDECLtcb_t GLOBALFAR *ptcb; /* Pointer to transformation control bloxk */{fix15 x_trans_type;fix15 y_trans_type;fix15 xx_mult;fix15 xy_mult;fix15 yx_mult;fix15 yy_mult;fix15 h_pos;fix15 v_pos;fix15 x_ppo;fix15 y_ppo;fix15 x_pos;fix15 y_pos;/* check for mirror image transformations */xx_mult = ptcb->xxmult;xy_mult = ptcb->xymult;yx_mult = ptcb->yxmult;yy_mult = ptcb->yymult;ptcb->mirror = ((((fix31)xx_mult*(fix31)yy_mult)- ((fix31)xy_mult*(fix31)yx_mult)) < 0) ? -1 : 1;if (sp_globals.pspecs->flags & BOGUS_MODE) /* Linear transformation requested? */ { ptcb->xtype = 4; ptcb->ytype = 4; ptcb->xppo = 0; ptcb->yppo = 0; ptcb->xpos = 0; ptcb->ypos = 0; }else /* Intelligent tranformation requested? */ { h_pos = ((ptcb->xoffset >> sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix; v_pos = ((ptcb->yoffset >> sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix; x_trans_type = 4; x_ppo = 0; x_pos = 0; y_trans_type = 4; y_ppo = 0; y_pos = 0; if (xy_mult == 0) { if (xx_mult >= 0) { x_trans_type = 0; /* X pix is function of X orus only */ x_ppo = xx_mult; x_pos = h_pos; } else { x_trans_type = 1; /* X pix is function of -X orus only */ x_ppo = -xx_mult; x_pos = -h_pos; } } else if (xx_mult == 0) { if (xy_mult >= 0) { x_trans_type = 2; /* X pix is function of Y orus only */ y_ppo = xy_mult; y_pos = h_pos; } else { x_trans_type = 3; /* X pix is function of -Y orus only */ y_ppo = -xy_mult; y_pos = -h_pos; } } if (yx_mult == 0) { if (yy_mult >= 0) { y_trans_type = 0; /* Y pix is function of Y orus only */ y_ppo = yy_mult; y_pos = v_pos; } else { y_trans_type = 1; /* Y pix is function of -Y orus only */ y_ppo = -yy_mult; y_pos = -v_pos; } } else if (yy_mult == 0) { if (yx_mult >= 0) { y_trans_type = 2; /* Y pix is function of X orus only */ x_ppo = yx_mult; x_pos = v_pos; } else { y_trans_type = 3; /* Y pix is function of -X orus only */ x_ppo = -yx_mult; x_pos = -v_pos; } } ptcb->xtype = x_trans_type; ptcb->ytype = y_trans_type; ptcb->xppo = x_ppo; ptcb->yppo = y_ppo; ptcb->xpos = x_pos; ptcb->ypos = y_pos; }sp_globals.normal = (ptcb->xtype != 4) && (ptcb->ytype != 4);ptcb->xmode = 4;ptcb->ymode = 4; SHOW(ptcb->xtype);SHOW(ptcb->ytype);SHOW(ptcb->xppo);SHOW(ptcb->yppo);SHOW(ptcb->xpos);SHOW(ptcb->ypos);}FUNCTION fix31 read_long(pointer)GDECLufix8 FONTFAR *pointer; /* Pointer to first byte of encrypted 3-byte integer *//* * Reads a 3-byte encrypted integer from the byte string starting at * the specified point. * Returns the decrypted value read as a signed integer. */{fix31 tmpfix31;tmpfix31 = (fix31)((*pointer++) ^ sp_globals.key4) << 8; /* Read middle byte */tmpfix31 += (fix31)(*pointer++) << 16; /* Read most significant byte */tmpfix31 += (fix31)((*pointer) ^ sp_globals.key6); /* Read least significant byte */return tmpfix31;}FUNCTION fix15 read_word_u(pointer)GDECLufix8 FONTFAR *pointer; /* Pointer to first byte of unencrypted 2-byte integer *//* * Reads a 2-byte unencrypted integer from the byte string starting at * the specified point. * Returns the decrypted value read as a signed integer. */{fix15 tmpfix15;tmpfix15 = (fix15)(*pointer++) << 8; /* Read most significant byte */tmpfix15 += (fix15)(*pointer); /* Add least significant byte */return tmpfix15;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -