Skip to content

Commit f774a64

Browse files
authored
Merge pull request #7683 from processing/font-docs
Add back docs for existing font methods
2 parents 21286a0 + 82d0a57 commit f774a64

File tree

2 files changed

+291
-6
lines changed

2 files changed

+291
-6
lines changed

src/type/p5.Font.js

+266-6
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class Font {
6565
/**
6666
* Checks whether a font has glyph point data and
6767
* can thus be used for textToPoints(), WEBGL mode, etc.
68+
* @private
6869
*/
6970
static hasGlyphData(textFont) {
7071
let { font } = textFont;
@@ -104,6 +105,62 @@ class Font {
104105
return glyphs.map(g => g.path.commands).flat();
105106
}
106107

108+
/**
109+
* Returns an array of points outlining a string of text written using the
110+
* font.
111+
*
112+
* Each point object in the array has three properties that describe the
113+
* point's location and orientation, called its path angle. For example,
114+
* `{ x: 10, y: 20, alpha: 450 }`.
115+
*
116+
* The first parameter, `str`, is a string of text. The second and third
117+
* parameters, `x` and `y`, are the text's position. By default, they set the
118+
* coordinates of the bounding box's bottom-left corner. See
119+
* <a href="#/p5/textAlign">textAlign()</a> for more ways to align text.
120+
*
121+
* The fourth parameter, `options`, is also optional. `font.textToPoints()`
122+
* expects an object with the following properties:
123+
*
124+
* `sampleFactor` is the ratio of the text's path length to the number of
125+
* samples. It defaults to 0.1. Higher values produce more points along the
126+
* path and are more precise.
127+
*
128+
* `simplifyThreshold` removes collinear points if it's set to a number other
129+
* than 0. The value represents the threshold angle to use when determining
130+
* whether two edges are collinear.
131+
*
132+
* @param {String} str string of text.
133+
* @param {Number} x x-coordinate of the text.
134+
* @param {Number} y y-coordinate of the text.
135+
* @param {Object} [options] object with sampleFactor and simplifyThreshold
136+
* properties.
137+
* @return {Array<Object>} array of point objects, each with `x`, `y`, and `alpha` (path angle) properties.
138+
*
139+
* @example
140+
* <div>
141+
* <code>
142+
* let font;
143+
*
144+
* async function setup() {
145+
* createCanvas(100, 100);
146+
* font = await loadFont('assets/inconsolata.otf');
147+
*
148+
* background(200);
149+
* textSize(35);
150+
*
151+
* // Get the point array.
152+
* let points = font.textToPoints('p5*js', 6, 60, { sampleFactor: 0.5 });
153+
*
154+
* // Draw a dot at each point.
155+
* for (let p of points) {
156+
* point(p.x, p.y);
157+
* }
158+
*
159+
* describe('A set of black dots outlining the text "p5*js" on a gray background.');
160+
* }
161+
* </code>
162+
* </div>
163+
*/
107164
textToPoints(str, x, y, width, height, options) {
108165
// By segmenting per contour, pointAtLength becomes much faster
109166
const contourPoints = this.textToContours(str, x, y, width, height, options);
@@ -113,6 +170,71 @@ class Font {
113170
}, []);
114171
}
115172

173+
/**
174+
* Returns an array of arrays of points outlining a string of text written using the
175+
* font. Each array represents a contour, so the letter O will have two outer arrays:
176+
* one for the outer edge of the shape, and one for the inner edge of the hole.
177+
*
178+
* Each point object in a contour array has three properties that describe the
179+
* point's location and orientation, called its path angle. For example,
180+
* `{ x: 10, y: 20, alpha: 450 }`.
181+
*
182+
* The first parameter, `str`, is a string of text. The second and third
183+
* parameters, `x` and `y`, are the text's position. By default, they set the
184+
* coordinates of the bounding box's bottom-left corner. See
185+
* <a href="#/p5/textAlign">textAlign()</a> for more ways to align text.
186+
*
187+
* The fourth parameter, `options`, is also optional. `font.textToPoints()`
188+
* expects an object with the following properties:
189+
*
190+
* `sampleFactor` is the ratio of the text's path length to the number of
191+
* samples. It defaults to 0.1. Higher values produce more points along the
192+
* path and are more precise.
193+
*
194+
* `simplifyThreshold` removes collinear points if it's set to a number other
195+
* than 0. The value represents the threshold angle to use when determining
196+
* whether two edges are collinear.
197+
*
198+
* @param {String} str string of text.
199+
* @param {Number} x x-coordinate of the text.
200+
* @param {Number} y y-coordinate of the text.
201+
* @param {Object} [options] object with sampleFactor and simplifyThreshold
202+
* properties.
203+
* @return {Array<Array<Object>>} array of point objects, each with `x`, `y`, and `alpha` (path angle) properties.
204+
*
205+
* @example
206+
* <div>
207+
* <code>
208+
* let font;
209+
*
210+
* async function setup() {
211+
* createCanvas(100, 100);
212+
* font = await loadFont('/assets/inconsolata.otf');
213+
* }
214+
*
215+
* function draw() {
216+
* background(200);
217+
* textAlign(CENTER, CENTER);
218+
* textSize(30);
219+
*
220+
* // Get the point array.
221+
* let contours = font.textToContours('p5*js', width/2, height/2, { sampleFactor: 0.5 });
222+
*
223+
* beginShape();
224+
* for (const pts of contours) {
225+
* beginContour();
226+
* for (const pt of pts) {
227+
* vertex(pt.x + 5*sin(pt.y*0.1 + millis()*0.01), pt.y);
228+
* }
229+
* endContour(CLOSE);
230+
* }
231+
* endShape();
232+
*
233+
* describe('The text p5*js wobbling over time');
234+
* }
235+
* </code>
236+
* </div>
237+
*/
116238
textToContours(str, x = 0, y = 0, width, height, options) {
117239
({ width, height, options } = this._parseArgs(width, height, options));
118240

@@ -688,20 +810,158 @@ function parseCreateArgs(...args/*path, name, onSuccess, onError*/) {
688810
function font(p5, fn) {
689811

690812
/**
691-
* TODO
813+
* A class to describe fonts. Create through <a href="#/p5/loadFont">`loadFont()`</a>.
692814
*
693815
* @class p5.Font
694816
*/
695817
p5.Font = Font;
696818

697819
/**
698-
* Load a font and returns a p5.Font instance. The font can be specified by its path or a url.
699-
* Optional arguments include the font name, descriptors for the FontFace object,
700-
* and callbacks for success and error.
820+
* Loads a font and creates a <a href="#/p5.Font">p5.Font</a> object.
821+
* `loadFont()` can load fonts in either .otf or .ttf format. Loaded fonts can
822+
* be used to style text on the canvas and in HTML elements.
823+
*
824+
* The first parameter, `path`, is the path to a font file.
825+
* Paths to local files should be relative. For example,
826+
* `'assets/inconsolata.otf'`. The Inconsolata font used in the following
827+
* examples can be downloaded for free
828+
* <a href="https://www.fontsquirrel.com/fonts/inconsolata" target="_blank">here</a>.
829+
* Paths to remote files should be URLs. For example,
830+
* `'https://example.com/inconsolata.otf'`. URLs may be blocked due to browser
831+
* security.
832+
*
833+
* In 2D mode, `path` can take on a few other forms. It could be a path to a CSS file,
834+
* such as one from <a href="https://fonts.google.com/">Google Fonts.</a> It could also
835+
* be a string with a <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face">CSS `@font-face` declaration.</a> It can also be an object containing key-value pairs with
836+
* properties that you would find in an `@font-face` block.
837+
*
838+
* The second parameter, `successCallback`, is optional. If a function is
839+
* passed, it will be called once the font has loaded. The callback function
840+
* may use the new <a href="#/p5.Font">p5.Font</a> object if needed.
841+
*
842+
* The third parameter, `failureCallback`, is also optional. If a function is
843+
* passed, it will be called if the font fails to load. The callback function
844+
* may use the error
845+
* <a href="https://developer.mozilla.org/en-US/docs/Web/API/Event" target="_blank">Event</a>
846+
* object if needed.
847+
*
848+
* Fonts can take time to load. `await` the result of `loadFont()` in
849+
* <a href="#/p5/setup">setup()</a> before using the result.
850+
*
701851
* @method loadFont
702-
* @param {...any} args - path, name, onSuccess, onError, descriptors
703-
* @returns a Promise that resolves with a p5.Font instance
852+
* @for p5
853+
* @param {String|Object} path path of the font to be loaded, a CSS `@font-face` string, or an object with font face properties.
854+
* @param {String} [name] An alias that can be used for this font in `textFont()`. Defaults to the name in the font's metadata.
855+
* @param {Function} [successCallback] function called with the
856+
* <a href="#/p5.Font">p5.Font</a> object after it
857+
* loads.
858+
* @param {Function} [failureCallback] function called with the error
859+
* <a href="https://developer.mozilla.org/en-US/docs/Web/API/Event" target="_blank">Event</a>
860+
* object if the font fails to load.
861+
* @return {Promise<p5.Font>} <a href="#/p5.Font">p5.Font</a> object.
862+
* @example
863+
* <div>
864+
* <code>
865+
* let font;
866+
*
867+
* async function setup() {
868+
* createCanvas(100, 100);
869+
* font = await loadFont('assets/inconsolata.otf');
870+
* fill('deeppink');
871+
* textFont(font);
872+
* textSize(36);
873+
* text('p5*js', 10, 50);
874+
*
875+
* describe('The text "p5*js" written in pink on a white background.');
876+
* }
877+
* </code>
878+
* </div>
879+
*
880+
* @example
881+
* <div>
882+
* <code>
883+
* function setup() {
884+
* createCanvas(100, 100);
885+
* loadFont('assets/inconsolata.otf', font => {
886+
* fill('deeppink');
887+
* textFont(font);
888+
* textSize(36);
889+
* text('p5*js', 10, 50);
890+
*
891+
* describe('The text "p5*js" written in pink on a white background.');
892+
* });
893+
* }
894+
* </code>
895+
* </div>
896+
*
897+
* @example
898+
* <div>
899+
* <code>
900+
* function setup() {
901+
* createCanvas(100, 100);
902+
* loadFont('assets/inconsolata.otf', success, failure);
903+
* }
904+
*
905+
* function success(font) {
906+
* fill('deeppink');
907+
* textFont(font);
908+
* textSize(36);
909+
* text('p5*js', 10, 50);
910+
*
911+
* describe('The text "p5*js" written in pink on a white background.');
912+
* }
913+
*
914+
* function failure(event) {
915+
* console.error('Oops!', event);
916+
* }
917+
* </code>
918+
* </div>
919+
*
920+
* @example
921+
* <div>
922+
* <code>
923+
* async function setup() {
924+
* createCanvas(100, 100);
925+
* await loadFont('assets/inconsolata.otf');
926+
* let p = createP('p5*js');
927+
* p.style('color', 'deeppink');
928+
* p.style('font-family', 'Inconsolata');
929+
* p.style('font-size', '36px');
930+
* p.position(10, 50);
931+
*
932+
* describe('The text "p5*js" written in pink on a white background.');
933+
* }
934+
* </code>
935+
* </div>
936+
*
937+
* @example
938+
* <div class="norender">
939+
* <code>
940+
* // Some other forms of loading fonts:
941+
* loadFont("https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,[email protected],200..800&display=swap");
942+
* loadFont(`@font-face { font-family: "Bricolage Grotesque", serif; font-optical-sizing: auto; font-weight: 400; font-style: normal; font-variation-settings: "wdth" 100; }`);
943+
* loadFont({
944+
* fontFamily: '"Bricolage Grotesque", serif',
945+
* fontOpticalSizing: 'auto',
946+
* fontWeight: 400,
947+
* fontStyle: 'normal',
948+
* fontVariationSettings: '"wdth" 100',
949+
* });
950+
* </code>
951+
* </div>
704952
*/
953+
/**
954+
* @method loadFont
955+
* @for p5
956+
* @param {String} path path of the font to be loaded.
957+
* @param {Function} [successCallback] function called with the
958+
* <a href="#/p5.Font">p5.Font</a> object after it
959+
* loads.
960+
* @param {Function} [failureCallback] function called with the error
961+
* <a href="https://developer.mozilla.org/en-US/docs/Web/API/Event" target="_blank">Event</a>
962+
* object if the font fails to load.
963+
* @returns {Promise<p5.Font>} The font.
964+
*/
705965
fn.loadFont = async function (...args/*path, name, onSuccess, onError, descriptors*/) {
706966

707967
let { path, name, success, error, descriptors } = parseCreateArgs(...args);

src/type/textCore.js

+25
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,7 @@ function textCore(p5, fn) {
13321332
* @returns {Number} If no arguments are provided, the current font weight
13331333
*
13341334
* @example
1335+
* <div>
13351336
* <code>
13361337
* function setup() {
13371338
* createCanvas(300, 200);
@@ -1365,6 +1366,30 @@ function textCore(p5, fn) {
13651366
* text("Bold Weight: " + boldWeight, 150, 100);
13661367
* }
13671368
* </code>
1369+
* </div>
1370+
*
1371+
* <div>
1372+
* <code>
1373+
* let font;
1374+
*
1375+
* async function setup() {
1376+
* createCanvas(100, 100);
1377+
* font = await loadFont(
1378+
* 'https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap'
1379+
* );
1380+
* }
1381+
*
1382+
* function draw() {
1383+
* background(255);
1384+
* textFont(font);
1385+
* textAlign(LEFT, TOP);
1386+
* textSize(35);
1387+
* textWeight(sin(millis() * 0.002) * 200 + 400);
1388+
* text('p5*js', 0, 10);
1389+
* describe('The text p5*js pulsing its weight over time');
1390+
* }
1391+
* </code>
1392+
* </div>
13681393
*/
13691394
/**
13701395
* @method textWeight

0 commit comments

Comments
 (0)