Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fonts not working #2391

Open
SalvoLunar opened this issue Jun 29, 2024 · 1 comment
Open

Fonts not working #2391

SalvoLunar opened this issue Jun 29, 2024 · 1 comment

Comments

@SalvoLunar
Copy link

SalvoLunar commented Jun 29, 2024

Hello there,

I've been trying to make custom fonts work in a lambda/.docker container for a week now but there seem to be no way to make it happen.

Here is my javascript code:

`
import { createCanvas, loadImage, registerFont } from 'canvas';
import createDOMPurify from 'dompurify';
import { JSDOM } from 'jsdom';

async function generateCanvasImage(params) {

const config = params.templateName === 'book1' ? book1Config : book2Config;
const imagesConfig = await fetchTemplate(
https://xxxx.s3.eu-west-1.amazonaws.com/${params.templateName}.json
);

registerFont('assets/fonts/bronic.ttf', { family: 'Bronic', weight: 'normal', style: 'regular' });
registerFont('assets/fonts/Neo-Regular.ttf', {family: 'Neo', weight: 'normal', style: 'regular'});

const scale = 3; // Increase for higher DPI; typical high-DPI screens use a scale of 2 or 3
const canvas = createCanvas(
config.pageSize.width * scale,
config.pageSize.height * scale
);
const ctx = canvas.getContext('2d');
ctx.scale(scale, scale);

const pageIndex = params.pageIndex;
const page = config.pages[pageIndex];

const pageCharacters = imagesConfig[pageIndex].characters;

//Draw background
const bg = await loadImage(page.background);
ctx.drawImage(bg, 0, 0, config.pageSize.width, config.pageSize.height);

// Draw characters
for (let i = 0; i < page.characters.length; i++) {
const character = page.characters[i];
const { size, position } = getCharacterSizeAndPosition(character, params);
const id = slugify(
character.id === 'pet'
? page-${pageIndex}-${params.petBreed}-${params.petColor}
: page-${pageIndex}-${params.companionAge}-${params.companionGender}-${params.companionSkin}-${params.companionHair}
);
logger.info(id, i);

if (
  typeof pageCharacters.filter((c) => c.id === character.id)[0] !==
  'undefined'
) {
  const characterImageObj = pageCharacters
    .filter((c) => c.id === character.id)[0]
    .prompts.filter((p) => p.id.toLowerCase() === id.toLowerCase())[0];
  if (
    typeof characterImageObj !== 'undefined' &&
    typeof characterImageObj.imgLocS3 !== 'undefined'
  ) {
    const characterImage = await fetchImage(
      characterImageObj.imgLocS3 + '?t=' + new Date().valueOf()
    );
    const img = await loadImage(
      `data:image/jpeg;base64,${Buffer.from(characterImage).toString(
        'base64'
      )}`
    );
    ctx.drawImage(img, position.x, position.y, size, size);
    // doc.image(Buffer.from(characterImage), position.x, position.y, { fit: [size, size], align: 'center', valign: 'center' });
  } else {
    logger.error(`Found undefined for ${id}`);
  }
} else {
  logger.error(`Found undefined character for ${id}`);
}

}

for (let o = 0; o < page.overlays.length; o++) {
let overlay = page.overlays[o];
console.log(overlay);
const img = await loadImage(overlay.url);
ctx.drawImage(
img,
overlay.position.x,
overlay.position.y,
config.pageSize.width,
config.pageSize.height
);
}

for (let t = 0; t < page.text_contents.length; t++) {
let text_content = page.text_contents[t];

ctx.fillStyle = '#D9FFF2';
console.log(`'${text_content.fontSize}px "${text_content.font}"'`);
ctx.font = `${text_content.fontSize}px "${text_content.font}"`;
ctx.textAlign = text_content.align;

ctx.fillText(
  replacePlaceholders(text_content.text, params),
  text_content.position.x,
  text_content.position.y
);

}

return canvas.toBuffer();
}`

These are my system details

"node version" 20
"node-canvas":"2.11.2",
"cairoVersion":"1.17.6",
"jpegVersion":"6b",
"gifVersion":"5.2.1",
"freetypeVersion":"2.13.0",
"pangoVersion":"1.48.10"

The whole application runs inside a lambda / docker container, this is the dockerfile

`FROM public.ecr.aws/lambda/nodejs:20

RUN dnf install -y gcc-c++
cairo
cairo-devel
pango
pango-devel
libjpeg
libjpeg-devel
giflib
giflib-devel
libpng
libpng-devel
pixman
pixman-devel
python3
make

ENV PKG_CONFIG_PATH=/usr/lib64/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig

RUN rm -rf /usr/share/fonts/*
RUN rm -rf /usr/local/share/fonts/*
RUN rm -rf ${HOME}/.local/share/fonts/*
RUN mkdir -p /usr/local/share/fonts/bronic
COPY assets/fonts/bronic.ttf /usr/local/share/fonts/bronic
RUN chmod 644 /usr/local/share/fonts/bronic/*
RUN mkdir -p /usr/local/share/fonts/allianz-neo
COPY assets/fonts/Neo-Regular.ttf /usr/local/share/fonts/neo
RUN chmod 644 /usr/local/share/fonts/allianz-neo/*

ENV FONTCONFIG_PATH /usr/local/share/fonts/
RUN fc-cache --really-force --verbose
COPY assets ${LAMBDA_TASK_ROOT}/assets
COPY templates ${LAMBDA_TASK_ROOT}/templates
RUN ls -la ${LAMBDA_TASK_ROOT}/*
COPY package*.json handler.js pageGenerator.js sizingLogic.js ${LAMBDA_TASK_ROOT}

WORKDIR ${LAMBDA_TASK_ROOT}

RUN chmod 777 ${LAMBDA_TASK_ROOT}/assets/fonts

RUN npm i node-gyp -g

RUN npm install

CMD ["handler.generatePages"]`

I've tried both the approaches installing the font directly onto docker and then just referencing it into my code, or using registerFont in the code and pointing to the correct ttf file.

Nothing seems to be working and there seems to be no utility to debug this, to verify if the fonts have been loaded correctly.

I can definitely see that the font file is found but then it just doesn't render.

Does anybody have any idea of how to solve this issue?

Thanks,
Salvo

@SalvoLunar
Copy link
Author

Nevermind.!!!.... I solved this issue adding:

RUN npm rebuild canvas --build-from-source

to my dockerfile!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant