Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
388e6ae
Move DeltaSetIndexMap to variations
simoncozens Dec 1, 2022
b577acb
DeltaSetIndexMap has two versions now
simoncozens Dec 2, 2022
ea4dae1
COLRv1 first draft
simoncozens Dec 2, 2022
c2e3e28
Fix offset/version errors for Paint table
simoncozens Dec 5, 2022
f13ec56
Use ClipList for bboxes in COLRv1 glyphs
simoncozens Dec 5, 2022
29c157c
Some tests (currently layers fails)
simoncozens Dec 5, 2022
96843a7
Fix palette index size
simoncozens Dec 6, 2022
ed63558
Allow for constructing Paints while parsing a Paint
simoncozens Dec 6, 2022
978b589
Return wrapped paint tree structures
simoncozens Dec 6, 2022
c5d402c
Remove debugging code
simoncozens Dec 6, 2022
f5b6e5c
Reformatting
simoncozens Dec 6, 2022
ed00f7d
Variable things use variable colour lines
simoncozens Dec 6, 2022
a187fa1
Handle components in colour glyphs
simoncozens Dec 6, 2022
8842816
There are now two types of delta set, with either 16/8 bit deltas or …
simoncozens Dec 6, 2022
c8056fe
Oops, bad naming
simoncozens Jan 5, 2023
d55cdf4
Instantiate some variable paint operations
simoncozens Jan 5, 2023
2e95a2e
Implement a bunch more paints, fix scaling issues
simoncozens May 22, 2023
2302e2c
Handle rotation point of linear gradient
simoncozens Jun 7, 2023
bfbb444
Instantiate var radial gradients
simoncozens Jun 8, 2023
d2cc0a8
Clean up code
simoncozens Jun 8, 2023
c88ccb7
Add COLRv1 test font from paintcompiler
simoncozens Jun 8, 2023
8c033c3
Bonus content! Allow for writing of variation data
simoncozens Jul 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 27 additions & 9 deletions src/TTFFont.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import LayoutEngine from './layout/LayoutEngine';
import TTFGlyph from './glyph/TTFGlyph';
import CFFGlyph from './glyph/CFFGlyph';
import SBIXGlyph from './glyph/SBIXGlyph';
import COLRGlyph from './glyph/COLRGlyph';
import { COLRGlyph, COLRv1Glyph } from './glyph/COLRGlyph';
import { PAINT_OPERATIONS } from './glyph/PaintOperation';
import GlyphVariationProcessor from './glyph/GlyphVariationProcessor';
import TTFSubset from './subset/TTFSubset';
import CFFSubset from './subset/CFFSubset';
Expand Down Expand Up @@ -386,17 +387,34 @@ export default class TTFFont {

_getBaseGlyph(glyph, characters = []) {
if (!this._glyphs[glyph]) {
if (this.directory.tables.glyf) {
this._glyphs[glyph] = new TTFGlyph(glyph, characters, this);

} else if (this.directory.tables['CFF '] || this.directory.tables.CFF2) {
this._glyphs[glyph] = new CFFGlyph(glyph, characters, this);
}
this._glyphs[glyph] = this._getBaseGlyphUncached(glyph, characters)
}

return this._glyphs[glyph] || null;
}

_getBaseGlyphUncached(glyph, characters = []) {
if (this.directory.tables.glyf) {
return new TTFGlyph(glyph, characters, this);
} else if (this.directory.tables['CFF '] || this.directory.tables.CFF2) {
return new CFFGlyph(glyph, characters, this);
}
}

_getColrGlyph(glyph, characters = []) {
if (this.COLR.version == 1 && this.COLR.baseGlyphList) {
for (let baseGlyph of this.COLR.baseGlyphList.baseGlyphPaintRecords) {
if (baseGlyph.gid == glyph) {
let colorGlyph = new COLRv1Glyph(glyph, characters, this)
colorGlyph.paint = (new PAINT_OPERATIONS[baseGlyph.paint.version])(baseGlyph.paint, this);
return colorGlyph
}
}
}
// Either v0 format, no BaseGlyphList, or not found -> treat as COLRv0
return new COLRGlyph(glyph, characters, this);
}

/**
* Returns a glyph object for the given glyph id.
* You can pass the array of code points this glyph represents for
Expand All @@ -412,8 +430,8 @@ export default class TTFFont {
this._glyphs[glyph] = new SBIXGlyph(glyph, characters, this);

} else if ((this.directory.tables.COLR) && (this.directory.tables.CPAL)) {
this._glyphs[glyph] = new COLRGlyph(glyph, characters, this);

// Each glyph may be either COLRv0 (layers) or COLRv1 (paint tree)
this._glyphs[glyph] = this._getColrGlyph(glyph, characters);
} else {
this._getBaseGlyph(glyph, characters);
}
Expand Down
49 changes: 48 additions & 1 deletion src/glyph/COLRGlyph.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class COLRLayer {
* Each glyph in this format contain a list of colored layers, each
* of which is another vector glyph.
*/
export default class COLRGlyph extends Glyph {
export class COLRGlyph extends Glyph {
type = 'COLR';

_getBBox() {
Expand Down Expand Up @@ -87,4 +87,51 @@ export default class COLRGlyph extends Glyph {

return;
}
_getContours() {
var base = this._font._getBaseGlyphUncached(this.id);
return base._getContours();
}

}

/**
* Represents a color (e.g. emoji) glyph in Microsoft/Google's COLRv1
* format. Each glyph in this format contains a directed acyclic graph
* of Paint structures.
*/
export class COLRv1Glyph extends COLRGlyph {
type = 'COLRv1';

_getBBox() {
// If we have a clip list item, use that
let colr = this._font.COLR;
if (colr.clipList) {
for (var clip of colr.clipList.clips) {
if (clip.startGlyphId <= this.id && this.id <= clip.endGlyphId) {
let box = clip.clipBox;
return new BBox(
box.xMin,
box.yMin,
box.xMax,
box.yMax
);
}
}
}
return super._getBBox();
}
render(ctx, size) {
// One scale only.
ctx.save();
let scale = 1 / this._font.unitsPerEm * size;
ctx.scale(scale, scale);

let paint = this.paint;
if (this._font.variationCoords) {
paint = paint.instantiate(this._font._variationProcessor);
}

paint.render(ctx, size);
ctx.restore();
}
}
Loading