#include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "wv.h" #include "bintree.h" /* allow figures within 3 units of each other to be considered the same */ int cellCompLT (void *a, void *b) { S16 *a2, *b2; if (cellCompEQ (a, b)) return (0); a2 = (S16 *) a; b2 = (S16 *) b; return (*a2 < (*b2) + 3); } int cellCompEQ (void *a, void *b) { int ret; S16 *a2, *b2; a2 = (S16 *) a; b2 = (S16 *) b; ret = abs (*a2 - *b2); if (ret <= 3) ret = 1; else ret = 0; return (ret); } void wvGetRowTap (wvParseStruct * ps, PAP * dpap, U32 para_intervals, BTE * btePapx, U32 * posPapx) { PAPX_FKP para_fkp; U32 para_fcFirst, para_fcLim = 0xffffffffL; PAP apap; U32 i; S32 j = 0; wvVersion ver = wvQuerySupported (&ps->fib, NULL); wvCopyPAP (&apap, dpap); wvInitPAPX_FKP (¶_fkp); i = wvStream_tell (ps->mainfd); wvTrace (("RowTab begin\n")); do { wvReleasePAPX_FKP (¶_fkp); wvGetSimpleParaBounds (ver, ¶_fkp, ¶_fcFirst, ¶_fcLim, i, btePapx, posPapx, para_intervals, ps->mainfd); wvTrace (("2: para from %x to %x\n", para_fcFirst, para_fcLim)); wvAssembleSimplePAP (ver, &apap, para_fcLim, ¶_fkp, ps); i = para_fcLim; } while (apap.fTtp == 0); wvTrace (("fTtp is %d\n", apap.fTtp)); wvReleasePAPX_FKP (¶_fkp); wvCopyTAP (&(dpap->ptap), &apap.ptap); for (j = 0; j < apap.ptap.itcMac + 1; j++) wvTrace (("This Row-->%d\n", apap.ptap.rgdxaCenter[j])); } void wvGetFullTableInit (wvParseStruct * ps, U32 para_intervals, BTE * btePapx, U32 * posPapx) { PAPX_FKP para_fkp; U32 para_fcFirst, para_fcLim = 0xffffffffL; PAP apap; U32 i, j = 0; TAP *test = NULL; wvVersion ver = wvQuerySupported (&ps->fib, NULL); if (ps->intable) return; wvInitPAPX_FKP (¶_fkp); i = wvStream_tell (ps->mainfd); wvTrace (("TOP\n")); do { wvReleasePAPX_FKP (¶_fkp); wvGetSimpleParaBounds (ver, ¶_fkp, ¶_fcFirst, ¶_fcLim, i, btePapx, posPapx, para_intervals, ps->mainfd); wvAssembleSimplePAP (ver, &apap, para_fcLim, ¶_fkp, ps); wvTrace (("para from %x to %x\n", para_fcFirst, para_fcLim)); i = para_fcLim; /* ignore the row end markers */ /*if (apap.ptap.itcMac)*/ /* we ascertain the number of rows by counting the end of row markers. NB: a row marker can have a 0 itcMac*/ if (apap.fTtp) { test = (TAP *) realloc (test, sizeof (TAP) * (j + 1)); wvCopyTAP (&(test[j]), &apap.ptap); wvTrace (("Row %d\n", j)); j++; } } while (apap.fInTable); wvTrace (("BOTTOM\n")); wvReleasePAPX_FKP (¶_fkp); wvSetTableInfo (ps, test, j); ps->intable = 1; ps->norows = j; wvFree (test); } /* ------------------------- | | | ------------------------- | | | | | | | ------------------------- | | ------------------------- | | | | ------------------------- ==> | | | | | | | | | As in this example we create a list of cell begin positions which is a superset of all begin positions in all rows, once we have this list we restart at the top of the table and figure out how many spans each cell has to achieve to match back up to its original boundaries. We will have to match boundaries that are with in 3 units of eachother to be the same boundary as that occurs frequently in word tables, (gagh!) */ void wvSetTableInfo (wvParseStruct * ps, TAP * ptap, int no) { BintreeInfo tree; Node *testn, *testp; int i, j, k; if (ps->vmerges) { wvTrace (("vmerges is not NULL\n")); for (i = 0; i < ps->norows; i++) wvFree (ps->vmerges[i]); wvFree (ps->vmerges); ps->vmerges = NULL; } if (no == 0) { wvWarning ("Broken tables, continuing and hoping for the best\n"); ps->nocellbounds = 0; return; } InitBintree (&tree, cellCompLT, cellCompEQ); wvTrace (("we still ok, no is %d\n", no)); for (i = 0; i < no; i++) { for (j = 0; j < ptap[i].itcMac + 1; j++) { wvTrace (("%d\n", ptap[i].rgdxaCenter[j])); InsertNode (&tree, (void *) &(ptap[i].rgdxaCenter[j])); } } wvTrace (("end of in\n")); testn = NextNode (&tree, NULL); ps->nocellbounds = tree.no_in_tree; wvFree (ps->cellbounds); if (tree.no_in_tree) ps->cellbounds = (S16 *) wvMalloc (sizeof (S16) * tree.no_in_tree); else ps->cellbounds = NULL; i = 0; wvTrace (("No in tree is %d\n", tree.no_in_tree)); while (testn != NULL) { ps->cellbounds[i++] = *((S16 *) testn->Data); wvTrace (("cellbound are %d\n", ps->cellbounds[i - 1])); testp = NextNode (&tree, testn); wvDeleteNode (&tree, testn); testn = testp; } wvTrace (("No in tree according to i is %d\n", i)); wvTrace (("end of out\n")); ps->vmerges = (S16 **) wvMalloc (sizeof (S16 *) * no); wvTrace (("no of rows is %d\n", no)); for (i = 0; i < no; i++) { ps->vmerges[i] = (S16 *) wvMalloc (sizeof (S16) * ptap[i].itcMac); wvTrace (("no of cells is %d\n", ptap[i].itcMac)); for (j = 0; j < ptap[i].itcMac; j++) ps->vmerges[i][j] = 1; } for (i = no - 1; i > 0; i--) { for (j = 0; j < ptap[i].itcMac; j++) { wvTrace ( ("Vertical merge is %d\n", ptap[i].rgtc[j].fVertMerge)); if (ptap[i].rgtc[j].fVertMerge) { wvTrace ( ("Vertical merge found, row %d, cell %d\n", i, j)); /* find a cell above me with the same boundaries if it is also merged increment it, and set myself to 0 else leave me alone */ for (k = 0; k < ptap[i - 1].itcMac; k++) /* the row above */ { wvTrace ( ("cell begins are %d %d\n", ptap[i - 1].rgdxaCenter[k], ptap[i].rgdxaCenter[j])); wvTrace ( ("cell ends are %d %d\n", ptap[i - 1].rgdxaCenter[k + 1], ptap[i].rgdxaCenter[j + 1])); if ( (cellCompEQ ((void *) &(ptap[i - 1].rgdxaCenter[k]), (void *) &(ptap[i].rgdxaCenter[j]))) && (cellCompEQ ((void *) &(ptap[i - 1].rgdxaCenter[k + 1]), (void *) &(ptap[i].rgdxaCenter[j + 1])))) { wvTrace (("found a cell above me, yippee\n")); if (ptap[i - 1].rgtc[k].fVertMerge) { ps->vmerges[i - 1][k] += ps->vmerges[i][j]; ps->vmerges[i][j] = 0; } } } } } } for (i = 0; i < no; i++) for (j = 0; j < ptap[i].itcMac; j++) wvTrace (("rowspan numbers are %d\n", ps->vmerges[i][j])); } /* table backgrounds */ /* 0 1 2 3 first row 4 5 6 7 even row 8 9 10 11 odd row 12 13 14 15 last row F E O L i v d a r e d s s n t t C C o C C o l o o l u l l u m u u m n m m n n n */ static int cellbgcolors[40][4][4] = { /*0 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*1 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*2 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*3 */ { {1, 1, 1, 1}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*4 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*5 */ { {12, 12, 12, 12}, {16, 8, 8, 8}, {16, 8, 8, 8}, {16, 8, 8, 8} }, /*6 */ { {9, 9, 9, 9}, {16, 16, 16, 16}, {16, 16, 16, 16}, {8, 8, 8, 8} }, /*7 */ { {2, 2, 2, 2}, {8, 8, 8, 8}, {8, 8, 8, 8}, {15, 15, 15, 15} }, /*8 */ { {1, 1, 1, 1}, {9, 11, 11, 11}, {9, 11, 11, 11}, {9, 11, 11, 11} }, /*9 */ { {6, 6, 6, 6}, {7, 7, 7, 16}, {7, 7, 7, 16}, {7, 7, 7, 16} }, /*10 */ { {1, 11, 11, 11}, {11, 3, 3, 3}, {11, 3, 3, 3}, {11, 3, 3, 3} }, /*11 */ { {16, 16, 7, 16}, {16, 16, 7, 16}, {16, 16, 7, 16}, {16, 16, 7, 16} }, /*12 */ { {9, 9, 9, 9}, {16, 16, 4, 16}, {16, 16, 4, 16}, {16, 16, 4, 16} }, /*13 */ { {9, 9, 9, 9}, {15, 15, 16, 15}, {15, 15, 16, 15}, {15, 15, 16, 15} }, /*14 */ { {1, 1, 1, 1}, {3, 3, 16, 3}, {3, 3, 16, 3}, {3, 3, 16, 3} }, /*15 */ { {15, 15, 8, 15}, {15, 15, 8, 15}, {15, 15, 8, 15}, {15, 15, 8, 15} }, /*16 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*17 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*18 */ { {7, 7, 7, 7}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*19 */ { {7, 7, 7, 7}, {8, 8, 8, 8}, {8, 8, 8, 8}, {7, 7, 7, 7} }, /*20 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*21 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*22 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*23 */ { {9, 9, 9, 9}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*24 */ { {16, 16, 16, 16}, {8, 8, 8, 8}, {16, 16, 16, 16}, {8, 8, 8, 8} }, /*25 */ { {11, 11, 11, 11}, {8, 8, 8, 8}, {4, 4, 4, 4}, {8, 8, 8, 8} }, /*26 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*27 */ { {15, 15, 15, 15}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*28 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*29 */ { {15, 15, 15, 15}, {15, 15, 15, 15}, {16, 16, 16, 16}, {15, 15, 15, 15} }, /*30 */ { {16, 16, 16, 16}, {7, 7, 7, 7}, {16, 16, 16, 16}, {8, 8, 8, 8} }, /*31 */ { {7, 7, 7, 7}, {6, 6, 6, 6}, {14, 14, 14, 14}, {6, 6, 6, 6} }, /*32 */ { {15, 15, 15, 15}, {15, 15, 15, 15}, {15, 15, 15, 15}, {15, 15, 15, 15} }, /*33 */ { {15, 15, 15, 15}, {15, 15, 15, 15}, {15, 15, 15, 15}, {15, 15, 15, 15} }, /*34 */ { {15, 15, 16, 15}, {15, 15, 16, 15}, {15, 15, 16, 15}, {15, 15, 16, 15} }, /*35 */ { {15, 15, 15, 15}, {15, 15, 15, 15}, {16, 16, 16, 16}, {15, 15, 15, 15} }, /*36 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*37 */ { {1, 1, 1, 1}, {8, 8, 8, 8}, {8, 8, 8, 8}, {8, 8, 8, 8} }, /*38 */ { {8, 8, 8, 8}, {8, 8, 8, 8}, {10, 10, 10, 10}, {5, 5, 5, 5} }, /*39 */ { {8, 8, 8, 8}, {4, 8, 8, 10}, {4, 8, 8, 10}, {4, 8, 8, 10} } }; /* determine where we should be in the grid, if we do not want the special end cases, and we are one of them, then shift into a new location in the grid, and output the color sitting there */ int wvCellBgColor (int whichrow, int whichcell, int nocells, int norows, TLP * tlp) { if (whichrow == norows - 1) whichrow = 3; else if (whichrow > 0) { if (isodd (whichrow)) whichrow = 2; else whichrow = 1; } if (whichcell == nocells - 1) whichcell = 3; else if (whichcell > 0) { if (isodd (whichcell)) whichcell = 2; else whichcell = 1; } wvTrace ( ("the cell index and bgcolor is %d %d %d,%d (last cell and row are %d %d)\n", tlp->itl, whichrow, whichcell, cellbgcolors[tlp->itl][whichrow][whichcell], nocells, norows)); if (tlp->itl >= 40) { wvWarning ("Table Look %d requested, but theres only %d in the list\n", tlp->itl + 1, 40); return (8); } return (cellbgcolors[tlp->itl][whichrow][whichcell]); } /* get the end cp of the piece i as a cp wvGetComplexParaBounds as fc's go to the end as a cp */ void TheTest (wvParseStruct * ps, U32 piece, BTE * btePapx, U32 * posPapx, U32 para_intervals) { U32 piececount; int ichartype; U8 chartype; U32 begincp, endcp; U32 beginfc, endfc; U32 i, j, k = 0; U32 para_fcFirst, para_fcLim; PAPX_FKP para_fkp; PAP apap; int cpiece = 0; wvVersion ver = wvQuerySupported (&ps->fib, NULL); long pos = wvStream_tell (ps->mainfd); wvInitPAPX_FKP (¶_fkp); para_fcFirst = wvConvertCPToFC (ps->currentcp, &ps->clx); for (piececount = piece; piececount < ps->clx.nopcd; piececount++) { ichartype = wvGetPieceBoundsFC (&beginfc, &endfc, &ps->clx, piececount); if(ichartype==-1) break; chartype = (U8) ichartype; wvStream_goto (ps->mainfd, beginfc); wvGetPieceBoundsCP (&begincp, &endcp, &ps->clx, piececount); if (k == 0) { wvTrace ( ("cp distance is %d, cp is %d\n", ps->currentcp - begincp, ps->currentcp)); wvTrace ( ("no of pieces is %d, this one is %d\n", ps->clx.nopcd, piece)); k++; begincp = ps->currentcp; beginfc = wvConvertCPToFC (ps->currentcp, &ps->clx); } wvTrace ( ("begin and end are %d %d (%x %x)\n", begincp, endcp, beginfc, endfc)); para_fcLim = 0xffffffffL; for (i = begincp, j = beginfc; (i < endcp && i < ps->fib.ccpText); i++, j += wvIncFC (chartype)) { if ((para_fcLim == 0xffffffffL) || (para_fcLim == j)) { wvReleasePAPX_FKP (¶_fkp); wvTrace ( ("cp and fc are %x(%d) %x\n", i, i, wvConvertCPToFC (i, &ps->clx))); cpiece = wvGetComplexParaBounds (ver, ¶_fkp, ¶_fcFirst, ¶_fcLim, wvConvertCPToFC (i, &ps->clx), &ps->clx, btePapx, posPapx, para_intervals, piececount, ps->mainfd); wvTrace ( ("para begin and end is %x %x, pieceend is %x\n", para_fcFirst, para_fcLim, wvConvertCPToFC (endcp, &ps->clx))); } if (j == para_fcFirst) { wvAssembleSimplePAP (ver, &apap, para_fcLim, ¶_fkp, ps); wvAssembleComplexPAP (ver, &apap, cpiece, ps); wvTrace ( ("table ttp are %d %d\n", apap.fInTable, apap.fTtp)); } } } wvStream_goto (ps->mainfd, pos); } void wvGetComplexFullTableInit (wvParseStruct * ps, U32 para_intervals, BTE * btePapx, U32 * posPapx, U32 piece) { PAPX_FKP para_fkp; U32 para_fcFirst, para_fcLim = 0xffffffffL; PAP apap; U32 i, j = 0, k = 0; S32 l; TAP *test = NULL; wvVersion ver = wvQuerySupported (&ps->fib, NULL); if (ps->intable) return; #if 0 /* some testing code */ wvTrace (("before test\n")); TheTest (ps, piece, btePapx, posPapx, para_intervals); wvTrace (("after test\n")); #endif wvInitPAPX_FKP (¶_fkp); i = wvStream_tell (ps->mainfd); wvTrace (("TOP\n")); do { wvTrace (("cycle again\n")); wvReleasePAPX_FKP (¶_fkp); wvTrace ( ("2: cp and fc are %x(%d) %x\n", i, i, wvConvertCPToFC (i, &ps->clx))); piece = wvGetComplexParaBounds (ver, ¶_fkp, ¶_fcFirst, ¶_fcLim, i, &ps->clx, btePapx, posPapx, para_intervals, piece, ps->mainfd); if (piece == 0xffffffffL) break; wvAssembleSimplePAP (ver, &apap, para_fcLim, ¶_fkp, ps); wvTrace (("para from %x to %x\n", para_fcFirst, para_fcLim)); wvAssembleComplexPAP (ver, &apap, piece, ps); wvTrace (("para from %x to %x\n", para_fcFirst, para_fcLim)); i = para_fcLim; /* ignore the row end markers */ /* if ((apap.ptap.itcMac) (apap.fTtp))*/ /* we ascertain the number of rows by counting the end of row markers. NB: a row marker can have a 0 itcMac*/ if (apap.fTtp) { test = (TAP *) realloc (test, sizeof (TAP) * (j + 1)); wvCopyTAP (&(test[j]), &apap.ptap); for (l = 0; l < apap.ptap.itcMac + 1; l++) wvTrace (("In This Row-->%d\n", apap.ptap.rgdxaCenter[l])); j++; } if (apap.fTtp) k++; } while (apap.fInTable); wvTrace (("BOTTOM\n")); #ifdef DEBUG if (piece == 0xffffffffL) wvTrace (("broken on line %d\n", j)); #endif wvTrace (("no of lines is %d %d\n", j, k)); wvReleasePAPX_FKP (¶_fkp); wvSetTableInfo (ps, test, j); ps->intable = 1; ps->norows = j; wvFree (test); } void wvGetComplexRowTap (wvParseStruct * ps, PAP * dpap, U32 para_intervals, BTE * btePapx, U32 * posPapx, U32 piece) { PAPX_FKP para_fkp; U32 para_fcFirst, para_fcLim = 0xffffffffL; PAP apap; U32 i; S32 j = 0; wvVersion ver = wvQuerySupported (&ps->fib, NULL); wvCopyPAP (&apap, dpap); wvInitPAPX_FKP (¶_fkp); i = wvStream_tell (ps->mainfd); do { wvReleasePAPX_FKP (¶_fkp); wvTrace ( ("3: cp and fc are %x(%d) %x\n", i, i, wvConvertCPToFC (i, &ps->clx))); piece = wvGetComplexParaBounds (ver, ¶_fkp, ¶_fcFirst, ¶_fcLim, i, &ps->clx, btePapx, posPapx, para_intervals, piece, ps->mainfd); if (piece == 0xffffffffL) break; wvAssembleSimplePAP (ver, &apap, para_fcLim, ¶_fkp, ps); wvAssembleComplexPAP (ver, &apap, piece, ps); wvTrace ( ("para from %x to %x, table is %d\n", para_fcFirst, para_fcLim, apap.fInTable)); i = para_fcLim; } while (apap.fTtp == 0); wvReleasePAPX_FKP (¶_fkp); wvCopyTAP (&(dpap->ptap), &apap.ptap); for (j = 0; j < apap.ptap.itcMac + 1; j++) wvTrace (("This Row-->%d\n", apap.ptap.rgdxaCenter[j])); }