summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/modules/canvas
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/canvas')
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/BUILD.gn13
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/DIR_METADATA4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/OWNERS3
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc786
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h103
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc187
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.h129
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.idl24
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.cc34
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.h50
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.idl12
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.cc82
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h24
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc101
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h46
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl29
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc24
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h10
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc77
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/idls.gni4
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc384
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.h213
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_source_union.h17
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/imagebitmap/window_create_image_bitmap.idl24
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/imagebitmap/worker_create_image_bitmap.idl13
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc48
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h8
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl21
33 files changed, 2094 insertions, 394 deletions
diff --git a/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn b/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn
index 3dee2798eee..2a069bf9356 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn
@@ -9,8 +9,14 @@ blink_modules_sources("canvas") {
sources = [
"canvas2d/base_rendering_context_2d.cc",
"canvas2d/base_rendering_context_2d.h",
+ "canvas2d/canvas_formatted_text.cc",
+ "canvas2d/canvas_formatted_text.h",
+ "canvas2d/canvas_formatted_text_run.cc",
+ "canvas2d/canvas_formatted_text_run.h",
"canvas2d/canvas_gradient.cc",
"canvas2d/canvas_gradient.h",
+ "canvas2d/canvas_image_source_util.cc",
+ "canvas2d/canvas_image_source_util.h",
"canvas2d/canvas_path.cc",
"canvas2d/canvas_path.h",
"canvas2d/canvas_pattern.cc",
@@ -32,15 +38,22 @@ blink_modules_sources("canvas") {
"htmlcanvas/canvas_context_creation_attributes_helpers.h",
"htmlcanvas/html_canvas_element_module.cc",
"htmlcanvas/html_canvas_element_module.h",
+ "imagebitmap/image_bitmap_factories.cc",
+ "imagebitmap/image_bitmap_factories.h",
"imagebitmap/image_bitmap_rendering_context.cc",
"imagebitmap/image_bitmap_rendering_context.h",
"imagebitmap/image_bitmap_rendering_context_base.cc",
"imagebitmap/image_bitmap_rendering_context_base.h",
+ "imagebitmap/image_bitmap_source_union.h",
"offscreencanvas/offscreen_canvas_module.cc",
"offscreencanvas/offscreen_canvas_module.h",
"offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc",
"offscreencanvas2d/offscreen_canvas_rendering_context_2d.h",
]
+
+ deps = [ "//third_party/blink/renderer/modules/webcodecs" ]
+ allow_circular_includes_from =
+ [ "//third_party/blink/renderer/modules/webcodecs" ]
}
fuzzer_test("canvas_fuzzer") {
diff --git a/chromium/third_party/blink/renderer/modules/canvas/DIR_METADATA b/chromium/third_party/blink/renderer/modules/canvas/DIR_METADATA
new file mode 100644
index 00000000000..73333465b1f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/DIR_METADATA
@@ -0,0 +1,4 @@
+monorail {
+ component: "Blink>Canvas"
+}
+team_email: "paint-dev@chromium.org" \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/canvas/OWNERS b/chromium/third_party/blink/renderer/modules/canvas/OWNERS
index 4abe99a57af..319149318fa 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/OWNERS
+++ b/chromium/third_party/blink/renderer/modules/canvas/OWNERS
@@ -6,6 +6,3 @@ yiyix@chromium.org
senorblanco@chromium.org
# lowLatency
mcasas@chromium.org
-
-# TEAM: paint-dev@chromium.org
-# COMPONENT: Blink>Canvas
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
index efc376143b4..98b485c0911 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -12,13 +12,9 @@
#include "base/metrics/histogram_functions.h"
#include "base/numerics/checked_math.h"
#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/renderer/core/css/cssom/css_url_image_value.h"
#include "third_party/blink/renderer/core/css/parser/css_parser.h"
#include "third_party/blink/renderer/core/html/canvas/text_metrics.h"
-#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
-#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
-#include "third_party/blink/renderer/core/svg/svg_image_element.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/path_2d.h"
#include "third_party/blink/renderer/platform/geometry/float_quad.h"
@@ -36,6 +32,15 @@ const char BaseRenderingContext2D::kLtrDirectionString[] = "ltr";
const char BaseRenderingContext2D::kAutoKerningString[] = "auto";
const char BaseRenderingContext2D::kNormalKerningString[] = "normal";
const char BaseRenderingContext2D::kNoneKerningString[] = "none";
+const char BaseRenderingContext2D::kUltraCondensedString[] = "ultra-condensed";
+const char BaseRenderingContext2D::kExtraCondensedString[] = "extra-condensed";
+const char BaseRenderingContext2D::kCondensedString[] = "condensed";
+const char BaseRenderingContext2D::kSemiCondensedString[] = "semi-condensed";
+const char BaseRenderingContext2D::kNormalStretchString[] = "normal";
+const char BaseRenderingContext2D::kSemiExpandedString[] = "semi-expanded";
+const char BaseRenderingContext2D::kExpandedString[] = "expanded";
+const char BaseRenderingContext2D::kExtraExpandedString[] = "extra-expanded";
+const char BaseRenderingContext2D::kUltraExpandedString[] = "ultra-expanded";
const char BaseRenderingContext2D::kNormalVariantString[] = "normal";
const char BaseRenderingContext2D::kSmallCapsVariantString[] = "small-caps";
const char BaseRenderingContext2D::kAllSmallCapsVariantString[] =
@@ -136,11 +141,11 @@ void BaseRenderingContext2D::RestoreMatrixClipStack(cc::PaintCanvas* c) const {
DCHECK(state_stack_.begin() < state_stack_.end());
for (curr_state = state_stack_.begin(); curr_state < state_stack_.end();
curr_state++) {
- c->setMatrix(SkMatrix::I());
+ c->setMatrix(SkM44());
if (curr_state->Get()) {
curr_state->Get()->PlaybackClips(c);
c->setMatrix(
- TransformationMatrixToSkMatrix(curr_state->Get()->GetTransform()));
+ TransformationMatrix::ToSkM44(curr_state->Get()->GetTransform()));
}
c->save();
}
@@ -175,6 +180,9 @@ void BaseRenderingContext2D::reset() {
DCHECK(c->getDeviceClipBounds(&clip_bounds));
DCHECK(clip_bounds == c->imageInfo().bounds());
#endif
+ // We only want to clear the backing buffer if the surface exists because
+ // this function is also used when the context is lost.
+ clearRect(0, 0, Width(), Height());
}
ValidateStateStack();
origin_tainted_by_content_ = false;
@@ -208,6 +216,15 @@ void BaseRenderingContext2D::IdentifiabilityMaybeUpdateForStyleUnion(
}
}
+RespectImageOrientationEnum
+BaseRenderingContext2D::RespectImageOrientationInternal(
+ CanvasImageSource* image_source) {
+ if ((image_source->IsImageBitmap() || image_source->IsImageElement()) &&
+ image_source->WouldTaintOrigin())
+ return kRespectImageOrientation;
+ return RespectImageOrientation();
+}
+
void BaseRenderingContext2D::strokeStyle(
StringOrCanvasGradientOrCanvasPattern& return_value) const {
ConvertCanvasStyleToUnionType(GetState().StrokeStyle(), return_value);
@@ -474,6 +491,8 @@ void BaseRenderingContext2D::setFilter(
}
void BaseRenderingContext2D::scale(double sx, double sy) {
+ // TODO(crbug.com/1140535): Investigate the performance impact of simply
+ // calling the 3d version of this function
cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return;
@@ -496,6 +515,33 @@ void BaseRenderingContext2D::scale(double sx, double sy) {
path_.Transform(AffineTransform().ScaleNonUniform(1.0 / fsx, 1.0 / fsy));
}
+void BaseRenderingContext2D::scale(double sx, double sy, double sz) {
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
+ if (!c)
+ return;
+
+ if (!std::isfinite(sx) || !std::isfinite(sy) || !std::isfinite(sz))
+ return;
+
+ TransformationMatrix new_transform = GetState().GetTransform();
+ float fsx = clampTo<float>(sx);
+ float fsy = clampTo<float>(sy);
+ float fsz = clampTo<float>(sz);
+ new_transform.Scale3d(fsx, fsy, fsz);
+ if (GetState().GetTransform() == new_transform)
+ return;
+
+ ModifiableState().SetTransform(new_transform);
+ if (!GetState().IsTransformInvertible())
+ return;
+
+ // SkCanvas has no 3d scale method for now
+ TransformationMatrix scale_matrix =
+ TransformationMatrix().Scale3d(fsx, fsy, fsz);
+ c->concat(TransformationMatrix::ToSkM44(scale_matrix));
+ path_.Transform(scale_matrix);
+}
+
void BaseRenderingContext2D::rotate(double angle_in_radians) {
cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
@@ -516,10 +562,70 @@ void BaseRenderingContext2D::rotate(double angle_in_radians) {
path_.Transform(AffineTransform().RotateRadians(-angle_in_radians));
}
+// All angles are in radians
+void BaseRenderingContext2D::rotate3d(double rx, double ry, double rz) {
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
+ if (!c)
+ return;
+
+ if (!std::isfinite(rx) || !std::isfinite(ry) || !std::isfinite(rz))
+ return;
+
+ TransformationMatrix rotation_matrix =
+ TransformationMatrix().Rotate3d(rad2deg(rx), rad2deg(ry), rad2deg(rz));
+
+ // Check if the transformation is a no-op and early out if that is the case.
+ TransformationMatrix new_transform =
+ GetState().GetTransform().Rotate3d(rad2deg(rx), rad2deg(ry), rad2deg(rz));
+ if (GetState().GetTransform() == new_transform)
+ return;
+
+ // Must call setTransform to set the IsTransformInvertible flag.
+ ModifiableState().SetTransform(new_transform);
+ if (!GetState().IsTransformInvertible())
+ return;
+
+ c->concat(TransformationMatrix::ToSkM44(rotation_matrix));
+ path_.Transform(rotation_matrix.Inverse());
+}
+
+void BaseRenderingContext2D::rotateAxis(double axisX,
+ double axisY,
+ double axisZ,
+ double angle_in_radians) {
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
+ if (!c)
+ return;
+
+ if (!std::isfinite(axisX) || !std::isfinite(axisY) || !std::isfinite(axisZ) ||
+ !std::isfinite(angle_in_radians))
+ return;
+
+ TransformationMatrix rotation_matrix = TransformationMatrix().Rotate3d(
+ axisX, axisY, axisZ, rad2deg(angle_in_radians));
+
+ // Check if the transformation is a no-op and early out if that is the case.
+ TransformationMatrix new_transform = GetState().GetTransform().Rotate3d(
+ axisX, axisY, axisZ, rad2deg(angle_in_radians));
+ if (GetState().GetTransform() == new_transform)
+ return;
+
+ // Must call setTransform to set the IsTransformInvertible flag.
+ ModifiableState().SetTransform(new_transform);
+ if (!GetState().IsTransformInvertible())
+ return;
+
+ c->concat(TransformationMatrix::ToSkM44(rotation_matrix));
+ path_.Transform(rotation_matrix.Inverse());
+}
+
void BaseRenderingContext2D::translate(double tx, double ty) {
+ // TODO(crbug.com/1140535): Investigate the performance impact of simply
+ // calling the 3d version of this function
cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return;
+
if (!GetState().IsTransformInvertible())
return;
@@ -537,16 +643,144 @@ void BaseRenderingContext2D::translate(double tx, double ty) {
ModifiableState().SetTransform(new_transform);
if (!GetState().IsTransformInvertible())
return;
+
c->translate(ftx, fty);
path_.Transform(AffineTransform().Translate(-ftx, -fty));
}
+void BaseRenderingContext2D::translate(double tx, double ty, double tz) {
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
+ if (!c)
+ return;
+
+ if (!std::isfinite(tx) || !std::isfinite(ty) || !std::isfinite(tz))
+ return;
+
+ // clamp to float to avoid float cast overflow when used as SkScalar
+ float ftx = clampTo<float>(tx);
+ float fty = clampTo<float>(ty);
+ float ftz = clampTo<float>(ty);
+
+ TransformationMatrix translation_matrix =
+ TransformationMatrix().Translate3d(ftx, fty, ftz);
+
+ // Check if the transformation is a no-op and early out if that is the case.
+ TransformationMatrix new_transform =
+ GetState().GetTransform().Translate3d(ftx, fty, ftz);
+ if (GetState().GetTransform() == new_transform)
+ return;
+
+ // We need to call SetTransform() to set the IsTransformInvertible flag.
+ ModifiableState().SetTransform(new_transform);
+ if (!GetState().IsTransformInvertible())
+ return;
+
+ c->concat(TransformationMatrix::ToSkM44(translation_matrix));
+ path_.Transform(translation_matrix.Inverse());
+}
+
+void BaseRenderingContext2D::perspective(double length) {
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
+ if (!c)
+ return;
+
+ if (length == 0 || !std::isfinite(length))
+ return;
+
+ float flength = clampTo<float>(length);
+
+ TransformationMatrix perspective_matrix =
+ TransformationMatrix().ApplyPerspective(flength);
+
+ // Check if the transformation is a no-op and early out if that is the case.
+ TransformationMatrix new_transform =
+ GetState().GetTransform().ApplyPerspective(flength);
+ if (GetState().GetTransform() == new_transform)
+ return;
+
+ // We need to call SetTransform() to set the IsTransformInvertible flag.
+ ModifiableState().SetTransform(new_transform);
+ if (!GetState().IsTransformInvertible())
+ return;
+
+ c->concat(TransformationMatrix::ToSkM44(perspective_matrix));
+ path_.Transform(perspective_matrix.Inverse());
+}
+
+void BaseRenderingContext2D::transform(double m11,
+ double m12,
+ double m13,
+ double m14,
+ double m21,
+ double m22,
+ double m23,
+ double m24,
+ double m31,
+ double m32,
+ double m33,
+ double m34,
+ double m41,
+ double m42,
+ double m43,
+ double m44) {
+ cc::PaintCanvas* c = GetOrCreatePaintCanvas();
+ if (!c)
+ return;
+
+ if (!std::isfinite(m11) || !std::isfinite(m12) || !std::isfinite(m13) ||
+ !std::isfinite(m14) || !std::isfinite(m21) || !std::isfinite(m22) ||
+ !std::isfinite(m23) || !std::isfinite(m24) || !std::isfinite(m31) ||
+ !std::isfinite(m32) || !std::isfinite(m33) || !std::isfinite(m34) ||
+ !std::isfinite(m41) || !std::isfinite(m42) || !std::isfinite(m43) ||
+ !std::isfinite(m44))
+ return;
+
+ // clamp to float to avoid float cast overflow when used as SkScalar
+ float fm11 = clampTo<float>(m11);
+ float fm12 = clampTo<float>(m12);
+ float fm13 = clampTo<float>(m13);
+ float fm14 = clampTo<float>(m14);
+ float fm21 = clampTo<float>(m21);
+ float fm22 = clampTo<float>(m22);
+ float fm23 = clampTo<float>(m23);
+ float fm24 = clampTo<float>(m24);
+ float fm31 = clampTo<float>(m31);
+ float fm32 = clampTo<float>(m32);
+ float fm33 = clampTo<float>(m33);
+ float fm34 = clampTo<float>(m34);
+ float fm41 = clampTo<float>(m41);
+ float fm42 = clampTo<float>(m42);
+ float fm43 = clampTo<float>(m43);
+ float fm44 = clampTo<float>(m44);
+
+ TransformationMatrix transform =
+ TransformationMatrix(fm11, fm12, fm13, fm14, fm21, fm22, fm23, fm24, fm31,
+ fm32, fm33, fm34, fm41, fm42, fm43, fm44);
+
+ // Check if the transformation is a no-op and early out if that is the case.
+ TransformationMatrix new_transform = GetState().GetTransform() * transform;
+ if (GetState().GetTransform() == new_transform)
+ return;
+
+ // Must call setTransform to set the IsTransformInvertible flag.
+ ModifiableState().SetTransform(new_transform);
+ if (!GetState().IsTransformInvertible())
+ return;
+
+ c->concat(TransformationMatrix::ToSkM44(transform));
+ path_.Transform(transform.Inverse());
+}
+
void BaseRenderingContext2D::transform(double m11,
double m12,
double m21,
double m22,
double dx,
double dy) {
+ // TODO(crbug.com/1140535) Investigate the performance implications of simply
+ // calling the 3d version above with:
+ // transform(m11, m12, 0, 0, m21, m22, 0, 0, 0, 0, 1, 0, dx, dy, 0, 1);
+
cc::PaintCanvas* c = GetOrCreatePaintCanvas();
if (!c)
return;
@@ -572,7 +806,7 @@ void BaseRenderingContext2D::transform(double m11,
if (!GetState().IsTransformInvertible())
return;
- c->concat(TransformationMatrixToSkMatrix(transform));
+ c->concat(TransformationMatrix::ToSkM44(transform));
path_.Transform(transform.Inverse());
}
@@ -590,7 +824,8 @@ void BaseRenderingContext2D::resetTransform() {
// resetTransform() resolves the non-invertible CTM state.
ModifiableState().ResetTransform();
- c->setMatrix(TransformationMatrixToSkMatrix(TransformationMatrix()));
+ // Set the SkCanvas' matrix to identity.
+ c->setMatrix(SkM44());
if (invertible_ctm)
path_.Transform(ctm);
@@ -611,37 +846,77 @@ void BaseRenderingContext2D::setTransform(double m11,
return;
resetTransform();
- // clamp to float to avoid float cast overflow when used as SkScalar
- float fm11 = clampTo<float>(m11);
- float fm12 = clampTo<float>(m12);
- float fm21 = clampTo<float>(m21);
- float fm22 = clampTo<float>(m22);
- float fdx = clampTo<float>(dx);
- float fdy = clampTo<float>(dy);
+ transform(m11, m12, m21, m22, dx, dy);
+}
- transform(fm11, fm12, fm21, fm22, fdx, fdy);
+void BaseRenderingContext2D::setTransform(double m11,
+ double m12,
+ double m13,
+ double m14,
+ double m21,
+ double m22,
+ double m23,
+ double m24,
+ double m31,
+ double m32,
+ double m33,
+ double m34,
+ double m41,
+ double m42,
+ double m43,
+ double m44) {
+ if (!std::isfinite(m11) || !std::isfinite(m12) || !std::isfinite(m13) ||
+ !std::isfinite(m14) || !std::isfinite(m21) || !std::isfinite(m22) ||
+ !std::isfinite(m23) || !std::isfinite(m24) || !std::isfinite(m31) ||
+ !std::isfinite(m32) || !std::isfinite(m33) || !std::isfinite(m34) ||
+ !std::isfinite(m41) || !std::isfinite(m42) || !std::isfinite(m43) ||
+ !std::isfinite(m44))
+ return;
+
+ resetTransform();
+ transform(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41,
+ m42, m43, m44);
}
-void BaseRenderingContext2D::setTransform(DOMMatrix2DInit* transform,
+void BaseRenderingContext2D::setTransform(DOMMatrixInit* transform,
ExceptionState& exception_state) {
DOMMatrixReadOnly* m =
- DOMMatrixReadOnly::fromMatrix2D(transform, exception_state);
+ DOMMatrixReadOnly::fromMatrix(transform, exception_state);
if (!m)
return;
- setTransform(m->m11(), m->m12(), m->m21(), m->m22(), m->m41(), m->m42());
+ // The new canvas 2d API supports 3d transforms.
+ // https://github.com/fserb/canvas2D/blob/master/spec/perspective-transforms.md
+ // If it is not enabled, throw 3d information away.
+ if (RuntimeEnabledFeatures::NewCanvas2DAPIEnabled()) {
+ setTransform(m->m11(), m->m12(), m->m13(), m->m14(), m->m21(), m->m22(),
+ m->m23(), m->m24(), m->m31(), m->m32(), m->m33(), m->m34(),
+ m->m41(), m->m42(), m->m43(), m->m44());
+ } else {
+ setTransform(m->m11(), m->m12(), m->m21(), m->m22(), m->m41(), m->m42());
+ }
}
DOMMatrix* BaseRenderingContext2D::getTransform() {
const TransformationMatrix& t = GetState().GetTransform();
DOMMatrix* m = DOMMatrix::Create();
- m->setA(t.A());
- m->setB(t.B());
- m->setC(t.C());
- m->setD(t.D());
- m->setE(t.E());
- m->setF(t.F());
+ m->setM11(t.M11());
+ m->setM12(t.M12());
+ m->setM13(t.M13());
+ m->setM14(t.M14());
+ m->setM21(t.M21());
+ m->setM22(t.M22());
+ m->setM23(t.M23());
+ m->setM24(t.M24());
+ m->setM31(t.M31());
+ m->setM32(t.M32());
+ m->setM33(t.M33());
+ m->setM34(t.M34());
+ m->setM41(t.M41());
+ m->setM42(t.M42());
+ m->setM43(t.M43());
+ m->setM44(t.M44());
return m;
}
@@ -983,63 +1258,6 @@ static inline void ClipRectsToImageRect(const FloatRect& image_rect,
dst_rect->Move(offset);
}
-static inline CanvasImageSource* ToImageSourceInternal(
- const CanvasImageSourceUnion& value,
- ExceptionState& exception_state) {
- if (value.IsCSSImageValue()) {
- return value.GetAsCSSImageValue();
- }
- if (value.IsHTMLImageElement())
- return value.GetAsHTMLImageElement();
- if (value.IsHTMLVideoElement()) {
- HTMLVideoElement* video = value.GetAsHTMLVideoElement();
- video->VideoWillBeDrawnToCanvas();
- return video;
- }
- if (value.IsSVGImageElement())
- return value.GetAsSVGImageElement();
- if (value.IsHTMLCanvasElement()) {
- if (static_cast<HTMLCanvasElement*>(value.GetAsHTMLCanvasElement())
- ->Size()
- .IsEmpty()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kInvalidStateError,
- "The image argument is a canvas element with a width "
- "or height of 0.");
- return nullptr;
- }
- return value.GetAsHTMLCanvasElement();
- }
- if (value.IsImageBitmap()) {
- if (static_cast<ImageBitmap*>(value.GetAsImageBitmap())->IsNeutered()) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- "The image source is detached");
- return nullptr;
- }
- return value.GetAsImageBitmap();
- }
- if (value.IsOffscreenCanvas()) {
- if (static_cast<OffscreenCanvas*>(value.GetAsOffscreenCanvas())
- ->IsNeutered()) {
- exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
- "The image source is detached");
- return nullptr;
- }
- if (static_cast<OffscreenCanvas*>(value.GetAsOffscreenCanvas())
- ->Size()
- .IsEmpty()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kInvalidStateError,
- "The image argument is an OffscreenCanvas element "
- "with a width or height of 0.");
- return nullptr;
- }
- return value.GetAsOffscreenCanvas();
- }
- NOTREACHED();
- return nullptr;
-}
-
void BaseRenderingContext2D::drawImage(
ScriptState* script_state,
const CanvasImageSourceUnion& image_source,
@@ -1047,10 +1265,11 @@ void BaseRenderingContext2D::drawImage(
double y,
ExceptionState& exception_state) {
CanvasImageSource* image_source_internal =
- ToImageSourceInternal(image_source, exception_state);
+ ToCanvasImageSource(image_source, exception_state);
if (!image_source_internal)
return;
- RespectImageOrientationEnum respect_orientation = RespectImageOrientation();
+ RespectImageOrientationEnum respect_orientation =
+ RespectImageOrientationInternal(image_source_internal);
FloatSize default_object_size(Width(), Height());
FloatSize source_rect_size = image_source_internal->ElementSize(
default_object_size, respect_orientation);
@@ -1070,12 +1289,13 @@ void BaseRenderingContext2D::drawImage(
double height,
ExceptionState& exception_state) {
CanvasImageSource* image_source_internal =
- ToImageSourceInternal(image_source, exception_state);
+ ToCanvasImageSource(image_source, exception_state);
if (!image_source_internal)
return;
FloatSize default_object_size(this->Width(), this->Height());
FloatSize source_rect_size = image_source_internal->ElementSize(
- default_object_size, RespectImageOrientation());
+ default_object_size,
+ RespectImageOrientationInternal(image_source_internal));
drawImage(script_state, image_source_internal, 0, 0, source_rect_size.Width(),
source_rect_size.Height(), x, y, width, height, exception_state);
}
@@ -1093,7 +1313,7 @@ void BaseRenderingContext2D::drawImage(
double dh,
ExceptionState& exception_state) {
CanvasImageSource* image_source_internal =
- ToImageSourceInternal(image_source, exception_state);
+ ToCanvasImageSource(image_source, exception_state);
if (!image_source_internal)
return;
drawImage(script_state, image_source_internal, sx, sy, sw, sh, dx, dy, dw, dh,
@@ -1131,12 +1351,14 @@ bool BaseRenderingContext2D::ShouldDrawImageAntialiased(
dest_rect.Height() * fabs(height_expansion) < 1;
}
-void BaseRenderingContext2D::DrawImageInternal(cc::PaintCanvas* c,
- CanvasImageSource* image_source,
- Image* image,
- const FloatRect& src_rect,
- const FloatRect& dst_rect,
- const PaintFlags* flags) {
+void BaseRenderingContext2D::DrawImageInternal(
+ cc::PaintCanvas* c,
+ CanvasImageSource* image_source,
+ Image* image,
+ const FloatRect& src_rect,
+ const FloatRect& dst_rect,
+ const SkSamplingOptions& sampling,
+ const PaintFlags* flags) {
int initial_save_count = c->getSaveCount();
PaintFlags image_flags = *flags;
@@ -1177,7 +1399,8 @@ void BaseRenderingContext2D::DrawImageInternal(cc::PaintCanvas* c,
// We always use the image-orientation property on the canvas element
// because the alternative would result in complex rules depending on
// the source of the image.
- RespectImageOrientationEnum respect_orientation = RespectImageOrientation();
+ RespectImageOrientationEnum respect_orientation =
+ RespectImageOrientationInternal(image_source);
FloatRect corrected_src_rect = src_rect;
if (respect_orientation == kRespectImageOrientation &&
!image->HasDefaultOrientation()) {
@@ -1185,7 +1408,7 @@ void BaseRenderingContext2D::DrawImageInternal(cc::PaintCanvas* c,
image->SizeAsFloat(kRespectImageOrientation), src_rect);
}
image_flags.setAntiAlias(ShouldDrawImageAntialiased(dst_rect));
- image->Draw(c, image_flags, dst_rect, corrected_src_rect,
+ image->Draw(c, image_flags, dst_rect, corrected_src_rect, sampling,
respect_orientation, Image::kDoNotClampImageToSourceRect,
Image::kSyncDecode);
} else {
@@ -1263,8 +1486,8 @@ void BaseRenderingContext2D::drawImage(ScriptState* script_state,
FloatRect src_rect = NormalizeRect(FloatRect(fsx, fsy, fsw, fsh));
FloatRect dst_rect = NormalizeRect(FloatRect(fdx, fdy, fdw, fdh));
- FloatSize image_size =
- image_source->ElementSize(default_object_size, RespectImageOrientation());
+ FloatSize image_size = image_source->ElementSize(
+ default_object_size, RespectImageOrientationInternal(image_source));
ClipRectsToImageRect(FloatRect(FloatPoint(), image_size), &src_rect,
&dst_rect);
@@ -1285,8 +1508,11 @@ void BaseRenderingContext2D::drawImage(ScriptState* script_state,
[this, &image_source, &image, &src_rect, dst_rect](
cc::PaintCanvas* c, const PaintFlags* flags) // draw lambda
{
+ SkSamplingOptions sampling(
+ flags ? flags->getFilterQuality() : kNone_SkFilterQuality,
+ SkSamplingOptions::kMedium_asMipmapLinear);
DrawImageInternal(c, image_source, image.get(), src_rect, dst_rect,
- flags);
+ sampling, flags);
},
[this, &dst_rect](const SkIRect& clip_bounds) // overdraw test lambda
{ return RectContainsTransformedRect(dst_rect, clip_bounds); },
@@ -1445,7 +1671,7 @@ CanvasPattern* BaseRenderingContext2D::createPattern(
const String& repetition_type,
ExceptionState& exception_state) {
CanvasImageSource* image_source_internal =
- ToImageSourceInternal(image_source, exception_state);
+ ToCanvasImageSource(image_source, exception_state);
if (!image_source_internal) {
return nullptr;
}
@@ -1483,7 +1709,8 @@ CanvasPattern* BaseRenderingContext2D::createPattern(
String::Format("The canvas %s is 0.",
image_source
->ElementSize(default_object_size,
- RespectImageOrientation())
+ RespectImageOrientationInternal(
+ image_source))
.Width()
? "height"
: "width"));
@@ -1543,56 +1770,44 @@ bool BaseRenderingContext2D::ComputeDirtyRect(
return true;
}
-ImageDataColorSettings*
-BaseRenderingContext2D::GetColorSettingsAsImageDataColorSettings() const {
- ImageDataColorSettings* color_settings = ImageDataColorSettings::Create();
- color_settings->setColorSpace(ColorSpaceAsString());
- if (PixelFormat() == CanvasPixelFormat::kF16)
- color_settings->setStorageFormat(kFloat32ArrayStorageFormatName);
- return color_settings;
-}
-
ImageData* BaseRenderingContext2D::createImageData(
ImageData* image_data,
ExceptionState& exception_state) const {
- ImageData* result = nullptr;
- ImageDataColorSettings* color_settings =
- GetColorSettingsAsImageDataColorSettings();
- result = ImageData::Create(image_data->Size(), color_settings);
- if (!result)
- exception_state.ThrowRangeError("Out of memory at ImageData creation");
- return result;
+ return ImageData::ValidateAndCreate(
+ image_data->Size().Width(), image_data->Size().Height(), base::nullopt,
+ image_data->getSettings(), exception_state,
+ ImageData::Context2DErrorMode);
}
ImageData* BaseRenderingContext2D::createImageData(
int sw,
int sh,
ExceptionState& exception_state) const {
- if (!sw || !sh) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kIndexSizeError,
- String::Format("The source %s is 0.", sw ? "height" : "width"));
- return nullptr;
- }
-
- IntSize size(abs(sw), abs(sh));
- ImageData* result = nullptr;
- ImageDataColorSettings* color_settings =
- GetColorSettingsAsImageDataColorSettings();
- result = ImageData::Create(size, color_settings);
-
- if (!result)
- exception_state.ThrowRangeError("Out of memory at ImageData creation");
- return result;
+ ImageDataSettings* image_data_settings = ImageDataSettings::Create();
+ image_data_settings->setColorSpace(kSRGBCanvasColorSpaceName);
+ image_data_settings->setStorageFormat(kUint8ClampedArrayStorageFormatName);
+ return ImageData::ValidateAndCreate(std::abs(sw), std::abs(sh), base::nullopt,
+ image_data_settings, exception_state,
+ ImageData::Context2DErrorMode);
}
ImageData* BaseRenderingContext2D::createImageData(
- unsigned width,
- unsigned height,
- ImageDataColorSettings* color_settings,
+ unsigned sw,
+ unsigned sh,
+ ImageDataSettings* image_data_settings,
ExceptionState& exception_state) const {
- return ImageData::CreateImageData(width, height, color_settings,
- exception_state);
+ return ImageData::ValidateAndCreate(sw, sh, base::nullopt,
+ image_data_settings, exception_state,
+ ImageData::Context2DErrorMode);
+}
+
+ImageData* BaseRenderingContext2D::getImageData(
+ int sx,
+ int sy,
+ int sw,
+ int sh,
+ ExceptionState& exception_state) {
+ return getImageDataInternal(sx, sy, sw, sh, nullptr, exception_state);
}
ImageData* BaseRenderingContext2D::getImageData(
@@ -1600,6 +1815,18 @@ ImageData* BaseRenderingContext2D::getImageData(
int sy,
int sw,
int sh,
+ ImageDataSettings* image_data_settings,
+ ExceptionState& exception_state) {
+ return getImageDataInternal(sx, sy, sw, sh, image_data_settings,
+ exception_state);
+}
+
+ImageData* BaseRenderingContext2D::getImageDataInternal(
+ int sx,
+ int sy,
+ int sw,
+ int sh,
+ ImageDataSettings* image_data_settings,
ExceptionState& exception_state) {
if (!base::CheckMul(sw, sh).IsValid<int>()) {
exception_state.ThrowRangeError("Out of memory at ImageData creation");
@@ -1643,91 +1870,144 @@ ImageData* BaseRenderingContext2D::getImageData(
return nullptr;
}
- IntRect image_data_rect(sx, sy, sw, sh);
- bool hasResourceProvider = CanCreateCanvas2dResourceProvider();
- ImageDataColorSettings* color_settings =
- GetColorSettingsAsImageDataColorSettings();
- if (!hasResourceProvider || isContextLost()) {
- ImageData* result =
- ImageData::Create(image_data_rect.Size(), color_settings);
- if (!result)
- exception_state.ThrowRangeError("Out of memory at ImageData creation");
- return result;
+ const IntRect image_data_rect(sx, sy, sw, sh);
+
+ if (!image_data_settings) {
+ image_data_settings = ImageDataSettings::Create();
+ image_data_settings->setColorSpace(kSRGBCanvasColorSpaceName);
+ image_data_settings->setStorageFormat(kUint8ClampedArrayStorageFormatName);
+ }
+
+ const ImageDataStorageFormat storage_format =
+ ImageData::GetImageDataStorageFormat(
+ image_data_settings->storageFormat());
+ if (!CanCreateCanvas2dResourceProvider() || isContextLost()) {
+ return ImageData::ValidateAndCreate(sw, sh, base::nullopt,
+ image_data_settings, exception_state,
+ ImageData::Context2DErrorMode);
}
- const CanvasColorParams& color_params = ColorParams();
// Deferred offscreen canvases might have recorded commands, make sure
// that those get drawn here
FinalizeFrame();
- scoped_refptr<StaticBitmapImage> snapshot = GetImage();
// TODO(crbug.com/1101055): Remove the check for NewCanvas2DAPI flag once
// released.
- // New Canvas2D API utilizes willReadFrequently attribute that let the users
- // indicate if a canvas will be read frequently through getImageData, thus
- // uses CPU rendering from the start in such cases. (crbug.com/1090180)
+ // TODO(crbug.com/1090180): New Canvas2D API utilizes willReadFrequently
+ // attribute that let the users indicate if a canvas will be read frequently
+ // through getImageData, thus uses CPU rendering from the start in such cases.
if (!RuntimeEnabledFeatures::NewCanvas2DAPIEnabled()) {
- // GetImagedata is faster in Unaccelerated canvases
- if (IsAccelerated()) {
+ // GetImagedata is faster in Unaccelerated canvases.
+ // In Desynchronized canvas disabling the acceleration will break
+ // putImageData: crbug.com/1112060.
+ if (IsAccelerated() && !IsDesynchronized()) {
DisableAcceleration();
base::UmaHistogramEnumeration("Blink.Canvas.GPUFallbackToCPU",
GPUFallbackToCPUScenario::kGetImageData);
}
}
- size_t size_in_bytes;
- if (!StaticBitmapImage::GetSizeInBytes(image_data_rect, color_params)
- .AssignIfValid(&size_in_bytes) ||
- size_in_bytes > v8::TypedArray::kMaxLength) {
- exception_state.ThrowRangeError("Out of memory at ImageData creation");
- return nullptr;
- }
-
- bool may_have_stray_area =
- IsAccelerated() // GPU readback may fail silently.
- || StaticBitmapImage::MayHaveStrayArea(snapshot, image_data_rect);
- ArrayBufferContents::InitializationPolicy initialization_policy =
- may_have_stray_area ? ArrayBufferContents::kZeroInitialize
- : ArrayBufferContents::kDontInitialize;
+ scoped_refptr<StaticBitmapImage> snapshot = GetImage();
- ArrayBufferContents contents(
- size_in_bytes, 1, ArrayBufferContents::kNotShared, initialization_policy);
- if (contents.DataLength() != size_in_bytes) {
- exception_state.ThrowRangeError("Out of memory at ImageData creation");
- return nullptr;
+ // Compute the ImageData's SkImageInfo;
+ SkImageInfo image_info;
+ {
+ SkColorType color_type = kRGBA_8888_SkColorType;
+ switch (storage_format) {
+ case kUint8ClampedArrayStorageFormat:
+ color_type = kRGBA_8888_SkColorType;
+ break;
+ case kUint16ArrayStorageFormat:
+ color_type = kR16G16B16A16_unorm_SkColorType;
+ break;
+ case kFloat32ArrayStorageFormat:
+ color_type = kRGBA_F32_SkColorType;
+ break;
+ default:
+ NOTREACHED();
+ }
+ sk_sp<SkColorSpace> color_space = CanvasColorSpaceToSkColorSpace(
+ CanvasColorSpaceFromName(image_data_settings->colorSpace()));
+ image_info = SkImageInfo::Make(sw, sh, color_type, kUnpremul_SkAlphaType,
+ color_space);
}
- if (!StaticBitmapImage::CopyToByteArray(
- snapshot,
- base::span<uint8_t>(reinterpret_cast<uint8_t*>(contents.Data()),
- contents.DataLength()),
- image_data_rect, color_params)) {
- exception_state.ThrowRangeError("Failed to copy image data");
- return nullptr;
+ // Compute the size of and allocate |contents|, the ArrayContentsBuffer.
+ ArrayBufferContents contents;
+ const size_t data_size_bytes = image_info.computeMinByteSize();
+ {
+ if (data_size_bytes > std::numeric_limits<unsigned int>::max()) {
+ exception_state.ThrowRangeError(
+ "Buffer size exceeds maximum heap object size.");
+ return nullptr;
+ }
+ if (SkImageInfo::ByteSizeOverflowed(data_size_bytes) ||
+ data_size_bytes > v8::TypedArray::kMaxLength) {
+ exception_state.ThrowRangeError("Out of memory at ImageData creation");
+ return nullptr;
+ }
+ ArrayBufferContents::InitializationPolicy initialization_policy =
+ ArrayBufferContents::kDontInitialize;
+ if (IsAccelerated()) {
+ // GPU readback may fail silently.
+ initialization_policy = ArrayBufferContents::kZeroInitialize;
+ } else if (snapshot) {
+ // Zero-initialize if some of the readback area is out of bounds.
+ if (image_data_rect.X() < 0 || image_data_rect.Y() < 0 ||
+ image_data_rect.MaxX() > snapshot->Size().Width() ||
+ image_data_rect.MaxY() > snapshot->Size().Height()) {
+ initialization_policy = ArrayBufferContents::kZeroInitialize;
+ }
+ }
+ contents =
+ ArrayBufferContents(data_size_bytes, 1, ArrayBufferContents::kNotShared,
+ initialization_policy);
+ if (contents.DataLength() != data_size_bytes) {
+ exception_state.ThrowRangeError("Out of memory at ImageData creation");
+ return nullptr;
+ }
}
- // Convert pixels to proper storage format if needed
- if (PixelFormat() != CanvasColorParams::GetNativeCanvasPixelFormat()) {
- ImageDataStorageFormat storage_format =
- ImageData::GetImageDataStorageFormat(color_settings->storageFormat());
- NotShared<DOMArrayBufferView> array_buffer_view =
- ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
- contents, PixelFormat(), storage_format);
- return ImageData::Create(image_data_rect.Size(), array_buffer_view,
- color_settings);
- }
- if (size_in_bytes > std::numeric_limits<unsigned int>::max()) {
- exception_state.ThrowRangeError(
- "Buffer size exceeds maximum heap object size.");
- return nullptr;
+ // Read pixels into |contents|.
+ if (snapshot) {
+ const bool read_pixels_successful =
+ snapshot->PaintImageForCurrentFrame().readPixels(
+ image_info, contents.Data(), image_info.minRowBytes(), sx, sy);
+ if (!read_pixels_successful) {
+ SkIRect bounds =
+ snapshot->PaintImageForCurrentFrame().GetSkImageInfo().bounds();
+ DCHECK(!bounds.intersect(SkIRect::MakeXYWH(sx, sy, sw, sh)));
+ }
}
- DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(std::move(contents));
- ImageData* imageData = ImageData::Create(
- image_data_rect.Size(),
- NotShared<DOMUint8ClampedArray>(DOMUint8ClampedArray::Create(
- array_buffer, 0, static_cast<unsigned int>(size_in_bytes))),
- color_settings);
+ // Wrap |contents| in an ImageData.
+ DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(std::move(contents));
+ NotShared<DOMArrayBufferView> data_array;
+ switch (storage_format) {
+ case kUint8ClampedArrayStorageFormat: {
+ size_t num_elements = data_size_bytes;
+ data_array = NotShared<DOMArrayBufferView>(
+ DOMUint8ClampedArray::Create(array_buffer, 0, num_elements));
+ break;
+ }
+ case kUint16ArrayStorageFormat: {
+ size_t num_elements = data_size_bytes / 2;
+ data_array = NotShared<DOMArrayBufferView>(
+ DOMUint16Array::Create(array_buffer, 0, num_elements));
+ break;
+ }
+ case kFloat32ArrayStorageFormat: {
+ size_t num_elements = data_size_bytes / 4;
+ data_array = NotShared<DOMArrayBufferView>(
+ DOMFloat32Array::Create(array_buffer, 0, num_elements));
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
+ ImageData* image_data = ImageData::ValidateAndCreate(
+ sw, sh, data_array, image_data_settings, exception_state,
+ ImageData::Context2DErrorMode);
if (!IsPaint2D()) {
int scaled_time = getScaledElapsedTime(
@@ -1740,8 +2020,7 @@ ImageData* BaseRenderingContext2D::getImageData(
"Blink.Canvas.GetImageDataScaledDuration.CPU", scaled_time);
}
}
-
- return imageData;
+ return image_data;
}
int BaseRenderingContext2D::getScaledElapsedTime(float width,
@@ -1779,7 +2058,7 @@ void BaseRenderingContext2D::putImageData(ImageData* data,
}
base::TimeTicks start_time = base::TimeTicks::Now();
- if (data->BufferBase()->IsDetached()) {
+ if (data->IsBufferBaseDetached()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"The source data has been detached.");
return;
@@ -1828,32 +2107,39 @@ void BaseRenderingContext2D::putImageData(ImageData* data,
// in sRGB color space and use uint8 pixel storage format. We use RGBA pixel
// order for both ImageData and CanvasResourceProvider, therefore no
// additional swizzling is needed.
- CanvasColorParams data_color_params = data->GetCanvasColorParams();
- CanvasColorParams context_color_params =
- CanvasColorParams(ColorParams().ColorSpace(), PixelFormat(), kNonOpaque);
-
- size_t data_length;
- if (!base::CheckMul(data->Size().Area(), context_color_params.BytesPerPixel())
- .AssignIfValid(&data_length))
- return;
-
- if (data_color_params.ColorSpace() != context_color_params.ColorSpace() ||
- data_color_params.PixelFormat() != context_color_params.PixelFormat() ||
- PixelFormat() == CanvasPixelFormat::kF16) {
- std::unique_ptr<uint8_t[]> converted_pixels(new uint8_t[data_length]);
- if (data->ImageDataInCanvasColorSettings(
- ColorParams().ColorSpace(), PixelFormat(), converted_pixels.get(),
- kRGBAColorType)) {
- PutByteArray(converted_pixels.get(),
- IntSize(data->width(), data->height()), source_rect,
- IntPoint(dest_offset));
+ SkPixmap data_pixmap = data->GetSkPixmap();
+ CanvasColorParams data_color_params(
+ data->GetCanvasColorSpace(),
+ data->GetImageDataStorageFormat() != kUint8ClampedArrayStorageFormat
+ ? CanvasPixelFormat::kF16
+ : CanvasPixelFormat::kUint8,
+ kNonOpaque);
+ if (data_color_params.ColorSpace() != GetCanvas2DColorParams().ColorSpace() ||
+ data_color_params.PixelFormat() !=
+ GetCanvas2DColorParams().PixelFormat() ||
+ GetCanvas2DColorParams().PixelFormat() == CanvasPixelFormat::kF16) {
+ SkImageInfo converted_info = data_pixmap.info();
+ converted_info =
+ converted_info.makeColorType(GetCanvas2DColorParams().GetSkColorType());
+ converted_info = converted_info.makeColorSpace(
+ GetCanvas2DColorParams().GetSkColorSpace());
+ if (converted_info.colorType() == kN32_SkColorType)
+ converted_info = converted_info.makeColorType(kRGBA_8888_SkColorType);
+
+ const size_t converted_data_bytes = converted_info.computeMinByteSize();
+ const size_t converted_row_bytes = converted_info.minRowBytes();
+ if (SkImageInfo::ByteSizeOverflowed(converted_data_bytes))
+ return;
+ std::unique_ptr<uint8_t[]> converted_pixels(
+ new uint8_t[converted_data_bytes]);
+ if (data_pixmap.readPixels(converted_info, converted_pixels.get(),
+ converted_row_bytes)) {
+ PutByteArray(
+ SkPixmap(converted_info, converted_pixels.get(), converted_row_bytes),
+ source_rect, IntPoint(dest_offset));
}
} else {
- // TODO(crbug.com/1115317): PutByteArray works with uint8 only. It should be
- // compatible with uint16 and float32.
- PutByteArray(data->data().GetAsUint8ClampedArray()->Data(),
- IntSize(data->width(), data->height()), source_rect,
- IntPoint(dest_offset));
+ PutByteArray(data_pixmap, source_rect, IntPoint(dest_offset));
}
if (!IsPaint2D()) {
@@ -1871,59 +2157,37 @@ void BaseRenderingContext2D::putImageData(ImageData* data,
DidDraw(dest_rect);
}
-void BaseRenderingContext2D::PutByteArray(const unsigned char* source,
- const IntSize& source_size,
+void BaseRenderingContext2D::PutByteArray(const SkPixmap& source,
const IntRect& source_rect,
const IntPoint& dest_point) {
if (!IsCanvas2DBufferValid())
return;
- uint8_t bytes_per_pixel = ColorParams().BytesPerPixel();
-
- DCHECK_GT(source_rect.Width(), 0);
- DCHECK_GT(source_rect.Height(), 0);
- int origin_x = source_rect.X();
+ DCHECK(IntRect(0, 0, source.width(), source.height()).Contains(source_rect));
int dest_x = dest_point.X() + source_rect.X();
DCHECK_GE(dest_x, 0);
DCHECK_LT(dest_x, Width());
- DCHECK_GE(origin_x, 0);
- DCHECK_LT(origin_x, source_rect.MaxX());
-
- int origin_y = source_rect.Y();
int dest_y = dest_point.Y() + source_rect.Y();
DCHECK_GE(dest_y, 0);
DCHECK_LT(dest_y, Height());
- DCHECK_GE(origin_y, 0);
- DCHECK_LT(origin_y, source_rect.MaxY());
- const base::CheckedNumeric<size_t> src_bytes_per_row_checked =
- base::CheckMul(bytes_per_pixel, source_size.Width());
- if (!src_bytes_per_row_checked.IsValid()) {
- VLOG(1) << "Invalid sizes";
- return;
- }
- const size_t src_bytes_per_row = src_bytes_per_row_checked.ValueOrDie();
- const void* src_addr =
- source + origin_y * src_bytes_per_row + origin_x * bytes_per_pixel;
-
- SkAlphaType alpha_type;
- if (kOpaque == ColorParams().GetOpacityMode()) {
+ SkImageInfo info =
+ source.info().makeWH(source_rect.Width(), source_rect.Height());
+ if (kOpaque == GetCanvas2DColorParams().GetOpacityMode()) {
// If the surface is opaque, tell it that we are writing opaque
// pixels. Writing non-opaque pixels to opaque is undefined in
// Skia. There is some discussion about whether it should be
// defined in skbug.com/6157. For now, we can get the desired
// behavior (memcpy) by pretending the write is opaque.
- alpha_type = kOpaque_SkAlphaType;
+ info = info.makeAlphaType(kOpaque_SkAlphaType);
} else {
- alpha_type = kUnpremul_SkAlphaType;
+ info = info.makeAlphaType(kUnpremul_SkAlphaType);
}
-
- SkImageInfo info = SkImageInfo::Make(
- source_rect.Width(), source_rect.Height(), ColorParams().GetSkColorType(),
- alpha_type, ColorParams().GetSkColorSpace());
if (info.colorType() == kN32_SkColorType)
info = info.makeColorType(kRGBA_8888_SkColorType);
- WritePixels(info, src_addr, src_bytes_per_row, dest_x, dest_y);
+
+ WritePixels(info, source.addr(source_rect.X(), source_rect.Y()),
+ source.rowBytes(), dest_x, dest_y);
}
void BaseRenderingContext2D::InflateStrokeRect(FloatRect& rect) const {
@@ -2077,6 +2341,10 @@ String BaseRenderingContext2D::fontKerning() const {
return FontDescription::ToString(GetState().GetFontKerning());
}
+String BaseRenderingContext2D::fontStretch() const {
+ return FontDescription::ToString(GetState().GetFontStretch());
+}
+
String BaseRenderingContext2D::fontVariantCaps() const {
return FontDescription::ToString(GetState().GetFontVariantCaps());
}
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
index 57554d72d86..679622118be 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/geometry/dom_matrix.h"
#include "third_party/blink/renderer/core/html/canvas/image_data.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.h"
+#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h"
@@ -24,9 +25,6 @@ class Color;
class Image;
class Path2D;
-typedef CSSImageValueOrHTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrImageBitmapOrOffscreenCanvas
- CanvasImageSourceUnion;
-
class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
public CanvasPath {
public:
@@ -82,21 +80,61 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
void reset();
void scale(double sx, double sy);
+ void scale(double sx, double sy, double sz);
void rotate(double angle_in_radians);
+ void rotate3d(double rx, double ry, double rz);
+ void rotateAxis(double axisX,
+ double axisY,
+ double axisZ,
+ double angle_in_radians);
void translate(double tx, double ty);
+ void translate(double tx, double ty, double tz);
+ void perspective(double length);
void transform(double m11,
double m12,
double m21,
double m22,
double dx,
double dy);
+ void transform(double m11,
+ double m12,
+ double m13,
+ double m14,
+ double m21,
+ double m22,
+ double m23,
+ double m24,
+ double m31,
+ double m32,
+ double m33,
+ double m34,
+ double m41,
+ double m42,
+ double m43,
+ double m44);
+ void setTransform(double m11,
+ double m12,
+ double m13,
+ double m14,
+ double m21,
+ double m22,
+ double m23,
+ double m24,
+ double m31,
+ double m32,
+ double m33,
+ double m34,
+ double m41,
+ double m42,
+ double m43,
+ double m44);
void setTransform(double m11,
double m12,
double m21,
double m22,
double dx,
double dy);
- void setTransform(DOMMatrix2DInit*, ExceptionState&);
+ void setTransform(DOMMatrixInit*, ExceptionState&);
virtual DOMMatrix* getTransform();
virtual void resetTransform();
@@ -185,16 +223,25 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
ImageData* createImageData(int width, int height, ExceptionState&) const;
ImageData* createImageData(unsigned,
unsigned,
- ImageDataColorSettings*,
+ ImageDataSettings*,
ExceptionState&) const;
// For deferred canvases this will have the side effect of drawing recorded
// commands in order to finalize the frame
- virtual ImageData* getImageData(int sx,
- int sy,
- int sw,
- int sh,
- ExceptionState&);
+ ImageData* getImageData(int sx, int sy, int sw, int sh, ExceptionState&);
+ ImageData* getImageData(int sx,
+ int sy,
+ int sw,
+ int sh,
+ ImageDataSettings*,
+ ExceptionState&);
+ virtual ImageData* getImageDataInternal(int sx,
+ int sy,
+ int sw,
+ int sh,
+ ImageDataSettings*,
+ ExceptionState&);
+
void putImageData(ImageData*, int dx, int dy, ExceptionState&);
void putImageData(ImageData*,
int dx,
@@ -244,17 +291,15 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
virtual bool HasAlpha() const = 0;
+ virtual bool IsDesynchronized() const {
+ NOTREACHED();
+ return false;
+ }
+
virtual bool isContextLost() const = 0;
virtual void WillDrawImage(CanvasImageSource*) const {}
- virtual String ColorSpaceAsString() const {
- return kSRGBCanvasColorSpaceName;
- }
- virtual CanvasPixelFormat PixelFormat() const {
- return CanvasColorParams::GetNativeCanvasPixelFormat();
- }
-
void RestoreMatrixClipStack(cc::PaintCanvas*) const;
String textAlign() const;
@@ -268,6 +313,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
String textRendering() const;
String fontKerning() const;
+ String fontStretch() const;
String fontVariantCaps() const;
void Trace(Visitor*) const override;
@@ -350,7 +396,10 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
void UnwindStateStack();
- virtual CanvasColorParams ColorParams() const { return CanvasColorParams(); }
+ // The implementations of this will query the CanvasColorParams from the
+ // CanvasRenderingContext.
+ virtual CanvasColorParams GetCanvas2DColorParams() const = 0;
+
virtual bool WritePixels(const SkImageInfo& orig_info,
const void* pixels,
size_t row_bytes,
@@ -389,6 +438,15 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
static const char kNormalKerningString[];
static const char kNoneKerningString[];
static const char kNormalVariantString[];
+ static const char kUltraCondensedString[];
+ static const char kExtraCondensedString[];
+ static const char kCondensedString[];
+ static const char kSemiCondensedString[];
+ static const char kNormalStretchString[];
+ static const char kSemiExpandedString[];
+ static const char kExpandedString[];
+ static const char kExtraExpandedString[];
+ static const char kUltraExpandedString[];
static const char kSmallCapsVariantString[];
static const char kAllSmallCapsVariantString[];
static const char kPetiteVariantString[];
@@ -434,6 +492,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
Image*,
const FloatRect& src_rect,
const FloatRect& dst_rect,
+ const SkSamplingOptions&,
const PaintFlags*);
void ClipInternal(const Path&, const String& winding_rule_string);
@@ -464,10 +523,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
// such as tainting from a filter applied to the canvas.
void SetOriginTaintedByContent();
- ImageDataColorSettings* GetColorSettingsAsImageDataColorSettings() const;
-
- void PutByteArray(const unsigned char* source,
- const IntSize& source_size,
+ void PutByteArray(const SkPixmap& source,
const IntRect& source_rect,
const IntPoint& dest_point);
virtual bool IsCanvas2DBufferValid() const {
@@ -482,6 +538,9 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin,
void IdentifiabilityMaybeUpdateForStyleUnion(
const StringOrCanvasGradientOrCanvasPattern& style);
+ RespectImageOrientationEnum RespectImageOrientationInternal(
+ CanvasImageSource*);
+
bool origin_tainted_by_content_;
DISALLOW_COPY_AND_ASSIGN(BaseRenderingContext2D);
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc
new file mode 100644
index 00000000000..87478d8b386
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.cc
@@ -0,0 +1,187 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.h"
+#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
+#include "third_party/blink/renderer/core/layout/layout_block_flow.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_child_layout_context.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
+#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
+#include "third_party/blink/renderer/core/paint/paint_info.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
+#include "third_party/blink/renderer/platform/fonts/font_description.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
+#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
+
+namespace blink {
+
+void CanvasFormattedText::Trace(Visitor* visitor) const {
+ visitor->Trace(text_runs_);
+ ScriptWrappable::Trace(visitor);
+}
+
+CanvasFormattedText* CanvasFormattedText::Create(
+ ExecutionContext* execution_context,
+ const String text) {
+ CanvasFormattedText* canvas_formatted_text =
+ MakeGarbageCollected<CanvasFormattedText>(execution_context);
+ CanvasFormattedTextRun* run =
+ MakeGarbageCollected<CanvasFormattedTextRun>(execution_context, text);
+ canvas_formatted_text->text_runs_.push_back(run);
+ canvas_formatted_text->block_->AddChild(run->GetLayoutObject());
+ return canvas_formatted_text;
+}
+
+CanvasFormattedText::CanvasFormattedText(ExecutionContext* execution_context) {
+ scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
+ style->SetDisplay(EDisplay::kBlock);
+ // Refrain from extending the use of document, apart from creating layout
+ // block flow. In the future we should handle execution_context's from worker
+ // threads that do not have a document.
+ auto* window = To<LocalDOMWindow>(execution_context);
+ block_ = LayoutBlockFlow::CreateAnonymous(window->document(), style,
+ LegacyLayout::kAuto);
+ block_->SetIsLayoutNGObjectForCanvasFormattedText(true);
+}
+
+void CanvasFormattedText::Dispose() {
+ // Detach all the anonymous children we added, since block_->Destroy will
+ // destroy them. We want the lifetime of the children to be managed by their
+ // corresponding CanvasFormattedTextRun and not destroyed at this point.
+ while (block_->FirstChild()) {
+ block_->RemoveChild(block_->FirstChild());
+ }
+ AllowDestroyingLayoutObjectInFinalizerScope scope;
+ if (block_)
+ block_->Destroy();
+}
+
+LayoutBlockFlow* CanvasFormattedText::GetLayoutBlock(
+ Document& document,
+ const FontDescription& defaultFont) {
+ scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
+ style->SetDisplay(EDisplay::kBlock);
+ style->SetFontDescription(defaultFont);
+ block_->SetStyle(style);
+ return block_;
+}
+
+CanvasFormattedTextRun* CanvasFormattedText::appendRun(
+ CanvasFormattedTextRun* run,
+ ExceptionState& exception_state) {
+ if (!CheckRunIsNotParented(run, &exception_state))
+ return nullptr;
+ text_runs_.push_back(run);
+ block_->AddChild(run->GetLayoutObject());
+ return run;
+}
+
+CanvasFormattedTextRun* CanvasFormattedText::setRun(
+ unsigned index,
+ CanvasFormattedTextRun* run,
+ ExceptionState& exception_state) {
+ if (!CheckRunsIndexBound(index, &exception_state) ||
+ !CheckRunIsNotParented(run, &exception_state))
+ return nullptr;
+ block_->AddChild(run->GetLayoutObject(),
+ text_runs_[index]->GetLayoutObject());
+ block_->RemoveChild(text_runs_[index]->GetLayoutObject());
+ text_runs_[index] = run;
+ return text_runs_[index];
+}
+
+CanvasFormattedTextRun* CanvasFormattedText::insertRun(
+ unsigned index,
+ CanvasFormattedTextRun* run,
+ ExceptionState& exception_state) {
+ if (!CheckRunIsNotParented(run, &exception_state))
+ return nullptr;
+ if (index == text_runs_.size())
+ return appendRun(run, exception_state);
+ if (!CheckRunsIndexBound(index, &exception_state))
+ return nullptr;
+ block_->AddChild(run->GetLayoutObject(),
+ text_runs_[index]->GetLayoutObject());
+ text_runs_.insert(index, run);
+ return text_runs_[index];
+}
+
+void CanvasFormattedText::deleteRun(unsigned index,
+ unsigned length,
+ ExceptionState& exception_state) {
+ if (!CheckRunsIndexBound(index, &exception_state))
+ return;
+ // Protect against overflow, do not perform math like index + length <
+ // text_runs_.size(). The length passed in can be close to INT_MAX.
+ if (text_runs_.size() - index < length) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kIndexSizeError,
+ ExceptionMessages::IndexExceedsMaximumBound("length", length,
+ text_runs_.size() - index));
+ return;
+ }
+
+ for (wtf_size_t i = index; i < index + length; i++) {
+ block_->RemoveChild(text_runs_[i]->GetLayoutObject());
+ }
+ block_->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation(
+ layout_invalidation_reason::kCanvasFormattedTextRunChange);
+ text_runs_.EraseAt(static_cast<wtf_size_t>(index),
+ static_cast<wtf_size_t>(length));
+}
+
+sk_sp<PaintRecord> CanvasFormattedText::PaintFormattedText(
+ Document& document,
+ const FontDescription& font,
+ double x,
+ double y,
+ double wrap_width,
+ FloatRect& bounds) {
+ LayoutBlockFlow* block = GetLayoutBlock(document, font);
+ NGBlockNode block_node(block);
+ NGInlineNode node(block);
+ // Call IsEmptyInline to force prepare layout.
+ if (node.IsEmptyInline())
+ return nullptr;
+
+ // TODO(sushraja) Once we add support for writing mode on the canvas formatted
+ // text, fix this to be not hardcoded horizontal top to bottom.
+ NGConstraintSpaceBuilder builder(
+ WritingMode::kHorizontalTb,
+ {WritingMode::kHorizontalTb, TextDirection::kLtr},
+ /* is_new_fc */ true);
+ LayoutUnit available_logical_width(wrap_width);
+ LogicalSize available_size = {available_logical_width, kIndefiniteSize};
+ builder.SetAvailableSize(available_size);
+ NGConstraintSpace space = builder.ToConstraintSpace();
+ scoped_refptr<const NGLayoutResult> block_results =
+ block_node.Layout(space, nullptr);
+ const auto& fragment =
+ To<NGPhysicalBoxFragment>(block_results->PhysicalFragment());
+ block->RecalcInlineChildrenVisualOverflow();
+ bounds = FloatRect(block->PhysicalVisualOverflowRect());
+
+ PaintController paint_controller(PaintController::Usage::kTransient);
+ paint_controller.UpdateCurrentPaintChunkProperties(nullptr,
+ PropertyTreeState::Root());
+ GraphicsContext graphics_context(paint_controller);
+ PhysicalOffset physical_offset((LayoutUnit(x)), (LayoutUnit(y)));
+ NGBoxFragmentPainter box_fragment_painter(fragment);
+ PaintInfo paint_info(graphics_context, CullRect::Infinite(),
+ PaintPhase::kForeground, kGlobalPaintNormalPhase,
+ kPaintLayerPaintingRenderingClipPathAsMask |
+ kPaintLayerPaintingRenderingResourceSubtree);
+ box_fragment_painter.PaintObject(paint_info, physical_offset);
+ paint_controller.CommitNewDisplayItems();
+ paint_controller.FinishCycle();
+ sk_sp<PaintRecord> recording =
+ paint_controller.GetPaintArtifact().GetPaintRecord(
+ PropertyTreeState::Root());
+ return recording;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.h
new file mode 100644
index 00000000000..f3284c1eeba
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.h
@@ -0,0 +1,129 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_FORMATTED_TEXT_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_FORMATTED_TEXT_H_
+
+#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_formatted_text_run.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/bindings/exception_messages.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/text/bidi_resolver.h"
+#include "third_party/blink/renderer/platform/text/bidi_text_run.h"
+#include "third_party/blink/renderer/platform/text/text_direction.h"
+#include "third_party/blink/renderer/platform/text/text_run_iterator.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+
+namespace blink {
+
+class LayoutBlockFlow;
+class FontDescription;
+class Document;
+
+class MODULES_EXPORT CanvasFormattedText final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_PRE_FINALIZER(CanvasFormattedText, Dispose);
+
+ public:
+ static CanvasFormattedText* Create(ExecutionContext* execution_context) {
+ return MakeGarbageCollected<CanvasFormattedText>(execution_context);
+ }
+
+ static CanvasFormattedText* Create(ExecutionContext* execution_context,
+ const String text);
+
+ static CanvasFormattedText* Create(ExecutionContext* execution_context,
+ CanvasFormattedTextRun* run,
+ ExceptionState& exception_state) {
+ CanvasFormattedText* canvas_formatted_text =
+ MakeGarbageCollected<CanvasFormattedText>(execution_context);
+ canvas_formatted_text->appendRun(run, exception_state);
+ return canvas_formatted_text;
+ }
+
+ explicit CanvasFormattedText(ExecutionContext* execution_context);
+ CanvasFormattedText(const CanvasFormattedText&) = delete;
+ CanvasFormattedText& operator=(const CanvasFormattedText&) = delete;
+
+ void Trace(Visitor* visitor) const override;
+
+ unsigned length() const { return text_runs_.size(); }
+
+ bool CheckRunsIndexBound(uint32_t index,
+ ExceptionState* exception_state) const {
+ if (index >= text_runs_.size()) {
+ if (exception_state) {
+ exception_state->ThrowDOMException(
+ DOMExceptionCode::kIndexSizeError,
+ ExceptionMessages::IndexExceedsMaximumBound("index", index,
+ text_runs_.size()));
+ }
+ return false;
+ }
+ return true;
+ }
+
+ bool CheckRunIsNotParented(CanvasFormattedTextRun* run,
+ ExceptionState* exception_state) const {
+ if (run->GetLayoutObject() && run->GetLayoutObject()->Parent()) {
+ if (exception_state) {
+ exception_state->ThrowDOMException(
+ DOMExceptionCode::kInvalidModificationError,
+ "The run is already a part of a formatted text. Remove it from "
+ "that formatted text before insertion.");
+ }
+ return false;
+ }
+ return true;
+ }
+
+ CanvasFormattedTextRun* getRun(unsigned index,
+ ExceptionState& exception_state) const {
+ if (!CheckRunsIndexBound(index, &exception_state))
+ return nullptr;
+ return text_runs_[index];
+ }
+
+ CanvasFormattedTextRun* appendRun(CanvasFormattedTextRun* run,
+ ExceptionState& exception_state);
+
+ CanvasFormattedTextRun* setRun(unsigned index,
+ CanvasFormattedTextRun* run,
+ ExceptionState& exception_state);
+
+ CanvasFormattedTextRun* insertRun(unsigned index,
+ CanvasFormattedTextRun* run,
+ ExceptionState& exception_state);
+
+ void deleteRun(unsigned index, ExceptionState& exception_state) {
+ deleteRun(index, 1, exception_state);
+ }
+
+ void deleteRun(unsigned index,
+ unsigned length,
+ ExceptionState& exception_state);
+
+ LayoutBlockFlow* GetLayoutBlock(Document& document,
+ const FontDescription& defaultFont);
+
+ sk_sp<PaintRecord> PaintFormattedText(Document& document,
+ const FontDescription& font,
+ double x,
+ double y,
+ double wrap_width,
+ FloatRect& bounds);
+
+ void Dispose();
+
+ private:
+ HeapVector<Member<CanvasFormattedTextRun>> text_runs_;
+ LayoutBlockFlow* block_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_FORMATTED_TEXT_H_
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.idl
new file mode 100644
index 00000000000..0e3b846cf6e
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.idl
@@ -0,0 +1,24 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+[
+ RuntimeEnabled=CanvasFormattedText,
+ Exposed=Window
+]
+interface CanvasFormattedText{
+ [CallWith=ExecutionContext] constructor();
+ [CallWith=ExecutionContext] constructor(DOMString text);
+ [CallWith=ExecutionContext, RaisesException] constructor(CanvasFormattedTextRun text);
+
+ [RaisesException] getter CanvasFormattedTextRun getRun(unsigned long index);
+ [RaisesException] CanvasFormattedTextRun appendRun(
+ CanvasFormattedTextRun newRun);
+ [RaisesException] setter CanvasFormattedTextRun setRun(
+ unsigned long index, CanvasFormattedTextRun run);
+ [RaisesException] CanvasFormattedTextRun insertRun(
+ unsigned long index, CanvasFormattedTextRun run);
+ [RaisesException] void deleteRun(unsigned long index);
+ [RaisesException] void deleteRun(unsigned long index, unsigned long length);
+
+ readonly attribute unsigned long length;
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.cc
new file mode 100644
index 00000000000..a09607b2a83
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.cc
@@ -0,0 +1,34 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.h"
+
+namespace blink {
+
+CanvasFormattedTextRun::CanvasFormattedTextRun(
+ ExecutionContext* execution_context,
+ const String text)
+ : text_(text) {
+ scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
+ style->SetDisplay(EDisplay::kInline);
+ // Refrain from extending the use of document, apart from creating layout
+ // text. In the future we should handle execution_context's from worker
+ // threads that do not have a document.
+ auto* window = To<LocalDOMWindow>(execution_context);
+ layout_text_ =
+ LayoutText::CreateAnonymous(*(window->document()), std::move(style),
+ text.Impl(), LegacyLayout::kAuto);
+ layout_text_->SetIsLayoutNGObjectForCanvasFormattedText(true);
+}
+
+void CanvasFormattedTextRun::Dispose() {
+ AllowDestroyingLayoutObjectInFinalizerScope scope;
+ if (layout_text_)
+ layout_text_->Destroy();
+}
+
+void CanvasFormattedTextRun::Trace(Visitor* visitor) const {
+ ScriptWrappable::Trace(visitor);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.h
new file mode 100644
index 00000000000..5818ae82442
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.h
@@ -0,0 +1,50 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_FORMATTED_TEXT_RUN_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_FORMATTED_TEXT_RUN_H_
+
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/layout/layout_text.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+class MODULES_EXPORT CanvasFormattedTextRun final : public ScriptWrappable {
+ DEFINE_WRAPPERTYPEINFO();
+ USING_PRE_FINALIZER(CanvasFormattedTextRun, Dispose);
+
+ public:
+ static CanvasFormattedTextRun* Create(ExecutionContext* execution_context,
+ const String text) {
+ return MakeGarbageCollected<CanvasFormattedTextRun>(execution_context,
+ text);
+ }
+
+ CanvasFormattedTextRun(ExecutionContext*, const String text);
+ CanvasFormattedTextRun(const CanvasFormattedTextRun&) = delete;
+ CanvasFormattedTextRun& operator=(const CanvasFormattedTextRun&) = delete;
+
+ String text() const { return text_; }
+ void setText(const String text) { text_ = text; }
+
+ unsigned length() const { return text_.length(); }
+
+ LayoutText* GetLayoutObject() { return layout_text_; }
+
+ void Trace(Visitor* visitor) const override;
+
+ void Dispose();
+
+ private:
+ String text_;
+
+ LayoutText* layout_text_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_FORMATTED_TEXT_RUN_H_
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.idl
new file mode 100644
index 00000000000..7e1ea4f1a93
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text_run.idl
@@ -0,0 +1,12 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+[
+ RuntimeEnabled=CanvasFormattedText,
+ Exposed=Window
+]
+interface CanvasFormattedTextRun{
+ [CallWith = ExecutionContext] constructor(DOMString text);
+
+ attribute DOMString text;
+}; \ No newline at end of file
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.cc
new file mode 100644
index 00000000000..b388139d389
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.cc
@@ -0,0 +1,82 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h"
+
+#include "third_party/blink/renderer/core/css/cssom/css_url_image_value.h"
+#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
+#include "third_party/blink/renderer/core/html/html_image_element.h"
+#include "third_party/blink/renderer/core/html/media/html_video_element.h"
+#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
+#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
+#include "third_party/blink/renderer/core/svg/svg_image_element.h"
+#include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
+
+namespace blink {
+
+CanvasImageSource* ToCanvasImageSource(const CanvasImageSourceUnion& value,
+ ExceptionState& exception_state) {
+ if (value.IsCSSImageValue())
+ return value.GetAsCSSImageValue();
+ if (value.IsHTMLImageElement())
+ return value.GetAsHTMLImageElement();
+ if (value.IsHTMLVideoElement()) {
+ HTMLVideoElement* video = value.GetAsHTMLVideoElement();
+ video->VideoWillBeDrawnToCanvas();
+ return video;
+ }
+ if (value.IsSVGImageElement())
+ return value.GetAsSVGImageElement();
+ if (value.IsHTMLCanvasElement()) {
+ if (static_cast<HTMLCanvasElement*>(value.GetAsHTMLCanvasElement())
+ ->Size()
+ .IsEmpty()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The image argument is a canvas element with a width "
+ "or height of 0.");
+ return nullptr;
+ }
+ return value.GetAsHTMLCanvasElement();
+ }
+ if (value.IsImageBitmap()) {
+ if (static_cast<ImageBitmap*>(value.GetAsImageBitmap())->IsNeutered()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The image source is detached");
+ return nullptr;
+ }
+ return value.GetAsImageBitmap();
+ }
+ if (value.IsOffscreenCanvas()) {
+ if (static_cast<OffscreenCanvas*>(value.GetAsOffscreenCanvas())
+ ->IsNeutered()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The image source is detached");
+ return nullptr;
+ }
+ if (static_cast<OffscreenCanvas*>(value.GetAsOffscreenCanvas())
+ ->Size()
+ .IsEmpty()) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ "The image argument is an OffscreenCanvas element "
+ "with a width or height of 0.");
+ return nullptr;
+ }
+ return value.GetAsOffscreenCanvas();
+ }
+ if (value.IsVideoFrame()) {
+ auto* video_frame = static_cast<VideoFrame*>(value.GetAsVideoFrame());
+ if (!video_frame->frame()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The VideoFrame has been closed");
+ return nullptr;
+ }
+ return video_frame;
+ }
+ NOTREACHED();
+ return nullptr;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h
new file mode 100644
index 00000000000..f003578953b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_image_source_util.h
@@ -0,0 +1,24 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_IMAGE_SOURCE_UTIL_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_IMAGE_SOURCE_UTIL_H_
+
+#include "third_party/blink/renderer/bindings/modules/v8/canvas_image_source.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+
+namespace blink {
+class CanvasImageSource;
+
+using CanvasImageSourceUnion =
+ CSSImageValueOrHTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrImageBitmapOrOffscreenCanvasOrVideoFrame;
+
+MODULES_EXPORT CanvasImageSource* ToCanvasImageSource(
+ const CanvasImageSourceUnion& value,
+ ExceptionState& exception_state);
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_CANVAS_IMAGE_SOURCE_UTIL_H_
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
index bd3bf105d7a..6a67606bfee 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
@@ -50,10 +50,7 @@ namespace blink {
void CanvasPath::closePath() {
if (path_.IsEmpty())
return;
-
- FloatRect bound_rect = path_.BoundingRect();
- if (bound_rect.Width() || bound_rect.Height())
- path_.CloseSubpath();
+ path_.CloseSubpath();
}
void CanvasPath::moveTo(double double_x, double double_y) {
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
index 22d3464e6e5..b3ef16c347a 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -38,8 +38,6 @@
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h"
#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h"
-#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
-#include "third_party/blink/public/common/privacy_budget/identifiable_surface.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/modules/v8/rendering_context.h"
@@ -245,6 +243,9 @@ void CanvasRenderingContext2D::DidSetSurfaceSize() {
void CanvasRenderingContext2D::Trace(Visitor* visitor) const {
visitor->Trace(hit_region_manager_);
+ visitor->Trace(dispatch_context_lost_event_timer_);
+ visitor->Trace(dispatch_context_restored_event_timer_);
+ visitor->Trace(try_restore_context_event_timer_);
visitor->Trace(filter_operations_);
CanvasRenderingContext::Trace(visitor);
BaseRenderingContext2D::Trace(visitor);
@@ -307,12 +308,8 @@ void CanvasRenderingContext2D::WillDrawImage(CanvasImageSource* source) const {
canvas()->WillDrawImageTo2DContext(source);
}
-String CanvasRenderingContext2D::ColorSpaceAsString() const {
- return CanvasRenderingContext::ColorSpaceAsString();
-}
-
-CanvasColorParams CanvasRenderingContext2D::ColorParams() const {
- return CanvasRenderingContext::ColorParams();
+CanvasColorParams CanvasRenderingContext2D::GetCanvas2DColorParams() const {
+ return CanvasRenderingContext::CanvasRenderingContextColorParams();
}
bool CanvasRenderingContext2D::WritePixels(const SkImageInfo& orig_info,
@@ -330,10 +327,6 @@ void CanvasRenderingContext2D::WillOverwriteCanvas() {
canvas()->GetCanvas2DLayerBridge()->WillOverwriteCanvas();
}
-CanvasPixelFormat CanvasRenderingContext2D::PixelFormat() const {
- return ColorParams().PixelFormat();
-}
-
void CanvasRenderingContext2D::Reset() {
// This is a multiple inheritance bootstrap
BaseRenderingContext2D::reset();
@@ -655,11 +648,7 @@ void CanvasRenderingContext2D::UpdateFilterReferences(
filter_operations_ = filters;
}
-void CanvasRenderingContext2D::ResourceContentChanged(InvalidationModeMask) {
- ResourceElementChanged();
-}
-
-void CanvasRenderingContext2D::ResourceElementChanged() {
+void CanvasRenderingContext2D::ResourceContentChanged(SVGResource*) {
ClearFilterReferences();
GetState().ClearResolvedFilter();
}
@@ -690,20 +679,15 @@ scoped_refptr<StaticBitmapImage> blink::CanvasRenderingContext2D::GetImage() {
return canvas()->GetCanvas2DLayerBridge()->NewImageSnapshot();
}
-ImageData* CanvasRenderingContext2D::getImageData(
+ImageData* CanvasRenderingContext2D::getImageDataInternal(
int sx,
int sy,
int sw,
int sh,
+ ImageDataSettings* image_data_settings,
ExceptionState& exception_state) {
- const IdentifiableSurface surface = IdentifiableSurface::FromTypeAndToken(
- IdentifiableSurface::Type::kCanvasReadback, GetContextType());
- if (IdentifiabilityStudySettings::Get()->ShouldSample(surface)) {
- blink::IdentifiabilityMetricBuilder(ukm_source_id_)
- .Set(surface, 0)
- .Record(ukm_recorder_);
- }
- return BaseRenderingContext2D::getImageData(sx, sy, sw, sh, exception_state);
+ return BaseRenderingContext2D::getImageDataInternal(
+ sx, sy, sw, sh, image_data_settings, exception_state);
}
void CanvasRenderingContext2D::FinalizeFrame() {
@@ -873,6 +857,39 @@ void CanvasRenderingContext2D::setFontKerning(
ModifiableState().SetFontKerning(kerning, Host()->GetFontSelector());
}
+void CanvasRenderingContext2D::setFontStretch(const String& font_stretch) {
+ if (!GetState().HasRealizedFont())
+ setFont(font());
+
+ String font_stretch_string = font_stretch.LowerASCII();
+ FontSelectionValue stretch_vale;
+ if (font_stretch_string == kUltraCondensedString)
+ stretch_vale = UltraCondensedWidthValue();
+ else if (font_stretch_string == kExtraCondensedString)
+ stretch_vale = ExtraCondensedWidthValue();
+ else if (font_stretch_string == kCondensedString)
+ stretch_vale = CondensedWidthValue();
+ else if (font_stretch_string == kSemiCondensedString)
+ stretch_vale = SemiCondensedWidthValue();
+ else if (font_stretch_string == kNormalStretchString)
+ stretch_vale = NormalWidthValue();
+ else if (font_stretch_string == kSemiExpandedString)
+ stretch_vale = SemiExpandedWidthValue();
+ else if (font_stretch_string == kExpandedString)
+ stretch_vale = ExpandedWidthValue();
+ else if (font_stretch_string == kExtraExpandedString)
+ stretch_vale = ExtraExpandedWidthValue();
+ else if (font_stretch_string == kUltraExpandedString)
+ stretch_vale = UltraExpandedWidthValue();
+ else
+ return;
+
+ if (GetState().GetFontStretch() == stretch_vale)
+ return;
+
+ ModifiableState().SetFontStretch(stretch_vale, Host()->GetFontSelector());
+}
+
void CanvasRenderingContext2D::setFontVariantCaps(
const String& font_variant_caps_string) {
if (!GetState().HasRealizedFont())
@@ -952,6 +969,28 @@ TextMetrics* CanvasRenderingContext2D::measureText(const String& text) {
GetState().GetTextAlign(), text);
}
+void CanvasRenderingContext2D::fillFormattedText(
+ CanvasFormattedText* formatted_text,
+ double x,
+ double y,
+ double wrap_width) {
+ if (!formatted_text)
+ return;
+
+ if (!GetState().HasRealizedFont())
+ setFont(font());
+
+ FloatRect bounds;
+ sk_sp<PaintRecord> recording = formatted_text->PaintFormattedText(
+ canvas()->GetDocument(), GetState().GetFontDescription(), x, y,
+ wrap_width, bounds);
+ Draw([recording](cc::PaintCanvas* c, const PaintFlags* flags) // draw lambda
+ { c->drawPicture(recording); },
+ [](const SkIRect& rect) { return false; }, bounds,
+ CanvasRenderingContext2DState::PaintType::kFillPaintType,
+ CanvasRenderingContext2DState::kNoImage);
+}
+
void CanvasRenderingContext2D::DrawTextInternal(
const String& text,
double x,
@@ -1099,8 +1138,8 @@ CanvasRenderingContext2D::getContextAttributes() const {
CanvasRenderingContext2DSettings::Create();
settings->setAlpha(CreationAttributes().alpha);
if (RuntimeEnabledFeatures::CanvasColorManagementEnabled()) {
- settings->setColorSpace(ColorSpaceAsString());
- settings->setPixelFormat(PixelFormatAsString());
+ settings->setColorSpace(GetCanvas2DColorParams().GetColorSpaceAsString());
+ settings->setPixelFormat(GetCanvas2DColorParams().GetPixelFormatAsString());
}
settings->setDesynchronized(Host()->LowLatencyEnabled());
if (RuntimeEnabledFeatures::NewCanvas2DAPIEnabled())
@@ -1151,7 +1190,11 @@ void CanvasRenderingContext2D::DrawFocusRing(const Path& path) {
if (!GetOrCreatePaintCanvas())
return;
- SkColor color = LayoutTheme::GetTheme().FocusRingColor().Rgb();
+ // TODO(crbug.com/929098) Need to pass an appropriate color scheme here.
+ SkColor color =
+ LayoutTheme::GetTheme()
+ .FocusRingColor(ComputedStyle::InitialStyle().UsedColorScheme())
+ .Rgb();
const int kFocusRingWidth = 5;
DrawPlatformFocusRing(path.GetSkPath(), GetPaintCanvas(), color,
/*width=*/kFocusRingWidth, /*radius=*/kFocusRingWidth);
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
index 4e6faada14c..0243cee60c5 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
@@ -31,6 +31,7 @@
#include "base/macros.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_formatted_text.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_rendering_context_2d_settings.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h"
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
@@ -39,6 +40,7 @@
#include "third_party/blink/renderer/core/style/filter_operations.h"
#include "third_party/blink/renderer/core/svg/svg_resource_client.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h"
+#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_formatted_text.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h"
#include "third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h"
#include "third_party/blink/renderer/modules/modules_export.h"
@@ -68,8 +70,8 @@ class HitTestCanvasResult;
class Path2D;
class TextMetrics;
-typedef CSSImageValueOrHTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrImageBitmapOrOffscreenCanvas
- CanvasImageSourceUnion;
+using CanvasImageSourceUnion =
+ CSSImageValueOrHTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrImageBitmapOrOffscreenCanvasOrVideoFrame;
class MODULES_EXPORT CanvasRenderingContext2D final
: public CanvasRenderingContext,
@@ -131,6 +133,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final
void setTextRendering(const String&);
void setFontKerning(const String&);
+ void setFontStretch(const String&);
void setFontVariantCaps(const String&);
void fillText(const String& text, double x, double y);
@@ -141,6 +144,11 @@ class MODULES_EXPORT CanvasRenderingContext2D final
CanvasRenderingContext2DSettings* getContextAttributes() const;
+ void fillFormattedText(CanvasFormattedText* formatted_text,
+ double x,
+ double y,
+ double wrap_width);
+
void drawFocusIfNeeded(Element*);
void drawFocusIfNeeded(Path2D*, Element*);
@@ -165,8 +173,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final
String GetIdFromControl(const Element*) override;
// SVGResourceClient implementation
- void ResourceContentChanged(InvalidationModeMask) override;
- void ResourceElementChanged() override;
+ void ResourceContentChanged(SVGResource*) override;
void UpdateFilterReferences(const FilterOperations&);
void ClearFilterReferences();
@@ -210,13 +217,16 @@ class MODULES_EXPORT CanvasRenderingContext2D final
void Trace(Visitor*) const override;
- ImageData* getImageData(int sx,
- int sy,
- int sw,
- int sh,
- ExceptionState&) override;
+ ImageData* getImageDataInternal(int sx,
+ int sy,
+ int sw,
+ int sh,
+ ImageDataSettings*,
+ ExceptionState&) final;
- CanvasColorParams ColorParamsForTest() const { return ColorParams(); }
+ CanvasColorParams ColorParamsForTest() const {
+ return GetCanvas2DColorParams();
+ }
IdentifiableToken IdentifiableTextToken() const override {
return identifiability_study_helper_.GetToken();
@@ -231,7 +241,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final
}
protected:
- CanvasColorParams ColorParams() const override;
+ CanvasColorParams GetCanvas2DColorParams() const override;
bool WritePixels(const SkImageInfo& orig_info,
const void* pixels,
size_t row_bytes,
@@ -267,14 +277,14 @@ class MODULES_EXPORT CanvasRenderingContext2D final
return CanvasRenderingContext::kContext2D;
}
- String ColorSpaceAsString() const override;
- CanvasPixelFormat PixelFormat() const override;
-
bool IsRenderingContext2D() const override { return true; }
bool IsComposited() const override;
bool IsAccelerated() const override;
bool IsOriginTopLeft() const override;
bool HasAlpha() const override { return CreationAttributes().alpha; }
+ bool IsDesynchronized() const override {
+ return CreationAttributes().desynchronized;
+ }
void SetIsInHiddenPage(bool) override;
void SetIsBeingDisplayed(bool) override;
void Stop() final;
@@ -289,10 +299,12 @@ class MODULES_EXPORT CanvasRenderingContext2D final
LostContextMode context_lost_mode_;
bool context_restorable_;
unsigned try_restore_context_attempt_count_;
- TaskRunnerTimer<CanvasRenderingContext2D> dispatch_context_lost_event_timer_;
- TaskRunnerTimer<CanvasRenderingContext2D>
+ HeapTaskRunnerTimer<CanvasRenderingContext2D>
+ dispatch_context_lost_event_timer_;
+ HeapTaskRunnerTimer<CanvasRenderingContext2D>
dispatch_context_restored_event_timer_;
- TaskRunnerTimer<CanvasRenderingContext2D> try_restore_context_event_timer_;
+ HeapTaskRunnerTimer<CanvasRenderingContext2D>
+ try_restore_context_event_timer_;
FilterOperations filter_operations_;
HashMap<String, FontDescription> fonts_resolved_using_current_style_;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
index 78e1c791ef2..f2ea9e5ee4c 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl
@@ -39,7 +39,8 @@ typedef (CSSImageValue or
HTMLVideoElement or
HTMLCanvasElement or
ImageBitmap or
- OffscreenCanvas) CanvasImageSource;
+ OffscreenCanvas or
+ VideoFrame) CanvasImageSource;
enum CanvasFillRule { "nonzero", "evenodd" };
enum ImageSmoothingQuality {"low", "medium", "high"};
@@ -57,11 +58,22 @@ interface CanvasRenderingContext2D {
// transformations (default transform is the identity matrix)
void scale(unrestricted double x, unrestricted double y);
+ [RuntimeEnabled=NewCanvas2DAPI] void scale(unrestricted double x, unrestricted double y, unrestricted double z);
void rotate(unrestricted double angle);
+ [RuntimeEnabled=NewCanvas2DAPI] void rotate3d(unrestricted double angleX, unrestricted double angleY, unrestricted double angleZ);
+ [RuntimeEnabled=NewCanvas2DAPI] void rotateAxis(unrestricted double axisX, unrestricted double axisY, unrestricted double axisZ, unrestricted double angle);
void translate(unrestricted double x, unrestricted double y);
+ [RuntimeEnabled=NewCanvas2DAPI] void translate(unrestricted double x, unrestricted double y, unrestricted double z);
+ [RuntimeEnabled=NewCanvas2DAPI] void perspective(unrestricted double length);
void transform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f);
+ [RuntimeEnabled=NewCanvas2DAPI] void transform(
+ unrestricted double m11, unrestricted double m12, unrestricted double m13, unrestricted double m14,
+ unrestricted double m21, unrestricted double m22, unrestricted double m23, unrestricted double m24,
+ unrestricted double m31, unrestricted double m32, unrestricted double m33, unrestricted double m34,
+ unrestricted double m41, unrestricted double m42, unrestricted double m43, unrestricted double m44
+ );
void setTransform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f);
- [RaisesException] void setTransform(optional DOMMatrix2DInit transform = {});
+ [RaisesException] void setTransform(optional DOMMatrixInit transform = {});
DOMMatrix getTransform();
void resetTransform();
@@ -116,6 +128,9 @@ interface CanvasRenderingContext2D {
void strokeText(DOMString text, unrestricted double x, unrestricted double y, optional unrestricted double maxWidth);
TextMetrics measureText(DOMString text);
+ // Render entire CanvasFormattedText with line wrapping (one-shot)
+ [RuntimeEnabled=CanvasFormattedText] void fillFormattedText(CanvasFormattedText formattedText, double x, double y, double wrapWidth);
+
// drawing images
[CallWith=ScriptState, RaisesException] void drawImage(CanvasImageSource image, unrestricted double x, unrestricted double y);
[CallWith=ScriptState, RaisesException] void drawImage(CanvasImageSource image, unrestricted double x, unrestricted double y, unrestricted double width, unrestricted double height);
@@ -134,7 +149,8 @@ interface CanvasRenderingContext2D {
[RaisesException] void putImageData(ImageData imagedata, [EnforceRange] long dx, [EnforceRange] long dy, [EnforceRange] long dirtyX, [EnforceRange] long dirtyY, [EnforceRange] long dirtyWidth, [EnforceRange] long dirtyHeight);
// https://github.com/WICG/canvas-color-space/blob/master/CanvasColorSpaceProposal.md
- [RuntimeEnabled=CanvasColorManagement, RaisesException] ImageData createImageData(unsigned long sw, unsigned long sh, ImageDataColorSettings imageDataColorSettings);
+ [RuntimeEnabled=CanvasColorManagement, RaisesException] ImageData getImageData([EnforceRange] long sx, [EnforceRange] long sy, [EnforceRange] long sw, [EnforceRange] long sh, ImageDataSettings imageDataSettings);
+ [RuntimeEnabled=CanvasColorManagement, RaisesException] ImageData createImageData([EnforceRange] long sw, [EnforceRange] long sh, ImageDataSettings imageDataSettings);
// Context state
// Should be merged with WebGL counterpart in CanvasRenderingContext, once no-longer experimental
@@ -159,11 +175,12 @@ interface CanvasRenderingContext2D {
attribute DOMString textAlign; // "start", "end", "left", "right", "center" (default: "start")
attribute DOMString textBaseline; // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic")
attribute DOMString direction; // "inherit", "rtl", "ltr" (default: "inherit")
- [RuntimeEnabled=NewCanvas2DAPI] attribute unrestricted double textLetterSpacing; // length in pixel (default: 0)
- [RuntimeEnabled=NewCanvas2DAPI] attribute unrestricted double textWordSpacing; // length in pixel (default: 0)
[RuntimeEnabled=NewCanvas2DAPI] attribute DOMString fontKerning; // "auto", "normal", "none" (default: "auto")
+ [RuntimeEnabled=NewCanvas2DAPI] attribute DOMString fontStretch; // "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "normal", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded" (default: normal)
[RuntimeEnabled=NewCanvas2DAPI] attribute DOMString fontVariantCaps; // "normal", "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "unicase", "titling-caps" (default: "normal")
+ [RuntimeEnabled=NewCanvas2DAPI] attribute unrestricted double textLetterSpacing; // length in pixel (default: 0)
[RuntimeEnabled=NewCanvas2DAPI] attribute DOMString textRendering; // "auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision" (default: auto)
+ [RuntimeEnabled=NewCanvas2DAPI] attribute unrestricted double textWordSpacing; // length in pixel (default: 0)
};
-CanvasRenderingContext2D includes CanvasPath; \ No newline at end of file
+CanvasRenderingContext2D includes CanvasPath;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
index 28d4ca0cf6d..d030abae93f 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h"
#include <memory>
+#include "base/metrics/histogram_functions.h"
#include "third_party/blink/renderer/core/css/resolver/filter_operation_resolver.h"
#include "third_party/blink/renderer/core/css/resolver/style_builder.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
@@ -28,7 +29,6 @@
#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/skia/include/effects/SkDashPathEffect.h"
-#include "third_party/skia/include/effects/SkDropShadowImageFilter.h"
static const char defaultFont[] = "10px sans-serif";
static const char defaultFilter[] = "none";
@@ -105,6 +105,7 @@ CanvasRenderingContext2DState::CanvasRenderingContext2DState(
word_spacing_(other.word_spacing_),
text_rendering_mode_(other.text_rendering_mode_),
font_kerning_(other.font_kerning_),
+ font_stretch_(other.font_stretch_),
font_variant_caps_(other.font_variant_caps_),
realized_font_(other.realized_font_),
is_transform_invertible_(other.is_transform_invertible_),
@@ -291,6 +292,16 @@ void CanvasRenderingContext2DState::SetFontKerning(
SetFont(font_description, selector);
}
+void CanvasRenderingContext2DState::SetFontStretch(
+ FontSelectionValue font_stretch,
+ FontSelector* selector) {
+ DCHECK(realized_font_);
+ FontDescription font_description(GetFontDescription());
+ font_description.SetStretch(font_stretch);
+ font_stretch_ = font_stretch;
+ SetFont(font_description, selector);
+}
+
void CanvasRenderingContext2DState::SetFontVariantCaps(
FontDescription::FontVariantCaps font_variant_caps,
FontSelector* selector) {
@@ -486,24 +497,24 @@ SkDrawLooper* CanvasRenderingContext2DState::ShadowAndForegroundDrawLooper()
sk_sp<PaintFilter> CanvasRenderingContext2DState::ShadowOnlyImageFilter()
const {
+ using ShadowMode = DropShadowPaintFilter::ShadowMode;
if (!shadow_only_image_filter_) {
const auto sigma = BlurRadiusToStdDev(shadow_blur_);
shadow_only_image_filter_ = sk_make_sp<DropShadowPaintFilter>(
shadow_offset_.Width(), shadow_offset_.Height(), sigma, sigma,
- shadow_color_, SkDropShadowImageFilter::kDrawShadowOnly_ShadowMode,
- nullptr);
+ shadow_color_, ShadowMode::kDrawShadowOnly, nullptr);
}
return shadow_only_image_filter_;
}
sk_sp<PaintFilter>
CanvasRenderingContext2DState::ShadowAndForegroundImageFilter() const {
+ using ShadowMode = DropShadowPaintFilter::ShadowMode;
if (!shadow_and_foreground_image_filter_) {
const auto sigma = BlurRadiusToStdDev(shadow_blur_);
shadow_and_foreground_image_filter_ = sk_make_sp<DropShadowPaintFilter>(
shadow_offset_.Width(), shadow_offset_.Height(), sigma, sigma,
- shadow_color_,
- SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, nullptr);
+ shadow_color_, ShadowMode::kDrawShadowAndForeground, nullptr);
}
return shadow_and_foreground_image_filter_;
}
@@ -591,6 +602,9 @@ void CanvasRenderingContext2DState::UpdateFilterQuality() const {
if (!image_smoothing_enabled_) {
UpdateFilterQualityWithSkFilterQuality(kNone_SkFilterQuality);
} else {
+ base::UmaHistogramExactLinear("Blink.Canvas.ImageSmoothingQuality",
+ static_cast<int>(image_smoothing_quality_),
+ static_cast<int>(kLast_SkFilterQuality) + 1);
UpdateFilterQualityWithSkFilterQuality(image_smoothing_quality_);
}
}
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h
index e4559b94190..237a1a8af61 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h
@@ -24,6 +24,12 @@ class CanvasStyle;
class CSSValue;
class Element;
+enum ShadowMode {
+ kDrawShadowAndForeground,
+ kDrawShadowOnly,
+ kDrawForegroundOnly
+};
+
class CanvasRenderingContext2DState final
: public GarbageCollected<CanvasRenderingContext2DState>,
public FontSelectorClient {
@@ -144,6 +150,9 @@ class CanvasRenderingContext2DState final
FontSelector* selector);
FontDescription::Kerning GetFontKerning() const { return font_kerning_; }
+ void SetFontStretch(FontSelectionValue font_stretch, FontSelector* selector);
+ FontSelectionValue GetFontStretch() const { return font_stretch_; }
+
void SetFontVariantCaps(FontDescription::FontVariantCaps font_kerning,
FontSelector* selector);
FontDescription::FontVariantCaps GetFontVariantCaps() const {
@@ -267,6 +276,7 @@ class CanvasRenderingContext2DState final
float word_spacing_{0};
TextRenderingMode text_rendering_mode_{TextRenderingMode::kAutoTextRendering};
FontDescription::Kerning font_kerning_{FontDescription::kAutoKerning};
+ FontSelectionValue font_stretch_{NormalWidthValue()};
FontDescription::FontVariantCaps font_variant_caps_{
FontDescription::kCapsNormal};
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
index 2dfcebff125..896a32b5cea 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
@@ -231,8 +231,8 @@ void CanvasRenderingContext2DTest::SetUp() {
canvas_element_ = To<HTMLCanvasElement>(GetDocument().getElementById("c"));
- full_image_data_ = ImageData::Create(IntSize(10, 10));
- partial_image_data_ = ImageData::Create(IntSize(2, 2));
+ full_image_data_ = ImageData::Create(10, 10, ASSERT_NO_EXCEPTION);
+ partial_image_data_ = ImageData::Create(2, 2, ASSERT_NO_EXCEPTION);
NonThrowableExceptionState exception_state;
auto* opaque_gradient =
@@ -310,12 +310,12 @@ class FakeCanvas2DLayerBridge : public Canvas2DLayerBridge {
class FakeCanvasResourceProvider : public CanvasResourceProvider {
public:
FakeCanvasResourceProvider(const IntSize& size,
- CanvasColorParams color_params,
+ CanvasResourceParams params,
RasterModeHint hint)
: CanvasResourceProvider(CanvasResourceProvider::kBitmap,
size,
kLow_SkFilterQuality,
- color_params,
+ params,
/*is_origin_top_left=*/false,
nullptr,
nullptr),
@@ -608,7 +608,7 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) {
IntSize size(10, 10);
std::unique_ptr<FakeCanvasResourceProvider> fake_resource_provider =
- std::make_unique<FakeCanvasResourceProvider>(size, CanvasColorParams(),
+ std::make_unique<FakeCanvasResourceProvider>(size, CanvasResourceParams(),
RasterModeHint::kPreferGPU);
std::unique_ptr<FakeCanvas2DLayerBridge> fake_2d_layer_bridge =
std::make_unique<FakeCanvas2DLayerBridge>(size, CanvasColorParams(),
@@ -639,8 +639,8 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) {
std::make_unique<FakeCanvas2DLayerBridge>(size2, CanvasColorParams(),
RasterModeHint::kPreferGPU);
std::unique_ptr<FakeCanvasResourceProvider> fake_resource_provider2 =
- std::make_unique<FakeCanvasResourceProvider>(size2, CanvasColorParams(),
- RasterModeHint::kPreferGPU);
+ std::make_unique<FakeCanvasResourceProvider>(
+ size2, CanvasResourceParams(), RasterModeHint::kPreferGPU);
anotherCanvas->SetResourceProviderForTesting(
std::move(fake_resource_provider2), std::move(fake_2d_layer_bridge2),
size2);
@@ -757,6 +757,7 @@ static void TestDrawSingleHighBitDepthPNGOnCanvas(
String filepath,
CanvasRenderingContext2D* context,
Document& document,
+ ImageDataSettings* color_setting,
ScriptState* script_state) {
scoped_refptr<SharedBuffer> pixel_buffer = test::ReadFromFile(filepath);
ASSERT_EQ(false, pixel_buffer->IsEmpty());
@@ -782,10 +783,11 @@ static void TestDrawSingleHighBitDepthPNGOnCanvas(
image_union.SetHTMLImageElement(image_element);
context->drawImage(script_state, image_union, 0, 0, exception_state);
- ImageData* image_data = context->getImageData(0, 0, 2, 2, exception_state);
+ ImageData* image_data =
+ context->getImageData(0, 0, 2, 2, color_setting, exception_state);
ImageDataArray data_array = image_data->data();
ASSERT_TRUE(data_array.IsFloat32Array());
- DOMArrayBufferView* buffer_view = data_array.GetAsFloat32Array().View();
+ DOMArrayBufferView* buffer_view = data_array.GetAsFloat32Array().Get();
ASSERT_EQ(16u, buffer_view->byteLength() / buffer_view->TypeSize());
float* actual_pixels = static_cast<float*>(buffer_view->BaseAddress());
@@ -826,6 +828,9 @@ static void TestDrawHighBitDepthPNGsOnWideGamutCanvas(
StringBuilder path;
path.Append(test::CoreTestDataPath());
path.Append("/png-16bit/");
+ ImageDataSettings* color_setting = ImageDataSettings::Create();
+ color_setting->setStorageFormat(kFloat32ArrayStorageFormatName);
+ color_setting->setColorSpace(canvas_color_space);
for (auto interlace : interlace_status) {
for (auto color_profile : color_profiles) {
for (auto alpha : alpha_status) {
@@ -837,7 +842,8 @@ static void TestDrawHighBitDepthPNGsOnWideGamutCanvas(
full_path.Append(alpha);
full_path.Append(".png");
TestDrawSingleHighBitDepthPNGOnCanvas(full_path.ToString(), context,
- document, script_state);
+ document, color_setting,
+ script_state);
}
}
}
@@ -845,8 +851,8 @@ static void TestDrawHighBitDepthPNGsOnWideGamutCanvas(
TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnP3Canvas) {
TestDrawHighBitDepthPNGsOnWideGamutCanvas(
- "p3", GetDocument(), Persistent<HTMLCanvasElement>(CanvasElement()),
- GetScriptState());
+ "display-p3", GetDocument(),
+ Persistent<HTMLCanvasElement>(CanvasElement()), GetScriptState());
}
TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnRec2020Canvas) {
@@ -897,14 +903,14 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings(
kRec2020CanvasColorSpaceName, kP3CanvasColorSpaceName};
CanvasPixelFormat canvas_pixel_formats[] = {
- CanvasPixelFormat::kRGBA8,
+ CanvasPixelFormat::kUint8,
CanvasPixelFormat::kF16,
CanvasPixelFormat::kF16,
CanvasPixelFormat::kF16,
};
String canvas_pixel_format_names[] = {
- kRGBA8CanvasPixelFormatName, kF16CanvasPixelFormatName,
+ kUint8CanvasPixelFormatName, kF16CanvasPixelFormatName,
kF16CanvasPixelFormatName, kF16CanvasPixelFormatName,
kF16CanvasPixelFormatName};
@@ -937,7 +943,7 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings(
EXPECT_EQ(data_length, data_f32->length());
ImageData* image_data = nullptr;
- ImageDataColorSettings* color_settings = ImageDataColorSettings::Create();
+ ImageDataSettings* image_data_settings = ImageDataSettings::Create();
int num_pixels = data_length / 4;
// At most four bytes are needed for Float32 output per color component.
@@ -947,7 +953,7 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings(
// Loop through different possible combinations of image data color space and
// storage formats and create the respective test image data objects.
for (unsigned i = 0; i < num_image_data_color_spaces; i++) {
- color_settings->setColorSpace(
+ image_data_settings->setColorSpace(
ImageData::CanvasColorSpaceName(image_data_color_spaces[i]));
for (unsigned j = 0; j < num_image_data_storage_formats; j++) {
@@ -955,24 +961,40 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings(
switch (image_data_storage_formats[j]) {
case kUint8ClampedArrayStorageFormat:
data_array = data_u8;
- color_settings->setStorageFormat(kUint8ClampedArrayStorageFormatName);
+ image_data_settings->setStorageFormat(
+ kUint8ClampedArrayStorageFormatName);
break;
case kUint16ArrayStorageFormat:
data_array = data_u16;
- color_settings->setStorageFormat(kUint16ArrayStorageFormatName);
+ image_data_settings->setStorageFormat(kUint16ArrayStorageFormatName);
break;
case kFloat32ArrayStorageFormat:
data_array = data_f32;
- color_settings->setStorageFormat(kFloat32ArrayStorageFormatName);
+ image_data_settings->setStorageFormat(kFloat32ArrayStorageFormatName);
break;
default:
NOTREACHED();
}
- image_data =
- ImageData::CreateForTest(IntSize(2, 2), data_array, color_settings);
+ image_data = ImageData::CreateForTest(IntSize(2, 2), data_array,
+ image_data_settings);
+ unsigned k = static_cast<unsigned>(canvas_colorspace_setting);
+ ImageDataSettings* canvas_color_setting = ImageDataSettings::Create();
+ canvas_color_setting->setColorSpace(
+ ImageData::CanvasColorSpaceName(canvas_color_spaces[k]));
+ switch (canvas_pixel_formats[k]) {
+ case CanvasPixelFormat::kUint8:
+ canvas_color_setting->setStorageFormat(
+ kUint8ClampedArrayStorageFormatName);
+ break;
+ case CanvasPixelFormat::kF16:
+ canvas_color_setting->setStorageFormat(
+ kFloat32ArrayStorageFormatName);
+ break;
+ default:
+ NOTREACHED();
+ }
- unsigned k = (unsigned)(canvas_colorspace_setting);
// Convert the original data used to create ImageData to the
// canvas color space and canvas pixel format.
EXPECT_TRUE(
@@ -995,14 +1017,15 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings(
NonThrowableExceptionState exception_state;
context->putImageData(image_data, 0, 0, exception_state);
- void* pixels_from_get_image_data =
- context->getImageData(0, 0, 2, 2, exception_state)
- ->BufferBase()
- ->Data();
+ const void* pixels_from_get_image_data =
+ context
+ ->getImageData(0, 0, 2, 2, canvas_color_setting, exception_state)
+ ->GetSkPixmap()
+ .addr();
ColorCorrectionTestUtils::CompareColorCorrectedPixels(
pixels_from_get_image_data, pixels_converted_manually.get(),
num_pixels,
- (canvas_pixel_formats[k] == CanvasPixelFormat::kRGBA8)
+ (canvas_pixel_formats[k] == CanvasPixelFormat::kUint8)
? kPixelFormat_8888
: kPixelFormat_ffff,
kAlphaUnmultiplied, kUnpremulRoundTripTolerance);
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc
index 4fecf3deee9..83c1620d804 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc
@@ -73,7 +73,9 @@ static Color CurrentColor(HTMLCanvasElement* canvas) {
}
static mojom::blink::ColorScheme ColorScheme(HTMLCanvasElement* canvas) {
- if (canvas && canvas->isConnected()) {
+ if (!canvas)
+ return mojom::blink::ColorScheme::kLight;
+ if (canvas->isConnected()) {
if (auto* style = canvas->GetComputedStyle())
return style->UsedColorScheme();
}
@@ -91,7 +93,7 @@ bool ParseColorOrCurrentColor(Color& parsed_color,
case kParsedSystemColor:
return true;
case kParsedCurrentColor:
- parsed_color = canvas ? CurrentColor(canvas) : Color::kBlack;
+ parsed_color = CurrentColor(canvas);
return true;
case kParseFailed:
return false;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
index 3ce12a41b15..106a7bb5c18 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
@@ -108,7 +108,7 @@ TEST_P(HTMLCanvasElementModuleTest, LowLatencyCanvasCompositorFrameOpacity) {
auto context_provider = viz::TestContextProvider::Create();
context_provider->UnboundTestContextGL()
->set_supports_gpu_memory_buffer_format(
- CanvasColorParams().GetBufferFormat(), true);
+ CanvasColorParams().GetAsResourceParams().GetBufferFormat(), true);
InitializeSharedGpuContext(context_provider.get());
// To intercept SubmitCompositorFrame/SubmitCompositorFrameSync messages sent
diff --git a/chromium/third_party/blink/renderer/modules/canvas/idls.gni b/chromium/third_party/blink/renderer/modules/canvas/idls.gni
index 582575f4478..96740fd08c7 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/idls.gni
+++ b/chromium/third_party/blink/renderer/modules/canvas/idls.gni
@@ -5,6 +5,8 @@
import("//third_party/blink/renderer/config.gni")
modules_idl_files = [
+ "canvas2d/canvas_formatted_text.idl",
+ "canvas2d/canvas_formatted_text_run.idl",
"canvas2d/canvas_gradient.idl",
"canvas2d/canvas_pattern.idl",
"canvas2d/canvas_rendering_context_2d.idl",
@@ -22,6 +24,8 @@ modules_dictionary_idl_files = [
modules_dependency_idl_files = [
"canvas2d/canvas_path.idl",
"htmlcanvas/html_canvas_element_module.idl",
+ "imagebitmap/window_create_image_bitmap.idl",
+ "imagebitmap/worker_create_image_bitmap.idl",
"offscreencanvas/offscreen_canvas_module.idl",
]
diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc
new file mode 100644
index 00000000000..d111834f2af
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.cc
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 2013, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/location.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
+#include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/fileapi/blob.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
+#include "third_party/blink/renderer/core/html/canvas/image_data.h"
+#include "third_party/blink/renderer/core/html/html_image_element.h"
+#include "third_party/blink/renderer/core/html/media/html_video_element.h"
+#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
+#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
+#include "third_party/blink/renderer/core/svg/svg_image_element.h"
+#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
+#include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
+#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
+#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
+#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h"
+#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+namespace {
+// This enum is used in a UMA histogram.
+enum CreateImageBitmapSource {
+ kCreateImageBitmapSourceBlob = 0,
+ kCreateImageBitmapSourceImageBitmap = 1,
+ kCreateImageBitmapSourceImageData = 2,
+ kCreateImageBitmapSourceHTMLCanvasElement = 3,
+ kCreateImageBitmapSourceHTMLImageElement = 4,
+ kCreateImageBitmapSourceHTMLVideoElement = 5,
+ kCreateImageBitmapSourceOffscreenCanvas = 6,
+ kCreateImageBitmapSourceSVGImageElement = 7,
+ kCreateImageBitmapSourceVideoFrame = 8,
+ kMaxValue = kCreateImageBitmapSourceVideoFrame,
+};
+
+} // namespace
+
+static inline ImageBitmapSource* ToImageBitmapSourceInternal(
+ const ImageBitmapSourceUnion& value,
+ const ImageBitmapOptions* options,
+ bool has_crop_rect) {
+ if (value.IsHTMLVideoElement()) {
+ UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+ kCreateImageBitmapSourceHTMLVideoElement);
+ return value.GetAsHTMLVideoElement();
+ }
+ if (value.IsHTMLImageElement()) {
+ UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+ kCreateImageBitmapSourceHTMLImageElement);
+ return value.GetAsHTMLImageElement();
+ }
+ if (value.IsSVGImageElement()) {
+ UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+ kCreateImageBitmapSourceSVGImageElement);
+ return value.GetAsSVGImageElement();
+ }
+ if (value.IsHTMLCanvasElement()) {
+ UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+ kCreateImageBitmapSourceHTMLCanvasElement);
+ return value.GetAsHTMLCanvasElement();
+ }
+ if (value.IsBlob()) {
+ UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+ kCreateImageBitmapSourceBlob);
+ return value.GetAsBlob();
+ }
+ if (value.IsImageData()) {
+ UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+ kCreateImageBitmapSourceImageData);
+ return value.GetAsImageData();
+ }
+ if (value.IsImageBitmap()) {
+ UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+ kCreateImageBitmapSourceImageBitmap);
+ return value.GetAsImageBitmap();
+ }
+ if (value.IsOffscreenCanvas()) {
+ UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+ kCreateImageBitmapSourceOffscreenCanvas);
+ return value.GetAsOffscreenCanvas();
+ }
+ if (value.IsVideoFrame()) {
+ UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.CreateImageBitmapSource",
+ kCreateImageBitmapSourceVideoFrame);
+ return value.GetAsVideoFrame();
+ }
+ NOTREACHED();
+ return nullptr;
+}
+
+ScriptPromise ImageBitmapFactories::CreateImageBitmapFromBlob(
+ ScriptState* script_state,
+ ImageBitmapSource* bitmap_source,
+ base::Optional<IntRect> crop_rect,
+ const ImageBitmapOptions* options) {
+ DCHECK(script_state->ContextIsValid());
+ ImageBitmapFactories& factory = From(*ExecutionContext::From(script_state));
+ ImageBitmapLoader* loader = ImageBitmapFactories::ImageBitmapLoader::Create(
+ factory, crop_rect, options, script_state);
+ factory.AddLoader(loader);
+ loader->LoadBlobAsync(static_cast<Blob*>(bitmap_source));
+ return loader->Promise();
+}
+
+ScriptPromise ImageBitmapFactories::CreateImageBitmap(
+ ScriptState* script_state,
+ const ImageBitmapSourceUnion& bitmap_source,
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
+ WebFeature feature = WebFeature::kCreateImageBitmap;
+ UseCounter::Count(ExecutionContext::From(script_state), feature);
+ ImageBitmapSource* bitmap_source_internal =
+ ToImageBitmapSourceInternal(bitmap_source, options, false);
+ if (!bitmap_source_internal)
+ return ScriptPromise();
+ return CreateImageBitmap(script_state, bitmap_source_internal,
+ base::Optional<IntRect>(), options, exception_state);
+}
+
+ScriptPromise ImageBitmapFactories::CreateImageBitmap(
+ ScriptState* script_state,
+ const ImageBitmapSourceUnion& bitmap_source,
+ int sx,
+ int sy,
+ int sw,
+ int sh,
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
+ WebFeature feature = WebFeature::kCreateImageBitmap;
+ UseCounter::Count(ExecutionContext::From(script_state), feature);
+ ImageBitmapSource* bitmap_source_internal =
+ ToImageBitmapSourceInternal(bitmap_source, options, true);
+ if (!bitmap_source_internal)
+ return ScriptPromise();
+ base::Optional<IntRect> crop_rect = IntRect(sx, sy, sw, sh);
+ return CreateImageBitmap(script_state, bitmap_source_internal, crop_rect,
+ options, exception_state);
+}
+
+ScriptPromise ImageBitmapFactories::CreateImageBitmap(
+ ScriptState* script_state,
+ ImageBitmapSource* bitmap_source,
+ base::Optional<IntRect> crop_rect,
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
+ if (crop_rect && (crop_rect->Width() == 0 || crop_rect->Height() == 0)) {
+ exception_state.ThrowRangeError(String::Format(
+ "The crop rect %s is 0.", crop_rect->Width() ? "height" : "width"));
+ return ScriptPromise();
+ }
+
+ if (bitmap_source->IsBlob()) {
+ return CreateImageBitmapFromBlob(script_state, bitmap_source, crop_rect,
+ options);
+ }
+
+ if (bitmap_source->BitmapSourceSize().Width() == 0 ||
+ bitmap_source->BitmapSourceSize().Height() == 0) {
+ exception_state.ThrowDOMException(
+ DOMExceptionCode::kInvalidStateError,
+ String::Format(
+ "The source image %s is 0.",
+ bitmap_source->BitmapSourceSize().Width() ? "height" : "width"));
+ return ScriptPromise();
+ }
+
+ return bitmap_source->CreateImageBitmap(script_state, crop_rect, options,
+ exception_state);
+}
+
+const char ImageBitmapFactories::kSupplementName[] = "ImageBitmapFactories";
+
+ImageBitmapFactories& ImageBitmapFactories::From(ExecutionContext& context) {
+ ImageBitmapFactories* supplement =
+ Supplement<ExecutionContext>::From<ImageBitmapFactories>(context);
+ if (!supplement) {
+ supplement = MakeGarbageCollected<ImageBitmapFactories>();
+ Supplement<ExecutionContext>::ProvideTo(context, supplement);
+ }
+ return *supplement;
+}
+
+void ImageBitmapFactories::AddLoader(ImageBitmapLoader* loader) {
+ pending_loaders_.insert(loader);
+}
+
+void ImageBitmapFactories::DidFinishLoading(ImageBitmapLoader* loader) {
+ DCHECK(pending_loaders_.Contains(loader));
+ pending_loaders_.erase(loader);
+}
+
+void ImageBitmapFactories::Trace(Visitor* visitor) const {
+ visitor->Trace(pending_loaders_);
+ Supplement<ExecutionContext>::Trace(visitor);
+}
+
+ImageBitmapFactories::ImageBitmapLoader::ImageBitmapLoader(
+ ImageBitmapFactories& factory,
+ base::Optional<IntRect> crop_rect,
+ ScriptState* script_state,
+ const ImageBitmapOptions* options)
+ : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)),
+ loader_(std::make_unique<FileReaderLoader>(
+ FileReaderLoader::kReadAsArrayBuffer,
+ this,
+ GetExecutionContext()->GetTaskRunner(TaskType::kFileReading))),
+ factory_(&factory),
+ resolver_(MakeGarbageCollected<ScriptPromiseResolver>(script_state)),
+ crop_rect_(crop_rect),
+ options_(options) {}
+
+void ImageBitmapFactories::ImageBitmapLoader::LoadBlobAsync(Blob* blob) {
+ loader_->Start(blob->GetBlobDataHandle());
+}
+
+ImageBitmapFactories::ImageBitmapLoader::~ImageBitmapLoader() {
+ DCHECK(!loader_);
+}
+
+void ImageBitmapFactories::ImageBitmapLoader::RejectPromise(
+ ImageBitmapRejectionReason reason) {
+ switch (reason) {
+ case kUndecodableImageBitmapRejectionReason:
+ resolver_->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kInvalidStateError,
+ "The source image could not be decoded."));
+ break;
+ case kAllocationFailureImageBitmapRejectionReason:
+ resolver_->Reject(MakeGarbageCollected<DOMException>(
+ DOMExceptionCode::kInvalidStateError,
+ "The ImageBitmap could not be allocated."));
+ break;
+ default:
+ NOTREACHED();
+ }
+ loader_.reset();
+ factory_->DidFinishLoading(this);
+}
+
+void ImageBitmapFactories::ImageBitmapLoader::ContextDestroyed() {
+ if (loader_)
+ factory_->DidFinishLoading(this);
+ loader_.reset();
+}
+
+void ImageBitmapFactories::ImageBitmapLoader::DidFinishLoading() {
+ auto contents = loader_->TakeContents();
+ loader_.reset();
+ if (!contents.IsValid()) {
+ RejectPromise(kAllocationFailureImageBitmapRejectionReason);
+ return;
+ }
+ ScheduleAsyncImageBitmapDecoding(std::move(contents));
+}
+
+void ImageBitmapFactories::ImageBitmapLoader::DidFail(FileErrorCode) {
+ RejectPromise(kUndecodableImageBitmapRejectionReason);
+}
+
+namespace {
+void DecodeImageOnDecoderThread(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ ArrayBufferContents contents,
+ ImageDecoder::AlphaOption alpha_option,
+ ColorBehavior color_behavior,
+ WTF::CrossThreadOnceFunction<
+ void(sk_sp<SkImage>, const ImageOrientationEnum)> result_callback) {
+ const bool data_complete = true;
+ std::unique_ptr<ImageDecoder> decoder = ImageDecoder::Create(
+ SegmentReader::CreateFromSkData(
+ SkData::MakeWithoutCopy(contents.Data(), contents.DataLength())),
+ data_complete, alpha_option, ImageDecoder::kDefaultBitDepth,
+ color_behavior);
+ sk_sp<SkImage> frame;
+ ImageOrientationEnum orientation = ImageOrientationEnum::kDefault;
+ if (decoder) {
+ orientation = decoder->Orientation().Orientation();
+ frame = ImageBitmap::GetSkImageFromDecoder(std::move(decoder));
+ }
+ PostCrossThreadTask(*task_runner, FROM_HERE,
+ CrossThreadBindOnce(std::move(result_callback),
+ std::move(frame), orientation));
+}
+} // namespace
+
+void ImageBitmapFactories::ImageBitmapLoader::ScheduleAsyncImageBitmapDecoding(
+ ArrayBufferContents contents) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ Thread::Current()->GetTaskRunner();
+ ImageDecoder::AlphaOption alpha_option =
+ options_->premultiplyAlpha() != "none"
+ ? ImageDecoder::AlphaOption::kAlphaPremultiplied
+ : ImageDecoder::AlphaOption::kAlphaNotPremultiplied;
+ ColorBehavior color_behavior = options_->colorSpaceConversion() == "none"
+ ? ColorBehavior::Ignore()
+ : ColorBehavior::Tag();
+ worker_pool::PostTask(
+ FROM_HERE,
+ CrossThreadBindOnce(
+ DecodeImageOnDecoderThread, std::move(task_runner),
+ std::move(contents), alpha_option, color_behavior,
+ CrossThreadBindOnce(&ImageBitmapFactories::ImageBitmapLoader::
+ ResolvePromiseOnOriginalThread,
+ WrapCrossThreadWeakPersistent(this))));
+}
+
+void ImageBitmapFactories::ImageBitmapLoader::ResolvePromiseOnOriginalThread(
+ sk_sp<SkImage> frame,
+ const ImageOrientationEnum orientation) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!frame) {
+ RejectPromise(kUndecodableImageBitmapRejectionReason);
+ return;
+ }
+ DCHECK(frame->width());
+ DCHECK(frame->height());
+ scoped_refptr<StaticBitmapImage> image =
+ UnacceleratedStaticBitmapImage::Create(std::move(frame), orientation);
+
+ image->SetOriginClean(true);
+ auto* image_bitmap =
+ MakeGarbageCollected<ImageBitmap>(image, crop_rect_, options_);
+ if (image_bitmap && image_bitmap->BitmapImage()) {
+ resolver_->Resolve(image_bitmap);
+ } else {
+ RejectPromise(kAllocationFailureImageBitmapRejectionReason);
+ return;
+ }
+ factory_->DidFinishLoading(this);
+}
+
+void ImageBitmapFactories::ImageBitmapLoader::Trace(Visitor* visitor) const {
+ ExecutionContextLifecycleObserver::Trace(visitor);
+ visitor->Trace(factory_);
+ visitor->Trace(resolver_);
+ visitor->Trace(options_);
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.h b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.h
new file mode 100644
index 00000000000..69f0dedd350
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_factories.h
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2013, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_IMAGEBITMAP_IMAGE_BITMAP_FACTORIES_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_IMAGEBITMAP_IMAGE_BITMAP_FACTORIES_H_
+
+#include <memory>
+
+#include "base/single_thread_task_runner.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/image_bitmap_source.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
+#include "third_party/blink/renderer/core/fileapi/file_reader_loader.h"
+#include "third_party/blink/renderer/core/fileapi/file_reader_loader_client.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
+#include "third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_source_union.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/blink/renderer/platform/bindings/name_client.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/geometry/int_rect.h"
+#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
+#include "third_party/blink/renderer/platform/supplementable.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
+
+class SkImage;
+
+namespace blink {
+
+class Blob;
+class ExecutionContext;
+class ImageBitmapSource;
+
+class MODULES_EXPORT ImageBitmapFactories final
+ : public GarbageCollected<ImageBitmapFactories>,
+ public Supplement<ExecutionContext>,
+ public NameClient {
+ public:
+ static const char kSupplementName[];
+
+ static ScriptPromise CreateImageBitmap(ScriptState*,
+ const ImageBitmapSourceUnion&,
+ const ImageBitmapOptions*,
+ ExceptionState&);
+ static ScriptPromise CreateImageBitmap(ScriptState*,
+ const ImageBitmapSourceUnion&,
+ int sx,
+ int sy,
+ int sw,
+ int sh,
+ const ImageBitmapOptions*,
+ ExceptionState&);
+ static ScriptPromise CreateImageBitmap(ScriptState*,
+ ImageBitmapSource*,
+ base::Optional<IntRect> crop_rect,
+ const ImageBitmapOptions*,
+ ExceptionState&);
+
+ // window.createImageBitmap()
+ static ScriptPromise createImageBitmap(
+ ScriptState* script_state,
+ LocalDOMWindow&,
+ const ImageBitmapSourceUnion& bitmap_source,
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
+ return CreateImageBitmap(script_state, bitmap_source, options,
+ exception_state);
+ }
+ static ScriptPromise createImageBitmap(
+ ScriptState* script_state,
+ LocalDOMWindow&,
+ const ImageBitmapSourceUnion& bitmap_source,
+ int sx,
+ int sy,
+ int sw,
+ int sh,
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
+ return CreateImageBitmap(script_state, bitmap_source, sx, sy, sw, sh,
+ options, exception_state);
+ }
+
+ // worker.createImageBitmap()
+ static ScriptPromise createImageBitmap(
+ ScriptState* script_state,
+ WorkerGlobalScope&,
+ const ImageBitmapSourceUnion& bitmap_source,
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
+ return CreateImageBitmap(script_state, bitmap_source, options,
+ exception_state);
+ }
+ static ScriptPromise createImageBitmap(
+ ScriptState* script_state,
+ WorkerGlobalScope&,
+ const ImageBitmapSourceUnion& bitmap_source,
+ int sx,
+ int sy,
+ int sw,
+ int sh,
+ const ImageBitmapOptions* options,
+ ExceptionState& exception_state) {
+ return CreateImageBitmap(script_state, bitmap_source, sx, sy, sw, sh,
+ options, exception_state);
+ }
+
+ virtual ~ImageBitmapFactories() = default;
+
+ void Trace(Visitor*) const override;
+ const char* NameInHeapSnapshot() const override {
+ return "ImageBitmapLoader";
+ }
+
+ private:
+ class ImageBitmapLoader final : public GarbageCollected<ImageBitmapLoader>,
+ public ExecutionContextLifecycleObserver,
+ public FileReaderLoaderClient {
+ public:
+ static ImageBitmapLoader* Create(ImageBitmapFactories& factory,
+ base::Optional<IntRect> crop_rect,
+ const ImageBitmapOptions* options,
+ ScriptState* script_state) {
+ return MakeGarbageCollected<ImageBitmapLoader>(factory, crop_rect,
+ script_state, options);
+ }
+
+ ImageBitmapLoader(ImageBitmapFactories&,
+ base::Optional<IntRect> crop_rect,
+ ScriptState*,
+ const ImageBitmapOptions*);
+
+ void LoadBlobAsync(Blob*);
+ ScriptPromise Promise() { return resolver_->Promise(); }
+
+ void Trace(Visitor*) const override;
+
+ ~ImageBitmapLoader() override;
+
+ private:
+ SEQUENCE_CHECKER(sequence_checker_);
+
+ enum ImageBitmapRejectionReason {
+ kUndecodableImageBitmapRejectionReason,
+ kAllocationFailureImageBitmapRejectionReason,
+ };
+
+ void RejectPromise(ImageBitmapRejectionReason);
+
+ void ScheduleAsyncImageBitmapDecoding(ArrayBufferContents);
+ void ResolvePromiseOnOriginalThread(sk_sp<SkImage>,
+ const ImageOrientationEnum);
+
+ // ExecutionContextLifecycleObserver
+ void ContextDestroyed() override;
+
+ // FileReaderLoaderClient
+ void DidStartLoading() override {}
+ void DidReceiveData() override {}
+ void DidFinishLoading() override;
+ void DidFail(FileErrorCode) override;
+
+ std::unique_ptr<FileReaderLoader> loader_;
+ Member<ImageBitmapFactories> factory_;
+ Member<ScriptPromiseResolver> resolver_;
+ base::Optional<IntRect> crop_rect_;
+ Member<const ImageBitmapOptions> options_;
+ };
+
+ static ImageBitmapFactories& From(ExecutionContext&);
+ static ScriptPromise CreateImageBitmapFromBlob(
+ ScriptState*,
+ ImageBitmapSource*,
+ base::Optional<IntRect> crop_rect,
+ const ImageBitmapOptions*);
+
+ void AddLoader(ImageBitmapLoader*);
+ void DidFinishLoading(ImageBitmapLoader*);
+
+ HeapHashSet<Member<ImageBitmapLoader>> pending_loaders_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_IMAGEBITMAP_IMAGE_BITMAP_FACTORIES_H_
diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc
index 4b94289ec16..6d57d4e62e1 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc
@@ -109,7 +109,8 @@ bool ImageBitmapRenderingContextBase::PushFrame() {
cc::PaintFlags paint_flags;
paint_flags.setBlendMode(SkBlendMode::kSrc);
Host()->ResourceProvider()->Canvas()->drawImage(
- image->PaintImageForCurrentFrame(), 0, 0, &paint_flags);
+ image->PaintImageForCurrentFrame(), 0, 0, SkSamplingOptions(),
+ &paint_flags);
scoped_refptr<CanvasResource> resource =
Host()->ResourceProvider()->ProduceCanvasResource();
Host()->PushFrame(
diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_source_union.h b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_source_union.h
new file mode 100644
index 00000000000..7f2c0f047d2
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_source_union.h
@@ -0,0 +1,17 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_IMAGEBITMAP_IMAGE_BITMAP_SOURCE_UNION_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_IMAGEBITMAP_IMAGE_BITMAP_SOURCE_UNION_H_
+
+#include "third_party/blink/renderer/bindings/modules/v8/image_bitmap_source.h"
+
+namespace blink {
+
+using ImageBitmapSourceUnion =
+ HTMLImageElementOrSVGImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrImageBitmapOrOffscreenCanvasOrVideoFrame;
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_IMAGEBITMAP_IMAGE_BITMAP_SOURCE_UNION_H_
diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/window_create_image_bitmap.idl b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/window_create_image_bitmap.idl
new file mode 100644
index 00000000000..8cf42d0f1c6
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/window_create_image_bitmap.idl
@@ -0,0 +1,24 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://html.spec.whatwg.org/C/#imagebitmapsource
+typedef (HTMLImageElement or
+ SVGImageElement or
+ HTMLVideoElement or
+ HTMLCanvasElement or
+ Blob or
+ ImageData or
+ ImageBitmap or
+ OffscreenCanvas or
+ VideoFrame) ImageBitmapSource;
+
+[
+ ImplementedAs=ImageBitmapFactories
+] partial interface Window {
+ // https://html.spec.whatwg.org/#windoworworkerglobalscope
+ [CallWith=ScriptState, RaisesException] Promise<ImageBitmap> createImageBitmap(
+ ImageBitmapSource imageBitmap, optional ImageBitmapOptions options = {});
+ [CallWith=ScriptState, RaisesException] Promise<ImageBitmap> createImageBitmap(
+ ImageBitmapSource imageBitmap, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options = {});
+};
diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/worker_create_image_bitmap.idl b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/worker_create_image_bitmap.idl
new file mode 100644
index 00000000000..ee0f155d8bc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/worker_create_image_bitmap.idl
@@ -0,0 +1,13 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ ImplementedAs=ImageBitmapFactories
+] partial interface WorkerGlobalScope {
+ // https://html.spec.whatwg.org/#windoworworkerglobalscope
+ [CallWith=ScriptState, RaisesException] Promise<ImageBitmap> createImageBitmap(
+ ImageBitmapSource imageBitmap, optional ImageBitmapOptions options = {});
+ [CallWith=ScriptState, RaisesException] Promise<ImageBitmap> createImageBitmap(
+ ImageBitmapSource imageBitmap, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options = {});
+};
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc
index 472c8aa6a88..92ffb0ee1e4 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc
@@ -148,7 +148,7 @@ TEST_P(OffscreenCanvasTest, CompositorFrameOpacity) {
const bool context_alpha = GetParam().alpha;
const auto canvas_resource = CanvasResourceSharedBitmap::Create(
- offscreen_canvas().Size(), CanvasColorParams(), nullptr /* provider */,
+ offscreen_canvas().Size(), CanvasResourceParams(), nullptr /* provider */,
kLow_SkFilterQuality);
EXPECT_TRUE(!!canvas_resource);
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
index eba6275b84f..aa61e529143 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
@@ -136,6 +136,7 @@ void OffscreenCanvasRenderingContext2D::FlushRecording() {
return;
GetCanvasResourceProvider()->FlushCanvas();
+ GetCanvasResourceProvider()->ReleaseLockedImages();
}
void OffscreenCanvasRenderingContext2D::FinalizeFrame() {
@@ -316,16 +317,9 @@ bool OffscreenCanvasRenderingContext2D::IsPaintable() const {
return Host()->ResourceProvider();
}
-String OffscreenCanvasRenderingContext2D::ColorSpaceAsString() const {
- return CanvasRenderingContext::ColorSpaceAsString();
-}
-
-CanvasPixelFormat OffscreenCanvasRenderingContext2D::PixelFormat() const {
- return ColorParams().PixelFormat();
-}
-
-CanvasColorParams OffscreenCanvasRenderingContext2D::ColorParams() const {
- return CanvasRenderingContext::ColorParams();
+CanvasColorParams OffscreenCanvasRenderingContext2D::GetCanvas2DColorParams()
+ const {
+ return CanvasRenderingContext::CanvasRenderingContextColorParams();
}
bool OffscreenCanvasRenderingContext2D::WritePixels(
@@ -535,6 +529,40 @@ void OffscreenCanvasRenderingContext2D::setFontKerning(
ModifiableState().SetFontKerning(kerning, Host()->GetFontSelector());
}
+void OffscreenCanvasRenderingContext2D::setFontStretch(
+ const String& font_stretch) {
+ if (!GetState().HasRealizedFont())
+ setFont(font());
+
+ String font_stretch_string = font_stretch.LowerASCII();
+ FontSelectionValue stretch_vale;
+ if (font_stretch_string == kUltraCondensedString)
+ stretch_vale = UltraCondensedWidthValue();
+ else if (font_stretch_string == kExtraCondensedString)
+ stretch_vale = ExtraCondensedWidthValue();
+ else if (font_stretch_string == kCondensedString)
+ stretch_vale = CondensedWidthValue();
+ else if (font_stretch_string == kSemiCondensedString)
+ stretch_vale = SemiCondensedWidthValue();
+ else if (font_stretch_string == kNormalStretchString)
+ stretch_vale = NormalWidthValue();
+ else if (font_stretch_string == kSemiExpandedString)
+ stretch_vale = SemiExpandedWidthValue();
+ else if (font_stretch_string == kExpandedString)
+ stretch_vale = ExpandedWidthValue();
+ else if (font_stretch_string == kExtraExpandedString)
+ stretch_vale = ExtraExpandedWidthValue();
+ else if (font_stretch_string == kUltraExpandedString)
+ stretch_vale = UltraExpandedWidthValue();
+ else
+ return;
+
+ if (GetState().GetFontStretch() == stretch_vale)
+ return;
+
+ ModifiableState().SetFontStretch(stretch_vale, Host()->GetFontSelector());
+}
+
void OffscreenCanvasRenderingContext2D::setFontVariantCaps(
const String& font_variant_caps_string) {
if (!GetState().HasRealizedFont())
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
index 5d5b0db0f86..42c9ddcb80f 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
@@ -82,6 +82,7 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final
void setTextWordSpacing(const double word_spacing);
void setTextRendering(const String&);
void setFontKerning(const String&);
+ void setFontStretch(const String&);
void setFontVariantCaps(const String&);
void fillText(const String& text, double x, double y);
@@ -122,6 +123,9 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final
void ValidateStateStackWithCanvas(const cc::PaintCanvas*) const final;
bool HasAlpha() const final { return CreationAttributes().alpha; }
+ bool IsDesynchronized() const final {
+ return CreationAttributes().desynchronized;
+ }
bool isContextLost() const override;
ImageBitmap* TransferToImageBitmap(ScriptState*) final;
@@ -143,7 +147,7 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final
}
protected:
- CanvasColorParams ColorParams() const override;
+ CanvasColorParams GetCanvas2DColorParams() const override;
bool WritePixels(const SkImageInfo& orig_info,
const void* pixels,
size_t row_bytes,
@@ -167,8 +171,6 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final
scoped_refptr<CanvasResource> ProduceCanvasResource();
- String ColorSpaceAsString() const override;
- CanvasPixelFormat PixelFormat() const override;
SkIRect dirty_rect_for_commit_;
bool is_valid_size_ = false;
diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
index 78d97b46178..50727f9025c 100644
--- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
+++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl
@@ -21,11 +21,22 @@
// transformations (default transform is the identity matrix)
void scale(unrestricted double x, unrestricted double y);
+ [RuntimeEnabled=NewCanvas2DAPI] void scale(unrestricted double x, unrestricted double y, unrestricted double z);
void rotate(unrestricted double angle);
+ [RuntimeEnabled=NewCanvas2DAPI] void rotate3d(unrestricted double angleX, unrestricted double angleY, unrestricted double angleZ);
+ [RuntimeEnabled=NewCanvas2DAPI] void rotateAxis(unrestricted double axisX, unrestricted double axisY, unrestricted double axisZ, unrestricted double angle);
void translate(unrestricted double x, unrestricted double y);
+ [RuntimeEnabled=NewCanvas2DAPI] void translate(unrestricted double x, unrestricted double y, unrestricted double z);
+ [RuntimeEnabled=NewCanvas2DAPI] void perspective(unrestricted double length);
void transform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f);
+ [RuntimeEnabled=NewCanvas2DAPI] void transform(
+ unrestricted double m11, unrestricted double m12, unrestricted double m13, unrestricted double m14,
+ unrestricted double m21, unrestricted double m22, unrestricted double m23, unrestricted double m24,
+ unrestricted double m31, unrestricted double m32, unrestricted double m33, unrestricted double m34,
+ unrestricted double m41, unrestricted double m42, unrestricted double m43, unrestricted double m44
+ );
void setTransform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f);
- [RaisesException] void setTransform(optional DOMMatrix2DInit transform = {});
+ [RaisesException] void setTransform(optional DOMMatrixInit transform = {});
DOMMatrix getTransform();
void resetTransform();
@@ -89,7 +100,8 @@
// If OffscreenCanva ships before color managed canvas, this method must remain behind flag.
// https://github.com/WICG/canvas-color-space/blob/master/CanvasColorSpaceProposal.md
- [RuntimeEnabled=CanvasColorManagement, RaisesException] ImageData createImageData(unsigned long sw, unsigned long sh, ImageDataColorSettings imageDataColorSettings);
+ [RuntimeEnabled=CanvasColorManagement, RaisesException] ImageData getImageData(long sx, long sy, long sw, long sh, ImageDataSettings imageDataSettings);
+ [RuntimeEnabled=CanvasColorManagement, RaisesException] ImageData createImageData(long sw, long sh, ImageDataSettings imageDataSettings);
// Line caps/joins
attribute unrestricted double lineWidth; // (default 1)
@@ -107,11 +119,12 @@
attribute DOMString textAlign; // "start", "end", "left", "right", "center" (default: "start")
attribute DOMString textBaseline; // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic")
attribute DOMString direction; // "inherit", "rtl", "ltr" (default: "inherit")
- [RuntimeEnabled=NewCanvas2DAPI] attribute unrestricted double textLetterSpacing; // length in pixel (default: 0)
- [RuntimeEnabled=NewCanvas2DAPI] attribute unrestricted double textWordSpacing; // length in pixel (default: 0)
[RuntimeEnabled=NewCanvas2DAPI] attribute DOMString fontKerning; // "auto", "normal", "none" (default: "auto")
+ [RuntimeEnabled=NewCanvas2DAPI] attribute DOMString fontStretch; // "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "normal", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded" (default: normal)
[RuntimeEnabled=NewCanvas2DAPI] attribute DOMString fontVariantCaps; // "normal", "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "unicase", "titling-caps" (default: "normal")
+ [RuntimeEnabled=NewCanvas2DAPI] attribute unrestricted double textLetterSpacing; // length in pixel (default: 0)
[RuntimeEnabled=NewCanvas2DAPI] attribute DOMString textRendering; // "auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision" (default: auto)
+ [RuntimeEnabled=NewCanvas2DAPI] attribute unrestricted double textWordSpacing; // length in pixel (default: 0)
};
OffscreenCanvasRenderingContext2D includes CanvasPath;