diff --git a/make/modules/java.desktop/lib/Awt2dLibraries.gmk b/make/modules/java.desktop/lib/Awt2dLibraries.gmk
index 96576bb8d94..47cfea05577 100644
--- a/make/modules/java.desktop/lib/Awt2dLibraries.gmk
+++ b/make/modules/java.desktop/lib/Awt2dLibraries.gmk
@@ -451,7 +451,7 @@ else
-DHB_NO_PRAGMA_GCC_DIAGNOSTIC
endif
ifeq ($(call isTargetOs, linux macosx), true)
- HARFBUZZ_CFLAGS += -DHAVE_INTEL_ATOMIC_PRIMITIVES
+ HARFBUZZ_CFLAGS += -DHAVE_INTEL_ATOMIC_PRIMITIVES -DHB_NO_VISIBILITY
endif
# Early re-canonizing has to be disabled to workaround an internal XlC compiler error
diff --git a/src/java.desktop/share/legal/harfbuzz.md b/src/java.desktop/share/legal/harfbuzz.md
index 9037354540b..3426352d51f 100644
--- a/src/java.desktop/share/legal/harfbuzz.md
+++ b/src/java.desktop/share/legal/harfbuzz.md
@@ -1,8 +1,8 @@
-## Harfbuzz v4.4.1
+## Harfbuzz v7.0.1
### Harfbuzz License
-https://github.com/harfbuzz/harfbuzz/blob/4.4.1/COPYING
+https://github.com/harfbuzz/harfbuzz/blob/7.0.1/COPYING
@@ -12,21 +12,22 @@ files names COPYING in subdirectories where applicable.
Copyright © 2010-2022 Google, Inc.
Copyright © 2018-2020 Ebrahim Byagowi
-Copyright © 2019-2020 Facebook, Inc.
-Copyright © 2012-2015 Mozilla Foundation.
-Copyright © 2011 Codethink Limited
-Copyright © 2008-2010 Nokia Corporation and/or its subsidiary(-ies)
-Copyright © 2009 Keith Stribley
-Copyright © 2009 Martin Hosken and SIL International
-Copyright © 2007 Chris Wilson
-Copyright © 2005-2022 Behdad Esfahbod
-Copyright © 2005 David Turner
Copyright © 2004-2013 Red Hat, Inc.
-Copyright © 1998-2004 David Turner and Werner Lemberg
-Copyright © 2016 Elie Roux
+Copyright © 2019 Facebook, Inc.
+Copyright © 2007 Chris Wilson
Copyright © 2018-2019 Adobe Inc.
+Copyright © 2006-2023 Behdad Esfahbod
+Copyright © 1998-2004 David Turner and Werner Lemberg
+Copyright © 2009 Keith Stribley
Copyright © 2018 Khaled Hosny
+Copyright © 2016 Elie Roux
Copyright © 2016 Igalia S.L.
+Copyright © 2015 Mozilla Foundation.
+Copyright © 1999 David Turner
+Copyright © 2005 Werner Lemberg
+Copyright © 2013-2015 Alexei Podtelezhnikov
+Copyright © 2022 Matthias Clasen
+Copyright © 2011 Codethink Limited
For full copyright notices consult the individual files in the package.
@@ -72,3 +73,23 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+### AUTHORS File Information
+```
+
+Behdad Esfahbod
+David Corbett
+David Turner
+Ebrahim Byagowi
+Garret Rieger
+Jonathan Kew
+Khaled Hosny
+Lars Knoll
+Martin Hosken
+Owen Taylor
+Roderick Sheeter
+Roozbeh Pournader
+Simon Hausmann
+Werner Lemberg
+
+```
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-color-cbdt-table.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh
similarity index 93%
rename from src/java.desktop/share/native/libharfbuzz/hb-ot-color-cbdt-table.hh
rename to src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh
index 70d78c74d3b..11aeda5297f 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-color-cbdt-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh
@@ -24,10 +24,11 @@
* Google Author(s): Seigo Nonaka, Calder Kitagawa
*/
-#ifndef HB_OT_COLOR_CBDT_TABLE_HH
-#define HB_OT_COLOR_CBDT_TABLE_HH
+#ifndef OT_COLOR_CBDT_CBDT_HH
+#define OT_COLOR_CBDT_CBDT_HH
-#include "hb-open-type.hh"
+#include "../../../hb-open-type.hh"
+#include "../../../hb-paint.hh"
/*
* CBLC -- Color Bitmap Location
@@ -67,7 +68,7 @@ _copy_data_to_cbdt (hb_vector_t *cbdt_prime,
{
unsigned int new_len = cbdt_prime->length + length;
if (unlikely (!cbdt_prime->alloc (new_len))) return false;
- memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length);
+ hb_memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length);
cbdt_prime->length = new_len;
return true;
}
@@ -80,12 +81,15 @@ struct SmallGlyphMetrics
return_trace (c->check_struct (this));
}
- void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) const
+ void get_extents (hb_font_t *font, hb_glyph_extents_t *extents, bool scale) const
{
- extents->x_bearing = font->em_scale_x (bearingX);
- extents->y_bearing = font->em_scale_y (bearingY);
- extents->width = font->em_scale_x (width);
- extents->height = font->em_scale_y (-static_cast(height));
+ extents->x_bearing = bearingX;
+ extents->y_bearing = bearingY;
+ extents->width = width;
+ extents->height = -static_cast (height);
+
+ if (scale)
+ font->scale_glyph_extents (extents);
}
HBUINT8 height;
@@ -307,7 +311,7 @@ struct IndexSubtable
}
}
- bool get_extents (hb_glyph_extents_t *extents HB_UNUSED) const
+ bool get_extents (hb_glyph_extents_t *extents HB_UNUSED, bool scale HB_UNUSED) const
{
switch (u.header.indexFormat)
{
@@ -468,13 +472,13 @@ struct IndexSubtableRecord
if (unlikely (!c->serializer->check_success (records->resize (records->length + 1))))
return_trace (false);
- (*records)[records->length - 1].firstGlyphIndex = 1;
- (*records)[records->length - 1].lastGlyphIndex = 0;
+ records->tail ().firstGlyphIndex = 1;
+ records->tail ().lastGlyphIndex = 0;
bitmap_size_context->size += IndexSubtableRecord::min_size;
c->serializer->push ();
- if (unlikely (!add_new_subtable (c, bitmap_size_context, &((*records)[records->length - 1]), lookup, base, start)))
+ if (unlikely (!add_new_subtable (c, bitmap_size_context, &(records->tail ()), lookup, base, start)))
{
c->serializer->pop_discard ();
c->serializer->revert (snap);
@@ -504,8 +508,8 @@ struct IndexSubtableRecord
return num_missing;
}
- bool get_extents (hb_glyph_extents_t *extents, const void *base) const
- { return (base+offsetToSubtable).get_extents (extents); }
+ bool get_extents (hb_glyph_extents_t *extents, const void *base, bool scale) const
+ { return (base+offsetToSubtable).get_extents (extents, scale); }
bool get_image_data (unsigned int gid,
const void *base,
@@ -833,7 +837,7 @@ struct CBDT
}
bool
- get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
+ get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents, bool scale = true) const
{
const void *base;
const BitmapSizeTable &strike = this->cblc->choose_strike (font);
@@ -841,7 +845,7 @@ struct CBDT
if (!subtable_record || !strike.ppemX || !strike.ppemY)
return false;
- if (subtable_record->get_extents (extents, base))
+ if (subtable_record->get_extents (extents, base, scale))
return true;
unsigned int image_offset = 0, image_length = 0, image_format = 0;
@@ -858,26 +862,29 @@ struct CBDT
if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
return false;
auto &glyphFormat17 = StructAtOffset (this->cbdt, image_offset);
- glyphFormat17.glyphMetrics.get_extents (font, extents);
+ glyphFormat17.glyphMetrics.get_extents (font, extents, scale);
break;
}
case 18: {
if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
return false;
auto &glyphFormat18 = StructAtOffset (this->cbdt, image_offset);
- glyphFormat18.glyphMetrics.get_extents (font, extents);
+ glyphFormat18.glyphMetrics.get_extents (font, extents, scale);
break;
}
default: return false; /* TODO: Support other image formats. */
}
/* Convert to font units. */
- float x_scale = upem / (float) strike.ppemX;
- float y_scale = upem / (float) strike.ppemY;
- extents->x_bearing = roundf (extents->x_bearing * x_scale);
- extents->y_bearing = roundf (extents->y_bearing * y_scale);
- extents->width = roundf (extents->width * x_scale);
- extents->height = roundf (extents->height * y_scale);
+ if (scale)
+ {
+ float x_scale = upem / (float) strike.ppemX;
+ float y_scale = upem / (float) strike.ppemY;
+ extents->x_bearing = roundf (extents->x_bearing * x_scale);
+ extents->y_bearing = roundf (extents->y_bearing * y_scale);
+ extents->width = roundf (extents->width * x_scale);
+ extents->height = roundf (extents->height * y_scale);
+ }
return true;
}
@@ -934,6 +941,32 @@ struct CBDT
bool has_data () const { return cbdt.get_length (); }
+ bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
+ {
+ hb_glyph_extents_t extents;
+ hb_glyph_extents_t pixel_extents;
+ hb_blob_t *blob = reference_png (font, glyph);
+
+ if (unlikely (blob == hb_blob_get_empty ()))
+ return false;
+
+ if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents)))
+ return false;
+
+ if (unlikely (!get_extents (font, glyph, &pixel_extents, false)))
+ return false;
+
+ bool ret = funcs->image (data,
+ blob,
+ pixel_extents.width, -pixel_extents.height,
+ HB_PAINT_IMAGE_FORMAT_PNG,
+ font->slant_xy,
+ &extents);
+
+ hb_blob_destroy (blob);
+ return ret;
+ }
+
private:
hb_blob_ptr_t cblc;
hb_blob_ptr_t cbdt;
@@ -994,4 +1027,4 @@ struct CBDT_accelerator_t : CBDT::accelerator_t {
} /* namespace OT */
-#endif /* HB_OT_COLOR_CBDT_TABLE_HH */
+#endif /* OT_COLOR_CBDT_CBDT_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-color-colr-table.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh
similarity index 68%
rename from src/java.desktop/share/native/libharfbuzz/hb-ot-color-colr-table.hh
rename to src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh
index 6b9e734615b..c286ee3c908 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-color-colr-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh
@@ -25,12 +25,14 @@
* Google Author(s): Calder Kitagawa
*/
-#ifndef HB_OT_COLOR_COLR_TABLE_HH
-#define HB_OT_COLOR_COLR_TABLE_HH
+#ifndef OT_COLOR_COLR_COLR_HH
+#define OT_COLOR_COLR_COLR_HH
-#include "hb-open-type.hh"
-#include "hb-ot-layout-common.hh"
-#include "hb-ot-var-common.hh"
+#include "../../../hb.hh"
+#include "../../../hb-open-type.hh"
+#include "../../../hb-ot-var-common.hh"
+#include "../../../hb-paint.hh"
+#include "../../../hb-paint-extents.hh"
/*
* COLR -- Color
@@ -38,17 +40,82 @@
*/
#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
-#ifndef HB_COLRV1_MAX_NESTING_LEVEL
-#define HB_COLRV1_MAX_NESTING_LEVEL 100
-#endif
-#ifndef COLRV1_ENABLE_SUBSETTING
-#define COLRV1_ENABLE_SUBSETTING 1
-#endif
+namespace OT {
+struct hb_paint_context_t;
+}
namespace OT {
struct COLR;
+
+struct Paint;
+
+struct hb_paint_context_t :
+ hb_dispatch_context_t
+{
+ template
+ return_t dispatch (const T &obj) { obj.paint_glyph (this); return hb_empty_t (); }
+ static return_t default_return_value () { return hb_empty_t (); }
+
+ const COLR* get_colr_table () const
+ { return reinterpret_cast (base); }
+
+public:
+ const void *base;
+ hb_paint_funcs_t *funcs;
+ void *data;
+ hb_font_t *font;
+ unsigned int palette_index;
+ hb_color_t foreground;
+ VarStoreInstancer &instancer;
+ int depth_left = HB_MAX_NESTING_LEVEL;
+ int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
+
+ hb_paint_context_t (const void *base_,
+ hb_paint_funcs_t *funcs_,
+ void *data_,
+ hb_font_t *font_,
+ unsigned int palette_,
+ hb_color_t foreground_,
+ VarStoreInstancer &instancer_) :
+ base (base_),
+ funcs (funcs_),
+ data (data_),
+ font (font_),
+ palette_index (palette_),
+ foreground (foreground_),
+ instancer (instancer_)
+ { }
+
+ hb_color_t get_color (unsigned int color_index, float alpha, hb_bool_t *is_foreground)
+ {
+ hb_color_t color = foreground;
+
+ *is_foreground = true;
+
+ if (color_index != 0xffff)
+ {
+ if (!funcs->custom_palette_color (data, color_index, &color))
+ {
+ unsigned int clen = 1;
+ hb_face_t *face = hb_font_get_face (font);
+
+ hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color);
+ }
+
+ *is_foreground = false;
+ }
+
+ return HB_COLOR (hb_color_get_blue (color),
+ hb_color_get_green (color),
+ hb_color_get_red (color),
+ hb_color_get_alpha (color) * alpha);
+ }
+
+ inline void recurse (const Paint &paint);
+};
+
struct hb_colrv1_closure_context_t :
hb_dispatch_context_t
{
@@ -102,7 +169,7 @@ struct hb_colrv1_closure_context_t :
hb_set_t *glyphs_,
hb_set_t *layer_indices_,
hb_set_t *palette_indices_,
- unsigned nesting_level_left_ = HB_COLRV1_MAX_NESTING_LEVEL) :
+ unsigned nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
base (base_),
glyphs (glyphs_),
layer_indices (layer_indices_),
@@ -145,7 +212,7 @@ struct BaseGlyphRecord
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this)));
+ return_trace (c->check_struct (this));
}
public:
@@ -164,6 +231,8 @@ struct BaseGlyphRecord
template
struct Variable
{
+ static constexpr bool is_variable = true;
+
Variable* copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
@@ -186,8 +255,26 @@ struct Variable
return_trace (c->check_struct (this) && value.sanitize (c));
}
+ void paint_glyph (hb_paint_context_t *c) const
+ {
+ value.paint_glyph (c, varIdxBase);
+ }
+
+ void get_color_stop (hb_paint_context_t *c,
+ hb_color_stop_t *stop,
+ const VarStoreInstancer &instancer) const
+ {
+ value.get_color_stop (c, stop, varIdxBase, instancer);
+ }
+
+ hb_paint_extend_t get_extend () const
+ {
+ return value.get_extend ();
+ }
+
protected:
T value;
+ public:
VarIdx varIdxBase;
public:
DEFINE_SIZE_STATIC (4 + T::static_size);
@@ -196,6 +283,10 @@ struct Variable
template
struct NoVariable
{
+ static constexpr bool is_variable = false;
+
+ static constexpr uint32_t varIdxBase = VarIdx::NO_VARIATION;
+
NoVariable* copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
@@ -217,6 +308,23 @@ struct NoVariable
return_trace (c->check_struct (this) && value.sanitize (c));
}
+ void paint_glyph (hb_paint_context_t *c) const
+ {
+ value.paint_glyph (c, varIdxBase);
+ }
+
+ void get_color_stop (hb_paint_context_t *c,
+ hb_color_stop_t *stop,
+ const VarStoreInstancer &instancer) const
+ {
+ value.get_color_stop (c, stop, VarIdx::NO_VARIATION, instancer);
+ }
+
+ hb_paint_extend_t get_extend () const
+ {
+ return value.get_extend ();
+ }
+
T value;
public:
DEFINE_SIZE_STATIC (T::static_size);
@@ -234,7 +342,7 @@ struct ColorStop
TRACE_SUBSET (this);
auto *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
- return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex),
+ return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex),
HB_SERIALIZE_ERROR_INT_OVERFLOW));
}
@@ -244,6 +352,17 @@ struct ColorStop
return_trace (c->check_struct (this));
}
+ void get_color_stop (hb_paint_context_t *c,
+ hb_color_stop_t *out,
+ uint32_t varIdx,
+ const VarStoreInstancer &instancer) const
+ {
+ out->offset = stopOffset.to_float(instancer (varIdx, 0));
+ out->color = c->get_color (paletteIndex,
+ alpha.to_float (instancer (varIdx, 1)),
+ &out->is_foreground);
+ }
+
F2DOT14 stopOffset;
HBUINT16 paletteIndex;
F2DOT14 alpha;
@@ -295,6 +414,52 @@ struct ColorLine
stops.sanitize (c));
}
+ /* get up to count stops from start */
+ unsigned int
+ get_color_stops (hb_paint_context_t *c,
+ unsigned int start,
+ unsigned int *count,
+ hb_color_stop_t *color_stops,
+ const VarStoreInstancer &instancer) const
+ {
+ unsigned int len = stops.len;
+
+ if (count && color_stops)
+ {
+ unsigned int i;
+ for (i = 0; i < *count && start + i < len; i++)
+ stops[start + i].get_color_stop (c, &color_stops[i], instancer);
+ *count = i;
+ }
+
+ return len;
+ }
+
+ HB_INTERNAL static unsigned int static_get_color_stops (hb_color_line_t *color_line,
+ void *color_line_data,
+ unsigned int start,
+ unsigned int *count,
+ hb_color_stop_t *color_stops,
+ void *user_data)
+ {
+ const ColorLine *thiz = (const ColorLine *) color_line_data;
+ hb_paint_context_t *c = (hb_paint_context_t *) user_data;
+ return thiz->get_color_stops (c, start, count, color_stops, c->instancer);
+ }
+
+ hb_paint_extend_t get_extend () const
+ {
+ return (hb_paint_extend_t) (unsigned int) extend;
+ }
+
+ HB_INTERNAL static hb_paint_extend_t static_get_extend (hb_color_line_t *color_line,
+ void *color_line_data,
+ void *user_data)
+ {
+ const ColorLine *thiz = (const ColorLine *) color_line_data;
+ return thiz->get_extend ();
+ }
+
Extend extend;
Array16Of> stops;
public:
@@ -358,14 +523,25 @@ struct Affine2x3
return_trace (c->check_struct (this));
}
- HBFixed xx;
- HBFixed yx;
- HBFixed xy;
- HBFixed yy;
- HBFixed dx;
- HBFixed dy;
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ c->funcs->push_transform (c->data,
+ xx.to_float (c->instancer (varIdxBase, 0)),
+ yx.to_float (c->instancer (varIdxBase, 1)),
+ xy.to_float (c->instancer (varIdxBase, 2)),
+ yy.to_float (c->instancer (varIdxBase, 3)),
+ dx.to_float (c->instancer (varIdxBase, 4)),
+ dy.to_float (c->instancer (varIdxBase, 5)));
+ }
+
+ F16DOT16 xx;
+ F16DOT16 yx;
+ F16DOT16 xy;
+ F16DOT16 yy;
+ F16DOT16 dx;
+ F16DOT16 dy;
public:
- DEFINE_SIZE_STATIC (6 * HBFixed::static_size);
+ DEFINE_SIZE_STATIC (6 * F16DOT16::static_size);
};
struct PaintColrLayers
@@ -377,7 +553,7 @@ struct PaintColrLayers
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
- return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers->get (firstLayerIndex),
+ return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers.get (firstLayerIndex),
HB_SERIALIZE_ERROR_INT_OVERFLOW));
return_trace (true);
@@ -389,6 +565,8 @@ struct PaintColrLayers
return_trace (c->check_struct (this));
}
+ inline void paint_glyph (hb_paint_context_t *c) const;
+
HBUINT8 format; /* format = 1 */
HBUINT8 numLayers;
HBUINT32 firstLayerIndex; /* index into COLRv1::layerList */
@@ -406,7 +584,7 @@ struct PaintSolid
TRACE_SUBSET (this);
auto *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
- return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes->get (paletteIndex),
+ return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex),
HB_SERIALIZE_ERROR_INT_OVERFLOW));
}
@@ -416,6 +594,17 @@ struct PaintSolid
return_trace (c->check_struct (this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ hb_bool_t is_foreground;
+ hb_color_t color;
+
+ color = c->get_color (paletteIndex,
+ alpha.to_float (c->instancer (varIdxBase, 0)),
+ &is_foreground);
+ c->funcs->color (c->data, is_foreground, color);
+ }
+
HBUINT8 format; /* format = 2(noVar) or 3(Var)*/
HBUINT16 paletteIndex;
F2DOT14 alpha;
@@ -444,6 +633,23 @@ struct PaintLinearGradient
return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ hb_color_line_t cl = {
+ (void *) &(this+colorLine),
+ (this+colorLine).static_get_color_stops, c,
+ (this+colorLine).static_get_extend, nullptr
+ };
+
+ c->funcs->linear_gradient (c->data, &cl,
+ x0 + c->instancer (varIdxBase, 0),
+ y0 + c->instancer (varIdxBase, 1),
+ x1 + c->instancer (varIdxBase, 2),
+ y1 + c->instancer (varIdxBase, 3),
+ x2 + c->instancer (varIdxBase, 4),
+ y2 + c->instancer (varIdxBase, 5));
+ }
+
HBUINT8 format; /* format = 4(noVar) or 5 (Var) */
Offset24To> colorLine; /* Offset (from beginning of PaintLinearGradient
* table) to ColorLine subtable. */
@@ -478,6 +684,23 @@ struct PaintRadialGradient
return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ hb_color_line_t cl = {
+ (void *) &(this+colorLine),
+ (this+colorLine).static_get_color_stops, c,
+ (this+colorLine).static_get_extend, nullptr
+ };
+
+ c->funcs->radial_gradient (c->data, &cl,
+ x0 + c->instancer (varIdxBase, 0),
+ y0 + c->instancer (varIdxBase, 1),
+ radius0 + c->instancer (varIdxBase, 2),
+ x1 + c->instancer (varIdxBase, 3),
+ y1 + c->instancer (varIdxBase, 4),
+ radius1 + c->instancer (varIdxBase, 5));
+ }
+
HBUINT8 format; /* format = 6(noVar) or 7 (Var) */
Offset24To> colorLine; /* Offset (from beginning of PaintRadialGradient
* table) to ColorLine subtable. */
@@ -512,6 +735,21 @@ struct PaintSweepGradient
return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ hb_color_line_t cl = {
+ (void *) &(this+colorLine),
+ (this+colorLine).static_get_color_stops, c,
+ (this+colorLine).static_get_extend, nullptr
+ };
+
+ c->funcs->sweep_gradient (c->data, &cl,
+ centerX + c->instancer (varIdxBase, 0),
+ centerY + c->instancer (varIdxBase, 1),
+ (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * (float) M_PI,
+ (endAngle.to_float (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI);
+ }
+
HBUINT8 format; /* format = 8(noVar) or 9 (Var) */
Offset24To> colorLine; /* Offset (from beginning of PaintSweepGradient
* table) to ColorLine subtable. */
@@ -523,7 +761,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 +785,17 @@ struct PaintGlyph
return_trace (c->check_struct (this) && paint.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c) const
+ {
+ c->funcs->push_inverse_root_transform (c->data, c->font);
+ c->funcs->push_clip_glyph (c->data, gid, c->font);
+ c->funcs->push_root_transform (c->data, c->font);
+ c->recurse (this+paint);
+ c->funcs->pop_transform (c->data);
+ c->funcs->pop_clip (c->data);
+ c->funcs->pop_transform (c->data);
+ }
+
HBUINT8 format; /* format = 10 */
Offset24To paint; /* Offset (from beginning of PaintGlyph table) to Paint subtable. */
HBUINT16 gid;
@@ -575,6 +823,8 @@ struct PaintColrGlyph
return_trace (c->check_struct (this));
}
+ inline void paint_glyph (hb_paint_context_t *c) const;
+
HBUINT8 format; /* format = 11 */
HBUINT16 gid;
public:
@@ -603,6 +853,13 @@ struct PaintTransform
transform.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c) const
+ {
+ (this+transform).paint_glyph (c);
+ c->recurse (this+src);
+ 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 +886,16 @@ struct PaintTranslate
return_trace (c->check_struct (this) && src.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ float ddx = dx + c->instancer (varIdxBase, 0);
+ float ddy = dy + c->instancer (varIdxBase, 1);
+
+ bool p1 = c->funcs->push_translate (c->data, ddx, ddy);
+ c->recurse (this+src);
+ if (p1) 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 +923,16 @@ struct PaintScale
return_trace (c->check_struct (this) && src.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
+ float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
+
+ bool p1 = c->funcs->push_scale (c->data, sx, sy);
+ c->recurse (this+src);
+ if (p1) 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 +960,22 @@ struct PaintScaleAroundCenter
return_trace (c->check_struct (this) && src.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
+ float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
+ float tCenterX = centerX + c->instancer (varIdxBase, 2);
+ float tCenterY = centerY + c->instancer (varIdxBase, 3);
+
+ bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
+ bool p2 = c->funcs->push_scale (c->data, sx, sy);
+ bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
+ c->recurse (this+src);
+ if (p3) c->funcs->pop_transform (c->data);
+ if (p2) c->funcs->pop_transform (c->data);
+ if (p1) 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 +1005,15 @@ struct PaintScaleUniform
return_trace (c->check_struct (this) && src.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ float s = scale.to_float (c->instancer (varIdxBase, 0));
+
+ bool p1 = c->funcs->push_scale (c->data, s, s);
+ c->recurse (this+src);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
+
HBUINT8 format; /* format = 20 (noVar) or 21(Var) */
Offset24To src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */
F2DOT14 scale;
@@ -738,6 +1040,21 @@ struct PaintScaleUniformAroundCenter
return_trace (c->check_struct (this) && src.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ float s = scale.to_float (c->instancer (varIdxBase, 0));
+ float tCenterX = centerX + c->instancer (varIdxBase, 1);
+ float tCenterY = centerY + c->instancer (varIdxBase, 2);
+
+ bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
+ bool p2 = c->funcs->push_scale (c->data, s, s);
+ bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
+ c->recurse (this+src);
+ if (p3) c->funcs->pop_transform (c->data);
+ if (p2) c->funcs->pop_transform (c->data);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
+
HBUINT8 format; /* format = 22 (noVar) or 23(Var) */
Offset24To src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */
F2DOT14 scale;
@@ -766,6 +1083,15 @@ struct PaintRotate
return_trace (c->check_struct (this) && src.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ float a = angle.to_float (c->instancer (varIdxBase, 0));
+
+ bool p1 = c->funcs->push_rotate (c->data, a);
+ c->recurse (this+src);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
+
HBUINT8 format; /* format = 24 (noVar) or 25(Var) */
Offset24To src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */
F2DOT14 angle;
@@ -792,6 +1118,21 @@ struct PaintRotateAroundCenter
return_trace (c->check_struct (this) && src.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ float a = angle.to_float (c->instancer (varIdxBase, 0));
+ float tCenterX = centerX + c->instancer (varIdxBase, 1);
+ float tCenterY = centerY + c->instancer (varIdxBase, 2);
+
+ bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
+ bool p2 = c->funcs->push_rotate (c->data, a);
+ bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
+ c->recurse (this+src);
+ if (p3) c->funcs->pop_transform (c->data);
+ if (p2) c->funcs->pop_transform (c->data);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
+
HBUINT8 format; /* format = 26 (noVar) or 27(Var) */
Offset24To src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */
F2DOT14 angle;
@@ -820,6 +1161,16 @@ struct PaintSkew
return_trace (c->check_struct (this) && src.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
+ float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
+
+ bool p1 = c->funcs->push_skew (c->data, sx, sy);
+ c->recurse (this+src);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
+
HBUINT8 format; /* format = 28(noVar) or 29 (Var) */
Offset24To src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */
F2DOT14 xSkewAngle;
@@ -847,6 +1198,22 @@ struct PaintSkewAroundCenter
return_trace (c->check_struct (this) && src.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+ {
+ float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
+ float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
+ float tCenterX = centerX + c->instancer (varIdxBase, 2);
+ float tCenterY = centerY + c->instancer (varIdxBase, 3);
+
+ bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
+ bool p2 = c->funcs->push_skew (c->data, sx, sy);
+ bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
+ c->recurse (this+src);
+ if (p3) c->funcs->pop_transform (c->data);
+ if (p2) c->funcs->pop_transform (c->data);
+ if (p1) c->funcs->pop_transform (c->data);
+ }
+
HBUINT8 format; /* format = 30(noVar) or 31 (Var) */
Offset24To src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */
F2DOT14 xSkewAngle;
@@ -879,6 +1246,14 @@ struct PaintComposite
backdrop.sanitize (c, this));
}
+ void paint_glyph (hb_paint_context_t *c) const
+ {
+ c->recurse (this+backdrop);
+ c->funcs->push_group (c->data);
+ c->recurse (this+src);
+ c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode);
+ }
+
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 */
@@ -887,6 +1262,11 @@ struct PaintComposite
DEFINE_SIZE_STATIC (8);
};
+struct ClipBoxData
+{
+ int xMin, yMin, xMax, yMax;
+};
+
struct ClipBoxFormat1
{
bool sanitize (hb_sanitize_context_t *c) const
@@ -895,6 +1275,14 @@ struct ClipBoxFormat1
return_trace (c->check_struct (this));
}
+ void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer HB_UNUSED) const
+ {
+ clip_box.xMin = xMin;
+ clip_box.yMin = yMin;
+ clip_box.xMax = xMax;
+ clip_box.yMax = yMax;
+ }
+
public:
HBUINT8 format; /* format = 1(noVar) or 2(Var)*/
FWORD xMin;
@@ -905,7 +1293,20 @@ struct ClipBoxFormat1
DEFINE_SIZE_STATIC (1 + 4 * FWORD::static_size);
};
-struct ClipBoxFormat2 : Variable {};
+struct ClipBoxFormat2 : Variable
+{
+ void get_clip_box (ClipBoxData &clip_box, const VarStoreInstancer &instancer) const
+ {
+ value.get_clip_box(clip_box, instancer);
+ if (instancer)
+ {
+ clip_box.xMin += _hb_roundf (instancer (varIdxBase, 0));
+ clip_box.yMin += _hb_roundf (instancer (varIdxBase, 1));
+ clip_box.xMax += _hb_roundf (instancer (varIdxBase, 2));
+ clip_box.yMax += _hb_roundf (instancer (varIdxBase, 3));
+ }
+ }
+};
struct ClipBox
{
@@ -922,8 +1323,8 @@ struct ClipBox
template
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
+ if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward (ds)...));
case 2: return_trace (c->dispatch (u.format2, std::forward (ds)...));
@@ -931,6 +1332,28 @@ struct ClipBox
}
}
+ bool get_extents (hb_glyph_extents_t *extents,
+ const VarStoreInstancer &instancer) const
+ {
+ ClipBoxData clip_box;
+ switch (u.format) {
+ case 1:
+ u.format1.get_clip_box (clip_box, instancer);
+ break;
+ case 2:
+ u.format2.get_clip_box (clip_box, instancer);
+ break;
+ default:
+ return false;
+ }
+
+ extents->x_bearing = clip_box.xMin;
+ extents->y_bearing = clip_box.yMax;
+ extents->width = clip_box.xMax - clip_box.xMin;
+ extents->height = clip_box.yMin - clip_box.yMax;
+ return true;
+ }
+
protected:
union {
HBUINT8 format; /* Format identifier */
@@ -941,6 +1364,9 @@ struct ClipBox
struct ClipRecord
{
+ int cmp (hb_codepoint_t g) const
+ { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; }
+
ClipRecord* copy (hb_serialize_context_t *c, const void *base) const
{
TRACE_SERIALIZE (this);
@@ -956,6 +1382,13 @@ struct ClipRecord
return_trace (c->check_struct (this) && clipBox.sanitize (c, base));
}
+ bool get_extents (hb_glyph_extents_t *extents,
+ const void *base,
+ const VarStoreInstancer &instancer) const
+ {
+ return (base+clipBox).get_extents (extents, instancer);
+ }
+
public:
HBUINT16 startGlyphID; // first gid clip applies to
HBUINT16 endGlyphID; // last gid clip applies to, inclusive
@@ -963,6 +1396,7 @@ struct ClipRecord
public:
DEFINE_SIZE_STATIC (7);
};
+DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord);
struct ClipList
{
@@ -1025,7 +1459,7 @@ struct ClipList
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
if (!c->serializer->check_assign (out->format, format, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
- const hb_set_t& glyphset = *c->plan->_glyphset_colred;
+ const hb_set_t& glyphset = c->plan->_glyphset_colred;
const hb_map_t &glyph_map = *c->plan->glyph_map;
hb_map_t new_gid_offset_map;
@@ -1051,11 +1485,26 @@ struct ClipList
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
+ // TODO Make a formatted struct!
return_trace (c->check_struct (this) && clips.sanitize (c, this));
}
+ bool
+ get_extents (hb_codepoint_t gid,
+ hb_glyph_extents_t *extents,
+ const VarStoreInstancer &instancer) const
+ {
+ auto *rec = clips.as_array ().bsearch (gid);
+ if (rec)
+ {
+ rec->get_extents (extents, this, instancer);
+ return true;
+ }
+ return false;
+ }
+
HBUINT8 format; // Set to 1.
- Array32Of clips; // Clip records, sorted by startGlyphID
+ SortedArray32Of clips; // Clip records, sorted by startGlyphID
public:
DEFINE_SIZE_ARRAY_SIZED (5, clips);
};
@@ -1068,7 +1517,7 @@ struct Paint
{
TRACE_SANITIZE (this);
- if (unlikely (!c->check_start_recursion (HB_COLRV1_MAX_NESTING_LEVEL)))
+ if (unlikely (!c->check_start_recursion (HB_MAX_NESTING_LEVEL)))
return_trace (c->no_dispatch_return_value ());
return_trace (c->end_recursion (this->dispatch (c, std::forward (ds)...)));
@@ -1077,8 +1526,8 @@ struct Paint
template
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
+ if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
TRACE_DISPATCH (this, u.format);
- if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.paintformat1, std::forward (ds)...));
case 2: return_trace (c->dispatch (u.paintformat2, std::forward (ds)...));
@@ -1120,38 +1569,40 @@ struct Paint
union {
HBUINT8 format;
PaintColrLayers paintformat1;
- PaintSolid paintformat2;
+ NoVariable paintformat2;
Variable paintformat3;
- PaintLinearGradient paintformat4;
+ NoVariable> paintformat4;
Variable> paintformat5;
- PaintRadialGradient paintformat6;
+ NoVariable> paintformat6;
Variable> paintformat7;
- PaintSweepGradient paintformat8;
+ NoVariable> paintformat8;
Variable> paintformat9;
PaintGlyph paintformat10;
PaintColrGlyph paintformat11;
PaintTransform paintformat12;
PaintTransform paintformat13;
- PaintTranslate paintformat14;
+ NoVariable paintformat14;
Variable paintformat15;
- PaintScale paintformat16;
+ NoVariable paintformat16;
Variable paintformat17;
- PaintScaleAroundCenter paintformat18;
+ NoVariable paintformat18;
Variable paintformat19;
- PaintScaleUniform paintformat20;
+ NoVariable paintformat20;
Variable paintformat21;
- PaintScaleUniformAroundCenter paintformat22;
+ NoVariable paintformat22;
Variable paintformat23;
- PaintRotate paintformat24;
+ NoVariable paintformat24;
Variable paintformat25;
- PaintRotateAroundCenter paintformat26;
+ NoVariable paintformat26;
Variable paintformat27;
- PaintSkew paintformat28;
+ NoVariable paintformat28;
Variable paintformat29;
- PaintSkewAroundCenter paintformat30;
+ NoVariable paintformat30;
Variable paintformat31;
PaintComposite paintformat32;
} u;
+ public:
+ DEFINE_SIZE_MIN (2);
};
struct BaseGlyphPaintRecord
@@ -1193,7 +1644,7 @@ struct BaseGlyphList : SortedArray32Of
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- const hb_set_t* glyphset = c->plan->_glyphset_colred;
+ const hb_set_t* glyphset = &c->plan->_glyphset_colred;
for (const auto& _ : as_array ())
{
@@ -1247,7 +1698,14 @@ struct COLR
{
static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR;
- bool has_data () const { return numBaseGlyphs; }
+ bool has_v0_data () const { return numBaseGlyphs; }
+ bool has_v1_data () const
+ {
+ if (version == 1)
+ return (this+baseGlyphList).len > 0;
+
+ return false;
+ }
unsigned int get_glyph_layers (hb_codepoint_t glyph,
unsigned int start_offset,
@@ -1356,7 +1814,7 @@ struct COLR
(this+baseGlyphsZ).sanitize (c, numBaseGlyphs) &&
(this+layersZ).sanitize (c, numLayers) &&
(version == 0 ||
- (COLRV1_ENABLE_SUBSETTING && version == 1 &&
+ (version == 1 &&
baseGlyphList.sanitize (c, this) &&
layerList.sanitize (c, this) &&
clipList.sanitize (c, this) &&
@@ -1427,7 +1885,7 @@ struct COLR
TRACE_SUBSET (this);
const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map;
- const hb_set_t& glyphset = *c->plan->_glyphset_colred;
+ const hb_set_t& glyphset = c->plan->_glyphset_colred;
auto base_it =
+ hb_range (c->plan->num_output_glyphs ())
@@ -1476,7 +1934,7 @@ struct COLR
if (unlikely (!c->plan->new_gid_for_old_gid (out_layers[i].glyphId, &new_gid)))
return hb_pair_t> (false, out_layers);
out_layers[i].glyphId = new_gid;
- out_layers[i].colorIdx = c->plan->colr_palettes->get (layers[i].colorIdx);
+ out_layers[i].colorIdx = c->plan->colr_palettes.get (layers[i].colorIdx);
}
return hb_pair_t> (true, out_layers);
@@ -1509,10 +1967,171 @@ struct COLR
colr_prime->layerList.serialize_subset (c, layerList, this);
colr_prime->clipList.serialize_subset (c, clipList, this);
colr_prime->varIdxMap.serialize_copy (c->serializer, varIdxMap, this);
- //TODO: subset varStore once it's implemented in fonttools
+ colr_prime->varStore.serialize_copy (c->serializer, varStore, this);
return_trace (true);
}
+ const Paint *get_base_glyph_paint (hb_codepoint_t glyph) const
+ {
+ const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList;
+ const BaseGlyphPaintRecord* record = get_base_glyph_paintrecord (glyph);
+ if (record)
+ {
+ const Paint &paint = &baseglyph_paintrecords+record->paint;
+ return &paint;
+ }
+ else
+ return nullptr;
+ }
+
+ bool
+ get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
+ {
+ if (version != 1)
+ return false;
+
+ VarStoreInstancer instancer (this+varStore,
+ this+varIdxMap,
+ hb_array (font->coords, font->num_coords));
+
+ if (get_clip (glyph, extents, instancer))
+ {
+ font->scale_glyph_extents (extents);
+ return true;
+ }
+
+ auto *extents_funcs = hb_paint_extents_get_funcs ();
+ hb_paint_extents_context_t extents_data;
+ bool ret = paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0));
+
+ hb_extents_t e = extents_data.get_extents ();
+ if (e.is_void ())
+ {
+ extents->x_bearing = 0;
+ extents->y_bearing = 0;
+ extents->width = 0;
+ extents->height = 0;
+ }
+ else
+ {
+ extents->x_bearing = e.xmin;
+ extents->y_bearing = e.ymax;
+ extents->width = e.xmax - e.xmin;
+ extents->height = e.ymin - e.ymax;
+ }
+
+ return ret;
+ }
+
+ bool
+ has_paint_for_glyph (hb_codepoint_t glyph) const
+ {
+ if (version == 1)
+ {
+ const Paint *paint = get_base_glyph_paint (glyph);
+
+ return paint != nullptr;
+ }
+
+ return false;
+ }
+
+ bool get_clip (hb_codepoint_t glyph,
+ hb_glyph_extents_t *extents,
+ const VarStoreInstancer instancer) const
+ {
+ return (this+clipList).get_extents (glyph,
+ extents,
+ instancer);
+ }
+
+ bool
+ paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const
+ {
+ VarStoreInstancer instancer (this+varStore,
+ this+varIdxMap,
+ hb_array (font->coords, font->num_coords));
+ hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
+
+ if (version == 1)
+ {
+ const Paint *paint = get_base_glyph_paint (glyph);
+ if (paint)
+ {
+ // COLRv1 glyph
+
+ VarStoreInstancer instancer (this+varStore,
+ this+varIdxMap,
+ hb_array (font->coords, font->num_coords));
+
+ bool is_bounded = true;
+ if (clip)
+ {
+ hb_glyph_extents_t extents;
+ if (get_clip (glyph, &extents, instancer))
+ {
+ font->scale_glyph_extents (&extents);
+ c.funcs->push_clip_rectangle (c.data,
+ extents.x_bearing,
+ extents.y_bearing + extents.height,
+ extents.x_bearing + extents.width,
+ extents.y_bearing);
+ }
+ else
+ {
+ auto *extents_funcs = hb_paint_extents_get_funcs ();
+ hb_paint_extents_context_t extents_data;
+
+ paint_glyph (font, glyph,
+ extents_funcs, &extents_data,
+ palette_index, foreground,
+ false);
+
+ hb_extents_t extents = extents_data.get_extents ();
+ is_bounded = extents_data.is_bounded ();
+
+ c.funcs->push_clip_rectangle (c.data,
+ extents.xmin,
+ extents.ymin,
+ extents.xmax,
+ extents.ymax);
+ }
+ }
+
+ c.funcs->push_root_transform (c.data, font);
+
+ if (is_bounded)
+ c.recurse (*paint);
+
+ c.funcs->pop_transform (c.data);
+
+ if (clip)
+ c.funcs->pop_clip (c.data);
+
+ return true;
+ }
+ }
+
+ const BaseGlyphRecord *record = get_base_glyph_record (glyph);
+ if (record && ((hb_codepoint_t) record->glyphId == glyph))
+ {
+ // COLRv0 glyph
+ for (const auto &r : (this+layersZ).as_array (numLayers)
+ .sub_array (record->firstLayerIdx, record->numLayers))
+ {
+ hb_bool_t is_foreground;
+ hb_color_t color = c.get_color (r.colorIdx, 1., &is_foreground);
+ c.funcs->push_clip_glyph (c.data, r.glyphId, c.font);
+ c.funcs->color (c.data, is_foreground, color);
+ c.funcs->pop_clip (c.data);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
protected:
HBUINT16 version; /* Table version number (starts at 0). */
HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */
@@ -1535,7 +2154,50 @@ struct COLR_accelerator_t : COLR::accelerator_t {
COLR_accelerator_t (hb_face_t *face) : COLR::accelerator_t (face) {}
};
+void
+hb_paint_context_t::recurse (const Paint &paint)
+{
+ if (unlikely (depth_left <= 0 || edge_count <= 0)) return;
+ depth_left--;
+ edge_count--;
+ paint.dispatch (this);
+ depth_left++;
+}
+
+void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const
+{
+ const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
+ for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
+ {
+ const Paint &paint = paint_offset_lists.get_paint (i);
+ c->funcs->push_group (c->data);
+ c->recurse (paint);
+ c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
+ }
+}
+
+void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const
+{
+ const COLR *colr_table = c->get_colr_table ();
+ const Paint *paint = colr_table->get_base_glyph_paint (gid);
+
+ hb_glyph_extents_t extents = {0};
+ bool has_clip_box = colr_table->get_clip (gid, &extents, c->instancer);
+
+ if (has_clip_box)
+ c->funcs->push_clip_rectangle (c->data,
+ extents.x_bearing,
+ extents.y_bearing + extents.height,
+ extents.x_bearing + extents.width,
+ extents.y_bearing);
+
+ if (paint)
+ c->recurse (*paint);
+
+ if (has_clip_box)
+ c->funcs->pop_clip (c->data);
+}
+
} /* namespace OT */
-
-#endif /* HB_OT_COLOR_COLR_TABLE_HH */
+#endif /* OT_COLOR_COLR_COLR_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-color-colrv1-closure.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/colrv1-closure.hh
similarity index 94%
rename from src/java.desktop/share/native/libharfbuzz/hb-ot-color-colrv1-closure.hh
rename to src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/colrv1-closure.hh
index fbaf2ec26b6..705863d4ade 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-color-colrv1-closure.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/colrv1-closure.hh
@@ -24,12 +24,11 @@
*
*/
-#ifndef HB_OT_COLR_COLRV1_CLOSURE_HH
-#define HB_OT_COLR_COLRV1_CLOSURE_HH
+#ifndef OT_COLOR_COLR_COLRV1_CLOSURE_HH
+#define OT_COLOR_COLR_COLRV1_CLOSURE_HH
-#include "hb-open-type.hh"
-#include "hb-ot-layout-common.hh"
-#include "hb-ot-color-colr-table.hh"
+#include "../../../hb-open-type.hh"
+#include "COLR.hh"
/*
* COLR -- Color
@@ -105,4 +104,4 @@ HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) cons
} /* namespace OT */
-#endif /* HB_OT_COLR_COLRV1_CLOSURE_HH */
+#endif /* OT_COLOR_COLR_COLRV1_CLOSURE_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-color-cpal-table.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh
similarity index 97%
rename from src/java.desktop/share/native/libharfbuzz/hb-ot-color-cpal-table.hh
rename to src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh
index 5558d518190..e177190710c 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-color-cpal-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh
@@ -25,12 +25,12 @@
* Google Author(s): Sascha Brawer
*/
-#ifndef HB_OT_COLOR_CPAL_TABLE_HH
-#define HB_OT_COLOR_CPAL_TABLE_HH
+#ifndef OT_COLOR_CPAL_CPAL_HH
+#define OT_COLOR_CPAL_CPAL_HH
-#include "hb-open-type.hh"
-#include "hb-ot-color.h"
-#include "hb-ot-name.h"
+#include "../../../hb-open-type.hh"
+#include "../../../hb-ot-color.h"
+#include "../../../hb-ot-name.h"
/*
@@ -239,7 +239,7 @@ struct CPAL
TRACE_SUBSET (this);
if (!numPalettes) return_trace (false);
- const hb_map_t *color_index_map = c->plan->colr_palettes;
+ const hb_map_t *color_index_map = &c->plan->colr_palettes;
if (color_index_map->is_empty ()) return_trace (false);
hb_set_t retained_color_indices;
@@ -319,4 +319,4 @@ struct CPAL
} /* namespace OT */
-#endif /* HB_OT_COLOR_CPAL_TABLE_HH */
+#endif /* OT_COLOR_CPAL_CPAL_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-color-sbix-table.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh
similarity index 88%
rename from src/java.desktop/share/native/libharfbuzz/hb-ot-color-sbix-table.hh
rename to src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh
index a46b2264770..55d770e9283 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-color-sbix-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh
@@ -25,11 +25,11 @@
* Google Author(s): Calder Kitagawa
*/
-#ifndef HB_OT_COLOR_SBIX_TABLE_HH
-#define HB_OT_COLOR_SBIX_TABLE_HH
+#ifndef OT_COLOR_SBIX_SBIX_HH
+#define OT_COLOR_SBIX_SBIX_HH
-#include "hb-open-type.hh"
-#include "hb-ot-layout-common.hh"
+#include "../../../hb-open-type.hh"
+#include "../../../hb-paint.hh"
/*
* sbix -- Standard Bitmap Graphics
@@ -213,10 +213,11 @@ struct sbix
bool get_extents (hb_font_t *font,
hb_codepoint_t glyph,
- hb_glyph_extents_t *extents) const
+ hb_glyph_extents_t *extents,
+ bool scale = true) const
{
/* We only support PNG right now, and following function checks type. */
- return get_png_extents (font, glyph, extents);
+ return get_png_extents (font, glyph, extents, scale);
}
hb_blob_t *reference_png (hb_font_t *font,
@@ -231,6 +232,37 @@ struct sbix
num_glyphs, available_ppem);
}
+ bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
+ {
+ if (!has_data ())
+ return false;
+
+ int x_offset = 0, y_offset = 0;
+ unsigned int strike_ppem = 0;
+ hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem);
+ hb_glyph_extents_t extents;
+ hb_glyph_extents_t pixel_extents;
+
+ if (blob == hb_blob_get_empty ())
+ return false;
+
+ if (!hb_font_get_glyph_extents (font, glyph, &extents))
+ return false;
+
+ if (unlikely (!get_extents (font, glyph, &pixel_extents, false)))
+ return false;
+
+ bool ret = funcs->image (data,
+ blob,
+ pixel_extents.width, -pixel_extents.height,
+ HB_PAINT_IMAGE_FORMAT_PNG,
+ font->slant_xy,
+ &extents);
+
+ hb_blob_destroy (blob);
+ return ret;
+ }
+
private:
const SBIXStrike &choose_strike (hb_font_t *font) const
@@ -285,7 +317,8 @@ struct sbix
bool get_png_extents (hb_font_t *font,
hb_codepoint_t glyph,
- hb_glyph_extents_t *extents) const
+ hb_glyph_extents_t *extents,
+ bool scale = true) const
{
/* Following code is safe to call even without data.
* But faster to short-circuit. */
@@ -310,22 +343,18 @@ struct sbix
extents->height = -1 * png.IHDR.height;
/* Convert to font units. */
- if (strike_ppem)
+ if (strike_ppem && scale)
{
float scale = font->face->get_upem () / (float) strike_ppem;
- extents->x_bearing = font->em_scalef_x (extents->x_bearing * scale);
- extents->y_bearing = font->em_scalef_y (extents->y_bearing * scale);
- extents->width = font->em_scalef_x (extents->width * scale);
- extents->height = font->em_scalef_y (extents->height * scale);
- }
- else
- {
- extents->x_bearing = font->em_scale_x (extents->x_bearing);
- extents->y_bearing = font->em_scale_y (extents->y_bearing);
- extents->width = font->em_scale_x (extents->width);
- extents->height = font->em_scale_y (extents->height);
+ extents->x_bearing = roundf (extents->x_bearing * scale);
+ extents->y_bearing = roundf (extents->y_bearing * scale);
+ extents->width = roundf (extents->width * scale);
+ extents->height = roundf (extents->height * scale);
}
+ if (scale)
+ font->scale_glyph_extents (extents);
+
hb_blob_destroy (blob);
return strike_ppem;
@@ -420,4 +449,4 @@ struct sbix_accelerator_t : sbix::accelerator_t {
} /* namespace OT */
-#endif /* HB_OT_COLOR_SBIX_TABLE_HH */
+#endif /* OT_COLOR_SBIX_SBIX_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-color-svg-table.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh
similarity index 83%
rename from src/java.desktop/share/native/libharfbuzz/hb-ot-color-svg-table.hh
rename to src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh
index 8d4dee92878..c8ff6ab743e 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-color-svg-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/svg/svg.hh
@@ -22,10 +22,12 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
-#ifndef HB_OT_COLOR_SVG_TABLE_HH
-#define HB_OT_COLOR_SVG_TABLE_HH
+#ifndef OT_COLOR_SVG_SVG_HH
+#define OT_COLOR_SVG_SVG_HH
-#include "hb-open-type.hh"
+#include "../../../hb-open-type.hh"
+#include "../../../hb-blob.hh"
+#include "../../../hb-paint.hh"
/*
* SVG -- SVG (Scalable Vector Graphics)
@@ -91,8 +93,31 @@ struct SVG
bool has_data () const { return table->has_data (); }
+ bool paint_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
+ {
+ if (!has_data ())
+ return false;
+
+ hb_blob_t *blob = reference_blob_for_glyph (glyph);
+
+ if (blob == hb_blob_get_empty ())
+ return false;
+
+ funcs->image (data,
+ blob,
+ 0, 0,
+ HB_PAINT_IMAGE_FORMAT_SVG,
+ font->slant_xy,
+ nullptr);
+
+ hb_blob_destroy (blob);
+ return true;
+ }
+
private:
hb_blob_ptr_t