Revert "Wide color gamut support and working example."
breaks CPU-backed canvaskit build
This reverts commit 3d52abc846
.
Reason for revert: <INSERT REASONING HERE>
Original change's description:
> Wide color gamut support and working example.
>
> Color space arguments accepted at surface creation, paint, gradient, and other call sites.
> Works correctly only when chrome happens to be rendering itself in the same color space
> the canvaskit user has chosen, there's not yet end to end color management of
> canvases supported in browsers.
>
> readPixels not yet working due to possible chrome bug.
>
> Change-Id: I3dea5b16c60a3871cd2a54f86716f4a438a90135
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/289733
> Commit-Queue: Nathaniel Nifong <nifong@google.com>
> Reviewed-by: Kevin Lubick <kjlubick@google.com>
TBR=kjlubick@google.com,brianosman@google.com,nifong@google.com
Change-Id: I2e03155c2512eec6730ecccda19df78174146008
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/291339
Reviewed-by: Nathaniel Nifong <nifong@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Commit-Queue: Nathaniel Nifong <nifong@google.com>
This commit is contained in:
parent
3d52abc846
commit
67e21a1925
@ -6,31 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- Support for wide-gamut color spaces DisplayP3 and AdobeRGB. However, correct representation on a
|
||||
WCG monitor requires that the browser is rendering everything to the DisplayP3 or AdobeRGB
|
||||
profile, since there is not yet any way to indicate to the browser that a canvas element has a
|
||||
non-sRGB color space. See color support example in extra.html. Only supported for WebGL2 backed
|
||||
surfaces.
|
||||
- Added `SkSurface.reportBackendType` which returns either 'CPU' or 'GPU'.
|
||||
- Added `SkSurface.imageInfo` which returns an ImageInfo object describing the size and color
|
||||
properties of the surface. colorSpace is added to ImageInfo everywhere it is used.
|
||||
|
||||
### Changed
|
||||
- We now compile/ship with Emscripten v1.39.16.
|
||||
- `CanvasKit.MakeCanvasSurface` accepts a new enum specifying one of the three color space and
|
||||
pixel format combinations supported by CanvasKit.
|
||||
- all `_Make*Shader` functions now accept a color space argument at the end. leaving it off or
|
||||
passing null makes it behave as it did before, defaulting to sRGB
|
||||
- `SkPaint.setColor` accepts a new color space argument, defaulting to sRGB.
|
||||
- We now compile/ship with Emscripten v1.39.16.
|
||||
|
||||
### Breaking
|
||||
- `CanvasKitInit(...)` now directly returns a Promise. As such, `CanvasKitInit(...).ready()`
|
||||
has been removed.
|
||||
- `CanvasKit.MakeCanvasSurface` no longer accepts width/height arguments to override those on
|
||||
the canvas element. Use the canvas element's width/height attributes to dictate the size of
|
||||
the drawing area, and use CSS width/height to set the size it will appear on the page
|
||||
(it is rescaled after drawing when css sizing applies).
|
||||
|
||||
## [0.15.0] - 2020-05-14
|
||||
|
||||
|
@ -1125,7 +1125,6 @@
|
||||
height: 50,
|
||||
alphaType: CanvasKit.AlphaType.Premul,
|
||||
colorType: CanvasKit.ColorType.RGBA_8888,
|
||||
colorSpace: CanvasKit.SkColorSpace.SRGB,
|
||||
});
|
||||
|
||||
if (!subSurface) {
|
||||
|
@ -35,9 +35,8 @@
|
||||
<h2> 3D perspective transformations </h2>
|
||||
<canvas id=camera3d width=500 height=500></canvas>
|
||||
|
||||
<h2> Support for extended color spaces </h2>
|
||||
<a href="chrome://flags/#force-color-profile">Force P3 profile</a>
|
||||
<canvas id=colorsupport width=300 height=300></canvas>
|
||||
<h2> Use of offscreen surfaces </h2>
|
||||
<canvas id=surfaces width=500 height=500></canvas>
|
||||
|
||||
<script type="text/javascript" src="/node_modules/canvaskit/bin/canvaskit.js"></script>
|
||||
|
||||
@ -80,7 +79,7 @@
|
||||
|
||||
SkpExample(CanvasKit, skpData);
|
||||
|
||||
ColorSupport(CanvasKit);
|
||||
SurfaceAPI1(CanvasKit);
|
||||
});
|
||||
|
||||
fetch(cdn + 'lego_loader.json').then((resp) => {
|
||||
@ -241,6 +240,76 @@ const curves = {
|
||||
"Bindings": []
|
||||
};
|
||||
|
||||
function SurfaceAPI1(CanvasKit) {
|
||||
const surface = CanvasKit.MakeCanvasSurface('surfaces');
|
||||
if (!surface) {
|
||||
console.error('Could not make surface');
|
||||
return;
|
||||
}
|
||||
console.log('SurfaceAPI1 top surface type = '+surface.reportBackendType() );
|
||||
const context = CanvasKit.currentContext();
|
||||
const canvas = surface.getCanvas();
|
||||
|
||||
//create a subsurface as a temporary workspace.
|
||||
const subSurface = surface.makeSurface({
|
||||
width: 50,
|
||||
height: 50,
|
||||
alphaType: CanvasKit.AlphaType.Premul,
|
||||
colorType: CanvasKit.ColorType.RGBA_8888,
|
||||
});
|
||||
|
||||
if (!subSurface) {
|
||||
console.error('Could not make subsurface');
|
||||
return;
|
||||
}
|
||||
console.log('SurfaceAPI1 subSurface type = '+subSurface.reportBackendType() );
|
||||
|
||||
// draw a small "scene"
|
||||
const paint = new CanvasKit.SkPaint();
|
||||
paint.setColor(CanvasKit.Color(139, 228, 135, 0.95)); // greenish
|
||||
paint.setStyle(CanvasKit.PaintStyle.Fill);
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
const subCanvas = subSurface.getCanvas();
|
||||
subCanvas.clear(CanvasKit.BLACK);
|
||||
subCanvas.drawRect(CanvasKit.LTRBRect(5, 15, 45, 40), paint);
|
||||
|
||||
paint.setColor(CanvasKit.Color(214, 93, 244)); // purplish
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const x = Math.random() * 50;
|
||||
const y = Math.random() * 50;
|
||||
|
||||
subCanvas.drawOval(CanvasKit.XYWHRect(x, y, 6, 6), paint);
|
||||
}
|
||||
|
||||
// Snap it off as an SkImage - this image will be in the form the
|
||||
// parent surface prefers (e.g. Texture for GPU / Raster for CPU).
|
||||
const img = subSurface.makeImageSnapshot();
|
||||
|
||||
// clean up the temporary surface
|
||||
subSurface.delete();
|
||||
paint.delete();
|
||||
|
||||
// Make it repeat a bunch with a shader
|
||||
const pattern = img.makeShader(CanvasKit.TileMode.Repeat, CanvasKit.TileMode.Mirror);
|
||||
const patternPaint = new CanvasKit.SkPaint();
|
||||
patternPaint.setShader(pattern);
|
||||
|
||||
let i = 0;
|
||||
|
||||
function drawFrame() {
|
||||
i++;
|
||||
CanvasKit.setCurrentContext(context);
|
||||
canvas.clear(CanvasKit.WHITE);
|
||||
|
||||
canvas.drawOval(CanvasKit.LTRBRect(i % 60, i % 60, 300 - (i% 60), 300 - (i % 60)), patternPaint);
|
||||
surface.flush();
|
||||
window.requestAnimationFrame(drawFrame);
|
||||
}
|
||||
window.requestAnimationFrame(drawFrame);
|
||||
|
||||
}
|
||||
|
||||
function ParagraphAPI1(CanvasKit, fontData) {
|
||||
if (!CanvasKit || !fontData) {
|
||||
return;
|
||||
@ -821,30 +890,4 @@ const curves = {
|
||||
|
||||
surface.requestAnimationFrame(drawFrame);
|
||||
}
|
||||
|
||||
function ColorSupport(CanvasKit) {
|
||||
const surface = CanvasKit.MakeCanvasSurface('colorsupport', CanvasKit.SkColorSpace.ADOBE_RGB);
|
||||
if (!surface) {
|
||||
console.error('Could not make surface');
|
||||
return;
|
||||
}
|
||||
const canvas = surface.getCanvas();
|
||||
|
||||
// If the surface is correctly initialized with a higher bit depth color type,
|
||||
// And chrome is compositing it into a buffer with the P3 color space,
|
||||
// then the inner round rect should be distinct and less saturated than the full red background.
|
||||
// Even if the monitor it is viewed on cannot accurately represent that color space.
|
||||
|
||||
let red = CanvasKit.Color4f(1, 0, 0, 1);
|
||||
let paint = new CanvasKit.SkPaint();
|
||||
paint.setColor(red, CanvasKit.SkColorSpace.ADOBE_RGB);
|
||||
canvas.drawPaint(paint);
|
||||
paint.setColor(red, CanvasKit.SkColorSpace.DISPLAY_P3);
|
||||
canvas.drawRoundRect(CanvasKit.LTRBRect(50, 50, 250, 250), 30, 30, paint);
|
||||
paint.setColor(red, CanvasKit.SkColorSpace.SRGB);
|
||||
canvas.drawRoundRect(CanvasKit.LTRBRect(100, 100, 200, 200), 30, 30, paint);
|
||||
|
||||
surface.flush();
|
||||
surface.delete();
|
||||
}
|
||||
</script>
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/core/SkColorFilter.h"
|
||||
#include "include/core/SkColorSpace.h"
|
||||
#include "include/core/SkData.h"
|
||||
#include "include/core/SkDrawable.h"
|
||||
#include "include/core/SkEncodedImageFormat.h"
|
||||
@ -110,29 +109,13 @@ struct SimpleImageInfo {
|
||||
int height;
|
||||
SkColorType colorType;
|
||||
SkAlphaType alphaType;
|
||||
sk_sp<SkColorSpace> colorSpace;
|
||||
// TODO color spaces?
|
||||
};
|
||||
|
||||
SkImageInfo toSkImageInfo(const SimpleImageInfo& sii) {
|
||||
return SkImageInfo::Make(sii.width, sii.height, sii.colorType, sii.alphaType, sii.colorSpace);
|
||||
return SkImageInfo::Make(sii.width, sii.height, sii.colorType, sii.alphaType);
|
||||
}
|
||||
|
||||
// Set the pixel format based on the colortype.
|
||||
// These degrees of freedom are removed from canvaskit only to keep the interface simpler.
|
||||
struct ColorSettings {
|
||||
ColorSettings(sk_sp<SkColorSpace> colorSpace) {
|
||||
if (colorSpace == nullptr || colorSpace->isSRGB()) {
|
||||
colorType = kRGBA_8888_SkColorType;
|
||||
pixFormat = GL_RGBA8;
|
||||
} else {
|
||||
colorType = kRGBA_F16_SkColorType;
|
||||
pixFormat = GL_RGBA16F;
|
||||
}
|
||||
};
|
||||
SkColorType colorType;
|
||||
GrGLenum pixFormat;
|
||||
};
|
||||
|
||||
#ifdef SK_GL
|
||||
sk_sp<GrContext> MakeGrContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context)
|
||||
{
|
||||
@ -148,27 +131,31 @@ sk_sp<GrContext> MakeGrContext(EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context)
|
||||
return grContext;
|
||||
}
|
||||
|
||||
sk_sp<SkSurface> MakeOnScreenGLSurface(sk_sp<GrContext> grContext, int width, int height,
|
||||
sk_sp<SkColorSpace> colorSpace) {
|
||||
sk_sp<SkSurface> MakeOnScreenGLSurface(sk_sp<GrContext> grContext, int width, int height) {
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClearStencil(0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
|
||||
// Wrap the frame buffer object attached to the screen in a Skia render
|
||||
// target so Skia can render to it
|
||||
GrGLint buffer;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &buffer);
|
||||
GrGLFramebufferInfo info;
|
||||
info.fFBOID = (GrGLuint) buffer;
|
||||
SkColorType colorType;
|
||||
|
||||
GrGLint stencil;
|
||||
glGetIntegerv(GL_STENCIL_BITS, &stencil);
|
||||
|
||||
const auto colorSettings = ColorSettings(colorSpace);
|
||||
info.fFormat = colorSettings.pixFormat;
|
||||
info.fFormat = GL_RGBA8;
|
||||
colorType = kRGBA_8888_SkColorType;
|
||||
|
||||
GrBackendRenderTarget target(width, height, 0, stencil, info);
|
||||
|
||||
sk_sp<SkSurface> surface(SkSurface::MakeFromBackendRenderTarget(grContext.get(), target,
|
||||
kBottomLeft_GrSurfaceOrigin, colorSettings.colorType, colorSpace, nullptr));
|
||||
kBottomLeft_GrSurfaceOrigin,
|
||||
colorType, nullptr, nullptr));
|
||||
return surface;
|
||||
}
|
||||
|
||||
@ -771,17 +758,16 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
return SkImage::MakeRasterData(info, pixelData, rowBytes);
|
||||
}), allow_raw_pointers());
|
||||
function("_MakeLinearGradientShader", optional_override([](SkPoint start, SkPoint end,
|
||||
uintptr_t /* SkColor4f* */ cPtr,
|
||||
uintptr_t /* SkScalar* */ pPtr,
|
||||
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
||||
int count, SkTileMode mode, uint32_t flags,
|
||||
uintptr_t /* SkScalar* */ mPtr,
|
||||
sk_sp<SkColorSpace> colorSpace)->sk_sp<SkShader> {
|
||||
uintptr_t /* SkScalar* */ mPtr)->sk_sp<SkShader> {
|
||||
SkPoint points[] = { start, end };
|
||||
// See comment above for uintptr_t explanation
|
||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
|
||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
||||
OptionalMatrix localMatrix(mPtr);
|
||||
return SkGradientShader::MakeLinear(points, colors, colorSpace, positions, count,
|
||||
// TODO(nifong): do not assume color space. Support and test wide gamut color gradients
|
||||
return SkGradientShader::MakeLinear(points, colors, SkColorSpace::MakeSRGB(), positions, count,
|
||||
mode, flags, &localMatrix);
|
||||
}), allow_raw_pointers());
|
||||
#ifdef SK_SERIALIZE_SKP
|
||||
@ -795,48 +781,42 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
}), allow_raw_pointers());
|
||||
#endif
|
||||
function("_MakeRadialGradientShader", optional_override([](SkPoint center, SkScalar radius,
|
||||
uintptr_t /* SkColor4f* */ cPtr,
|
||||
uintptr_t /* SkScalar* */ pPtr,
|
||||
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
||||
int count, SkTileMode mode, uint32_t flags,
|
||||
uintptr_t /* SkScalar* */ mPtr,
|
||||
sk_sp<SkColorSpace> colorSpace)->sk_sp<SkShader> {
|
||||
uintptr_t /* SkScalar* */ mPtr)->sk_sp<SkShader> {
|
||||
// See comment above for uintptr_t explanation
|
||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
|
||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
||||
OptionalMatrix localMatrix(mPtr);
|
||||
return SkGradientShader::MakeRadial(center, radius, colors, colorSpace, positions, count,
|
||||
return SkGradientShader::MakeRadial(center, radius, colors, SkColorSpace::MakeSRGB(), positions, count,
|
||||
mode, flags, &localMatrix);
|
||||
}), allow_raw_pointers());
|
||||
function("_MakeSweepGradientShader", optional_override([](SkScalar cx, SkScalar cy,
|
||||
uintptr_t /* SkColor4f* */ cPtr,
|
||||
uintptr_t /* SkScalar* */ pPtr,
|
||||
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
||||
int count, SkTileMode mode,
|
||||
SkScalar startAngle, SkScalar endAngle,
|
||||
uint32_t flags,
|
||||
uintptr_t /* SkScalar* */ mPtr,
|
||||
sk_sp<SkColorSpace> colorSpace)->sk_sp<SkShader> {
|
||||
uintptr_t /* SkScalar* */ mPtr)->sk_sp<SkShader> {
|
||||
// See comment above for uintptr_t explanation
|
||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*>(cPtr);
|
||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
||||
OptionalMatrix localMatrix(mPtr);
|
||||
return SkGradientShader::MakeSweep(cx, cy, colors, colorSpace, positions, count,
|
||||
return SkGradientShader::MakeSweep(cx, cy, colors, SkColorSpace::MakeSRGB(), positions, count,
|
||||
mode, startAngle, endAngle, flags,
|
||||
&localMatrix);
|
||||
}), allow_raw_pointers());
|
||||
function("_MakeTwoPointConicalGradientShader", optional_override([](
|
||||
SkPoint start, SkScalar startRadius,
|
||||
SkPoint end, SkScalar endRadius,
|
||||
uintptr_t /* SkColor4f* */ cPtr,
|
||||
uintptr_t /* SkScalar* */ pPtr,
|
||||
uintptr_t /* SkColor4f* */ cPtr, uintptr_t /* SkScalar* */ pPtr,
|
||||
int count, SkTileMode mode, uint32_t flags,
|
||||
uintptr_t /* SkScalar* */ mPtr,
|
||||
sk_sp<SkColorSpace> colorSpace)->sk_sp<SkShader> {
|
||||
uintptr_t /* SkScalar* */ mPtr)->sk_sp<SkShader> {
|
||||
// See comment above for uintptr_t explanation
|
||||
const SkColor4f* colors = reinterpret_cast<const SkColor4f*> (cPtr);
|
||||
const SkScalar* positions = reinterpret_cast<const SkScalar*>(pPtr);
|
||||
OptionalMatrix localMatrix(mPtr);
|
||||
return SkGradientShader::MakeTwoPointConical(start, startRadius, end, endRadius,
|
||||
colors, colorSpace, positions, count, mode,
|
||||
colors, SkColorSpace::MakeSRGB(), positions, count, mode,
|
||||
flags, &localMatrix);
|
||||
}), allow_raw_pointers());
|
||||
|
||||
@ -1277,9 +1257,8 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.function("setAntiAlias", &SkPaint::setAntiAlias)
|
||||
.function("setAlphaf", &SkPaint::setAlphaf)
|
||||
.function("setBlendMode", &SkPaint::setBlendMode)
|
||||
.function("_setColor", optional_override([](SkPaint& self, uintptr_t /* float* */ cPtr,
|
||||
sk_sp<SkColorSpace> colorSpace) {
|
||||
self.setColor(ptrToSkColor4f(cPtr), colorSpace.get());
|
||||
.function("_setColor", optional_override([](SkPaint& self, uintptr_t /* float* */ cPtr) {
|
||||
self.setColor(ptrToSkColor4f(cPtr));
|
||||
}))
|
||||
.function("setColorFilter", &SkPaint::setColorFilter)
|
||||
.function("setFilterQuality", &SkPaint::setFilterQuality)
|
||||
@ -1293,21 +1272,6 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.function("setStrokeWidth", &SkPaint::setStrokeWidth)
|
||||
.function("setStyle", &SkPaint::setStyle);
|
||||
|
||||
class_<SkColorSpace>("SkColorSpace")
|
||||
.smart_ptr<sk_sp<SkColorSpace>>("sk_sp<SkColorSpace>")
|
||||
.class_function("Equals", optional_override([](sk_sp<SkColorSpace> a, sk_sp<SkColorSpace> b)->bool {
|
||||
return SkColorSpace::Equals(a.get(), b.get());
|
||||
}))
|
||||
// These are private because they are to be called once in interface.js to
|
||||
// avoid clients having to delete the returned objects.
|
||||
.class_function("_MakeSRGB", &SkColorSpace::MakeSRGB)
|
||||
.class_function("_MakeDisplayP3", optional_override([]()->sk_sp<SkColorSpace> {
|
||||
return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3);
|
||||
}))
|
||||
.class_function("_MakeAdobeRGB", optional_override([]()->sk_sp<SkColorSpace> {
|
||||
return SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, SkNamedGamut::kAdobeRGB);
|
||||
}));
|
||||
|
||||
class_<SkPathEffect>("SkPathEffect")
|
||||
.smart_ptr<sk_sp<SkPathEffect>>("sk_sp<SkPathEffect>")
|
||||
.class_function("MakeCorner", &SkCornerPathEffect::Make)
|
||||
@ -1441,8 +1405,8 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.smart_ptr<sk_sp<SkShader>>("sk_sp<SkShader>")
|
||||
.class_function("Blend", select_overload<sk_sp<SkShader>(SkBlendMode, sk_sp<SkShader>, sk_sp<SkShader>)>(&SkShaders::Blend))
|
||||
.class_function("_Color",
|
||||
optional_override([](uintptr_t /* float* */ cPtr, sk_sp<SkColorSpace> colorSpace)->sk_sp<SkShader> {
|
||||
return SkShaders::Color(ptrToSkColor4f(cPtr), colorSpace);
|
||||
optional_override([](uintptr_t /* float* */ cPtr)->sk_sp<SkShader> {
|
||||
return SkShaders::Color(ptrToSkColor4f(cPtr), SkColorSpace::MakeSRGB());
|
||||
})
|
||||
)
|
||||
.class_function("Lerp", select_overload<sk_sp<SkShader>(float, sk_sp<SkShader>, sk_sp<SkShader>)>(&SkShaders::Lerp));
|
||||
@ -1493,10 +1457,6 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.smart_ptr<sk_sp<SkSurface>>("sk_sp<SkSurface>")
|
||||
.function("_flush", select_overload<void()>(&SkSurface::flushAndSubmit))
|
||||
.function("getCanvas", &SkSurface::getCanvas, allow_raw_pointers())
|
||||
.function("imageInfo", optional_override([](SkSurface& self)->SimpleImageInfo {
|
||||
const auto& ii = self.imageInfo();
|
||||
return {ii.width(), ii.height(), ii.colorType(), ii.alphaType(), ii.refColorSpace()};
|
||||
}))
|
||||
.function("height", &SkSurface::height)
|
||||
.function("makeImageSnapshot", select_overload<sk_sp<SkImage>()>(&SkSurface::makeImageSnapshot))
|
||||
.function("makeImageSnapshot", select_overload<sk_sp<SkImage>(const SkIRect& bounds)>(&SkSurface::makeImageSnapshot))
|
||||
@ -1694,6 +1654,7 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.value("TrianglesStrip", SkVertices::VertexMode::kTriangleStrip_VertexMode)
|
||||
.value("TriangleFan", SkVertices::VertexMode::kTriangleFan_VertexMode);
|
||||
|
||||
|
||||
// A value object is much simpler than a class - it is returned as a JS
|
||||
// object and does not require delete().
|
||||
// https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#value-types
|
||||
@ -1729,11 +1690,10 @@ EMSCRIPTEN_BINDINGS(Skia) {
|
||||
.field("fBottom", &SkIRect::fBottom);
|
||||
|
||||
value_object<SimpleImageInfo>("SkImageInfo")
|
||||
.field("width", &SimpleImageInfo::width)
|
||||
.field("height", &SimpleImageInfo::height)
|
||||
.field("colorType", &SimpleImageInfo::colorType)
|
||||
.field("alphaType", &SimpleImageInfo::alphaType)
|
||||
.field("colorSpace", &SimpleImageInfo::colorSpace);
|
||||
.field("width", &SimpleImageInfo::width)
|
||||
.field("height", &SimpleImageInfo::height)
|
||||
.field("colorType", &SimpleImageInfo::colorType)
|
||||
.field("alphaType", &SimpleImageInfo::alphaType);
|
||||
|
||||
// SkPoints can be represented by [x, y]
|
||||
value_array<SkPoint>("SkPoint")
|
||||
|
@ -26,10 +26,6 @@
|
||||
CanvasKit.MakeCanvasSurface = CanvasKit.MakeSWCanvasSurface;
|
||||
}
|
||||
|
||||
// Note that color spaces are currently not supported in CPU surfaces. due to the limitation
|
||||
// canvas.getContext('2d').putImageData imposes a limitatin of using an RGBA_8888 color type.
|
||||
// TODO(nifong): support WGC color spaces while still using an RGBA_8888 color type when
|
||||
// on a cpu backend.
|
||||
CanvasKit.MakeSurface = function(width, height) {
|
||||
/* @dict */
|
||||
var imageInfo = {
|
||||
@ -39,7 +35,6 @@
|
||||
// Since we are sending these pixels directly into the HTML canvas,
|
||||
// (and those pixels are un-premultiplied, i.e. straight r,g,b,a)
|
||||
'alphaType': CanvasKit.AlphaType.Unpremul,
|
||||
'colorSpace': CanvasKit.SkColorSpace.SRGB,
|
||||
}
|
||||
var pixelLen = width * height * 4; // it's 8888, so 4 bytes per pixel
|
||||
// Allocate the buffer of pixels to be drawn into.
|
||||
|
@ -259,17 +259,6 @@ var CanvasKit = {
|
||||
scaled: function() {},
|
||||
},
|
||||
|
||||
SkColorSpace: {
|
||||
Equals: function() {},
|
||||
SRGB: {},
|
||||
DISPLAY_P3: {},
|
||||
ADOBE_RGB: {},
|
||||
// private API (from C++ bindings)
|
||||
_MakeSRGB: function() {},
|
||||
_MakeDisplayP3: function() {},
|
||||
_MakeAdobeRGB: function() {},
|
||||
},
|
||||
|
||||
SkContourMeasureIter: {
|
||||
next: function() {},
|
||||
},
|
||||
@ -531,7 +520,6 @@ var CanvasKit = {
|
||||
// public API (from C++ bindings)
|
||||
/** @return {CanvasKit.SkCanvas} */
|
||||
getCanvas: function() {},
|
||||
imageInfo: function() {},
|
||||
/** @return {CanvasKit.SkImage} */
|
||||
makeImageSnapshot: function() {},
|
||||
makeSurface: function() {},
|
||||
|
@ -41,22 +41,19 @@
|
||||
return CanvasKit.currentContext() || 0;
|
||||
};
|
||||
|
||||
// idOrElement can be of types:
|
||||
// arg can be of types:
|
||||
// - String - in which case it is interpreted as an id of a
|
||||
// canvas element.
|
||||
// - HTMLCanvasElement - in which the provided canvas element will
|
||||
// be used directly.
|
||||
// colorSpace - sk_sp<SkColorSpace> - one of the supported color spaces:
|
||||
// CanvasKit.SkColorSpace.SRGB
|
||||
// CanvasKit.SkColorSpace.DISPLAY_P3
|
||||
// CanvasKit.SkColorSpace.ADOBE_RGB
|
||||
CanvasKit.MakeWebGLCanvasSurface = function(idOrElement, colorSpace) {
|
||||
colorSpace = colorSpace || null;
|
||||
var canvas = idOrElement;
|
||||
// Width and height can be provided to override those on the canvas
|
||||
// element, or specify a height for when a context is provided.
|
||||
CanvasKit.MakeWebGLCanvasSurface = function(arg, width, height) {
|
||||
var canvas = arg;
|
||||
if (canvas.tagName !== 'CANVAS') {
|
||||
canvas = document.getElementById(idOrElement);
|
||||
canvas = document.getElementById(arg);
|
||||
if (!canvas) {
|
||||
throw 'Canvas with id ' + idOrElement + ' was not found';
|
||||
throw 'Canvas with id ' + arg + ' was not found';
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,6 +64,10 @@
|
||||
throw 'failed to create webgl context: err ' + ctx;
|
||||
}
|
||||
|
||||
if (!canvas && (!width || !height)) {
|
||||
throw 'height and width must be provided with context';
|
||||
}
|
||||
|
||||
var grcontext = this.MakeGrContext(ctx);
|
||||
|
||||
if (grcontext) {
|
||||
@ -75,10 +76,12 @@
|
||||
grcontext.setResourceCacheLimitBytes(RESOURCE_CACHE_BYTES);
|
||||
}
|
||||
|
||||
// Note that canvas.width/height here is used because it gives the size of the buffer we're
|
||||
// rendering into. This may not be the same size the element is displayed on the page, which
|
||||
// constrolled by css, and available in canvas.clientWidth/height.
|
||||
var surface = this.MakeOnScreenGLSurface(grcontext, canvas.width, canvas.height, colorSpace);
|
||||
|
||||
// Maybe better to use clientWidth/height. See:
|
||||
// https://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html
|
||||
var surface = this.MakeOnScreenGLSurface(grcontext,
|
||||
width || canvas.width,
|
||||
height || canvas.height);
|
||||
if (!surface) {
|
||||
SkDebug('falling back from GPU implementation to a SW based one');
|
||||
// we need to throw away the old canvas (which was locked to
|
||||
|
@ -848,8 +848,7 @@ function CanvasRenderingContext2D(skcanvas) {
|
||||
}
|
||||
var img = CanvasKit.MakeImage(imageData.data, imageData.width, imageData.height,
|
||||
CanvasKit.AlphaType.Unpremul,
|
||||
CanvasKit.ColorType.RGBA_8888,
|
||||
CanvasKit.SkColorSpace.SRGB);
|
||||
CanvasKit.ColorType.RGBA_8888);
|
||||
var src = CanvasKit.XYWHRect(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
|
||||
var dst = CanvasKit.XYWHRect(x+dirtyX, y+dirtyY, dirtyWidth, dirtyHeight);
|
||||
var inverted = CanvasKit.SkMatrix.invert(this._currentTransform);
|
||||
|
@ -8,12 +8,6 @@
|
||||
CanvasKit.onRuntimeInitialized = function() {
|
||||
// All calls to 'this' need to go in externs.js so closure doesn't minify them away.
|
||||
|
||||
// Create single copies of all three supported color spaces
|
||||
// These are sk_sp<SkColorSpace>
|
||||
CanvasKit.SkColorSpace.SRGB = CanvasKit.SkColorSpace._MakeSRGB();
|
||||
CanvasKit.SkColorSpace.DISPLAY_P3 = CanvasKit.SkColorSpace._MakeDisplayP3();
|
||||
CanvasKit.SkColorSpace.ADOBE_RGB = CanvasKit.SkColorSpace._MakeAdobeRGB();
|
||||
|
||||
// Add some helpers for matrices. This is ported from SkMatrix.cpp
|
||||
// to save complexity and overhead of going back and forth between
|
||||
// C++ and JS layers.
|
||||
@ -1013,16 +1007,11 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
|
||||
// returns Uint8Array
|
||||
CanvasKit.SkCanvas.prototype.readPixels = function(x, y, w, h, alphaType,
|
||||
colorType, colorSpace, dstRowBytes) {
|
||||
colorType, dstRowBytes) {
|
||||
// supply defaults (which are compatible with HTMLCanvas's getImageData)
|
||||
alphaType = alphaType || CanvasKit.AlphaType.Unpremul;
|
||||
colorType = colorType || CanvasKit.ColorType.RGBA_8888;
|
||||
colorSpace = colorSpace || CanvasKit.SkColorSpace.SRGB;
|
||||
var pixBytes = 4;
|
||||
if (colorType === CanvasKit.ColorType.RGBA_F16) {
|
||||
pixBytes = 8;
|
||||
}
|
||||
dstRowBytes = dstRowBytes || (pixBytes * w);
|
||||
dstRowBytes = dstRowBytes || (4 * w);
|
||||
|
||||
var len = h * dstRowBytes
|
||||
var pptr = CanvasKit._malloc(len);
|
||||
@ -1031,7 +1020,6 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
'height': h,
|
||||
'colorType': colorType,
|
||||
'alphaType': alphaType,
|
||||
'colorSpace': colorSpace,
|
||||
}, pptr, dstRowBytes, x, y);
|
||||
if (!ok) {
|
||||
CanvasKit._free(pptr);
|
||||
@ -1048,7 +1036,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
// pixels is a TypedArray. No matter the input size, it will be treated as
|
||||
// a Uint8Array (essentially, a byte array).
|
||||
CanvasKit.SkCanvas.prototype.writePixels = function(pixels, srcWidth, srcHeight,
|
||||
destX, destY, alphaType, colorType, colorSpace) {
|
||||
destX, destY, alphaType, colorType) {
|
||||
if (pixels.byteLength % (srcWidth * srcHeight)) {
|
||||
throw 'pixels length must be a multiple of the srcWidth * srcHeight';
|
||||
}
|
||||
@ -1056,7 +1044,6 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
// supply defaults (which are compatible with HTMLCanvas's putImageData)
|
||||
alphaType = alphaType || CanvasKit.AlphaType.Unpremul;
|
||||
colorType = colorType || CanvasKit.ColorType.RGBA_8888;
|
||||
colorSpace = colorSpace || CanvasKit.SkColorSpace.SRGB;
|
||||
var srcRowBytes = bytesPerPixel * srcWidth;
|
||||
|
||||
var pptr = CanvasKit._malloc(pixels.byteLength);
|
||||
@ -1067,7 +1054,6 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
'height': srcHeight,
|
||||
'colorType': colorType,
|
||||
'alphaType': alphaType,
|
||||
'colorSpace': colorSpace,
|
||||
}, pptr, srcRowBytes, destX, destY);
|
||||
|
||||
CanvasKit._free(pptr);
|
||||
@ -1107,11 +1093,9 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
return copyColorFromWasm(cPtr);
|
||||
}
|
||||
|
||||
CanvasKit.SkPaint.prototype.setColor = function(color4f, colorSpace) {
|
||||
colorSpace = colorSpace || null; // null will be replaced with sRGB in the C++ method.
|
||||
// emscripten wouldn't bind undefined to the sk_sp<SkColorSpace> expected here.
|
||||
CanvasKit.SkPaint.prototype.setColor = function(color4f) {
|
||||
var cPtr = copy1dArray(color4f, CanvasKit.HEAPF32);
|
||||
this._setColor(cPtr, colorSpace);
|
||||
this._setColor(cPtr);
|
||||
CanvasKit._free(cPtr);
|
||||
}
|
||||
|
||||
@ -1176,23 +1160,21 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
return dpe;
|
||||
}
|
||||
|
||||
CanvasKit.SkShader.Color = function(color4f, colorSpace) {
|
||||
colorSpace = colorSpace || null
|
||||
CanvasKit.SkShader.Color = function(color4f) {
|
||||
var cPtr = copy1dArray(color4f, CanvasKit.HEAPF32);
|
||||
var result = CanvasKit.SkShader._Color(cPtr, colorSpace);
|
||||
var result = CanvasKit.SkShader._Color(cPtr);
|
||||
CanvasKit._free(cPtr);
|
||||
return result;
|
||||
}
|
||||
|
||||
CanvasKit.SkShader.MakeLinearGradient = function(start, end, colors, pos, mode, localMatrix, flags, colorSpace) {
|
||||
colorSpace = colorSpace || null
|
||||
CanvasKit.SkShader.MakeLinearGradient = function(start, end, colors, pos, mode, localMatrix, flags) {
|
||||
var colorPtr = copy2dArray(colors, CanvasKit.HEAPF32);
|
||||
var posPtr = copy1dArray(pos, CanvasKit.HEAPF32);
|
||||
flags = flags || 0;
|
||||
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||
|
||||
var lgs = CanvasKit._MakeLinearGradientShader(start, end, colorPtr, posPtr,
|
||||
colors.length, mode, flags, localMatrixPtr, colorSpace);
|
||||
colors.length, mode, flags, localMatrixPtr);
|
||||
|
||||
CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(colorPtr);
|
||||
@ -1200,15 +1182,14 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
return lgs;
|
||||
}
|
||||
|
||||
CanvasKit.SkShader.MakeRadialGradient = function(center, radius, colors, pos, mode, localMatrix, flags, colorSpace) {
|
||||
colorSpace = colorSpace || null
|
||||
CanvasKit.SkShader.MakeRadialGradient = function(center, radius, colors, pos, mode, localMatrix, flags) {
|
||||
var colorPtr = copy2dArray(colors, CanvasKit.HEAPF32);
|
||||
var posPtr = copy1dArray(pos, CanvasKit.HEAPF32);
|
||||
flags = flags || 0;
|
||||
var localMatrixPtr = copy3x3MatrixToWasm(localMatrix);
|
||||
|
||||
var rgs = CanvasKit._MakeRadialGradientShader(center, radius, colorPtr, posPtr,
|
||||
colors.length, mode, flags, localMatrixPtr, colorSpace);
|
||||
colors.length, mode, flags, localMatrixPtr);
|
||||
|
||||
CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(colorPtr);
|
||||
@ -1216,8 +1197,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
return rgs;
|
||||
}
|
||||
|
||||
CanvasKit.SkShader.MakeSweepGradient = function(cx, cy, colors, pos, mode, localMatrix, flags, startAngle, endAngle, colorSpace) {
|
||||
colorSpace = colorSpace || null
|
||||
CanvasKit.SkShader.MakeSweepGradient = function(cx, cy, colors, pos, mode, localMatrix, flags, startAngle, endAngle) {
|
||||
var colorPtr = copy2dArray(colors, CanvasKit.HEAPF32);
|
||||
var posPtr = copy1dArray(pos, CanvasKit.HEAPF32);
|
||||
flags = flags || 0;
|
||||
@ -1228,7 +1208,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
var sgs = CanvasKit._MakeSweepGradientShader(cx, cy, colorPtr, posPtr,
|
||||
colors.length, mode,
|
||||
startAngle, endAngle, flags,
|
||||
localMatrixPtr, colorSpace);
|
||||
localMatrixPtr);
|
||||
|
||||
CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(colorPtr);
|
||||
@ -1237,8 +1217,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
}
|
||||
|
||||
CanvasKit.SkShader.MakeTwoPointConicalGradient = function(start, startRadius, end, endRadius,
|
||||
colors, pos, mode, localMatrix, flags, colorSpace) {
|
||||
colorSpace = colorSpace || null
|
||||
colors, pos, mode, localMatrix, flags) {
|
||||
var colorPtr = copy2dArray(colors, CanvasKit.HEAPF32);
|
||||
var posPtr = copy1dArray(pos, CanvasKit.HEAPF32);
|
||||
flags = flags || 0;
|
||||
@ -1246,7 +1225,7 @@ CanvasKit.onRuntimeInitialized = function() {
|
||||
|
||||
var rgs = CanvasKit._MakeTwoPointConicalGradientShader(
|
||||
start, startRadius, end, endRadius,
|
||||
colorPtr, posPtr, colors.length, mode, flags, localMatrixPtr, colorSpace);
|
||||
colorPtr, posPtr, colors.length, mode, flags, localMatrixPtr);
|
||||
|
||||
CanvasKit._free(localMatrixPtr);
|
||||
CanvasKit._free(colorPtr);
|
||||
@ -1356,14 +1335,13 @@ CanvasKit.MakeImageFromEncoded = function(data) {
|
||||
|
||||
// pixels must be a Uint8Array with bytes representing the pixel values
|
||||
// (e.g. each set of 4 bytes could represent RGBA values for a single pixel).
|
||||
CanvasKit.MakeImage = function(pixels, width, height, alphaType, colorType, colorSpace) {
|
||||
CanvasKit.MakeImage = function(pixels, width, height, alphaType, colorType) {
|
||||
var bytesPerPixel = pixels.length / (width * height);
|
||||
var info = {
|
||||
'width': width,
|
||||
'height': height,
|
||||
'alphaType': alphaType,
|
||||
'colorType': colorType,
|
||||
'colorSpace': colorSpace,
|
||||
};
|
||||
var pptr = copy1dArray(pixels, CanvasKit.HEAPU8);
|
||||
// No need to _free pptr, Image takes it with SkData::MakeFromMalloc
|
||||
|
@ -116,7 +116,6 @@ describe('Core canvas behavior', () => {
|
||||
const imageInfo = {
|
||||
alphaType: CanvasKit.AlphaType.Unpremul,
|
||||
colorType: CanvasKit.ColorType.RGBA_8888,
|
||||
colorSpace: CanvasKit.SkColorSpace.SRGB,
|
||||
width: img.width(),
|
||||
height: img.height(),
|
||||
};
|
||||
@ -173,8 +172,7 @@ describe('Core canvas behavior', () => {
|
||||
0, 0, 255, 255, // opaque blue
|
||||
255, 0, 255, 100, // transparent purple
|
||||
]);
|
||||
const img = CanvasKit.MakeImage(pixels, 1, 4, CanvasKit.AlphaType.Unpremul, CanvasKit.ColorType.RGBA_8888,
|
||||
CanvasKit.SkColorSpace.SRGB);
|
||||
const img = CanvasKit.MakeImage(pixels, 1, 4, CanvasKit.AlphaType.Unpremul, CanvasKit.ColorType.RGBA_8888);
|
||||
canvas.drawImage(img, 1, 1, paint);
|
||||
img.delete();
|
||||
});
|
||||
@ -307,8 +305,7 @@ describe('Core canvas behavior', () => {
|
||||
[transparentGreen, CanvasKit.BLUE, CanvasKit.RED],
|
||||
[0, 0.65, 1.0],
|
||||
CanvasKit.TileMode.Mirror,
|
||||
CanvasKit.SkMatrix.skewed(0.5, 0, 100, 100),
|
||||
null, // color space
|
||||
CanvasKit.SkMatrix.skewed(0.5, 0, 100, 100)
|
||||
);
|
||||
paint.setShader(rgsSkew);
|
||||
r = CanvasKit.LTRBRect(0, 100, 100, 200);
|
||||
@ -321,8 +318,7 @@ describe('Core canvas behavior', () => {
|
||||
[0, 0.65, 1.0],
|
||||
CanvasKit.TileMode.Mirror,
|
||||
CanvasKit.SkMatrix.skewed(0.5, 0, 100, 100),
|
||||
1, // interpolate colors in premul
|
||||
null, // color space
|
||||
1 // interpolate colors in premul
|
||||
);
|
||||
paint.setShader(rgsSkewPremul);
|
||||
r = CanvasKit.LTRBRect(100, 100, 200, 200);
|
||||
@ -354,8 +350,7 @@ describe('Core canvas behavior', () => {
|
||||
[10, 110], 60, // end, radius
|
||||
[transparentGreen, CanvasKit.BLUE, CanvasKit.RED],
|
||||
[0, 0.65, 1.0],
|
||||
CanvasKit.TileMode.Mirror,
|
||||
null, // color space
|
||||
CanvasKit.TileMode.Mirror
|
||||
);
|
||||
paint.setShader(cgs);
|
||||
let r = CanvasKit.LTRBRect(0, 0, 100, 100);
|
||||
@ -370,7 +365,6 @@ describe('Core canvas behavior', () => {
|
||||
CanvasKit.TileMode.Mirror,
|
||||
null, // no local matrix
|
||||
1, // interpolate colors in premul
|
||||
null, // color space
|
||||
);
|
||||
paint.setShader(cgsPremul);
|
||||
r = CanvasKit.LTRBRect(100, 0, 200, 100);
|
||||
@ -383,8 +377,7 @@ describe('Core canvas behavior', () => {
|
||||
[transparentGreen, CanvasKit.BLUE, CanvasKit.RED],
|
||||
[0, 0.65, 1.0],
|
||||
CanvasKit.TileMode.Mirror,
|
||||
CanvasKit.SkMatrix.rotated(Math.PI/4, 0, 100),
|
||||
null, // color space
|
||||
CanvasKit.SkMatrix.rotated(Math.PI/4, 0, 100)
|
||||
);
|
||||
paint.setShader(cgs45);
|
||||
r = CanvasKit.LTRBRect(0, 100, 100, 200);
|
||||
@ -398,8 +391,7 @@ describe('Core canvas behavior', () => {
|
||||
[0, 0.65, 1.0],
|
||||
CanvasKit.TileMode.Mirror,
|
||||
CanvasKit.SkMatrix.rotated(Math.PI/4, 100, 100),
|
||||
1, // interpolate colors in premul
|
||||
null, // color space
|
||||
1 // interpolate colors in premul
|
||||
);
|
||||
paint.setShader(cgs45Premul);
|
||||
r = CanvasKit.LTRBRect(100, 100, 200, 200);
|
||||
@ -593,83 +585,6 @@ describe('Core canvas behavior', () => {
|
||||
expect(paint.getColor()).toEqual(Float32Array.of(3.3, 2.2, 1.1, 0.5));
|
||||
});
|
||||
|
||||
describe('ColorSpace Support', () => {
|
||||
it('Can create an SRGB 8888 surface', () => {
|
||||
const colorSpace = CanvasKit.SkColorSpace.SRGB;
|
||||
const surface = CanvasKit.MakeCanvasSurface('test', CanvasKit.SkColorSpace.SRGB);
|
||||
expect(surface).toBeTruthy('Could not make surface');
|
||||
let info = surface.imageInfo()
|
||||
expect(info.alphaType).toEqual(CanvasKit.AlphaType.Unpremul);
|
||||
expect(info.colorType).toEqual(CanvasKit.ColorType.RGBA_8888);
|
||||
expect(CanvasKit.SkColorSpace.Equals(info.colorSpace, colorSpace))
|
||||
.toBeTruthy("Surface not created with correct color space.");
|
||||
|
||||
const pixels = surface.getCanvas().readPixels(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
|
||||
CanvasKit.AlphaType.Unpremul, CanvasKit.ColorType.RGBA_8888, colorSpace);
|
||||
expect(pixels).toBeTruthy('Could not read pixels from surface');
|
||||
});
|
||||
it('Can create a Display P3 surface', () => {
|
||||
const colorSpace = CanvasKit.SkColorSpace.DISPLAY_P3;
|
||||
const surface = CanvasKit.MakeCanvasSurface('test', CanvasKit.SkColorSpace.DISPLAY_P3);
|
||||
expect(surface).toBeTruthy('Could not make surface');
|
||||
if (surface.reportBackendType() !== 'GPU') {
|
||||
console.log('Not expecting color space support in cpu backed suface.');
|
||||
return;
|
||||
}
|
||||
let info = surface.imageInfo()
|
||||
expect(info.alphaType).toEqual(CanvasKit.AlphaType.Unpremul);
|
||||
expect(info.colorType).toEqual(CanvasKit.ColorType.RGBA_F16);
|
||||
expect(CanvasKit.SkColorSpace.Equals(info.colorSpace, colorSpace))
|
||||
.toBeTruthy("Surface not created with correct color space.");
|
||||
|
||||
const pixels = surface.getCanvas().readPixels(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
|
||||
CanvasKit.AlphaType.Unpremul, CanvasKit.ColorType.RGBA_F16, colorSpace);
|
||||
expect(pixels).toBeTruthy('Could not read pixels from surface');
|
||||
});
|
||||
it('Can create an Adobe RGB surface', () => {
|
||||
const colorSpace = CanvasKit.SkColorSpace.ADOBE_RGB;
|
||||
const surface = CanvasKit.MakeCanvasSurface('test', CanvasKit.SkColorSpace.ADOBE_RGB);
|
||||
expect(surface).toBeTruthy('Could not make surface');
|
||||
if (surface.reportBackendType() !== 'GPU') {
|
||||
console.log('Not expecting color space support in cpu backed suface.');
|
||||
return;
|
||||
}
|
||||
let info = surface.imageInfo()
|
||||
expect(info.alphaType).toEqual(CanvasKit.AlphaType.Unpremul);
|
||||
expect(info.colorType).toEqual(CanvasKit.ColorType.RGBA_F16);
|
||||
expect(CanvasKit.SkColorSpace.Equals(info.colorSpace, colorSpace))
|
||||
.toBeTruthy("Surface not created with correct color space.");
|
||||
|
||||
const pixels = surface.getCanvas().readPixels(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
|
||||
CanvasKit.AlphaType.Unpremul, CanvasKit.ColorType.RGBA_F16, colorSpace);
|
||||
expect(pixels).toBeTruthy('Could not read pixels from surface');
|
||||
});
|
||||
|
||||
it('combine draws from several color spaces', () => {
|
||||
const surface = CanvasKit.MakeCanvasSurface('test', CanvasKit.SkColorSpace.ADOBE_RGB);
|
||||
expect(surface).toBeTruthy('Could not make surface');
|
||||
if (surface.reportBackendType() !== 'GPU') {
|
||||
console.log('Not expecting color space support in cpu backed suface.');
|
||||
return;
|
||||
}
|
||||
const canvas = surface.getCanvas();
|
||||
|
||||
let paint = new CanvasKit.SkPaint();
|
||||
paint.setColor(CanvasKit.RED, CanvasKit.SkColorSpace.ADOBE_RGB);
|
||||
canvas.drawPaint(paint);
|
||||
paint.setColor(CanvasKit.RED, CanvasKit.SkColorSpace.DISPLAY_P3); // 93.7 in adobeRGB
|
||||
canvas.drawRect(CanvasKit.LTRBRect(200, 0, 400, 600), paint);
|
||||
paint.setColor(CanvasKit.RED, CanvasKit.SkColorSpace.SRGB); // 85.9 in adobeRGB
|
||||
canvas.drawRect(CanvasKit.LTRBRect(400, 0, 600, 600), paint);
|
||||
|
||||
// this test paints three bands of red, each the maximum red that a color space supports.
|
||||
// They are each represented by skia by some color in the Adobe RGB space of the surface,
|
||||
// as floats between 0 and 1.
|
||||
|
||||
// TODO(nifong) readpixels and verify correctness after f32 readpixels bug is fixed
|
||||
});
|
||||
}); // end describe('ColorSpace Support')
|
||||
|
||||
describe('DOMMatrix support', () => {
|
||||
gm('sweep_gradient_dommatrix', (canvas) => {
|
||||
const paint = new CanvasKit.SkPaint();
|
||||
|
Loading…
Reference in New Issue
Block a user