jsPDF icon indicating copy to clipboard operation
jsPDF copied to clipboard

Text centers incorrectly with nonzero charSpace

Open avelican opened this issue 3 years ago • 3 comments

let pdf = new jspdf.jsPDF();
let page_height = pdf.internal.pageSize.getHeight();
let page_width = pdf.internal.pageSize.getWidth(); 
let x_center = page_width / 2;
let y1 = page_height / 3;
let y2 = y1 + 12;
let y3 = y1 + 24;
let txt = "The quick brown fox jumps over the lazy dog."; 

pdf.text(txt, x_center, y1, { align: 'center', charSpace: 0 });
pdf.text(txt, x_center, y2, { align: 'center', charSpace: -1 });
pdf.text(txt, x_center, y3, { align: 'center', charSpace: 1 });

pdf.save('charspace_bug.pdf');

Expectation: All lines are centered around x_center.

Result: Only the { charSpace: 0 } line is centered. Other lines are left-aligned to that line's left edge.

Hypothesis: jsPDF calculates the starting coordinate before the charSpace transformation is applied?

avelican avatar Apr 07 '22 22:04 avelican

Attempted to work around this manually with pdf.getStringUnitWidth(); and discovered that this function always returns the same value regardless of the charSpace given:

pdf.getStringUnitWidth("hello there", { charSpace: 0 }); // gives 4.63
pdf.getStringUnitWidth("hello there", { charSpace: 1 }); // gives 4.63

avelican avatar Apr 07 '22 22:04 avelican

Added a workaround to my print function:

if(options.align == 'center'){
	let x_coord = page_center_x;
	// workaround for charspace alignment bug
	if(options.charSpace && options.charSpace != 0){
		let adjustment = options.charSpace * pdf.getStringUnitWidth(text);
		pdf.text(text, x_coord - adjustment, y_coord, options);
	}else{
		pdf.text(text, x_coord, y_coord, options);
	}
}

Arrived at this through trial and error and with a little help from WolframAlpha's formula simplification feature :)

avelican avatar Apr 07 '22 23:04 avelican

Thanks for the report. Could you prepare a pull request?

HackbrettXXX avatar Apr 14 '22 10:04 HackbrettXXX