Token导航 LogoToken导航TokenDH.com
研究检索需要联网github未标认证来源可访问许可证需确认审计提醒

slug-font-renderingslug 字体渲染

Agent Skill

slug-font-rendering 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

23,097

周安装

982

GitHub Stars

39

下载量

8,092
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:slug-font-rendering(slug 字体渲染)
来源仓库:https://github.com/aradotso/trending-skills
仓库路径:skills/slug-font-rendering
安装命令:
npx skills add https://github.com/aradotso/trending-skills --skill slug-font-rendering
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/aradotso/trending-skills --skill slug-font-rendering

简介

用于查找、检索和筛选相关信息,支持基于关键词或任务场景定位内容。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中快速获取候选结果。
  • 可结合来源仓库和原始 README 继续核验具体用法和功能细节。
  • 安装前建议确认权限范围和是否涉及联网、命令执行或文件读写。
  • 维护状态不明时,建议先评估稳定性再投入生产使用。

SKILL.md

Slug Font Rendering Algorithm

Skill by ara.so — Daily 2026 Skills collection.

Slug is a reference implementation of the Slug font rendering algorithm — a GPU-accelerated technique for rendering vector fonts and glyphs at arbitrary scales with high quality anti-aliasing. It works by encoding glyph outlines as lists of quadratic Bézier curves and line segments, then resolving coverage directly in fragment shaders without pre-rasterized textures.

Paper: JCGT 2017 — Slug Algorithm Blog (updates): A Decade of Slug License: MIT — Patent dedicated to public domain. Credit required if distributed.


What Slug Does

  • Renders TrueType/OpenType glyphs entirely on the GPU
  • No texture atlases or pre-rasterization needed
  • Scales to any resolution without quality loss
  • Anti-aliased coverage computed per-fragment using Bézier math
  • Works with any rendering API that supports programmable shaders (D3D11/12, Vulkan, Metal via translation)

Repository Structure

Slug/
├── slug.hlsl          # Core fragment shader — coverage computation
├── band.hlsl          # Band-based optimization for glyph rendering
├── curve.hlsl         # Quadratic Bézier and line segment evaluation
├── README.md

Installation / Integration

Slug is a reference implementation — you integrate the HLSL shaders into your own rendering pipeline.

Step 1: Clone the Repository

git clone https://github.com/EricLengyel/Slug.git

Step 2: Include the Shaders

Copy the .hlsl files into your shader directory and include them in your pipeline:

#include "slug.hlsl"
#include "curve.hlsl"

Step 3: Prepare Glyph Data on the CPU

You must preprocess font outlines (TrueType/OTF) into Slug's curve buffer format:

  • Decompose glyph contours into quadratic Bézier segments and line segments
  • Upload curve data to a GPU buffer (structured buffer or texture buffer)
  • Precompute per-glyph "band" metadata for the band optimization

Core Concepts

Glyph Coordinate System

  • Glyph outlines live in font units (typically 0–2048 or 0–1000 per em)
  • The fragment shader receives a position in glyph space via interpolated vertex attributes
  • Coverage is computed by counting signed curve crossings in the Y direction (winding number)

Curve Data Format

Each curve entry in the GPU buffer stores:

// Line segment: p0, p1
// Quadratic Bézier: p0, p1 (control), p2

struct CurveRecord
{
    float2 p0;   // Start point
    float2 p1;   // Control point (or end point for lines)
    float2 p2;   // End point (unused for lines — flagged via type)
    // Type/flags encoded separately or in padding
};

Band Optimization

The glyph bounding box is divided into horizontal bands. Each band stores only the curves that intersect it, reducing per-fragment work from O(all curves) to O(local curves).


Key Shader Code & Patterns

Fragment Shader Entry Point (Conceptual Integration)

// Inputs from vertex shader
struct PS_Input
{
    float4 position  : SV_Position;
    float2 glyphCoord : TEXCOORD0;  // Position in glyph/font units
    // Band index or precomputed band data
    nointerpolation uint bandOffset : TEXCOORD1;
    nointerpolation uint curveCount : TEXCOORD2;
};

