or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

font-loading.mdfont-utils.mdindex.mdreact-hooks.mdserver-side.md
tile.json

font-utils.mddocs/

Font Utilities

Utility functions for advanced font operations including text rendering to images. Provides platform-specific functionality for creating images from text with custom fonts.

Capabilities

Render Text to Image

Create images with custom text and font styling (iOS and Android only).

/**
 * Creates an image with provided text using specified font and styling options
 * @param glyphs - Text content to be rendered as an image
 * @param options - Rendering configuration options
 * @returns Promise resolving to image result with URI, dimensions
 */
function renderToImageAsync(
  glyphs: string,
  options?: RenderToImageOptions
): Promise<RenderToImageResult>;

interface RenderToImageOptions {
  /** Font family name (must be loaded or system font) */
  fontFamily?: string;
  /** Font size in points */
  size?: number;
  /** Text color (CSS color string or React Native color format) */
  color?: string;
}

interface RenderToImageResult {
  /** File URI to the generated image */
  uri: string;
  /** Image width in pixels */
  width: number;
  /** Image height in pixels */
  height: number;
}

Usage Examples:

import { renderToImageAsync, loadAsync } from 'expo-font';

// Simple text to image with default styling
async function createSimpleTextImage() {
  const result = await renderToImageAsync('Hello World!');
  
  console.log('Image created:', result.uri);
  console.log('Dimensions:', result.width, 'x', result.height);
  
  // Use the image URI in an Image component
  return <Image source={{ uri: result.uri }} />;
}

// Custom styling with loaded font
async function createStyledTextImage() {
  // First load a custom font
  await loadAsync({
    'CustomFont': require('./assets/fonts/CustomFont.ttf')
  });

  // Create image with custom styling
  const result = await renderToImageAsync('Styled Text', {
    fontFamily: 'CustomFont',
    size: 48,
    color: '#ff6b6b'
  });

  return (
    <Image 
      source={{ uri: result.uri }} 
      style={{ width: result.width, height: result.height }}
    />
  );
}

// Dynamic text image generation
async function createDynamicTextImage(text: string, fontSize: number) {
  const result = await renderToImageAsync(text, {
    fontFamily: 'System', // Use system font
    size: fontSize,
    color: 'rgba(0, 0, 0, 0.8)' // Semi-transparent black
  });

  return result;
}

// Error handling
async function createTextImageWithErrorHandling(text: string) {
  try {
    const result = await renderToImageAsync(text, {
      fontFamily: 'NonexistentFont', // This will fall back to system font
      size: 24,
      color: '#333333'
    });
    return result;
  } catch (error) {
    console.error('Failed to create text image:', error);
    // Fallback: use default styling
    return await renderToImageAsync(text);
  }
}

Advanced Use Cases

import { renderToImageAsync } from 'expo-font';
import { shareAsync } from 'expo-sharing';
import { manipulateAsync, SaveFormat } from 'expo-image-manipulator';

// Create shareable text images
async function createShareableQuote(quote: string, author: string) {
  // Create main quote image
  const quoteImage = await renderToImageAsync(`"${quote}"`, {
    fontFamily: 'serif',
    size: 32,
    color: '#2c3e50'
  });

  // Create author attribution
  const authorImage = await renderToImageAsync(`— ${author}`, {
    fontFamily: 'sans-serif',
    size: 18,
    color: '#7f8c8d'
  });

  // You could combine these images using image manipulation libraries
  // Then share the result
  await shareAsync(quoteImage.uri);
}

// Generate text-based watermarks
async function createWatermark(text: string) {
  const watermark = await renderToImageAsync(text, {
    fontFamily: 'monospace',
    size: 14,
    color: 'rgba(255, 255, 255, 0.3)' // Semi-transparent white
  });

  return watermark;
}

// Create text badges or labels
async function createBadge(label: string, color: string) {
  return await renderToImageAsync(label.toUpperCase(), {
    fontFamily: 'sans-serif-medium',
    size: 12,
    color: color
  });
}

// Generate text for accessibility purposes
async function createAltTextImage(altText: string) {
  return await renderToImageAsync(altText, {
    fontFamily: 'sans-serif',
    size: 16,
    color: '#000000'
  });
}

Integration with File System

import { renderToImageAsync } from 'expo-font';
import * as FileSystem from 'expo-file-system';

// Save rendered text image to device storage
async function saveTextImageToDevice(text: string, filename: string) {
  // Render text to image
  const textImage = await renderToImageAsync(text, {
    fontFamily: 'sans-serif',
    size: 24,
    color: '#000000'
  });

  // Define save location
  const fileUri = `${FileSystem.documentDirectory}${filename}.png`;

  // Copy from temporary location to permanent storage
  await FileSystem.copyAsync({
    from: textImage.uri,
    to: fileUri
  });

  console.log('Text image saved to:', fileUri);
  return { ...textImage, uri: fileUri };
}

// Create and cache text images
async function createCachedTextImage(text: string, cacheKey: string) {
  const cacheDir = `${FileSystem.cacheDirectory}text-images/`;
  const cachedPath = `${cacheDir}${cacheKey}.png`;

  // Check if cached version exists
  const cacheInfo = await FileSystem.getInfoAsync(cachedPath);
  if (cacheInfo.exists) {
    const size = await FileSystem.readAsStringAsync(
      `${cacheDir}${cacheKey}.json`
    );
    const dimensions = JSON.parse(size);
    return { uri: cachedPath, ...dimensions };
  }

  // Create new image
  const result = await renderToImageAsync(text, {
    size: 20,
    color: '#333'
  });

  // Ensure cache directory exists
  await FileSystem.makeDirectoryAsync(cacheDir, { intermediates: true });

  // Save to cache
  await FileSystem.copyAsync({ from: result.uri, to: cachedPath });
  await FileSystem.writeAsStringAsync(
    `${cacheDir}${cacheKey}.json`,
    JSON.stringify({ width: result.width, height: result.height })
  );

  return { ...result, uri: cachedPath };
}

Platform Support and Limitations

Supported Platforms

  • iOS: Full support with native text rendering
  • Android: Full support with native text rendering
  • Web: Not supported (function will throw UnavailabilityError)

Font Requirements

  • Custom fonts must be loaded using loadAsync() before use
  • System fonts are available immediately:
    • iOS: 'System', 'Helvetica', 'Times', 'Courier', etc.
    • Android: 'sans-serif', 'serif', 'monospace', etc.

Color Format Support

Accepts multiple color formats:

  • Hex colors: '#ff0000', '#f00'
  • RGB/RGBA: 'rgb(255, 0, 0)', 'rgba(255, 0, 0, 0.5)'
  • Named colors: 'red', 'blue', 'transparent'
  • React Native color formats

Performance Considerations

  • Image generation is synchronous on the native thread
  • Large text or high font sizes may impact performance
  • Consider caching generated images for repeated use
  • Clean up temporary image files when no longer needed

Error Scenarios

  • UnavailabilityError: Function not available on current platform (web)
  • Font not found: Falls back to system default font
  • Invalid color: May fall back to default black color
  • Memory issues: Large images may cause memory warnings