/** * Cell management for scanline rasterization * * Based on FreeType's ftgrays.c cell accumulation approach. * Each cell tracks coverage and area for anti-aliased rendering. * * Uses pool-based allocation with overflow detection for bounded memory. */ /** * Pool overflow error - thrown when cell pool is exhausted */ export declare class PoolOverflowError extends Error { constructor(); } /** * A cell accumulates coverage information for one pixel */ export interface Cell { /** X coordinate in pixels */ x: number; /** Accumulated signed area */ area: number; /** Accumulated coverage (winding number contribution) */ cover: number; /** Next cell in linked list (index into pool, -1 for end) */ next: number; } /** * Cell storage with pool-based allocation and linked lists per scanline. * Matches FreeType's approach for bounded memory usage. */ export declare class CellBuffer { /** Fixed-size cell pool */ private pool; /** Pool size */ private poolSize; /** Next free cell index */ private freeIndex; /** Per-scanline linked list heads (index into pool, -1 for empty) */ private ycells; /** Band bounds (Y range for current render pass) */ private bandMinY; private bandMaxY; /** Bounding box of active cells */ minY: number; maxY: number; minX: number; maxX: number; /** Current position for incremental cell updates */ private currentX; private currentY; private currentCellIndex; /** Clip bounds in pixels */ private clipMinX; private clipMinY; private clipMaxX; private clipMaxY; /** Null cell index (sentinel at end of pool) */ private nullCellIndex; /** Whether band bounds have been set */ private bandSet; constructor(poolSize?: number); /** * Set clipping bounds */ setClip(minX: number, minY: number, maxX: number, maxY: number): void; /** * Set band bounds for current render pass */ setBandBounds(minY: number, maxY: number): void; /** * Clear all cells for new band */ reset(): void; /** * Set current position (in subpixel coordinates) * @throws PoolOverflowError if pool is exhausted */ setCurrentCell(x: number, y: number): void; /** * Find or create a cell at the given pixel position * @throws PoolOverflowError if pool is exhausted */ private findOrCreateCell; /** * Ensure ycells array can accommodate the given Y coordinate * Used for backward compatibility when setBandBounds is not called */ private ensureYCellsCapacity; /** * Add area and cover to current cell */ addArea(area: number, cover: number): void; /** * Get current cell area (for accumulation) */ getArea(): number; /** * Get current cell cover */ getCover(): number; /** * Get all cells for a given Y coordinate, sorted by X */ getCellsForRow(y: number): Cell[]; /** * Iterate over all cells in scanline order within band */ iterateCells(): Generator<{ y: number; cells: Cell[]; }>; /** * Iterate scanlines directly without allocating cell arrays * Returns first cell index for each row, caller walks linked list via pool */ iterateScanlines(): Generator<{ y: number; firstCellIndex: number; }>; /** * Get the cell pool for direct access during sweep */ getPool(): Cell[]; /** * Get the null cell index (sentinel value) */ getNullIndex(): number; /** * Get ycells array for direct iteration (avoids generator overhead) */ getYCells(): number[]; /** * Get band minimum Y for coordinate calculation */ getBandMinY(): number; /** * Iterate cells for a single row (for band sweep) */ iterateRowCells(y: number): Generator; /** * Get number of cells currently allocated */ getCellCount(): number; /** * Check if pool is near capacity */ isNearCapacity(): boolean; } /** * Convert cell coverage to 8-bit grayscale value * * The area is accumulated in 2*PIXEL_BITS precision. * We need to shift down to get 0-255 coverage. */ export declare function coverageToGray(area: number): number; /** * Apply non-zero winding fill rule */ export declare function applyNonZeroRule(cover: number): number; /** * Apply even-odd fill rule */ export declare function applyEvenOddRule(cover: number): number;