[canvaskit] Allow users to load their own fonts
Instead of using the test font(s), now ship with a small
(100k) Monospace font. This can be disabled by:
compile.sh no_font ...
This saves about 350k (164k gzipped) in binary size.
Bug: skia:
Change-Id: I195e3b35bea86d0f096066c1c6a44a4b602571f3
Reviewed-on: https://skia-review.googlesource.com/c/176580
Reviewed-by: Ben Wagner <bungeman@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 201b86c..42cc2c8 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -69,8 +69,8 @@
skia_use_sfntly = skia_use_icu
skia_enable_atlas_text = is_skia_dev_build && skia_enable_gpu
skia_enable_fontmgr_empty = false
- skia_enable_fontmgr_custom = (is_linux || target_cpu == "wasm") &&
- skia_use_freetype && !skia_use_fontconfig
+ skia_enable_fontmgr_custom =
+ is_linux && skia_use_freetype && !skia_use_fontconfig
skia_enable_fontmgr_custom_empty = is_fuchsia && skia_use_freetype
skia_enable_fontmgr_android = skia_use_expat && skia_use_freetype
skia_enable_fontmgr_fuchsia = is_fuchsia
@@ -414,6 +414,20 @@
]
}
+optional("fontmgr_wasm") {
+ enabled = target_cpu == "wasm"
+
+ deps = [
+ ":typeface_freetype",
+ ]
+ sources = [
+ "src/ports/SkFontMgr_custom.cpp",
+ "src/ports/SkFontMgr_custom.h",
+ "src/ports/SkFontMgr_custom_embedded.cpp",
+ "src/ports/SkFontMgr_custom_embedded_factory.cpp",
+ ]
+}
+
optional("fontmgr_fuchsia") {
enabled = skia_enable_fontmgr_fuchsia
@@ -872,6 +886,7 @@
":fontmgr_empty",
":fontmgr_fontconfig",
":fontmgr_fuchsia",
+ ":fontmgr_wasm",
":heif",
":hsw",
":jpeg",
diff --git a/experimental/canvaskit/.gitignore b/experimental/canvaskit/.gitignore
index d8b83df..2c681f5 100644
--- a/experimental/canvaskit/.gitignore
+++ b/experimental/canvaskit/.gitignore
@@ -1 +1,2 @@
package-lock.json
+fonts/*.cpp
\ No newline at end of file
diff --git a/experimental/canvaskit/CHANGELOG.md b/experimental/canvaskit/CHANGELOG.md
index 6990c59..7922db0 100644
--- a/experimental/canvaskit/CHANGELOG.md
+++ b/experimental/canvaskit/CHANGELOG.md
@@ -9,6 +9,7 @@
### Added
- Add Canvas2D JS layer. This mirrors the HTML Canvas API. This may be omitted at compile time
it by adding `no_canvas` to the `compile.sh` invocation.
+- `CanvasKit.FontMgr.DefaultRef()` and `fontmgr.MakeTypefaceFromData` to load fonts.
### Fixed
- `SkPath.addRect` now correctly draws counter-clockwise vs clockwise.
@@ -19,6 +20,11 @@
and `localMatrix` have been exposed.
- `SkPath.arcTo` now takes `startAngle`, `sweepAngle`, `forceMoveTo` as additional parameters.
- `SkPath.stroke` has a new option `precision` It defaults to 1.0.
+- CanvasKit comes with one font (NotoMono) instead of the Skia TestTypeface. Clients are encouraged
+ to use the new `fontmgr.MakeTypefaceFromData` for more font variety.
+
+### Removed
+- `CanvasKit.initFonts()` - no longer needed.
diff --git a/experimental/canvaskit/canvaskit/Roboto-Regular.ttf b/experimental/canvaskit/canvaskit/Roboto-Regular.ttf
new file mode 100644
index 0000000..0e58508
--- /dev/null
+++ b/experimental/canvaskit/canvaskit/Roboto-Regular.ttf
Binary files differ
diff --git a/experimental/canvaskit/canvaskit/Roboto-Regular.woff b/experimental/canvaskit/canvaskit/Roboto-Regular.woff
new file mode 100644
index 0000000..f823258
--- /dev/null
+++ b/experimental/canvaskit/canvaskit/Roboto-Regular.woff
Binary files differ
diff --git a/experimental/canvaskit/canvaskit/example.html b/experimental/canvaskit/canvaskit/example.html
index 8ec6c14..9650130 100644
--- a/experimental/canvaskit/canvaskit/example.html
+++ b/experimental/canvaskit/canvaskit/example.html
@@ -60,6 +60,8 @@
var onboardingJSON = null;
var fullBounds = {fLeft: 0, fTop: 0, fRight: 500, fBottom: 500};
+ var robotoData = null;
+
var bonesImageData = null;
CanvasKitInit({
locateFile: (file) => '/node_modules/canvaskit/bin/'+file,
@@ -71,9 +73,8 @@
// Thus, the setTimeout to run on the next microtask avoids this second loading
// and the log spew.
setTimeout(() => {
- CK.initFonts();
CanvasKit = CK;
- DrawingExample(CanvasKit);
+ DrawingExample(CanvasKit, robotoData);
PathExample(CanvasKit);
InkExample(CanvasKit);
// Set bounds to fix the 4:3 resolution of the legos
@@ -136,7 +137,17 @@
});
});
- function DrawingExample(CanvasKit) {
+ fetch('./Roboto-Regular.woff').then((resp) => {
+ resp.arrayBuffer().then((buffer) => {
+ robotoData = buffer;
+ DrawingExample(CanvasKit, robotoData)
+ });
+ });
+
+ function DrawingExample(CanvasKit, robotoData) {
+ if (!robotoData || !CanvasKit) {
+ return;
+ }
const surface = CanvasKit.MakeCanvasSurface('patheffect');
if (!surface) {
console.error('Could not make surface');
@@ -148,10 +159,14 @@
const paint = new CanvasKit.SkPaint();
+ const fontMgr = CanvasKit.SkFontMgr.RefDefault();
+ let roboto = fontMgr.MakeTypefaceFromData(robotoData);
+
const textPaint = new CanvasKit.SkPaint();
textPaint.setColor(CanvasKit.RED);
textPaint.setTextSize(30);
textPaint.setAntiAlias(true);
+ textPaint.setTypeface(roboto);
let i = 0;
@@ -554,7 +569,7 @@
ctx.lineTo(220, 120);
ctx.scale(3.0, 3.0);
- ctx.font = '6pt Arial';
+ ctx.font = '6pt Noto Mono';
ctx.fillText('This text should be huge', 10, 80);
ctx.resetTransform();
@@ -623,7 +638,7 @@
ctx.stroke();
ctx.fillStyle = 'green';
- ctx.font = '16pt Arial';
+ ctx.font = '16pt Noto Mono';
ctx.fillText('This should be shadowed', 20, 80);
ctx.beginPath();
@@ -690,7 +705,7 @@
ctx.lineTo(300, 400);
ctx.stroke();
- ctx.font = '36pt Arial';
+ ctx.font = '36pt Noto Mono';
ctx.strokeText('Dashed', 20, 350);
ctx.fillText('Not Dashed', 20, 400);
@@ -849,7 +864,7 @@
for (let canvas of [skcanvas, realCanvas]) {
let ctx = canvas.getContext('2d');
- ctx.font = '11px Arial';
+ ctx.font = '11px Noto Mono';
// Draw some visual aids
ctx.fillText('path-nonzero', 30, 15);
ctx.fillText('path-evenodd', 150, 15);
@@ -1025,8 +1040,8 @@
pos, CanvasKit.TileMode.Mirror, transform);
paint.setShader(shader);
- paint.setTextSize(100);
- canvas.drawText("Radial", 10, 200, paint);
+ paint.setTextSize(75);
+ canvas.drawText('Radial', 10, 200, paint);
surface.flush();
}
</script>
diff --git a/experimental/canvaskit/canvaskit/node.example.js b/experimental/canvaskit/canvaskit/node.example.js
index b9afb7f..f507e57 100644
--- a/experimental/canvaskit/canvaskit/node.example.js
+++ b/experimental/canvaskit/canvaskit/node.example.js
@@ -4,11 +4,9 @@
const fs = require('fs');
const path = require('path');
-
CanvasKitInit({
locateFile: (file) => __dirname + '/bin/'+file,
-}).then((CK) => {
- CanvasKit = CK;
+}).then((CanvasKit) => {
let canvas = CanvasKit.MakeCanvas(300, 300);
let img = fs.readFileSync(path.join(__dirname, 'test.png'));
@@ -41,8 +39,7 @@
console.log('<img src="' + canvas.toDataURL() + '" />');
});
-function fancyAPI() {
- CanvasKit.initFonts();
+function fancyAPI(CanvasKit) {
console.log('loaded');
let surface = CanvasKit.MakeSurface(300, 300);
@@ -50,23 +47,28 @@
const paint = new CanvasKit.SkPaint();
+ const fontMgr = CanvasKit.SkFontMgr.RefDefault();
+ let robotoData = fs.readFileSync(path.join(__dirname, './Roboto-Regular.woff'));
+ const roboto = fontMgr.MakeTypefaceFromData(robotoData);
+
const textPaint = new CanvasKit.SkPaint();
textPaint.setColor(CanvasKit.Color(40, 0, 0));
textPaint.setTextSize(30);
textPaint.setAntiAlias(true);
+ textPaint.setTypeface(roboto);
- const path = starPath(CanvasKit);
+ const skpath = starPath(CanvasKit);
const dpe = CanvasKit.MakeSkDashPathEffect([15, 5, 5, 10], 1);
paint.setPathEffect(dpe);
- paint.setStyle(CanvasKit.PaintStyle.STROKE);
+ paint.setStyle(CanvasKit.PaintStyle.Stroke);
paint.setStrokeWidth(5.0);
paint.setAntiAlias(true);
paint.setColor(CanvasKit.Color(66, 129, 164, 1.0));
canvas.clear(CanvasKit.Color(255, 255, 255, 1.0));
- canvas.drawPath(path, paint);
+ canvas.drawPath(skpath, paint);
canvas.drawText('Try Clicking!', 10, 280, textPaint);
surface.flush();
@@ -87,10 +89,10 @@
console.log(`<img src="data:image/png;base64,${b64encoded}" />`);
dpe.delete();
- path.delete();
- canvas.delete();
+ skpath.delete();
textPaint.delete();
paint.delete();
+ roboto.delete();
surface.dispose();
}
diff --git a/experimental/canvaskit/canvaskit_bindings.cpp b/experimental/canvaskit/canvaskit_bindings.cpp
index 330e604..0fe3d33 100644
--- a/experimental/canvaskit/canvaskit_bindings.cpp
+++ b/experimental/canvaskit/canvaskit_bindings.cpp
@@ -42,7 +42,9 @@
#include "SkStrokeRec.h"
#include "SkSurface.h"
#include "SkSurfaceProps.h"
-#include "SkTestFontMgr.h"
+#include "SkTypeface.h"
+#include "SkTypes.h"
+
#include "SkTrimPathEffect.h"
#include "SkVertices.h"
@@ -79,9 +81,6 @@
using BoneWeights = SkVertices::BoneWeights;
using Bone = SkVertices::Bone;
-void EMSCRIPTEN_KEEPALIVE initFonts() {
- gSkFontMgr_DefaultFactory = &sk_tool_utils::MakePortableFontMgr;
-}
#if SK_SUPPORT_GPU
// Wraps the WebGL context in an SkSurface and returns it.
@@ -435,6 +434,10 @@
}
template<>
+ void raw_destructor<SkTypeface>(SkTypeface *ptr) {
+ }
+
+ template<>
void raw_destructor<SkVertices>(SkVertices *ptr) {
}
}
@@ -452,7 +455,6 @@
// types Pi, Pf"). But, we can just pretend they are numbers and cast them to be pointers and
// the compiler is happy.
EMSCRIPTEN_BINDINGS(Skia) {
- function("initFonts", &initFonts);
#if SK_SUPPORT_GPU
function("_getWebGLSurface", &getWebGLSurface, allow_raw_pointers());
function("currentContext", &emscripten_webgl_get_current_context);
@@ -679,6 +681,31 @@
.smart_ptr<sk_sp<SkData>>("sk_sp<SkData>>")
.function("size", &SkData::size);
+ class_<SkFontMgr>("SkFontMgr")
+ .smart_ptr<sk_sp<SkFontMgr>>("sk_sp<SkFontMgr>")
+ .class_function("RefDefault", &SkFontMgr::RefDefault)
+#ifdef SK_DEBUG
+ .function("dumpFamilies", optional_override([](SkFontMgr& self) {
+ int numFam = self.countFamilies();
+ SkDebugf("There are %d font families\n");
+ for (int i = 0 ; i< numFam; i++) {
+ SkString s;
+ self.getFamilyName(i, &s);
+ SkDebugf("\t%s", s.c_str());
+ }
+ }))
+#endif
+ .function("countFamilies", &SkFontMgr::countFamilies)
+ .function("_makeTypefaceFromData", optional_override([](SkFontMgr& self,
+ uintptr_t /* uint8_t* */ fPtr,
+ int flen)->sk_sp<SkTypeface> {
+ // See comment above for uintptr_t explanation
+ uint8_t* font = reinterpret_cast<uint8_t*>(fPtr);
+ sk_sp<SkData> fontData = SkData::MakeFromMalloc(font, flen);
+
+ return self.makeFromData(fontData);
+ }), allow_raw_pointers());
+
class_<SkImage>("SkImage")
.smart_ptr<sk_sp<SkImage>>("sk_sp<SkImage>")
.function("height", &SkImage::height)
@@ -729,6 +756,7 @@
.function("setStrokeMiter", &SkPaint::setStrokeMiter)
.function("setStrokeWidth", &SkPaint::setStrokeWidth)
.function("setStyle", &SkPaint::setStyle)
+ .function("setTypeface", &SkPaint::setTypeface)
.function("setTextSize", &SkPaint::setTextSize);
class_<SkPathEffect>("SkPathEffect")
@@ -792,6 +820,9 @@
.function("makeImageSnapshot", select_overload<sk_sp<SkImage>(const SkIRect& bounds)>(&SkSurface::makeImageSnapshot))
.function("getCanvas", &SkSurface::getCanvas, allow_raw_pointers());
+ class_<SkTypeface>("SkTypeface")
+ .smart_ptr<sk_sp<SkTypeface>>("sk_sp<SkTypeface>");
+
class_<SkVertices>("SkVertices")
.smart_ptr<sk_sp<SkVertices>>("sk_sp<SkVertices>")
.function("_applyBones", optional_override([](SkVertices& self, uintptr_t /* Bone* */ bptr, int boneCount)->sk_sp<SkVertices> {
diff --git a/experimental/canvaskit/compile.sh b/experimental/canvaskit/compile.sh
index a7eea23..b915599 100755
--- a/experimental/canvaskit/compile.sh
+++ b/experimental/canvaskit/compile.sh
@@ -96,6 +96,19 @@
HTML_CANVAS_API=""
fi
+BUILTIN_FONT="$BASE_DIR/fonts/NotoMono-Regular.ttf.cpp"
+if [[ $@ == *no_font* ]]; then
+ echo "Omitting the built-in font(s)"
+ BUILTIN_FONT=""
+else
+ # Generate the font's binary file (which is covered by .gitignore)
+ python tools/embed_resources.py \
+ --name SK_EMBEDDED_FONTS \
+ --input $BASE_DIR/fonts/NotoMono-Regular.ttf \
+ --output $BASE_DIR/fonts/NotoMono-Regular.ttf.cpp \
+ --align 4
+fi
+
# Turn off exiting while we check for ninja (which may not be on PATH)
set +e
NINJA=`which ninja`
@@ -191,9 +204,8 @@
--pre-js $BASE_DIR/helper.js \
--pre-js $BASE_DIR/interface.js \
$HTML_CANVAS_API \
+ $BUILTIN_FONT \
$BASE_DIR/canvaskit_bindings.cpp \
- tools/fonts/SkTestFontMgr.cpp \
- tools/fonts/SkTestTypeface.cpp \
$WASM_SKOTTIE \
$WASM_MANAGED_SKOTTIE \
$BUILD_DIR/libskia.a \
diff --git a/experimental/canvaskit/externs.js b/experimental/canvaskit/externs.js
index eaff311..3280cb3 100644
--- a/experimental/canvaskit/externs.js
+++ b/experimental/canvaskit/externs.js
@@ -50,7 +50,6 @@
currentContext: function() {},
getColorComponents: function() {},
getSkDataBytes: function() {},
- initFonts: function() {},
multiplyByAlpha: function() {},
setCurrentContext: function() {},
@@ -103,6 +102,15 @@
delete: function() {},
},
+ SkFontMgr: {
+ // public API (from C++ bindings)
+ RefDefault: function() {},
+ countFamilies: function() {},
+
+ // private API
+ _makeTypefaceFromData: function() {},
+ },
+
SkImage: {
// public API (from C++ bindings)
height: function() {},
@@ -148,6 +156,7 @@
setStrokeWidth: function() {},
setStyle: function() {},
setTextSize: function() {},
+ setTypeface: function() {},
//private API
delete: function() {},
@@ -420,6 +429,8 @@
CanvasKit.SkCanvas.prototype.readPixels = function() {};
CanvasKit.SkCanvas.prototype.writePixels = function() {};
+CanvasKit.SkFontMgr.prototype.MakeTypefaceFromData = function() {};
+
// Define StrokeOpts object
var StrokeOpts = {};
StrokeOpts.prototype.width;
diff --git a/experimental/canvaskit/fonts/NotoMono-Regular.ttf b/experimental/canvaskit/fonts/NotoMono-Regular.ttf
new file mode 100644
index 0000000..3560a3a
--- /dev/null
+++ b/experimental/canvaskit/fonts/NotoMono-Regular.ttf
Binary files differ
diff --git a/experimental/canvaskit/fonts/README.md b/experimental/canvaskit/fonts/README.md
new file mode 100644
index 0000000..6e2addb
--- /dev/null
+++ b/experimental/canvaskit/fonts/README.md
@@ -0,0 +1,3 @@
+To generate the files in here:
+
+ python tools/embed_resources.py --name SK_EMBEDDED_FONTS --input ~/Downloads/NotoMono-Regular.ttf --output experimental/canvaskit/NotoMono-Regular.ttf.cpp --align 4
\ No newline at end of file
diff --git a/experimental/canvaskit/htmlcanvas/font.js b/experimental/canvaskit/htmlcanvas/font.js
index 04edbda..549208d 100644
--- a/experimental/canvaskit/htmlcanvas/font.js
+++ b/experimental/canvaskit/htmlcanvas/font.js
@@ -2,9 +2,9 @@
var units = 'px|pt|pc|in|cm|mm|%|em|ex|ch|rem|q';
var fontSizeRegex = new RegExp('([\\d\\.]+)(' + units + ')');
-var defaultHeight = 12;
+var defaultHeight = 16;
// Based off of node-canvas's parseFont
-// returns font size in *points* (original impl was in px);
+// returns font size in px, which represents the em width.
function parseFontSize(fontStr) {
// This is naive and doesn't account for line-height yet
// (but neither does node-canvas's?)
@@ -17,23 +17,22 @@
var unit = fontSize[2];
switch (unit) {
case 'pt':
- return size;
- case 'px':
- return size * 3/4;
- case 'pc':
- return size * 12;
- case 'in':
- return size * 72;
- case 'cm':
- return size * 72.0 / 2.54;
- case 'mm':
- return size * (72.0 / 25.4);
- case '%':
- return size * (defaultHeight / 100);
case 'em':
case 'rem':
- return size * defaultHeight;
- case 'q':
- return size * (96 / 25.4 / 3);
+ return size * 4/3;
+ case 'px':
+ return size;
+ case 'pc':
+ return size * 16;
+ case 'in':
+ return size * 96;
+ case 'cm':
+ return size * 96.0 / 2.54;
+ case 'mm':
+ return size * (96.0 / 25.4);
+ case 'q': // quarter millimeters
+ return size * (96.0 / 25.4 / 4);
+ case '%':
+ return size * (defaultHeight / 75);
}
}
\ No newline at end of file
diff --git a/experimental/canvaskit/htmlcanvas/htmlcanvas.js b/experimental/canvaskit/htmlcanvas/htmlcanvas.js
index cfcdf23..b756b26 100644
--- a/experimental/canvaskit/htmlcanvas/htmlcanvas.js
+++ b/experimental/canvaskit/htmlcanvas/htmlcanvas.js
@@ -1,6 +1,4 @@
CanvasKit.MakeCanvas = function(width, height) {
- // TODO(kjlubick) do fonts the "correct" way
- CanvasKit.initFonts();
var surf = CanvasKit.MakeSurface(width, height);
if (surf) {
return new HTMLCanvas(surf);
diff --git a/experimental/canvaskit/interface.js b/experimental/canvaskit/interface.js
index a40c568..704721a 100644
--- a/experimental/canvaskit/interface.js
+++ b/experimental/canvaskit/interface.js
@@ -402,6 +402,29 @@
return ok;
}
+ // fontData should be an arrayBuffer
+ CanvasKit.SkFontMgr.prototype.MakeTypefaceFromData = function(fontData) {
+ var data = new Uint8Array(fontData);
+
+ var fptr = CanvasKit._malloc(data.byteLength);
+ CanvasKit.HEAPU8.set(data, fptr);
+ var font = this._makeTypefaceFromData(fptr, data.byteLength);
+ if (!font) {
+ SkDebug('Could not decode font data');
+ // We do not need to free the data since the C++ will do that for us
+ // on a failed decode (at least, it appears to).
+ return null;
+ }
+ // We cannot free this data until after the font stops being used
+ // (otherwise nothing draws)
+ var realDelete = font.delete.bind(font);
+ font.delete = function() {
+ CanvasKit._free(fptr);
+ realDelete();
+ }
+ return font;
+ }
+
// Run through the JS files that are added at compile time.
if (CanvasKit._extraInitializations) {
CanvasKit._extraInitializations.forEach(function(init) {
diff --git a/experimental/canvaskit/perf/animation.bench.js b/experimental/canvaskit/perf/animation.bench.js
index 7c3a530..3c64451 100644
--- a/experimental/canvaskit/perf/animation.bench.js
+++ b/experimental/canvaskit/perf/animation.bench.js
@@ -13,7 +13,6 @@
locateFile: (file) => '/canvaskit/'+file,
}).then((_CanvasKit) => {
CanvasKit = _CanvasKit;
- CanvasKit.initFonts();
resolve();
});
}
diff --git a/experimental/canvaskit/tests/canvas2d.spec.js b/experimental/canvaskit/tests/canvas2d.spec.js
index a823087..82c8371 100644
--- a/experimental/canvaskit/tests/canvas2d.spec.js
+++ b/experimental/canvaskit/tests/canvas2d.spec.js
@@ -13,7 +13,6 @@
locateFile: (file) => '/canvaskit/'+file,
}).then((_CanvasKit) => {
CanvasKit = _CanvasKit;
- CanvasKit.initFonts();
resolve();
});
}
@@ -243,7 +242,7 @@
ctx.lineTo(220, 120);
ctx.scale(3.0, 3.0);
- ctx.font = '6pt Arial';
+ ctx.font = '6pt Noto Mono';
ctx.fillText('This text should be huge', 10, 80);
ctx.resetTransform();
@@ -305,7 +304,7 @@
ctx.stroke();
ctx.fillStyle = 'green';
- ctx.font = '16pt Arial';
+ ctx.font = '16pt Noto Mono';
ctx.fillText('This should be shadowed', 20, 80);
ctx.beginPath();
@@ -368,7 +367,7 @@
ctx.lineTo(300, 400);
ctx.stroke();
- ctx.font = '36pt Arial';
+ ctx.font = '36pt Noto Mono';
ctx.strokeText('Dashed', 20, 350);
ctx.fillText('Not Dashed', 20, 400);
});
@@ -580,7 +579,7 @@
];
multipleCanvasTest('points_in_path_stroke', done, (canvas) => {
let ctx = canvas.getContext('2d');
- ctx.font = '20px Arial';
+ ctx.font = '20px Noto Mono';
// Draw some visual aids
ctx.fillText('path-nonzero', 60, 30);
ctx.fillText('path-evenodd', 300, 30);
diff --git a/experimental/canvaskit/tests/path.spec.js b/experimental/canvaskit/tests/path.spec.js
index 48a1ad8..c3a7f65 100644
--- a/experimental/canvaskit/tests/path.spec.js
+++ b/experimental/canvaskit/tests/path.spec.js
@@ -13,7 +13,6 @@
locateFile: (file) => '/canvaskit/'+file,
}).then((_CanvasKit) => {
CanvasKit = _CanvasKit;
- CanvasKit.initFonts();
resolve();
});
}
diff --git a/tools/embed_resources.py b/tools/embed_resources.py
index 56d5982..98b6c96 100644
--- a/tools/embed_resources.py
+++ b/tools/embed_resources.py
@@ -44,7 +44,7 @@
# Write the resources.
index = 0
for f in args.input:
- out('static const uint8_t resource{0:d}[] SK_STRUCT_ALIGN({1:d}) = {{\n'
+ out('alignas({1:d}) static const uint8_t resource{0:d}[] = {{\n'
.format(index, args.align))
bytes_written = 0
bytes_on_line = 0