summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Röttsches <drott@chromium.org>2021-06-22 15:01:19 +0300
committerWerner Lemberg <wl@gnu.org>2021-07-01 06:49:03 +0200
commit286da6c528ace3443d993370c798cdc09011200b (patch)
tree6694214a3d46faec3fc13c82d628f78a47c692a7
parent0348c627b19864203c0eb3752f49850851a65200 (diff)
downloadfreetype2-286da6c528ace3443d993370c798cdc09011200b.tar.gz
[sfnt] Support PaintScale in 'COLR' v1 parsing.
* include/freetype/ftcolor.h (FT_PaintFormat): Renumber values, add `FT_COLR_PAINTFORMAT_SCALE`. (FT_PaintScale): New structure to represent 'PaintScale*' tables. (FT_COLR_Paint): Updated. * src/sfnt/ttcolr.c (FT_PaintFormat_Internal): New enumeration. (read_paint): Parse 'PaintScale' and friends.
-rw-r--r--ChangeLog12
-rw-r--r--include/freetype/ftcolor.h78
-rw-r--r--src/sfnt/ttcolr.c58
3 files changed, 138 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index eccf4a1c7..9209ea8e7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2021-06-30 Dominik Röttsches <drott@chromium.org>
+ [sfnt] Support PaintScale in 'COLR' v1 parsing.
+
+ * include/freetype/ftcolor.h (FT_PaintFormat): Renumber values, add
+ `FT_COLR_PAINTFORMAT_SCALE`.
+ (FT_PaintScale): New structure to represent 'PaintScale*' tables.
+ (FT_COLR_Paint): Updated.
+
+ * src/sfnt/ttcolr.c (FT_PaintFormat_Internal): New enumeration.
+ (read_paint): Parse 'PaintScale' and friends.
+
+2021-06-30 Dominik Röttsches <drott@chromium.org>
+
[sfnt] Handle fonts without layer list in 'COLR' v1.
'COLR' v1 fonts do not necessarily need to have a layer list; for
diff --git a/include/freetype/ftcolor.h b/include/freetype/ftcolor.h
index 63b3565da..59e6f15e3 100644
--- a/include/freetype/ftcolor.h
+++ b/include/freetype/ftcolor.h
@@ -475,12 +475,18 @@ FT_BEGIN_HEADER
* extensions to the 'COLR' table, see
* 'https://github.com/googlefonts/colr-gradients-spec'.
*
- * Only non-variable format identifiers are listed in this enumeration;
- * as soon as support for variable 'COLR' v1 fonts is implemented,
- * interpolation is performed dependent on axis coordinates, which are
- * configured on the @FT_Face through @FT_Set_Var_Design_Coordinates.
- * This implies that always static (interpolated) values are returned
- * for both variable and non-variable formats.
+ * The enumeration values losely correspond with the format numbers of
+ * the specification: FreeType always returns a fully specified 'Paint'
+ * structure for the 'Transform', 'Translate', 'Scale', 'Rotate', and
+ * 'Skew' table types even though the specification has different formats
+ * depending on whether or not a center is specified, whether the scale
+ * is uniform in x and y~direction or not, etc. Also, only non-variable
+ * format identifiers are listed in this enumeration; as soon as support
+ * for variable 'COLR' v1 fonts is implemented, interpolation is
+ * performed dependent on axis coordinates, which are configured on the
+ * @FT_Face through @FT_Set_Var_Design_Coordinates. This implies that
+ * always static, readily interpolated values are returned in the 'Paint'
+ * structures.
*
* @since:
* 2.11 -- **currently experimental only!** There might be changes
@@ -498,10 +504,11 @@ FT_BEGIN_HEADER
FT_COLR_PAINTFORMAT_COLR_GLYPH = 11,
FT_COLR_PAINTFORMAT_TRANSFORM = 12,
FT_COLR_PAINTFORMAT_TRANSLATE = 14,
- FT_COLR_PAINTFORMAT_ROTATE = 16,
- FT_COLR_PAINTFORMAT_SKEW = 18,
- FT_COLR_PAINTFORMAT_COMPOSITE = 20,
- FT_COLR_PAINT_FORMAT_MAX = 21,
+ FT_COLR_PAINTFORMAT_SCALE = 16,
+ FT_COLR_PAINTFORMAT_ROTATE = 24,
+ FT_COLR_PAINTFORMAT_SKEW = 28,
+ FT_COLR_PAINTFORMAT_COMPOSITE = 32,
+ FT_COLR_PAINT_FORMAT_MAX = 33,
FT_COLR_PAINTFORMAT_UNSUPPORTED = 255
} FT_PaintFormat;
@@ -1104,6 +1111,56 @@ FT_BEGIN_HEADER
/**************************************************************************
*
* @struct:
+ * FT_PaintScale
+ *
+ * @description:
+ * A structure representing all of the 'COLR' v1 'PaintScale*' paint
+ * tables. Used for scaling downstream paints by a given x and y~scale,
+ * with a given center. This structure is used for all 'PaintScale*'
+ * types that are part of specification; fields of this structure are
+ * filled accordingly. If there is a center, the center values are set,
+ * otherwise they are set to the zero coordinate. If the source font
+ * file has 'PaintScaleUniform*' set, the scale values are set
+ * accordingly to the same value.
+ *
+ * @fields:
+ * paint ::
+ * An @FT_OpaquePaint object referencing the paint that is to be
+ * scaled.
+ *
+ * scale_x ::
+ * Scale factor in x~direction.
+ *
+ * scale_y ::
+ * Scale factor in y~direction.
+ *
+ * center_x ::
+ * x~coordinate of center point to scale from.
+ *
+ * center_y ::
+ * y~coordinate of center point to scale from.
+ *
+ * @since:
+ * 2.11 -- **currently experimental only!** There might be changes
+ * without retaining backward-compatibility of both the API and ABI.
+ *
+ */
+ typedef struct FT_PaintScale_
+ {
+ FT_OpaquePaint paint;
+
+ FT_Fixed scale_x;
+ FT_Fixed scale_y;
+
+ FT_Fixed center_x;
+ FT_Fixed center_y;
+
+ } FT_PaintScale;
+
+
+ /**************************************************************************
+ *
+ * @struct:
* FT_PaintRotate
*
* @description:
@@ -1277,6 +1334,7 @@ FT_BEGIN_HEADER
FT_PaintSweepGradient sweep_gradient;
FT_PaintTransform transform;
FT_PaintTranslate translate;
+ FT_PaintScale scale;
FT_PaintRotate rotate;
FT_PaintSkew skew;
FT_PaintComposite composite;
diff --git a/src/sfnt/ttcolr.c b/src/sfnt/ttcolr.c
index 34accddb3..bd478ab9b 100644
--- a/src/sfnt/ttcolr.c
+++ b/src/sfnt/ttcolr.c
@@ -49,6 +49,17 @@
#define COLR_HEADER_SIZE 14U
+ typedef enum FT_PaintFormat_Internal_
+ {
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER = 18,
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM = 20,
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER = 22,
+ FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER = 26,
+ FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER = 30
+
+ } FT_PaintFormat_Internal;
+
+
typedef struct BaseGlyphRecord_
{
FT_UShort gid;
@@ -561,6 +572,53 @@
return 1;
}
+ else if ( apaint->format ==
+ FT_COLR_PAINTFORMAT_SCALE ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER )
+ {
+ apaint->u.scale.paint.p = child_table_p;
+ apaint->u.scale.paint.insert_root_transform = 0;
+
+ /* All scale paints get at least one scale value. */
+ apaint->u.scale.scale_x = FT_NEXT_LONG( p );
+
+ /* Non-uniform ones read an extra y value. */
+ if ( apaint->format ==
+ FT_COLR_PAINTFORMAT_SCALE ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER )
+ apaint->u.scale.scale_y = FT_NEXT_LONG( p );
+ else
+ apaint->u.scale.scale_y = apaint->u.scale.scale_x;
+
+ /* Scale paints that have a center read center coordinates, */
+ /* otherwise the center is (0,0). */
+ if ( (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER ||
+ (FT_PaintFormat_Internal)apaint->format ==
+ FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER )
+ {
+ apaint->u.scale.center_x = FT_NEXT_LONG ( p );
+ apaint->u.scale.center_y = FT_NEXT_LONG ( p );
+ }
+ else
+ {
+ apaint->u.scale.center_x = 0;
+ apaint->u.scale.center_y = 0;
+ }
+
+ /* FT 'COLR' v1 API output format always returns fully defined */
+ /* structs; we thus set the format to the public API value. */
+ apaint->format = FT_COLR_PAINTFORMAT_SCALE;
+
+ return 1;
+ }
+
else if ( apaint->format == FT_COLR_PAINTFORMAT_ROTATE )
{
apaint->u.rotate.paint.p = child_table_p;