Skip to content

Fill glyph patterns column by column - #2511

Open
nikosavola wants to merge 4 commits into
KLayout:masterfrom
nikosavola:pr-text-glyphs
Open

nikosavola wants to merge 4 commits into
KLayout:masterfrom
nikosavola:pr-text-glyphs

Conversation

@nikosavola

@nikosavola nikosavola commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Text labels take most of the render time when a layout has many of them, and most of that is Bitmap::fill_pattern. It worked out the clipping and shift of each 32 pixel column again for every row of a glyph, and looked up scanline out of line for every word. Now the column work is done once, and each row is one shift and one or two ORs. Bitmap::scanline is inline for scanlines that already exist. Only the allocation stays out of line.

In a headless render of a layout with many labels, fill_pattern was 42% of the instructions and the scanline lookup another 13%. The render is now about 1.4 times faster, the instruction count drops from 10.0G to 6.3G, and the images are the same bit for bit.

The first test draws random texts into bitmaps and checks a hash of all pixels. The expected value comes from the code before the change.

This also fixes a bug in the clipped path. When a glyph starts above the top edge of the bitmap, fill_pattern skipped the clipped rows by whole words instead of whole rows, so the pattern pointer went out of step and the text was garbled. Fonts with more than one word per row are affected. The step is now one row of stride words. The second test renders the same text into a short and a tall bitmap and checks that the clipped rows match the fully drawn one. That test fails on the code before the fix.

- random texts at all alignments, partly outside bitmaps of several widths, at two font resolutions
- the expected values come from the code before the column-wise fill
- `fill_pattern` worked out the clipping and shift of each 32 pixel column again for every row, and looked up the scanline out of line for every word. The column work is now done once, and each row is one shift and one or two ORs
- `Bitmap::scanline` returns existing scanlines inline, only the allocation stays out of line
- fill_pattern advanced the pattern pointer by one word per skipped row, but a font row takes stride words
- with the wide fonts (stride 2 and up) the rows seen of a cut-off glyph came from the wrong pattern rows, garbling the text
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant