diff --git a/src/serve_rendered.js b/src/serve_rendered.js index 2a82804..ec590b6 100644 --- a/src/serve_rendered.js +++ b/src/serve_rendered.js @@ -1,12 +1,24 @@ 'use strict'; +// SECTION START +// +// The order of the two imports below is important. +// For an unknown reason, if the order is reversed, rendering can crash. +// This happens on ARM: +// > terminate called after throwing an instance of 'std::runtime_error' +// > what(): Cannot read GLX extensions. +import 'canvas'; +import '@maplibre/maplibre-gl-native'; +// +// SECTION END + import advancedPool from 'advanced-pool'; import fs from 'node:fs'; import path from 'path'; import url from 'url'; import util from 'util'; import zlib from 'zlib'; -import sharp from 'sharp'; // sharp has to be required before node-canvas on linux but after it on windows. see https://github.com/lovell/sharp/issues/371 +import sharp from 'sharp'; import clone from 'clone'; import Color from 'color'; import express from 'express'; @@ -428,24 +440,9 @@ const respondImage = ( return res.status(500).header('Content-Type', 'text/plain').send(err); } - // Fix semi-transparent outlines on raw, premultiplied input - // https://github.com/maptiler/tileserver-gl/issues/350#issuecomment-477857040 - for (let i = 0; i < data.length; i += 4) { - const alpha = data[i + 3]; - const norm = alpha / 255; - if (alpha === 0) { - data[i] = 0; - data[i + 1] = 0; - data[i + 2] = 0; - } else { - data[i] = data[i] / norm; - data[i + 1] = data[i + 1] / norm; - data[i + 2] = data[i + 2] / norm; - } - } - const image = sharp(data, { raw: { + premultiplied: true, width: params.width * scale, height: params.height * scale, channels: 4, diff --git a/src/utils.js b/src/utils.js index 8ed2d9c..4fdf43a 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,7 +1,8 @@ 'use strict'; import path from 'path'; -import fs from 'node:fs'; +import fsPromises from 'fs/promises'; +import fs, { existsSync } from 'node:fs'; import clone from 'clone'; import glyphCompose from '@mapbox/glyph-pbf-composite'; @@ -166,30 +167,18 @@ export const getFontsPbf = async ( export const listFonts = async (fontPath) => { const existingFonts = {}; - const fontListingPromise = new Promise((resolve, reject) => { - fs.readdir(fontPath, (err, files) => { - if (err) { - reject(err); - return; - } - for (const file of files) { - fs.stat(path.join(fontPath, file), (err, stats) => { - if (err) { - reject(err); - return; - } - if ( - stats.isDirectory() && - fs.existsSync(path.join(fontPath, file, '0-255.pbf')) - ) { - existingFonts[path.basename(file)] = true; - } - }); - } - resolve(); - }); - }); - await fontListingPromise; + + const files = await fsPromises.readdir(fontPath); + for (const file of files) { + const stats = await fsPromises.stat(path.join(fontPath, file)); + if ( + stats.isDirectory() && + existsSync(path.join(fontPath, file, '0-255.pbf')) + ) { + existingFonts[path.basename(file)] = true; + } + } + return existingFonts; };