From 8377341b289f47a8e63d448b5a3376dfdd464734 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 14 Dec 2022 22:03:52 -0500 Subject: [PATCH] wip: implement paint_glyph --- src/harfbuzz-subset.cc | 1 + src/harfbuzz.cc | 1 + src/hb-ot-color-colr-table.hh | 204 ++++++++++++++++++++++++++++++++-- src/meson.build | 1 + 4 files changed, 199 insertions(+), 8 deletions(-) diff --git a/src/harfbuzz-subset.cc b/src/harfbuzz-subset.cc index 4eeb99fe7..c5c66747a 100644 --- a/src/harfbuzz-subset.cc +++ b/src/harfbuzz-subset.cc @@ -14,6 +14,7 @@ #include "hb-number.cc" #include "hb-ot-cff1-table.cc" #include "hb-ot-cff2-table.cc" +#include "hb-ot-color-colr-table.cc" #include "hb-ot-color.cc" #include "hb-ot-face.cc" #include "hb-ot-font.cc" diff --git a/src/harfbuzz.cc b/src/harfbuzz.cc index d5bb3880e..03196eaa6 100644 --- a/src/harfbuzz.cc +++ b/src/harfbuzz.cc @@ -19,6 +19,7 @@ #include "hb-number.cc" #include "hb-ot-cff1-table.cc" #include "hb-ot-cff2-table.cc" +#include "hb-ot-color-colr-table.cc" #include "hb-ot-color.cc" #include "hb-ot-face.cc" #include "hb-ot-font.cc" diff --git a/src/hb-ot-color-colr-table.hh b/src/hb-ot-color-colr-table.hh index 1fe3ee420..1ec48dc00 100644 --- a/src/hb-ot-color-colr-table.hh +++ b/src/hb-ot-color-colr-table.hh @@ -31,6 +31,7 @@ #include "hb-open-type.hh" #include "hb-ot-layout-common.hh" #include "hb-ot-var-common.hh" +#include "hb-paint.hh" /* * COLR -- Color @@ -45,6 +46,31 @@ namespace OT { struct COLR; + +struct hb_paint_context_t; + +struct Paint; + +static void paint_dispatch (const Paint *paint, hb_paint_context_t *c); + +struct hb_paint_context_t { + + const COLR* get_colr_table () const + { return reinterpret_cast (base); } + +public: + const void *base; + hb_paint_funcs_t *funcs; + void *data; + + hb_paint_context_t (const void *base_, hb_paint_funcs_t *funcs_, void *data_) : + base(base_), + funcs(funcs_), + data(data_) + {} + +}; + struct hb_colrv1_closure_context_t : hb_dispatch_context_t { @@ -182,6 +208,11 @@ struct Variable return_trace (c->check_struct (this) && value.sanitize (c)); } + void paint_glyph (hb_paint_context_t *c) const + { + value.paint_glyph (c); + } + protected: T value; public: @@ -216,6 +247,11 @@ struct NoVariable return_trace (c->check_struct (this) && value.sanitize (c)); } + void paint_glyph (hb_paint_context_t *c) const + { + value.paint_glyph (c); + } + T value; public: DEFINE_SIZE_STATIC (T::static_size); @@ -357,6 +393,14 @@ struct Affine2x3 return_trace (c->check_struct (this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->push_transform (c->data, + xx.to_float (), yx.to_float (), + xy.to_float (), yy.to_float (), + dx.to_float (), dy.to_float ()); + } + F16DOT16 xx; F16DOT16 yx; F16DOT16 xy; @@ -388,6 +432,8 @@ struct PaintColrLayers return_trace (c->check_struct (this)); } + void paint_glyph (hb_paint_context_t *c) const; + HBUINT8 format; /* format = 1 */ HBUINT8 numLayers; HBUINT32 firstLayerIndex; /* index into COLRv1::layerList */ @@ -415,6 +461,11 @@ struct PaintSolid return_trace (c->check_struct (this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->solid (c->data, paletteIndex); + } + HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ HBUINT16 paletteIndex; F2DOT14 alpha; @@ -443,6 +494,11 @@ struct PaintLinearGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->linear_gradient (c->data, nullptr, x0, y0, x1, y1, x2, y2); + } + HBUINT8 format; /* format = 4(noVar) or 5 (Var) */ Offset24To> colorLine; /* Offset (from beginning of PaintLinearGradient * table) to ColorLine subtable. */ @@ -477,6 +533,11 @@ struct PaintRadialGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->radial_gradient (c->data, nullptr, x0, y0, radius0, x1, y1, radius1); + } + HBUINT8 format; /* format = 6(noVar) or 7 (Var) */ Offset24To> colorLine; /* Offset (from beginning of PaintRadialGradient * table) to ColorLine subtable. */ @@ -511,6 +572,11 @@ struct PaintSweepGradient return_trace (c->check_struct (this) && colorLine.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->sweep_gradient (c->data, nullptr, centerX, centerY, startAngle, endAngle); + } + HBUINT8 format; /* format = 8(noVar) or 9 (Var) */ Offset24To> colorLine; /* Offset (from beginning of PaintSweepGradient * table) to ColorLine subtable. */ @@ -522,8 +588,6 @@ struct PaintSweepGradient DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size + 2 * F2DOT14::static_size); }; -struct Paint; - // Paint a non-COLR glyph, filled as indicated by paint. struct PaintGlyph { @@ -548,6 +612,13 @@ struct PaintGlyph return_trace (c->check_struct (this) && paint.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->push_clip (c->data, gid); + paint_dispatch (&(this+paint), c); + c->funcs->pop_clip (c->data); + } + HBUINT8 format; /* format = 10 */ Offset24To paint; /* Offset (from beginning of PaintGlyph table) to Paint subtable. */ HBUINT16 gid; @@ -575,6 +646,12 @@ struct PaintColrGlyph return_trace (c->check_struct (this)); } + void paint_glyph (hb_paint_context_t *c) const + { + // FIXME clipbox + //paint_glyph (c->data, gid); + } + HBUINT8 format; /* format = 11 */ HBUINT16 gid; public: @@ -603,6 +680,13 @@ struct PaintTransform transform.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + (this+transform).paint_glyph (c); + paint_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); + } + HBUINT8 format; /* format = 12(noVar) or 13 (Var) */ Offset24To src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */ Offset24To> transform; @@ -629,6 +713,13 @@ struct PaintTranslate return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->push_transform (c->data, 0, 0, 0, 0, 0, 0); + paint_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); + } + HBUINT8 format; /* format = 14(noVar) or 15 (Var) */ Offset24To src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */ FWORD dx; @@ -656,6 +747,13 @@ struct PaintScale return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->push_transform (c->data, scaleX, 0, 0, scaleY, 0, 0); + paint_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); + } + HBUINT8 format; /* format = 16 (noVar) or 17(Var) */ Offset24To src; /* Offset (from beginning of PaintScale table) to Paint subtable. */ F2DOT14 scaleX; @@ -683,6 +781,17 @@ struct PaintScaleAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->push_transform (c->data, 0, 0, 0, 0, centerX, centerY); + c->funcs->push_transform (c->data, scaleX, 0, 0, scaleY, 0, 0); + c->funcs->push_transform (c->data, 0, 0, 0, 0, - centerX, - centerY); + paint_dispatch (&(this+src), c); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + c->funcs->pop_transform (c->data); + } + HBUINT8 format; /* format = 18 (noVar) or 19(Var) */ Offset24To src; /* Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable. */ F2DOT14 scaleX; @@ -712,6 +821,10 @@ struct PaintScaleUniform return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + } + HBUINT8 format; /* format = 20 (noVar) or 21(Var) */ Offset24To src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */ F2DOT14 scale; @@ -738,6 +851,10 @@ struct PaintScaleUniformAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + } + HBUINT8 format; /* format = 22 (noVar) or 23(Var) */ Offset24To src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */ F2DOT14 scale; @@ -766,6 +883,10 @@ struct PaintRotate return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + } + HBUINT8 format; /* format = 24 (noVar) or 25(Var) */ Offset24To src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */ F2DOT14 angle; @@ -792,6 +913,10 @@ struct PaintRotateAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + } + HBUINT8 format; /* format = 26 (noVar) or 27(Var) */ Offset24To src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */ F2DOT14 angle; @@ -820,6 +945,10 @@ struct PaintSkew return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + } + HBUINT8 format; /* format = 28(noVar) or 29 (Var) */ Offset24To src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */ F2DOT14 xSkewAngle; @@ -847,6 +976,10 @@ struct PaintSkewAroundCenter return_trace (c->check_struct (this) && src.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + } + HBUINT8 format; /* format = 30(noVar) or 31 (Var) */ Offset24To src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */ F2DOT14 xSkewAngle; @@ -879,6 +1012,16 @@ struct PaintComposite backdrop.sanitize (c, this)); } + void paint_glyph (hb_paint_context_t *c) const + { + c->funcs->push_group (c->data); + paint_dispatch (&(this+backdrop), c); + c->funcs->push_group (c->data); + paint_dispatch (&(this+src), c); + c->funcs->pop_group_and_composite (c->data, (hb_paint_composite_mode_t) (int)mode); + c->funcs->pop_group_and_composite (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + } + HBUINT8 format; /* format = 32 */ Offset24To src; /* Offset (from beginning of PaintComposite table) to source Paint subtable. */ CompositeMode mode; /* If mode is unrecognized use COMPOSITE_CLEAR */ @@ -979,11 +1122,6 @@ struct ClipBox return true; } - void paint_glyph (hb_font_t *font, hb_codepoint_t glyph, - hb_paint_funcs_t *funcs, void *paint_data) const - { - } - protected: union { HBUINT8 format; /* Format identifier */ @@ -1195,6 +1333,45 @@ struct Paint } } + void paint_glyph (hb_paint_context_t *c) const + { + switch (u.format) { + case 1: u.paintformat1.paint_glyph (c); break; + case 2: u.paintformat2.paint_glyph (c); break; + case 3: u.paintformat3.paint_glyph (c); break; + case 4: u.paintformat4.paint_glyph (c); break; + case 5: u.paintformat5.paint_glyph (c); break; + case 6: u.paintformat6.paint_glyph (c); break; + case 7: u.paintformat7.paint_glyph (c); break; + case 8: u.paintformat8.paint_glyph (c); break; + case 9: u.paintformat9.paint_glyph (c); break; + case 10: u.paintformat10.paint_glyph (c); break; + case 11: u.paintformat11.paint_glyph (c); break; + case 12: u.paintformat12.paint_glyph (c); break; + case 13: u.paintformat13.paint_glyph (c); break; + case 14: u.paintformat14.paint_glyph (c); break; + case 15: u.paintformat15.paint_glyph (c); break; + case 16: u.paintformat16.paint_glyph (c); break; + case 17: u.paintformat17.paint_glyph (c); break; + case 18: u.paintformat18.paint_glyph (c); break; + case 19: u.paintformat19.paint_glyph (c); break; + case 20: u.paintformat20.paint_glyph (c); break; + case 21: u.paintformat21.paint_glyph (c); break; + case 22: u.paintformat22.paint_glyph (c); break; + case 23: u.paintformat23.paint_glyph (c); break; + case 24: u.paintformat24.paint_glyph (c); break; + case 25: u.paintformat25.paint_glyph (c); break; + case 26: u.paintformat26.paint_glyph (c); break; + case 27: u.paintformat27.paint_glyph (c); break; + case 28: u.paintformat28.paint_glyph (c); break; + case 29: u.paintformat29.paint_glyph (c); break; + case 30: u.paintformat30.paint_glyph (c); break; + case 31: u.paintformat31.paint_glyph (c); break; + case 32: u.paintformat32.paint_glyph (c); break; + default: assert (0); + } + } + protected: union { HBUINT8 format; @@ -1618,6 +1795,12 @@ struct COLR void paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { + hb_paint_context_t c (this, funcs, data); + const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList; + const BaseGlyphPaintRecord* record = get_base_glyph_paintrecord (glyph); + const Paint &paint = &baseglyph_paintrecords+record->paint; + + paint.paint_glyph (&c); } protected: @@ -1642,7 +1825,12 @@ struct COLR_accelerator_t : COLR::accelerator_t { COLR_accelerator_t (hb_face_t *face) : COLR::accelerator_t (face) {} }; +static void +paint_dispatch (const Paint *paint, hb_paint_context_t *c) +{ + paint->paint_glyph (c); +} + } /* namespace OT */ - #endif /* HB_OT_COLOR_COLR_TABLE_HH */ diff --git a/src/meson.build b/src/meson.build index 463a3b349..164bb17f0 100644 --- a/src/meson.build +++ b/src/meson.build @@ -75,6 +75,7 @@ hb_base_sources = files( 'hb-ot-cmap-table.hh', 'hb-ot-color-cbdt-table.hh', 'hb-ot-color-colr-table.hh', + 'hb-ot-color-colr-table.cc', 'hb-ot-color-cpal-table.hh', 'hb-ot-color-sbix-table.hh', 'hb-ot-color-svg-table.hh',