From 951d1217b1e4acb1ca88a004e92a93c349c8802a Mon Sep 17 00:00:00 2001 From: Julian Waller Date: Mon, 28 Mar 2022 23:25:59 +0100 Subject: [PATCH] feat: customisable font scale --- src/atem.ts | 15 ++++++++++++++- src/lib/multiviewLabel.ts | 20 +++++++++++++------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/atem.ts b/src/atem.ts index b6071d9df..a3b8b9f0f 100644 --- a/src/atem.ts +++ b/src/atem.ts @@ -240,11 +240,13 @@ export class BasicAtem extends EventEmitter { export class Atem extends BasicAtem { #multiviewerFontFace: Promise + #multiviewerFontScale: number constructor(options?: AtemOptions) { super(options) this.#multiviewerFontFace = PLazy.from(async () => loadFont()) + this.#multiviewerFontScale = 1.0 } /** @@ -264,6 +266,17 @@ export class Atem extends BasicAtem { this.#multiviewerFontFace = Promise.resolve(loadedFont) } + /** + * Set the scale factor for the multiviewer text. Default is 1 + */ + public setMultiviewerFontScale(scale: number | null): void { + if (typeof scale === 'number') { + if (scale <= 0) throw new Error('Scale must be greater than 0') + this.#multiviewerFontScale = scale + } else if (scale === null) { + this.#multiviewerFontScale = 1.0 + } + } public async changeProgramInput(input: number, me = 0): Promise { const command = new Commands.ProgramInputCommand(me, input) @@ -1019,7 +1032,7 @@ export class Atem extends BasicAtem { const fontFace = await this.#multiviewerFontFace - const buffer = generateMultiviewerLabel(fontFace, text, props) + const buffer = generateMultiviewerLabel(fontFace, this.#multiviewerFontScale, text, props) // Note: we should probably validate the buffer looks like it doesn't contain crashy data, but as we generate we can trust it return this.dataTransferManager.uploadMultiViewerLabel(inputId, buffer) } diff --git a/src/lib/multiviewLabel.ts b/src/lib/multiviewLabel.ts index ac20a8a04..15fb3518d 100644 --- a/src/lib/multiviewLabel.ts +++ b/src/lib/multiviewLabel.ts @@ -136,17 +136,19 @@ function calculateWidthAndTrimText( function drawTextToBuffer( face: FontFace, + fontScale: number, buffer: Buffer, spec: ResolutionSpec, rawText: string, bufferYOffset: number, bufferWidth: number ): void { - face.setPixelSizes(spec.fontHeight, spec.fontHeight) + const fontHeight = spec.fontHeight * fontScale + face.setPixelSizes(fontHeight, fontHeight) const { width: textWidth, str: newStr } = calculateWidthAndTrimText(face, rawText, spec.width - spec.xPad * 2) const boundaryWidth = Math.floor(textWidth + spec.xPad * 2) - const boundaryHeight = Math.floor(spec.fontHeight + spec.yPadTop + spec.yPadBottom) + const boundaryHeight = Math.floor(fontHeight + spec.yPadTop + spec.yPadBottom) const bufferXOffset = Math.floor((bufferWidth - spec.width) / 2) // Fill background of boundary, and a 2px border @@ -190,7 +192,7 @@ function drawTextToBuffer( const maxLeft = boundaryXOffset + spec.width + spec.xPad let charLeft = boundaryXOffset + spec.xPad - const textTop = boundaryYOffset + spec.fontHeight + spec.yPadTop + const textTop = boundaryYOffset + fontHeight + spec.yPadTop // Draw text characters for (let i = 0; i < newStr.length; i++) { @@ -239,7 +241,12 @@ export interface GenerateMultiviewerLabelProps { * @param props Specify which resolutions to generate for * @returns Buffer */ -export function generateMultiviewerLabel(face: FontFace, str: string, props: GenerateMultiviewerLabelProps): Buffer { +export function generateMultiviewerLabel( + face: FontFace, + fontScale: number, + str: string, + props: GenerateMultiviewerLabelProps +): Buffer { // Calculate the sizes let width: number | undefined let height = 0 @@ -264,7 +271,7 @@ export function generateMultiviewerLabel(face: FontFace, str: string, props: Gen let yOffset = 0 const drawRes = (spec: ResolutionSpec): void => { - drawTextToBuffer(face, buffer, spec, str, yOffset, width2) + drawTextToBuffer(face, fontScale, buffer, spec, str, yOffset, width2) yOffset += spec.height } @@ -325,8 +332,7 @@ export function calculateGenerateMultiviewerLabelProps( } export async function loadFont(fontPath?: string): Promise { - // if (!fontPath) fontPath = path.join(__dirname, '../../assets/roboto/Roboto-Regular.ttf') - if (!fontPath) fontPath = path.join(__dirname, '../../assets/Helvetica.ttf') + if (!fontPath) fontPath = path.join(__dirname, '../../assets/roboto/Roboto-Regular.ttf') const fontFile = await readFile(fontPath) return NewMemoryFace(fontFile)