// Glyph curve data buffer
StructuredBuffer<float4> CurveBuffer : register(t0);

float4 PS_Slug(PS_Input input) : SV_Target
{
    float coverage = ComputeGlyphCoverage(
        input.glyphCoord,
        CurveBuffer,
        input.bandOffset,
        input.curveCount
    );

    // Premultiplied alpha output
    float4 color = float4(textColor.rgb * coverage, coverage);
    return color;
}

Quadratic Bézier Coverage Computation

The heart of the algorithm — computing signed coverage from a quadratic Bézier:

// Evaluate whether a quadratic bezier contributes to coverage at point p
// p0: start, p1: control, p2: end
// Returns signed coverage contribution
float QuadraticBezierCoverage(float2 p, float2 p0, float2 p1, float2 p2)
{
    // Transform to canonical space
    float2 a = p1 - p0;
    float2 b = p0 - 2.0 * p1 + p2;

    // Find t values where bezier Y == p.y
    float2 delta = p - p0;

    float A = b.y;
    float B = a.y;
    float C = p0.y - p.y;

    float coverage = 0.0;

    if (abs(A) > 1e-6)
    {
        float disc = B * B - A * C;
        if (disc >= 0.0)
        {
            float sqrtDisc = sqrt(disc);
            float t0 = (-B - sqrtDisc) / A;
            float t1 = (-B + sqrtDisc) / A;

            // For each valid t in [0,1], compute x and check winding
            if (t0 >= 0.0 && t0 <= 1.0)
            {
                float x = (A * t0 + 2.0 * B) * t0 + p0.x + delta.x;
                // ... accumulate signed coverage
            }
            if (t1 >= 0.0 && t1 <= 1.0)
            {
                float x = (A * t1 + 2.0 * B) * t1 + p0.x + delta.x;
                // ... accumulate signed coverage
            }
        }
    }
    else
    {
        // Degenerate to linear case
        float t = -C / (2.0 * B);
        if (t >= 0.0 && t <= 1.0)
        {
            float x = 2.0 * a.x * t + p0.x;
            // ... accumulate signed coverage
        }
    }

    return coverage;
}

Line Segment Coverage

// Signed coverage contribution of a line segment from p0 to p1
float LineCoverage(float2 p, float2 p0, float2 p1)
{
    // Check Y range
    float minY = min(p0.y, p1.y);
    float maxY = max(p0.y, p1.y);

    if (p.y < minY || p.y >= maxY)
        return 0.0;

    // Interpolate X at p.y
    float t = (p.y - p0.y) / (p1.y - p0.y);
    float x = lerp(p0.x, p1.x, t);

    // Winding: +1 if p is to the left (inside), -1 if right
    float dir = (p1.y > p0.y) ? 1.0 : -1.0;
    return (p.x <= x) ? dir : 0.0;
}

Anti-Aliasing with Partial Coverage

For smooth edges, use the distance to the nearest curve for sub-pixel anti-aliasing:

// Compute AA coverage using partial pixel coverage
// windingNumber: integer winding from coverage pass
// distToEdge: signed distance to nearest curve (in pixels)
float AntiAliasedCoverage(int windingNumber, float distToEdge)
{
    // Non-zero winding rule
    bool inside = (windingNumber != 0);

    // Smooth transition at edges using clamp
    float edgeCoverage = clamp(distToEdge + 0.5, 0.0, 1.0);

    return inside ? edgeCoverage : (1.0 - edgeCoverage);
}

Vertex Shader Pattern

struct VS_Input
{
    float2 position   : POSITION;     // Glyph quad corner in screen/world space
    float2 glyphCoord : TEXCOORD0;    // Corresponding glyph-space coordinate
    uint   bandOffset : TEXCOORD1;    // Offset into curve buffer for this glyph
    uint   curveCount : TEXCOORD2;    // Number of curves in band
};

struct VS_Output
{
    float4 position   : SV_Position;
    float2 glyphCoord : TEXCOORD0;
    nointerpolation uint bandOffset : TEXCOORD1;
    nointerpolation uint curveCount : TEXCOORD2;
};

