@weasel-js/font 1.15.0 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -447,6 +447,18 @@ function _resetBakeQueueForTests() {
447
447
  // src/dynamic/glyphRasterizer.ts
448
448
  var BAKE_SIZE = 48;
449
449
  var PAD = 8;
450
+ function pathBounds(d) {
451
+ const b = [Infinity, Infinity, -Infinity, -Infinity];
452
+ const nums = d.match(/-?\d*\.?\d+(?:e-?\d+)?/gi) ?? [];
453
+ for (let k = 0; k + 1 < nums.length; k += 2) {
454
+ const x = Number(nums[k]), y = Number(nums[k + 1]);
455
+ if (x < b[0]) b[0] = x;
456
+ if (y < b[1]) b[1] = y;
457
+ if (x > b[2]) b[2] = x;
458
+ if (y > b[3]) b[3] = y;
459
+ }
460
+ return b;
461
+ }
450
462
  var COLORED_BELOW = 240;
451
463
  function premultipliedColor(data) {
452
464
  const out = new Uint8ClampedArray(data.length);
@@ -533,6 +545,28 @@ function createCanvasRasterizer() {
533
545
  for (let i = 0; i < alpha.length; i++) alpha[i] = data[i * 4 + 3];
534
546
  return { ...box, alpha };
535
547
  },
548
+ rasterizePath(d) {
549
+ const [minX, minY, maxX, maxY] = pathBounds(d);
550
+ const blank = { width: 0, height: 0, alpha: new Uint8ClampedArray(0), left: 0, top: 0, advance: 0 };
551
+ if (!(maxX > minX && maxY > minY)) return blank;
552
+ const x0 = Math.floor(minX * BAKE_SIZE), y0 = Math.floor(minY * BAKE_SIZE);
553
+ const w = Math.ceil(maxX * BAKE_SIZE) - x0 + 2 * PAD;
554
+ const h = Math.ceil(maxY * BAKE_SIZE) - y0 + 2 * PAD;
555
+ if (canvas.width < w || canvas.height < h) {
556
+ canvas.width = Math.max(canvas.width, w);
557
+ canvas.height = Math.max(canvas.height, h);
558
+ }
559
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
560
+ ctx.clearRect(0, 0, w, h);
561
+ ctx.setTransform(BAKE_SIZE, 0, 0, BAKE_SIZE, PAD - x0, PAD - y0);
562
+ ctx.fillStyle = "#fff";
563
+ ctx.fill(new Path2D(d));
564
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
565
+ const data = ctx.getImageData(0, 0, w, h).data;
566
+ const alpha = new Uint8ClampedArray(w * h);
567
+ for (let i = 0; i < alpha.length; i++) alpha[i] = data[i * 4 + 3];
568
+ return { width: w, height: h, alpha, left: x0 - PAD, top: PAD - y0, advance: 0 };
569
+ },
536
570
  rasterizeColor(family, weight, style, text, size) {
537
571
  const { data, ...box } = draw(family, weight, style, text, size);
538
572
  const rgba = premultipliedColor(data);
@@ -627,6 +661,7 @@ function forgetGlyphs2(face) {
627
661
  face.font.charMap.clear();
628
662
  face.font.chars.length = 0;
629
663
  face.clusters.clear();
664
+ face.shaped.clear();
630
665
  }
631
666
  onPagesEmptied(() => {
632
667
  for (const face of faces2.values()) forgetGlyphs2(face);
@@ -696,12 +731,14 @@ function getDynamicFace(family, weight, style) {
696
731
  page: -1
697
732
  });
698
733
  const clusters = /* @__PURE__ */ new Map();
734
+ const shaped = /* @__PURE__ */ new Map();
699
735
  const face = {
700
736
  family,
701
737
  weight,
702
738
  style,
703
739
  font,
704
740
  clusters,
741
+ shaped,
705
742
  requestGlyph(cp) {
706
743
  const cached = font.charMap.get(cp);
707
744
  if (cached) return cached;
@@ -723,6 +760,15 @@ function getDynamicFace(family, weight, style) {
723
760
  addSharpSource(char, font.common.base, (size) => r.rasterizeColor?.(family, weight, style, text, size) ?? null);
724
761
  }
725
762
  return char;
763
+ },
764
+ requestShaped(key2, d) {
765
+ const cached = shaped.get(key2);
766
+ if (cached !== void 0) return cached;
767
+ const raster = typeof Path2D === "undefined" ? null : r.rasterizePath?.(d) ?? null;
768
+ const char = raster && record(0, raster);
769
+ shaped.set(key2, char);
770
+ if (char && raster) requestBake(char, raster);
771
+ return char;
726
772
  }
727
773
  };
728
774
  measureFace(face);
@@ -748,6 +794,7 @@ function refreshFamilies(families) {
748
794
  for (const face of faces2.values()) {
749
795
  if (keys && !face.family.split(",").some((name) => keys.has(familyKey(name)))) continue;
750
796
  for (const char of face.font.chars) dropped.add(char);
797
+ for (const char of face.shaped.values()) if (char) dropped.add(char);
751
798
  for (const char of face.clusters.values()) {
752
799
  if (!char) continue;
753
800
  dropped.add(char);
@@ -1844,5 +1891,5 @@ function _resetDomFacesForTests() {
1844
1891
  }
1845
1892
 
1846
1893
  export { BAKE_SIZE, DEFAULT_BAKE_BUDGET, MAX_SHARP_LEVEL, PAGE_SIZE, SDF_RADIUS, __setGlyphRasterizerForTests, _getPagesForTests, _resetDomFacesForTests, _resetDynamicFontsForTests, _resetFallbackForTests, _resetFontOutlinesForTests, _resetFontRegistryForTests, cachedFontVariant, claimFallbackWarning, colorPageTextureId, createOpenTypeParser, cssFontFamily, cssFontFamilyLoading, dynamicPageTextureId, ensureFontTexture, faceGeneration, faceMetricsFor, fallbackWarningClaimed, fontOutlineRegistry, fontPending, fontRegistry, getDefaultFontFamily, getFont, getFontFallbackPolicy, glyphGeneration, glyphOutline, hasFontOutlines, isCanvasFont, listCanvasFonts, listFontOutlines, listFontWeights, listFonts, loadFontOutlines, markAllFontsNotUploaded, outlineMetrics, outlineStatus, refreshCanvasFont, registerCanvasFont, registerFont, registerFontOutlines, resetBakeBudget, resolveFontVariant, resolveGlyphFallback, setDefaultFontFamily, setFontFallbackPolicy, sharpColorPageTextureId, sharperColorGlyph, subscribeGlyphReady, syncColorPageTexture, syncDynamicPageTexture, syncSharpColorPageTexture, textureCacheKey, unregisterCanvasFont, unregisterFontOutlines, warmFonts };
1847
- //# sourceMappingURL=chunk-SP6N5MJQ.js.map
1848
- //# sourceMappingURL=chunk-SP6N5MJQ.js.map
1894
+ //# sourceMappingURL=chunk-I7OQG2DF.js.map
1895
+ //# sourceMappingURL=chunk-I7OQG2DF.js.map