UNPKG

console-toolkit

Version:

Toolkit to produce a fancy console output (boxes, tables, charts, colors).

217 lines (201 loc) 7.21 kB
export const drawRect = (bmp, x0, y0, x1, y1, value = 1) => { if (x1 < x0) [x0, x1] = [x1, x0]; if (y1 < y0) [y0, y1] = [y1, y0]; let indexL = bmp.getWordIndex(x0, y0), indexR = bmp.getWordIndex(x1, y0); const mask0 = bmp.getWordMask(x0, 0), mask1 = bmp.getWordMask(x1, 0), rowMask = (1 << bmp.blockWidth) - 1, firstRows = y0 % bmp.blockHeight, firstRowShift = bmp.blockWidth * firstRows, height = y1 - y0 + 1; if (firstRows + (y1 - y0) < bmp.blockHeight) { if (indexL === indexR) { // our rows are in a word: calculate a block mask const mask = ~(mask0 - 1) & (mask1 | (mask1 - 1)); // apply the mask to the last incomplete block let fullMask = mask; for (let i = 1; i < height; ++i) fullMask = (fullMask << bmp.blockWidth) | mask; fullMask <<= firstRowShift; bmp.bitmap[indexL] = value > 0 ? bmp.bitmap[indexL] | fullMask : value < 0 ? bmp.bitmap[indexL] ^ fullMask : bmp.bitmap[indexL] & ~fullMask; return; } // our rows are all in one block vertically but over several words // calculate a left mask and a right masks const maskL = ~(mask0 - 1) & rowMask, maskR = mask1 | (mask1 - 1); // calculate masks let fullMaskL = maskL, fullMaskR = maskR, fullMaskM = ((1 << (bmp.blockWidth * height)) - 1) << firstRowShift; for (let i = 1; i < height; ++i) { fullMaskL = (fullMaskL << bmp.blockWidth) | maskL; fullMaskR = (fullMaskR << bmp.blockWidth) | maskR; } fullMaskL <<= firstRowShift; fullMaskR <<= firstRowShift; // apply masks bmp.bitmap[indexL] = value > 0 ? bmp.bitmap[indexL] | fullMaskL : value < 0 ? bmp.bitmap[indexL] ^ fullMaskL : bmp.bitmap[indexL] & ~fullMaskL; for (let index = indexL + 1; index < indexR; ++index) bmp.bitmap[index] = value > 0 ? bmp.bitmap[index] | fullMaskM : value < 0 ? bmp.bitmap[index] ^ fullMaskM : bmp.bitmap[index] & ~fullMaskM; bmp.bitmap[indexR] = value > 0 ? bmp.bitmap[indexR] | fullMaskR : value < 0 ? bmp.bitmap[indexR] ^ fullMaskR : bmp.bitmap[indexR] & ~fullMaskR; return; } const rowsOverFullBlock = height - (firstRows ? bmp.blockHeight - firstRows : 0), fullLines = Math.floor(rowsOverFullBlock / bmp.blockHeight), lastRows = rowsOverFullBlock % bmp.blockHeight; if (indexL === indexR) { // our row is confined in a word: calculate a row mask const mask = ~(mask0 - 1) & (mask1 | (mask1 - 1)); if (firstRows) { // apply the mask to the first incomplete block let fullMask = mask; for (let i = 1, n = bmp.blockHeight - firstRows; i < n; ++i) fullMask = (fullMask << bmp.blockWidth) | mask; fullMask <<= firstRowShift; bmp.bitmap[indexL] = value > 0 ? bmp.bitmap[indexL] | fullMask : value < 0 ? bmp.bitmap[indexL] ^ fullMask : bmp.bitmap[indexL] & ~fullMask; indexL += bmp.lineSize; } if (fullLines) { // calculate a mask for full blocks let fullMask = mask; for (let i = 1; i < bmp.blockHeight; ++i) fullMask = (fullMask << bmp.blockWidth) | mask; // apply the mask to full blocks for (let i = 0; i < fullLines; ++i, indexL += bmp.lineSize) bmp.bitmap[indexL] = value > 0 ? bmp.bitmap[indexL] | fullMask : value < 0 ? bmp.bitmap[indexL] ^ fullMask : bmp.bitmap[indexL] & ~fullMask; } if (lastRows) { // apply the mask to the last incomplete block let fullMask = mask; for (let i = 1; i < lastRows; ++i) fullMask = (fullMask << bmp.blockWidth) | mask; bmp.bitmap[indexL] = value > 0 ? bmp.bitmap[indexL] | fullMask : value < 0 ? bmp.bitmap[indexL] ^ fullMask : bmp.bitmap[indexL] & ~fullMask; } return; } // calculate a left mask and a right masks const maskL = ~(mask0 - 1) & rowMask, maskR = mask1 | (mask1 - 1); if (firstRows) { // apply the mask to the first incomplete block let fullMaskL = maskL, fullMaskR = maskR, fullMaskM = ((1 << (bmp.blockWidth * (bmp.blockHeight - firstRows))) - 1) << firstRowShift; for (let i = 1, n = bmp.blockHeight - firstRows; i < n; ++i) { fullMaskL = (fullMaskL << bmp.blockWidth) | maskL; fullMaskR = (fullMaskR << bmp.blockWidth) | maskR; } fullMaskL <<= firstRowShift; fullMaskR <<= firstRowShift; bmp.bitmap[indexL] = value > 0 ? bmp.bitmap[indexL] | fullMaskL : value < 0 ? bmp.bitmap[indexL] ^ fullMaskL : bmp.bitmap[indexL] & ~fullMaskL; for (let index = indexL + 1; index < indexR; ++index) bmp.bitmap[index] = value > 0 ? bmp.bitmap[index] | fullMaskM : value < 0 ? bmp.bitmap[index] ^ fullMaskM : bmp.bitmap[index] & ~fullMaskM; bmp.bitmap[indexR] = value > 0 ? bmp.bitmap[indexR] | fullMaskR : value < 0 ? bmp.bitmap[indexR] ^ fullMaskR : bmp.bitmap[indexR] & ~fullMaskR; indexL += bmp.lineSize; indexR += bmp.lineSize; } if (fullLines) { // calculate masks let fullMaskL = maskL, fullMaskR = maskR; for (let i = 1; i < bmp.blockHeight; ++i) { fullMaskL = (fullMaskL << bmp.blockWidth) | maskL; fullMaskR = (fullMaskR << bmp.blockWidth) | maskR; } // apply masks for (let i = 0; i < fullLines; ++i, indexL += bmp.lineSize, indexR += bmp.lineSize) { bmp.bitmap[indexL] = value > 0 ? bmp.bitmap[indexL] | fullMaskL : value < 0 ? bmp.bitmap[indexL] ^ fullMaskL : bmp.bitmap[indexL] & ~fullMaskL; for (let index = indexL + 1; index < indexR; ++index) bmp.bitmap[index] = value > 0 ? ~0 : value < 0 ? ~bmp.bitmap[index] : 0; bmp.bitmap[indexR] = value > 0 ? bmp.bitmap[indexR] | fullMaskR : value < 0 ? bmp.bitmap[indexR] ^ fullMaskR : bmp.bitmap[indexR] & ~fullMaskR; } } if (lastRows) { // apply the mask to an incomplete block let fullMaskL = maskL, fullMaskR = maskR, fullMaskM = (1 << (bmp.blockWidth * lastRows)) - 1; for (let i = 1; i < lastRows; ++i) { fullMaskL = (fullMaskL << bmp.blockWidth) | maskL; fullMaskR = (fullMaskR << bmp.blockWidth) | maskR; } bmp.bitmap[indexL] = value > 0 ? bmp.bitmap[indexL] | fullMaskL : value < 0 ? bmp.bitmap[indexL] ^ fullMaskL : bmp.bitmap[indexL] & ~fullMaskL; for (let index = indexL + 1; index < indexR; ++index) bmp.bitmap[index] = value > 0 ? bmp.bitmap[index] | fullMaskM : value < 0 ? bmp.bitmap[index] ^ fullMaskM : bmp.bitmap[index] & ~fullMaskM; bmp.bitmap[indexR] = value > 0 ? bmp.bitmap[indexR] | fullMaskR : value < 0 ? bmp.bitmap[indexR] ^ fullMaskR : bmp.bitmap[indexR] & ~fullMaskR; } }; export default drawRect;