diff --git a/lib/render.js b/lib/render.js index bf7dcc9..9f9fc51 100644 --- a/lib/render.js +++ b/lib/render.js @@ -86,15 +86,25 @@ const getAttr = (e, opt, step, lsbm, msbm) => { const x = opt.vflip ? step * ((msbm + lsbm) / 2) : step * (opt.mod - ((msbm + lsbm) / 2) - 1); + + const sliceLen = msbm - lsbm + 1; + const laneStart = opt.index * opt.mod; + const sliceLsbGlobal = Math.max(e.lsb, laneStart); + const shift = sliceLsbGlobal - e.lsb; if (!Array.isArray(e.attr)) { - return getLabel(e.attr, x, 0, step, e.bits); + const val = typeof e.attr === 'number' ? (e.attr >> shift) : e.attr; + return getLabel(val, x, 0, step, sliceLen); } - return e.attr.reduce((prev, a, i) => - (a === undefined || a === null) - ? prev - : prev.concat([getLabel(a, x, opt.fontsize * i, step, e.bits)]), - ['g', {}]); + return e.attr.reduce( + (prev, a, i) => { + if (a === undefined || a === null) return prev; + const val = typeof a === 'number' ? (a >> shift) : a; + return prev.concat([ + getLabel(val, x, opt.fontsize * i, step, sliceLen), + ]); + }, + ['g', {}]); }; const labelArr = (desc, opt) => { @@ -107,29 +117,26 @@ const labelArr = (desc, opt) => { const names = ['g', tt(round(step / 2), round(0.5 * height + 0.4 * fontsize - 6))]; const attrs = ['g', tt(round(step / 2), round(height + 0.7 * fontsize - 2))]; desc.map(e => { - let lsbm = 0; - let msbm = mod - 1; - let lsb = index * mod; - let msb = (index + 1) * mod - 1; - if (((e.lsb / mod) >> 0) === index) { - lsbm = e.lsbm; - lsb = e.lsb; - if (((e.msb / mod) >> 0) === index) { - msb = e.msb; - msbm = e.msbm; - } - } else { - if (((e.msb / mod) >> 0) === index) { - msb = e.msb; - msbm = e.msbm; - } else if (!(lsb > e.lsb && msb < e.msb)) { - return; - } + const laneStart = index * mod; + const laneEnd = (index + 1) * mod - 1; + + // Skip if no overlap + if (e.msb < laneStart || e.lsb >= laneEnd + 1) { + return; } + + let lsbm = Math.max(0, e.lsb - laneStart); + let msbm = Math.min(mod - 1, e.msb - laneStart); + + const startsInLane = e.lsb >= laneStart && e.lsb <= laneEnd; + const endsInLane = e.msb >= laneStart && e.msb <= laneEnd; + const lsbLabel = (startsInLane ? e.lsb : laneStart) + offset; + const msbLabel = (endsInLane ? e.msb : laneEnd) + offset; + if (!compact) { - bits.push(text(lsb + offset, step * (vflip ? lsbm : (mod - lsbm - 1)))); + bits.push(text(lsbLabel, step * (vflip ? lsbm : (mod - lsbm - 1)))); if (lsbm !== msbm) { - bits.push(text(msb + offset, step * (vflip ? msbm : (mod - msbm - 1)))); + bits.push(text(msbLabel, step * (vflip ? msbm : (mod - msbm - 1)))); } } if (e.name !== undefined) {