/** * Gray-scale anti-aliased rasterizer * * Based on FreeType's ftgrays.c - a coverage-based scanline rasterizer * that produces high-quality anti-aliased output. * * Algorithm overview: * 1. Convert outline to line segments (flatten curves) * 2. For each line segment, compute coverage contribution to cells * 3. Sweep scanlines, accumulating coverage * 4. Convert coverage to grayscale pixels * * Key concepts: * - cover: accumulated vertical change (winding contribution) * - area: accumulated (y-delta * x-position) for edge anti-aliasing * * Band processing: * - Large glyphs are divided into vertical bands * - Each band is rendered with bounded memory pool * - On overflow, band is bisected and retried */ import type { Bitmap, FillRule, Span } from "./types.ts"; /** * Rasterizer state */ export declare class GrayRaster { private cells; private x; private y; private minX; private minY; private maxX; private maxY; constructor(); /** * Set clip rectangle (in pixels) */ setClip(minX: number, minY: number, maxX: number, maxY: number): void; /** * Set band bounds for current render pass */ setBandBounds(minY: number, maxY: number): void; /** * Reset rasterizer state */ reset(): void; /** * Move to a new position (start new contour) * Coordinates are in subpixel units (ONE_PIXEL per pixel) */ moveTo(x: number, y: number): void; /** * Draw line to position */ lineTo(toX: number, toY: number): void; /** * Render a line from current position to (toX, toY) * This is the core rasterization algorithm. */ private renderLine; /** * Render a line segment within a single scanline */ private renderScanline; /** * Multiply and divide with 64-bit precision */ private mulDiv; /** * Draw a quadratic Bezier curve using adaptive subdivision * Uses flatness test to minimize line segments at small font sizes */ conicTo(cx: number, cy: number, toX: number, toY: number): void; /** * Recursive quadratic subdivision with flatness test * Uses FreeType's exact flatness metric: |P0 + P2 - 2*P1| (second derivative) */ private subdivConic; /** * Draw a cubic Bezier curve */ cubicTo(cx1: number, cy1: number, cx2: number, cy2: number, x: number, y: number): void; private subdivCubic; /** * Sweep all cells and render to bitmap * * Supports both top-down (positive pitch) and bottom-up (negative pitch) bitmaps. * For positive pitch: y=0 is at top of image (first row in buffer) * For negative pitch: y=0 is at bottom of image (last row in buffer) */ sweep(bitmap: Bitmap, fillRule?: FillRule): void; private applyFillRule; private fillSpan; private setPixel; /** * Sweep and call span callback (unbuffered) * @param callback Span callback function * @param fillRule Fill rule to apply * @param userData User data passed to callback (like FreeType's render_span_data) */ sweepSpans(callback: (y: number, spans: Span[], userData: T) => void, fillRule?: FillRule, userData?: T): void; /** * Sweep with span buffering (like FreeType's gray_sweep_direct) * Buffers up to 16 spans before flushing for better performance * @param callback Span callback function * @param fillRule Fill rule to apply * @param minX Minimum X clip bound * @param maxX Maximum X clip bound * @param userData User data passed to callback (like FreeType's render_span_data) */ sweepDirect(callback: (y: number, spans: Span[], userData: T) => void, fillRule?: FillRule, minX?: number, maxX?: number, userData?: T): void; /** * Render with band processing for bounded memory. * Divides large glyphs into bands, retries with bisection on overflow. * Supports both Y-dimension (vertical) and X-dimension (horizontal) bisection * like FreeType's ftgrays.c gray_convert_glyph. * * @param bitmap Target bitmap * @param decomposeFn Function that decomposes outline to rasterizer commands * @param bounds Glyph bounds (minY, maxY, optionally minX, maxX) * @param fillRule Fill rule to apply */ renderWithBands(bitmap: Bitmap, decomposeFn: () => void, bounds: { minY: number; maxY: number; minX?: number; maxX?: number; }, fillRule?: FillRule): void; /** * Render a single band with X clipping * @returns true on success, false on pool overflow */ private renderBandWithXClip; /** * Sweep a band with X clipping and render to bitmap */ private sweepBandWithXClip; }