struct ttf_graphics_state { u32 stack[TTF_ENGINE_STACK]; u32 stack_head; bool auto_flip; f32 control_value_cut_in; // f26dot6 u32 delta_base; u32 delta_shift; struct v2f projection_vector; struct v2f freedom_vector; struct v2f dual_projection_vector; int gep0; int gep1; int gep2; u32 instruction_control; int loop; f32 minimum_distance; // 1/64-th of a pixel, f26dot6 int round_state; int rp0; int rp1; int rp2; bool scan_control; f32 single_width_cut_in; // 1/64-th of a pixel, f26dot6 int single_width_value; // Funits }; struct ttf_function { u32 from; u32 to; }; enum ttf_instruction { /* Pushing data onto the interpreter stack */ NPUSHB = 0x40, NPUSHW = 0x41, PUSHB = 0xB0, PUSHB_TOP = 0xB7, PUSHW = 0xB8, PUSHW_TOP = 0xBF, /* Managing the Storage Area */ RS = 0x43, WS = 0x42, WCVTP = 0x44, WCVTF = 0x70, RCVT = 0x45, /* Managing the Graphics State */ SVTCA = 0x00, SVTCA_TOP = 0x01, SPVTCA = 0x02, SPVTCA_TOP = 0x03, SFVTCA = 0x04, SFVTCA_TOP = 0x05, SPVTL = 0x06, SPVTL_TOP = 0x07, SFVTL = 0x08, SFVTL_TOP = 0x09, SFVTPV = 0x0E, SDPVTL = 0x86, SDPVTL_TOP = 0x87, SPVFS = 0x0A, SFVFS = 0x0B, GPV = 0x0C, GFV = 0x0D, SRP0 = 0x10, SRP1 = 0x11, SRP2 = 0x12, SZP0 = 0x13, SZP1 = 0x14, SZP2 = 0x15, SZPS = 0x16, RTHG = 0x19, RTG = 0x18, RTDG = 0x3D, RDTG = 0x7D, RUTG = 0x7C, ROFF = 0x7A, SROUND = 0x76, S45ROUND = 0x77, SLOOP = 0x17, SMD = 0x1A, INSTCTRL = 0x8E, SCANCTRL = 0x85, SCANTYPE = 0x8D, SCVTCI = 0x1D, SSWCI = 0x1E, SSW = 0x1F, FLIPON = 0x4D, FLIPOFF = 0x4E, SANGW = 0x7E, SDB = 0x5E, SDS = 0x5F, /* Reading and writing data */ GC_ = 0x46, GC_TOP = 0x47, // name collisiton with GC from Xlib.h SCFS = 0x48, MD = 0x49, MD_TOP = 0x4A, MPPEM = 0x4B, MPS = 0x4C, /* Managing outlines */ FLIPPT = 0x80, FLIPRGON = 0x81, FLIPRGOFF = 0x82, SHP = 0x32, SHP_TOP = 0x33, SHC = 0x34, SHC_TOP = 0x35, SHZ = 0x36, SHZ_TOP = 0x37, SHPIX = 0x38, MSIRP = 0x3A, MSIRP_TOP = 0x3B, MDAP = 0x2E, MDAP_TOP = 0x2F, MIAP = 0x3E, MIAP_TOP = 0x3F, MDRP = 0xC0, MDRP_TOP = 0xDF, MIRP = 0xE0, MIRP_TOP = 0xFF, ALIGNRP = 0x3C, ISECT = 0x0F, ALIGNPTS = 0x27, IP = 0x39, UTP = 0x29, IUP = 0x30, IUP_TOP = 0x31, /* Managing exceptions */ DELTAP1 = 0x5D, DELTAP2 = 0x71, DELTAP3 = 0x72, DELTAC1 = 0x73, DELTAC2 = 0x74, DELTAC3 = 0x75, /* Managing the stack */ DUP = 0x20, POP = 0x21, CLEAR = 0x22, SWAP = 0x23, DEPTH = 0x24, CINDEX = 0x25, MINDEX = 0x26, ROLL = 0x8A, /* Managing the flow of control */ IF = 0x58, ELSE = 0x1B, EIF = 0x59, JROT = 0x78, JMPR = 0x1C, JROF = 0x79, /* Logical functions */ LT = 0x50, LTEQ = 0x51, GT = 0x52, GTEQ = 0x53, EQ = 0x54, NEQ = 0x55, ODD = 0x56, EVEN = 0x57, AND = 0x5A, OR = 0x5B, NOT = 0x5C, /* Arithmetic and math instructions */ ADD = 0x60, SUB = 0x61, DIV = 0x62, MUL = 0x63, ABS = 0x64, NEG = 0x65, FLOOR = 0x66, CEILING = 0x67, MAX = 0x8B, MIN = 0x8C, /* Compensating for the engine characteristics */ ROUND = 0x68, ROUND_TOP = 0x6B, NROUND = 0x6C, NROUND_TOP = 0x6F, /* Defining and using functions and instructions */ FDEF = 0x2C, ENDF = 0x2D, CALL = 0x2B, LOOPCALL = 0x2A, IDEF = 0x89, /* Debugging */ DEBUG = 0x4F, /* Miscellaneous instructions */ GETINFO = 0x88, GETVARIATION = 0x91, }; static char * ttfe_instruction_name(enum ttf_instruction instruction) { switch (instruction) { case NPUSHB: return("NPUSHB"); case NPUSHW: return("NPUSHW"); case PUSHB ... PUSHB_TOP: return("PUSHB"); case PUSHW ... PUSHW_TOP: return("PUSHW"); case RS: return("RS"); case WS: return("WS"); case WCVTP: return("WCVTP"); case WCVTF: return("WCVTF"); case RCVT: return("RCVT"); case SVTCA ... SVTCA_TOP: return("SVTCA"); case SPVTCA ... SPVTCA_TOP: return("SPVTCA"); case SFVTCA ... SFVTCA_TOP: return("SFVTCA"); case SPVTL ... SPVTL_TOP: return("SPVTL"); case SFVTL ... SFVTL_TOP: return("SFVTL"); case SFVTPV: return("SFVTPV"); case SDPVTL ... SDPVTL_TOP: return("SDPVTL"); case SPVFS: return("SPVFS"); case SFVFS: return("SFVFS"); case GPV: return("GPV"); case GFV: return("GFV"); case SRP0: return("SRP0"); case SRP1: return("SRP1"); case SRP2: return("SRP2"); case SZP0: return("SZP0"); case SZP1: return("SZP1"); case SZP2: return("SZP2"); case SZPS: return("SZPS"); case RTHG: return("RTHG"); case RTG: return("RTG"); case RTDG: return("RTDG"); case RDTG: return("RDTG"); case RUTG: return("RUTG"); case ROFF: return("ROFF"); case SROUND: return("SROUND"); case S45ROUND: return("S45ROUND"); case SLOOP: return("SLOOP"); case SMD: return("SMD"); case INSTCTRL: return("INSTCTRL"); case SCANCTRL: return("SCANCTRL"); case SCANTYPE: return("SCANTYPE"); case SCVTCI: return("SCVTCI"); case SSWCI: return("SSWCI"); case SSW: return("SSW"); case FLIPON: return("FLIPON"); case FLIPOFF: return("FLIPOFF"); case SANGW: return("SANGW"); case SDB: return("SDB"); case SDS: return("SDS"); case GC_ ... GC_TOP: return("GC_"); case SCFS: return("SCFS"); case MD ... MD_TOP: return("MD"); case MPPEM: return("MPPEM"); case MPS: return("MPS"); case FLIPPT: return("FLIPPT"); case FLIPRGON: return("FLIPRGON"); case FLIPRGOFF: return("FLIPRGOFF"); case SHP ... SHP_TOP: return("SHP"); case SHC ... SHC_TOP: return("SHC"); case SHZ ... SHZ_TOP: return("SHZ"); case SHPIX: return("SHPIX"); case MSIRP ... MSIRP_TOP: return("MSIRP"); case MDAP ... MDAP_TOP: return("MDAP"); case MIAP ... MIAP_TOP: return("MIAP"); case MDRP ... MDRP_TOP: return("MDRP"); case MIRP ... MIRP_TOP: return("MIRP"); case ALIGNRP: return("ALIGNRP"); case ISECT: return("ISECT"); case ALIGNPTS: return("ALIGNPTS"); case IP: return("IP"); case UTP: return("UTP"); case IUP ... IUP_TOP: return("IUP"); case DELTAP1: return("DELTAP1"); case DELTAP2: return("DELTAP2"); case DELTAP3: return("DELTAP3"); case DELTAC1: return("DELTAC1"); case DELTAC2: return("DELTAC2"); case DELTAC3: return("DELTAC3"); case DUP: return("DUP"); case POP: return("POP"); case CLEAR: return("CLEAR"); case SWAP: return("SWAP"); case DEPTH: return("DEPTH"); case CINDEX: return("CINDEX"); case MINDEX: return("MINDEX"); case ROLL: return("ROLL"); case IF: return("IF"); case ELSE: return("ELSE"); case EIF: return("EIF"); case JROT: return("JROT"); case JMPR: return("JMPR"); case JROF: return("JROF"); case LT: return("LT"); case LTEQ: return("LTEQ"); case GT: return("GT"); case GTEQ: return("GTEQ"); case EQ: return("EQ"); case NEQ: return("NEQ"); case ODD: return("ODD"); case EVEN: return("EVEN"); case AND: return("AND"); case OR: return("OR"); case NOT: return("NOT"); case ADD: return("ADD"); case SUB: return("SUB"); case DIV: return("DIV"); case MUL: return("MUL"); case ABS: return("ABS"); case NEG: return("NEG"); case FLOOR: return("FLOOR"); case CEILING: return("CEILING"); case MAX: return("MAX"); case MIN: return("MIN"); case ROUND ... ROUND_TOP: return("ROUND"); case NROUND ... NROUND_TOP: return("NROUND"); case FDEF: return("FDEF"); case ENDF: return("ENDF"); case CALL: return("CALL"); case LOOPCALL: return("LOOPCALL"); case IDEF: return("IDEF"); case DEBUG: return("DEBUG"); case GETINFO: return("GETINFO"); case GETVARIATION: return("GETVARIATION"); default: return(""); } } static struct ttf_graphics_state default_graphics_state() { struct ttf_graphics_state result; result.stack_head = 0; result.auto_flip = false; result.control_value_cut_in = 17.0f / 16.0f; result.delta_base = 0; result.delta_shift = 3; //result.dual_projection_vector result.freedom_vector = (struct v2f) { 1.0f, 0.0f }; result.projection_vector = (struct v2f) { 1.0f, 0.0f }; result.gep0 = 1; result.gep1 = 1; result.gep2 = 1; result.instruction_control = 0; result.loop = 1; result.minimum_distance = 64; // 1/64-th of a pixel, f26dot6 result.round_state = 1; result.rp0 = 0; result.rp1 = 0; result.rp2 = 0; result.scan_control = 0; result.single_width_cut_in = 0; // 1/64-th of a pixel, f26dot6 result.single_width_value = 0; // Funits return(result); }