--- src/text.cc
+++ src/text.cc	2026-04-26 20:58:17.210610855 +0000
@@ -1,8 +1,27 @@
 #include "text.h"
 
-#include <SkPath.h>
-#include <SkTextBlob.h>
-#include <SkTypeface.h>
+#include <include/core/SkFontMgr.h>
+#include <include/core/SkPath.h>
+#include <include/core/SkPathBuilder.h>
+#include <include/core/SkTextBlob.h>
+#include <include/core/SkTypeface.h>
+#ifdef __APPLE__
+#include <include/ports/SkFontMgr_mac_ct.h>
+#else
+#include <include/ports/SkFontMgr_fontconfig.h>
+#endif
+
+static sk_sp<SkFontMgr> get_font_mgr() {
+    static sk_sp<SkFontMgr> mgr;
+    if (!mgr) {
+#ifdef __APPLE__
+        mgr = SkFontMgr_New_CoreText(nullptr);
+#else
+        mgr = SkFontMgr_New_FontConfig(nullptr, nullptr);
+#endif
+    }
+    return mgr;
+}
 
 FontStyle AttrsToFontStyle(Attr attrs) {
   if (attrs.flags & Attr::kBold) {
@@ -35,6 +54,7 @@
 }
 
 void GlyphRenderer::SetFont(string name) {
+  sk_sp<SkFontMgr> fontMgr = get_font_mgr();
   SkFontStyle styles[] = {
     SkFontStyle::Normal(),
     SkFontStyle::Bold(),
@@ -42,7 +62,28 @@
   };
 
   for (int i = 0; i < kStyleEnd; i++) {
-    m_styled_fonts[i].font.setTypeface(SkTypeface::MakeFromName(name.c_str(), styles[i]));
+    sk_sp<SkTypeface> typeface = fontMgr->matchFamilyStyle(name.c_str(), styles[i]);
+    // Fallback chain for when requested font isn't found
+    if (!typeface) {
+#ifdef __APPLE__
+      // macOS fallback fonts
+      typeface = fontMgr->matchFamilyStyle("Menlo", styles[i]);
+      if (!typeface) {
+        typeface = fontMgr->matchFamilyStyle("Monaco", styles[i]);
+      }
+#else
+      // Linux fallback fonts
+      typeface = fontMgr->matchFamilyStyle("DejaVu Sans Mono", styles[i]);
+      if (!typeface) {
+        typeface = fontMgr->matchFamilyStyle("Liberation Mono", styles[i]);
+      }
+#endif
+      // Last resort: use default typeface
+      if (!typeface) {
+        typeface = fontMgr->legacyMakeTypeface(nullptr, styles[i]);
+      }
+    }
+    m_styled_fonts[i].font.setTypeface(typeface);
   }
 
   UpdateForFontChange();
@@ -59,8 +100,10 @@
     }
   }
 
-  styled_font.font.textToGlyphs(&c, sizeof(c), kUTF32_SkTextEncoding, &m_glyphs[index], 1);
-  return m_glyphs[index] != 0;
+  SkGlyphID glyph;
+  styled_font.font.textToGlyphs(&c, sizeof(c), SkTextEncoding::kUTF32, {&glyph, 1});
+  m_glyphs[index] = glyph;
+  return glyph != 0;
 }
 
 void GlyphRenderer::ClearGlyph(int index) {
@@ -75,21 +118,26 @@
 SkScalar GlyphRenderer::FindWidth() {
   auto &styled_font = m_styled_fonts[kStyleNormal];
 
-  if (styled_font.metrics.fAvgCharWidth) {
-    return styled_font.metrics.fAvgCharWidth;
-  }
-
+  // Prefer actual glyph width over fAvgCharWidth which may be inaccurate
   if (SkGlyphID glyph = styled_font.glyph_cache['x']) {
-    SkScalar width;
-    styled_font.font.getWidthsBounds(&glyph, 1, &width, nullptr, nullptr);
-    fmt::print("{}\n", width);
-    return width;
+    return styled_font.font.getWidth(glyph);
   }
 
+  // Fallback to measuring 'x' directly
   SkRect bounds;
   const char *s = "x";
-  styled_font.font.measureText(s, sizeof(s[0]), kUTF8_SkTextEncoding, &bounds);
-  return bounds.width();
+  styled_font.font.measureText(s, sizeof(s[0]), SkTextEncoding::kUTF8, &bounds);
+  if (bounds.width() > 0) {
+    return bounds.width();
+  }
+
+  // Last resort: use fAvgCharWidth if available
+  if (styled_font.metrics.fAvgCharWidth > 0) {
+    return styled_font.metrics.fAvgCharWidth;
+  }
+
+  // Emergency fallback: estimate based on font size
+  return styled_font.font.getSize() * 0.6f;
 }
 
 SkScalar GlyphRenderer::FindBaselineOffset() {
@@ -141,12 +189,13 @@
       }
       SkScalar end_x = positions[i - 1].x() + FindWidth();
 
-      SkPath path;
-      path.moveTo(begin_x, last_y + y_offset);
-      path.lineTo(end_x, last_y + y_offset);
+      // Skia m144+: SkPath is immutable, use SkPathBuilder
+      SkPathBuilder pathBuilder;
+      pathBuilder.moveTo(begin_x, last_y + y_offset);
+      pathBuilder.lineTo(end_x, last_y + y_offset);
 
       paint.setStrokeWidth(stroke_width);
-      canvas->drawPath(path, paint);
+      canvas->drawPath(pathBuilder.detach(), paint);
 
       if (i < end) {
         last_y = positions[i].y();
@@ -168,7 +217,7 @@
     for (char c = 0; c < kCharMax; c++) {
       if (isprint(c)) {
         SkGlyphID glyph;
-        font.textToGlyphs(&c, sizeof(c), kUTF8_SkTextEncoding, &glyph, 1);
+        font.textToGlyphs(&c, sizeof(c), SkTextEncoding::kUTF8, {&glyph, 1});
         if (glyph) {
           glyph_cache[c] = glyph;
         }
