From f8b44bf17c952097f5ef12a1fac081c0372879cb Mon Sep 17 00:00:00 2001 From: Julian Waller Date: Wed, 23 Mar 2022 22:43:59 +0000 Subject: [PATCH] feat: rounded corners on multiviewer labels --- src/lib/multiviewColours.json | 178 ---------------------------------- src/lib/multiviewLabel.ts | 88 ++++++++++++++--- 2 files changed, 76 insertions(+), 190 deletions(-) delete mode 100644 src/lib/multiviewColours.json diff --git a/src/lib/multiviewColours.json b/src/lib/multiviewColours.json deleted file mode 100644 index 7ac80d2cd..000000000 --- a/src/lib/multiviewColours.json +++ /dev/null @@ -1,178 +0,0 @@ -{ - "0.2": { "172": 6, "173": 222, "174": 156, "175": 229, "176": 227, "177": 219 }, - "0.48": { "177": 158, "178": 18, "179": 159 }, - "0.7": { - "39": 14, - "40": 29, - "41": 85, - "42": 132, - "43": 17, - "45": 30, - "46": 96, - "48": 136, - "49": 186, - "51": 101, - "52": 13, - "54": 19, - "55": 72, - "57": 217, - "58": 124, - "59": 130, - "60": 123, - "61": 47, - "62": 28, - "63": 51, - "64": 32, - "65": 192, - "66": 166, - "67": 56, - "68": 167, - "69": 193, - "70": 189, - "71": 172, - "73": 198, - "75": 41, - "76": 154, - "77": 81, - "79": 109, - "80": 199, - "81": 60, - "82": 108, - "83": 37, - "85": 12, - "86": 15, - "87": 153, - "89": 142, - "90": 68, - "92": 35, - "93": 173, - "94": 141, - "96": 197, - "97": 144, - "99": 94, - "100": 116, - "101": 42, - "103": 214, - "104": 40, - "106": 46, - "107": 184, - "108": 181, - "110": 127, - "111": 175, - "113": 31, - "114": 150, - "115": 213, - "116": 73, - "117": 95, - "118": 86, - "120": 191, - "121": 117, - "123": 135, - "124": 208, - "125": 22, - "127": 78, - "128": 107, - "130": 179, - "131": 210, - "132": 119, - "134": 58, - "135": 67, - "137": 209, - "138": 171, - "139": 110, - "141": 89, - "142": 103, - "143": 133, - "144": 43, - "145": 202, - "146": 137, - "148": 66, - "149": 39, - "150": 151, - "151": 129, - "152": 71, - "154": 200, - "155": 26, - "156": 111, - "157": 128, - "159": 16, - "161": 23, - "162": 196, - "163": 201, - "164": 36, - "165": 106, - "166": 207, - "168": 205, - "169": 69, - "170": 139, - "171": 62, - "172": 105, - "173": 90, - "175": 203, - "176": 216, - "177": 54, - "179": 99, - "180": 100, - "182": 88, - "183": 146, - "184": 145, - "186": 74, - "187": 80, - "189": 204, - "190": 180, - "191": 84, - "192": 138, - "193": 212, - "194": 215, - "196": 24, - "197": 63, - "199": 187, - "200": 118, - "201": 148, - "203": 183, - "204": 57, - "206": 102, - "207": 206, - "208": 44, - "210": 152, - "211": 190, - "213": 134, - "214": 59, - "215": 182, - "217": 87, - "218": 48, - "219": 174, - "220": 125, - "221": 104, - "223": 140, - "224": 188, - "225": 92, - "226": 131, - "227": 178, - "228": 64, - "230": 70, - "231": 76, - "232": 65, - "233": 79, - "234": 121, - "235": 113, - "237": 176, - "238": 177, - "239": 211, - "241": 75, - "242": 120, - "244": 82, - "245": 93, - "246": 98, - "248": 122, - "249": 53, - "251": 115, - "252": 45, - "253": 55, - "254": 34 - }, - "0.05": { "150": 194, "160": 168, "167": 160 }, - "0.3": { "173": 164, "174": 195, "175": 165, "176": 161, "177": 169 }, - "0.42": { "176": 170, "177": 162 }, - "0.55": { "177": 228, "178": 230, "179": 225 } -} diff --git a/src/lib/multiviewLabel.ts b/src/lib/multiviewLabel.ts index ea8ea1c36..6d080f7bf 100644 --- a/src/lib/multiviewLabel.ts +++ b/src/lib/multiviewLabel.ts @@ -5,7 +5,8 @@ import { getVideoModeInfo } from './atemUtil' /** * Colour lookup table for converting 8bit grey to the atem encoding - * Note: not every colour is available, so values have been extrapolated to fill in the gaps + * Note: not every colour is available, so values have been extrapolated to fill in the gaps. + * Also the background colour has been filled in for lower values, to ensure that the text doesnt accidentally remove the background */ const colourLookupTable = [ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, @@ -20,6 +21,14 @@ const colourLookupTable = [ 79, 121, 113, 176, 176, 177, 211, 75, 75, 120, 82, 82, 93, 98, 122, 122, 53, 115, 115, 45, 55, 34, 34, ] +function fillResolutionSpec(spec: Omit): ResolutionSpec { + return { + ...spec, + cornerRight: spec.corner.map((buf) => { + return Buffer.from(buf).reverse() + }), + } +} interface ResolutionSpec { width: number height: number @@ -27,35 +36,72 @@ interface ResolutionSpec { yPadBottom: number yPadTop: number fontHeight: number + + borderColour: number + corner: Buffer[] + cornerRight: Buffer[] } -const Res4K: ResolutionSpec = { +const Res4K = fillResolutionSpec({ width: 640, height: 100, xPad: 10, yPadBottom: 8, yPadTop: 4, fontHeight: 46, -} -const Res1080: ResolutionSpec = { + + borderColour: 0x05, + corner: [ + Buffer.from([0, 0, 0, 0, 0, 0, 223, 2, 162, 220, 20]), + Buffer.from([0, 0, 0, 0, 223, 195, 20, 5, 5, 5, 5]), + Buffer.from([0, 0, 0, 7, 3, 5, 5, 110, 141, 124, 29]), + Buffer.from([0, 0, 7, 220, 5, 200, 97, 14, 14, 14, 14]), + Buffer.from([0, 223, 3, 5, 209, 29, 14, 14, 14, 14, 14]), + Buffer.from([0, 219, 5, 200, 29, 14, 14, 14, 14, 14, 14]), + Buffer.from([223, 20, 5, 97, 14, 14, 14, 14, 14, 14, 14]), + Buffer.from([2, 5, 110, 14, 14, 14, 14, 14, 14, 14, 14]), + Buffer.from([162, 5, 141, 14, 14, 14, 14, 14, 14, 14, 14]), + Buffer.from([220, 5, 124, 14, 14, 14, 14, 14, 14, 14, 14]), + Buffer.from([20, 5, 29, 14, 14, 14, 14, 14, 14, 14, 14]), + ], +}) +const Res1080 = fillResolutionSpec({ width: 320, height: 50, xPad: 10, yPadBottom: 8, yPadTop: 4, fontHeight: 26, -} -const Res720: ResolutionSpec = { + + borderColour: 0x05, + corner: [ + Buffer.from([0, 0, 1, 229, 230, 20]), + Buffer.from([0, 7, 158, 5, 5, 5]), + Buffer.from([1, 158, 5, 23, 37, 101]), + Buffer.from([229, 5, 23, 29, 14, 14]), + Buffer.from([230, 5, 37, 14, 14, 14]), + Buffer.from([20, 5, 101, 14, 14, 14]), + ], +}) +const Res720 = fillResolutionSpec({ width: 320, // TODO - is this correct for all models? height: 40, xPad: 10, yPadBottom: 8, yPadTop: 4, - fontHeight: 16, -} + fontHeight: 17, + + borderColour: 170, + corner: [ + Buffer.from([0, 0, 160, 169]), + Buffer.from([0, 165, 165, 169]), + Buffer.from([160, 165, 56, 14]), + Buffer.from([169, 169, 14, 14]), + ], +}) // const transparentColour = 0 // encoded value const bgColour = colourLookupTable[0] // 'background' value -const borderColour = 0x05 // encoded value +// const borderColour = 0x05 // encoded value function calculateWidthAndTrimText( face: FontFace, @@ -113,15 +159,33 @@ function drawTextToBuffer( const isBorder = y == 0 || y == 1 || y === boundaryHeight - 1 || y === boundaryHeight - 2 if (isBorder) { - drawHorizontalLine(y, 0, boundaryWidth, borderColour) + drawHorizontalLine(y, 0, boundaryWidth, spec.borderColour) } else { - drawHorizontalLine(y, 0, 2, borderColour) - drawHorizontalLine(y, boundaryWidth - 2, 2, borderColour) + drawHorizontalLine(y, 0, 2, spec.borderColour) + drawHorizontalLine(y, boundaryWidth - 2, 2, spec.borderColour) drawHorizontalLine(y, 2, boundaryWidth - 4, bgColour) } } + // Patch on the rounded corners + for (let i = 0; i < spec.corner.length; i++) { + const cornerBufferLeft = spec.corner[i] + const cornerBufferRight = spec.cornerRight[i] + + const offsetTopLeft = (boundaryYOffset + i) * bufferWidth + boundaryXOffset + cornerBufferLeft.copy(buffer, offsetTopLeft) + + const offsetBottomLeft = (boundaryYOffset + boundaryHeight - i - 1) * bufferWidth + boundaryXOffset + cornerBufferLeft.copy(buffer, offsetBottomLeft) + + const offsetTopRight = offsetTopLeft + boundaryWidth - cornerBufferRight.length + cornerBufferRight.copy(buffer, offsetTopRight) + + const offsetBottomRight = offsetBottomLeft + boundaryWidth - cornerBufferRight.length + cornerBufferRight.copy(buffer, offsetBottomRight) + } + const maxLeft = boundaryXOffset + spec.width + spec.xPad let charLeft = boundaryXOffset + spec.xPad const textTop = boundaryYOffset + spec.fontHeight + spec.yPadTop