From d7583b014e584d733321031677d11c24a8c7bfd3 Mon Sep 17 00:00:00 2001 From: Dave Pagurek Date: Fri, 20 Dec 2024 13:34:09 -0500 Subject: [PATCH] Make angles respect angleMode --- src/type/p5.Font.js | 13 +++++++-- test/unit/visual/cases/typography.js | 27 ++++++++++++++++++ .../000.png | Bin 0 -> 2205 bytes .../metadata.json | 3 ++ .../000.png | Bin 0 -> 2205 bytes .../metadata.json | 3 ++ 6 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 test/unit/visual/screenshots/Typography/textToPoints/Fonts point angles work in DEGREES mode/000.png create mode 100644 test/unit/visual/screenshots/Typography/textToPoints/Fonts point angles work in DEGREES mode/metadata.json create mode 100644 test/unit/visual/screenshots/Typography/textToPoints/Fonts point angles work in RADIANS mode/000.png create mode 100644 test/unit/visual/screenshots/Typography/textToPoints/Fonts point angles work in RADIANS mode/metadata.json diff --git a/src/type/p5.Font.js b/src/type/p5.Font.js index 9e7d333492..12d883a2a0 100644 --- a/src/type/p5.Font.js +++ b/src/type/p5.Font.js @@ -151,7 +151,7 @@ function font(p5, fn) { cmdContours[cmdContours.length - 1].push(cmd); } - return cmdContours.map((commands) => pathToPoints(commands, options)); + return cmdContours.map((commands) => pathToPoints(commands, options, this)); } textToModel(str, x, y, width, height, options) { @@ -678,7 +678,7 @@ function font(p5, fn) { return path; }; - function pathToPoints(cmds, options) { + function pathToPoints(cmds, options, font) { const parseOpts = (options, defaults) => { if (typeof options !== 'object') { @@ -720,12 +720,19 @@ function font(p5, fn) { const totalPoints = Math.ceil(path.getTotalLength() * opts.sampleFactor); let points = []; + const mode = font._pInst.angleMode(); + const DEGREES = font._pInst.DEGREES; for (let i = 0; i < totalPoints; i++) { const length = path.getTotalLength() * (i / (totalPoints - 1)); points.push({ ...path.getPointAtLength(length), get angle() { - return path.getAngleAtLength(length) * 180 / Math.PI; + const angle = path.getAngleAtLength(length); + if (mode === DEGREES) { + return angle * 180 / Math.PI; + } else { + return angle; + } }, // For backwards compatibility get alpha() { diff --git a/test/unit/visual/cases/typography.js b/test/unit/visual/cases/typography.js index e9aa7a26be..e8984da241 100644 --- a/test/unit/visual/cases/typography.js +++ b/test/unit/visual/cases/typography.js @@ -440,6 +440,33 @@ visualSuite("Typography", function () { p5.endShape(); screenshot(); }); + + for (const mode of ['RADIANS', 'DEGREES']) { + visualTest(`Fonts point angles work in ${mode} mode`, async function(p5, screenshot) { + p5.createCanvas(100, 100); + const font = await p5.loadFont( + '/unit/assets/Inconsolata-Bold.ttf' + ); + p5.background(255); + p5.strokeWeight(2); + p5.textSize(50); + p5.angleMode(p5[mode]); + const pts = font.textToPoints('p5*js', 0, 50, { sampleFactor: 0.25 }); + p5.beginShape(p5.LINES); + for (const { x, y, angle } of pts) { + p5.vertex( + x - 5 * p5.cos(angle), + y - 5 * p5.sin(angle) + ); + p5.vertex( + x + 5 * p5.cos(angle), + y + 5 * p5.sin(angle) + ); + } + p5.endShape(); + screenshot(); + }); + } }); visualSuite('textToContours', function() { diff --git a/test/unit/visual/screenshots/Typography/textToPoints/Fonts point angles work in DEGREES mode/000.png b/test/unit/visual/screenshots/Typography/textToPoints/Fonts point angles work in DEGREES mode/000.png new file mode 100644 index 0000000000000000000000000000000000000000..6dbe5f2148ddbae619bd849b431dd1c187eb82af GIT binary patch literal 2205 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