fix(bbb-export-annotations): Handle text rendering issue (#20857)
* Handle error when imagemagick fails to render * Update bbb-export-annotations/workers/process.js Co-authored-by: Anton Georgiev <antobinary@users.noreply.github.com> * Update bbb-export-annotations/workers/process.js Co-authored-by: Anton Georgiev <antobinary@users.noreply.github.com> * Add more detailed logs --------- Co-authored-by: Anton Georgiev <antobinary@users.noreply.github.com>
This commit is contained in:
parent
352f3ebd58
commit
656cdb44cf
@ -130,6 +130,7 @@ function escapeText(string) {
|
|||||||
.replace(/</g, '\\<');
|
.replace(/</g, '\\<');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rasterizes text into an image. Returns true if successful, false otherwise.
|
||||||
function render_textbox(textColor, font, fontSize, textAlign, text, id, textBoxWidth = null) {
|
function render_textbox(textColor, font, fontSize, textAlign, text, id, textBoxWidth = null) {
|
||||||
fontSize = to_pt(fontSize) * config.process.textScaleFactor;
|
fontSize = to_pt(fontSize) * config.process.textScaleFactor;
|
||||||
text = escapeText(text);
|
text = escapeText(text);
|
||||||
@ -155,12 +156,15 @@ function render_textbox(textColor, font, fontSize, textAlign, text, id, textBoxW
|
|||||||
path.join(dropbox, `text${id}.png`),
|
path.join(dropbox, `text${id}.png`),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
try {
|
const result = cp.spawnSync(config.shared.imagemagick, commands, {shell: false});
|
||||||
cp.spawnSync(config.shared.imagemagick, commands, {shell: false});
|
|
||||||
} catch (error) {
|
if (result.error || result.status !== 0) {
|
||||||
logger.error(`ImageMagick failed to render textbox in job ${jobId}: ${error.message}`);
|
logger.error(`ImageMagick failed to render textbox in job ${jobId}: ${error.message}`);
|
||||||
statusUpdate.setError();
|
statusUpdate.setError();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_gap(dash, size) {
|
function get_gap(dash, size) {
|
||||||
@ -607,10 +611,10 @@ function overlay_shape_label(svg, annotation) {
|
|||||||
const label_center_x = shape_x + shape_width * x_offset;
|
const label_center_x = shape_x + shape_width * x_offset;
|
||||||
const label_center_y = shape_y + shape_height * y_offset;
|
const label_center_y = shape_y + shape_height * y_offset;
|
||||||
|
|
||||||
render_textbox(fontColor, font, fontSize, textAlign, text, id);
|
const renderStatus = render_textbox(fontColor, font, fontSize, textAlign, text, id);
|
||||||
const shape_label = path.join(dropbox, `text${id}.png`);
|
const shape_label = path.join(dropbox, `text${id}.png`);
|
||||||
|
|
||||||
if (fs.existsSync(shape_label)) {
|
if (fs.existsSync(shape_label) && renderStatus) {
|
||||||
// Poll results must fit inside shape, unlike other rectangle labels.
|
// Poll results must fit inside shape, unlike other rectangle labels.
|
||||||
// Linewrapping handled by client.
|
// Linewrapping handled by client.
|
||||||
const ref = `file://${dropbox}/text${id}.png`;
|
const ref = `file://${dropbox}/text${id}.png`;
|
||||||
@ -634,6 +638,8 @@ function overlay_shape_label(svg, annotation) {
|
|||||||
'height': labelHeight,
|
'height': labelHeight,
|
||||||
'xlink:href': ref,
|
'xlink:href': ref,
|
||||||
}).up();
|
}).up();
|
||||||
|
} else {
|
||||||
|
logger.warn(`Could not render status in overlay_shape_label for ${annotation}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,25 +657,29 @@ function overlay_sticky(svg, annotation) {
|
|||||||
const text = annotation.text;
|
const text = annotation.text;
|
||||||
const id = sanitize(annotation.id);
|
const id = sanitize(annotation.id);
|
||||||
|
|
||||||
render_textbox(textColor, font, fontSize, textAlign, text, id, textBoxWidth);
|
const renderStatus = render_textbox(textColor, font, fontSize, textAlign, text, id, textBoxWidth);
|
||||||
|
|
||||||
// Overlay transparent text image over empty sticky note
|
// Overlay transparent text image over empty sticky note
|
||||||
svg.ele('g', {
|
if (renderStatus) {
|
||||||
transform: `rotate(${rotation}, ${textBox_x + (textBoxWidth / 2)}, ${textBox_y + (textBoxHeight / 2)})`,
|
svg.ele('g', {
|
||||||
}).ele('rect', {
|
transform: `rotate(${rotation}, ${textBox_x + (textBoxWidth / 2)}, ${textBox_y + (textBoxHeight / 2)})`,
|
||||||
x: textBox_x,
|
}).ele('rect', {
|
||||||
y: textBox_y,
|
x: textBox_x,
|
||||||
width: textBoxWidth,
|
y: textBox_y,
|
||||||
height: textBoxHeight,
|
width: textBoxWidth,
|
||||||
fill: backgroundColor,
|
height: textBoxHeight,
|
||||||
}).up()
|
fill: backgroundColor,
|
||||||
.ele('image', {
|
}).up()
|
||||||
'x': textBox_x,
|
.ele('image', {
|
||||||
'y': textBox_y,
|
'x': textBox_x,
|
||||||
'width': textBoxWidth,
|
'y': textBox_y,
|
||||||
'height': textBoxHeight,
|
'width': textBoxWidth,
|
||||||
'xlink:href': `file://${dropbox}/text${id}.png`,
|
'height': textBoxHeight,
|
||||||
}).up();
|
'xlink:href': `file://${dropbox}/text${id}.png`,
|
||||||
|
}).up();
|
||||||
|
} else {
|
||||||
|
logger.warn(`Could not render status in overlay_sticky for ${annotation}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function overlay_triangle(svg, annotation) {
|
function overlay_triangle(svg, annotation) {
|
||||||
@ -719,20 +729,24 @@ function overlay_text(svg, annotation) {
|
|||||||
const rotation = rad_to_degree(annotation.rotation);
|
const rotation = rad_to_degree(annotation.rotation);
|
||||||
const [textBox_x, textBox_y] = annotation.point;
|
const [textBox_x, textBox_y] = annotation.point;
|
||||||
|
|
||||||
render_textbox(fontColor, font, fontSize, textAlign, text, id);
|
const renderStatus = render_textbox(fontColor, font, fontSize, textAlign, text, id);
|
||||||
|
|
||||||
const rotation_x = textBox_x + (textBoxWidth / 2);
|
if (renderStatus) {
|
||||||
const rotation_y = textBox_y + (textBoxHeight / 2);
|
const rotation_x = textBox_x + (textBoxWidth / 2);
|
||||||
|
const rotation_y = textBox_y + (textBoxHeight / 2);
|
||||||
|
|
||||||
svg.ele('g', {
|
svg.ele('g', {
|
||||||
transform: `rotate(${rotation} ${rotation_x} ${rotation_y})`,
|
transform: `rotate(${rotation} ${rotation_x} ${rotation_y})`,
|
||||||
}).ele('image', {
|
}).ele('image', {
|
||||||
'x': textBox_x,
|
'x': textBox_x,
|
||||||
'y': textBox_y,
|
'y': textBox_y,
|
||||||
'width': textBoxWidth,
|
'width': textBoxWidth,
|
||||||
'height': textBoxHeight,
|
'height': textBoxHeight,
|
||||||
'xlink:href': `file://${dropbox}/text${id}.png`,
|
'xlink:href': `file://${dropbox}/text${id}.png`,
|
||||||
}).up();
|
}).up();
|
||||||
|
} else {
|
||||||
|
logger.warn(`Could not render status in render_textbox for ${annotation}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function overlay_annotation(svg, currentAnnotation) {
|
function overlay_annotation(svg, currentAnnotation) {
|
||||||
|
Loading…
Reference in New Issue
Block a user