VS_Output VS_Slug(VS_Input input)
{
    VS_Output output;
    output.position   = mul(float4(input.position, 0.0, 1.0), WorldViewProjection);
    output.glyphCoord = input.glyphCoord;
    output.bandOffset = input.bandOffset;
    output.curveCount = input.curveCount;
    return output;
}

CPU-Side Data Preparation (Pseudocode)

// 1. Load font file and extract glyph outlines
FontOutline outline = LoadGlyphOutline(font, glyphIndex);

// 2. Decompose to quadratic Beziers (TrueType is already quadratic)
//    OTF cubic curves must be approximated/split into quadratics
std::vector<SlugCurve> curves = DecomposeToQuadratics(outline);

// 3. Compute bands
float bandHeight = outline.bounds.height / NUM_BANDS;
std::vector<BandData> bands = ComputeBands(curves, NUM_BANDS, bandHeight);

// 4. Upload to GPU
UploadStructuredBuffer(curveBuffer, curves.data(), curves.size());
UploadStructuredBuffer(bandBuffer, bands.data(), bands.size());

// 5. Per glyph instance: store bandOffset and curveCount per band
//    in vertex data so the fragment shader can index directly

Render State Requirements

// Blend state: premultiplied alpha
BlendState SlugBlend
{
    BlendEnable    = TRUE;
    SrcBlend       = ONE;           // Premultiplied
    DestBlend      = INV_SRC_ALPHA;
    BlendOp        = ADD;
    SrcBlendAlpha  = ONE;
    DestBlendAlpha = INV_SRC_ALPHA;
    BlendOpAlpha   = ADD;
};

// Depth: typically write disabled for text overlay
DepthStencilState SlugDepth
{
    DepthEnable    = FALSE;
    DepthWriteMask = ZERO;
};

// Rasterizer: no backface culling (glyph quads are 2D)
RasterizerState SlugRaster
{
    CullMode = NONE;
    FillMode = SOLID;
};

Common Patterns

Rendering a String

// For each glyph in string:
for (auto& glyph : string.glyphs)
{
    // Emit a quad (2 triangles) covering the glyph bounding box
    // Each vertex carries:
    //   - screen position
    //   - glyph-space coordinate (the same corner in font units)
    //   - bandOffset + curveCount for the fragment shader

    float2 min = glyph.screenMin;
    float2 max = glyph.screenMax;
    float2 glyphMin = glyph.fontMin;
    float2 glyphMax = glyph.fontMax;

    EmitQuad(min, max, glyphMin, glyphMax,
             glyph.bandOffset, glyph.curveCount);
}

Scaling Text

Scaling is handled entirely on the CPU side by transforming the screen-space quad. The glyph-space coordinates stay constant — the fragment shader always works in font units.

float scale = desiredPixelSize / font.unitsPerEm;
float2 screenMin = origin + glyph.fontMin * scale;
float2 screenMax = origin + glyph.fontMax * scale;

Troubleshooting

ProblemCauseFix
Glyph appears hollow/invertedWinding order reversedCheck contour orientation; TrueType uses clockwise for outer contours
Jagged edgesAnti-aliasing not appliedEnsure distance-to-edge is computed and used in final coverage
Performance poorBand optimization not activeVerify per-fragment curve count is small (< ~20); increase band count
Cubic curves not renderingOTF cubic Béziers unsupported nativelySplit cubics into quadratic approximations on CPU
Artifacts at glyph overlapCurves not clipped to bandClip curve Y range to band extents before upload
Black box instead of glyphBlend state wrongUse premultiplied alpha blend (ONE, INV_SRC_ALPHA)
Missing glyphsBand offset incorrectValidate bandOffset indexing aligns with buffer layout

Credits & Attribution

Per the license: if you distribute software using this code, you must give credit to Eric Lengyel and the Slug algorithm.

Suggested attribution:

Font rendering uses the Slug Algorithm by Eric Lengyel (https://jcgt.org/published/0006/02/02/)

References

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

33.96%
按下载量换算2,748

Claude

30.79%
按下载量换算2,492

Cursor

21.07%
按下载量换算1,705

Gemini CLI

10.26%
按下载量换算830

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

可疑

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills