Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -43279,6 +43279,7 @@ ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html/clip.dart + ../../../flu
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html/color_filter.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html/debug_canvas_reuse_overlay.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html/dom_canvas.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html/image.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html/image_filter.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html/offset.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html/opacity.dart + ../../../flutter/LICENSE
Expand Down Expand Up @@ -43311,7 +43312,7 @@ ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html/shaders/vertex_shaders.d
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html/surface.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html/surface_stats.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html/transform.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html_image_codec.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/html_image_element_codec.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/image_decoder.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/initialization.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/js_interop/js_app.dart + ../../../flutter/LICENSE
Expand All @@ -43328,7 +43329,6 @@ ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/navigation/history.dart + ../
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/noto_font.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/noto_font_encoding.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/onscreen_logging.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/picture.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/platform_dispatcher.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/platform_dispatcher/app_lifecycle_state.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/lib/web_ui/lib/src/engine/platform_dispatcher/view_focus_binding.dart + ../../../flutter/LICENSE
Expand Down Expand Up @@ -46156,6 +46156,7 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/clip.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/color_filter.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/debug_canvas_reuse_overlay.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/dom_canvas.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/image.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/image_filter.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/offset.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/opacity.dart
Expand Down Expand Up @@ -46188,7 +46189,7 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/shaders/vertex_shaders.dar
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/surface.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/surface_stats.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/transform.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html_image_codec.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html_image_element_codec.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/image_decoder.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/initialization.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/js_interop/js_app.dart
Expand All @@ -46205,7 +46206,6 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/navigation/history.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/noto_font.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/noto_font_encoding.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/onscreen_logging.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/picture.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/platform_dispatcher.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/platform_dispatcher/app_lifecycle_state.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/platform_dispatcher/view_focus_binding.dart
Expand Down
4 changes: 2 additions & 2 deletions lib/web_ui/lib/src/engine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export 'engine/html/clip.dart';
export 'engine/html/color_filter.dart';
export 'engine/html/debug_canvas_reuse_overlay.dart';
export 'engine/html/dom_canvas.dart';
export 'engine/html/image.dart';
export 'engine/html/image_filter.dart';
export 'engine/html/offset.dart';
export 'engine/html/opacity.dart';
Expand Down Expand Up @@ -105,7 +106,7 @@ export 'engine/html/shaders/vertex_shaders.dart';
export 'engine/html/surface.dart';
export 'engine/html/surface_stats.dart';
export 'engine/html/transform.dart';
export 'engine/html_image_codec.dart';
export 'engine/html_image_element_codec.dart';
export 'engine/image_decoder.dart';
export 'engine/initialization.dart';
export 'engine/js_interop/js_app.dart';
Expand All @@ -122,7 +123,6 @@ export 'engine/navigation/history.dart';
export 'engine/noto_font.dart';
export 'engine/noto_font_encoding.dart';
export 'engine/onscreen_logging.dart';
export 'engine/picture.dart';
export 'engine/platform_dispatcher.dart';
export 'engine/platform_dispatcher/app_lifecycle_state.dart';
export 'engine/platform_dispatcher/view_focus_binding.dart';
Expand Down
130 changes: 74 additions & 56 deletions lib/web_ui/lib/src/engine/html/bitmap_canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import '../display.dart';
import '../dom.dart';
import '../engine_canvas.dart';
import '../frame_reference.dart';
import '../html_image_codec.dart';
import '../text/canvas_paragraph.dart';
import '../util.dart';
import '../vector_math.dart';
import 'clip.dart';
import 'color_filter.dart';
import 'dom_canvas.dart';
import 'image.dart';
import 'painting.dart';
import 'path/path.dart';
import 'recording_canvas.dart';
Expand Down Expand Up @@ -207,7 +207,8 @@ class BitmapCanvas extends EngineCanvas {

static int heightToPhysical(double height) {
final double boundsHeight = height + 1;
return (boundsHeight * EngineFlutterDisplay.instance.browserDevicePixelRatio)
return (boundsHeight *
EngineFlutterDisplay.instance.browserDevicePixelRatio)
.ceil() +
2 * kPaddingPixels;
}
Expand Down Expand Up @@ -252,7 +253,8 @@ class BitmapCanvas extends EngineCanvas {
/// * [PersistedPicture._recycleCanvas] which also uses this method
/// for the same reason.
bool isReusable() {
return _devicePixelRatio == EngineFlutterDisplay.instance.browserDevicePixelRatio;
return _devicePixelRatio ==
EngineFlutterDisplay.instance.browserDevicePixelRatio;
}

/// Returns a "data://" URI containing a representation of the image in this
Expand Down Expand Up @@ -365,12 +367,12 @@ class BitmapCanvas extends EngineCanvas {
return false;
}
return _renderStrategy.isInsideSvgFilterTree ||
_contains3dTransform ||
(_childOverdraw &&
!_canvasPool.hasCanvas &&
paint.maskFilter == null &&
paint.shader == null &&
paint.style != ui.PaintingStyle.stroke);
_contains3dTransform ||
(_childOverdraw &&
!_canvasPool.hasCanvas &&
paint.maskFilter == null &&
paint.shader == null &&
paint.style != ui.PaintingStyle.stroke);
}

/// Same as [_useDomForRenderingFill] but allows stroke as well.
Expand All @@ -381,13 +383,13 @@ class BitmapCanvas extends EngineCanvas {
return false;
}
return _renderStrategy.isInsideSvgFilterTree ||
_contains3dTransform ||
((_childOverdraw ||
_renderStrategy.hasImageElements ||
_renderStrategy.hasParagraphs) &&
!_canvasPool.hasCanvas &&
paint.maskFilter == null &&
paint.shader == null);
_contains3dTransform ||
((_childOverdraw ||
_renderStrategy.hasImageElements ||
_renderStrategy.hasParagraphs) &&
!_canvasPool.hasCanvas &&
paint.maskFilter == null &&
paint.shader == null);
}

@override
Expand Down Expand Up @@ -512,7 +514,8 @@ class BitmapCanvas extends EngineCanvas {
@override
void drawCircle(ui.Offset c, double radius, SurfacePaintData paint) {
if (_useDomForRenderingFillAndStroke(paint)) {
final ui.Rect rect = adjustRectForDom(ui.Rect.fromCircle(center: c, radius: radius), paint);
final ui.Rect rect = adjustRectForDom(
ui.Rect.fromCircle(center: c, radius: radius), paint);
final DomHTMLElement element = buildDrawRectElement(
rect, paint, 'draw-circle', _canvasPool.currentTransform);
_drawElement(element, rect.topLeft, paint);
Expand Down Expand Up @@ -572,7 +575,8 @@ class BitmapCanvas extends EngineCanvas {
final bool isStroke = paint.style == ui.PaintingStyle.stroke;
final String cssColor = colorValueToCssString(paint.color);
final double sigma = paint.maskFilter!.webOnlySigma;
if (ui_web.browser.browserEngine == ui_web.BrowserEngine.webkit && !isStroke) {
if (ui_web.browser.browserEngine == ui_web.BrowserEngine.webkit &&
!isStroke) {
// A bug in webkit leaves artifacts when this element is animated
// with filter: blur, we use boxShadow instead.
element.style.boxShadow = '0px 0px ${sigma * 2.0}px $cssColor';
Expand Down Expand Up @@ -625,7 +629,8 @@ class BitmapCanvas extends EngineCanvas {
ui.Image image, ui.Offset p, SurfacePaintData paint) {
final HtmlImage htmlImage = image as HtmlImage;
final ui.BlendMode? blendMode = paint.blendMode;
final EngineHtmlColorFilter? colorFilter = createHtmlColorFilter(paint.colorFilter);
final EngineHtmlColorFilter? colorFilter =
createHtmlColorFilter(paint.colorFilter);
DomHTMLElement imgElement;
if (colorFilter is ModeHtmlColorFilter) {
imgElement = _createImageElementWithBlend(
Expand Down Expand Up @@ -748,8 +753,7 @@ class BitmapCanvas extends EngineCanvas {
targetWidth *= image.width / src.width;
targetHeight *= image.height / src.height;
}
_applyTargetSize(
imgElement as DomHTMLElement, targetWidth, targetHeight);
_applyTargetSize(imgElement as DomHTMLElement, targetWidth, targetHeight);
if (requiresClipping) {
restore();
}
Expand Down Expand Up @@ -831,7 +835,8 @@ class BitmapCanvas extends EngineCanvas {
ui.BlendMode colorFilterBlendMode,
SurfacePaintData paint) {
// For srcIn blendMode, we use an svg filter to apply to image element.
final SvgFilter svgFilter = svgFilterFromBlendMode(filterColor, colorFilterBlendMode);
final SvgFilter svgFilter =
svgFilterFromBlendMode(filterColor, colorFilterBlendMode);
rootElement.append(svgFilter.element);
_children.add(svgFilter.element);
final DomHTMLElement imgElement = _reuseOrCreateImage(image);
Expand Down Expand Up @@ -893,7 +898,8 @@ class BitmapCanvas extends EngineCanvas {
///
/// The text is drawn starting at coordinates ([x], [y]). It uses the current
/// font set by the most recent call to [setCssFont].
void drawText(String text, double x, double y, {ui.PaintingStyle? style, List<ui.Shadow>? shadows}) {
void drawText(String text, double x, double y,
{ui.PaintingStyle? style, List<ui.Shadow>? shadows}) {
final DomCanvasRenderingContext2D ctx = _canvasPool.context;
if (shadows != null) {
ctx.save();
Expand Down Expand Up @@ -932,27 +938,23 @@ class BitmapCanvas extends EngineCanvas {
// Cannot composite if the paragraph cannot be drawn into bitmap canvas
// in the first place.
paragraph.canDrawOnCanvas &&
// Cannot composite if there's no bitmap canvas to composite into.
// Creating a new bitmap canvas just to draw text doesn't make sense.
_canvasPool.hasCanvas &&
!_childOverdraw &&
// Bitmap canvas introduces correctness issues in the presence of SVG
// filters, so prefer plain HTML in this case.
!_renderStrategy.isInsideSvgFilterTree;
// Cannot composite if there's no bitmap canvas to composite into.
// Creating a new bitmap canvas just to draw text doesn't make sense.
_canvasPool.hasCanvas &&
!_childOverdraw &&
// Bitmap canvas introduces correctness issues in the presence of SVG
// filters, so prefer plain HTML in this case.
!_renderStrategy.isInsideSvgFilterTree;

if (canCompositeIntoBitmapCanvas) {
paragraph.paint(this, offset);
return;
}

final DomElement paragraphElement =
drawParagraphElement(paragraph, offset);
final DomElement paragraphElement = drawParagraphElement(paragraph, offset);
if (_canvasPool.isClipped) {
final List<DomElement> clipElements = _clipContent(
_canvasPool.clipStack!,
paragraphElement,
offset,
_canvasPool.currentTransform);
final List<DomElement> clipElements = _clipContent(_canvasPool.clipStack!,
paragraphElement, offset, _canvasPool.currentTransform);
for (final DomElement clipElement in clipElements) {
rootElement.append(clipElement);
_children.add(clipElement);
Expand Down Expand Up @@ -1050,7 +1052,8 @@ class BitmapCanvas extends EngineCanvas {
void endOfPaint() {
_canvasPool.endOfPaint();
_elementCache?.commitFrame();
if (_contains3dTransform && ui_web.browser.browserEngine == ui_web.BrowserEngine.webkit) {
if (_contains3dTransform &&
ui_web.browser.browserEngine == ui_web.BrowserEngine.webkit) {
// Copy the children list to avoid concurrent modification.
final List<DomElement> children = rootElement.children.toList();
for (final DomElement element in children) {
Expand Down Expand Up @@ -1080,10 +1083,12 @@ class BitmapCanvas extends EngineCanvas {
final double width = ui.window.physicalSize.width * dpr;
final double height = ui.window.physicalSize.height * dpr;
final Vector3 topLeft = inverted.perspectiveTransform(x: 0, y: 0, z: 0);
final Vector3 topRight = inverted.perspectiveTransform(x: width, y: 0, z: 0);
final Vector3 topRight =
inverted.perspectiveTransform(x: width, y: 0, z: 0);
final Vector3 bottomRight =
inverted.perspectiveTransform(x: width, y: height, z: 0);
final Vector3 bottomLeft = inverted.perspectiveTransform(x: 0, y: height, z: 0);
final Vector3 bottomLeft =
inverted.perspectiveTransform(x: 0, y: height, z: 0);
return ui.Rect.fromLTRB(
math.min(topLeft.x,
math.min(topRight.x, math.min(bottomRight.x, bottomLeft.x))),
Expand Down Expand Up @@ -1254,13 +1259,17 @@ SvgBlendMode? blendModeToSvgEnum(ui.BlendMode? blendMode) {
case ui.BlendMode.srcATop:
return const SvgBlendMode(kCompositeSourceAtop, SVG_FEBLEND_MODE_UNKNOWN);
case ui.BlendMode.dstOver:
return const SvgBlendMode(kCompositeDestinationOver, SVG_FEBLEND_MODE_UNKNOWN);
return const SvgBlendMode(
kCompositeDestinationOver, SVG_FEBLEND_MODE_UNKNOWN);
case ui.BlendMode.dstIn:
return const SvgBlendMode(kCompositeDestinationIn, SVG_FEBLEND_MODE_UNKNOWN);
return const SvgBlendMode(
kCompositeDestinationIn, SVG_FEBLEND_MODE_UNKNOWN);
case ui.BlendMode.dstOut:
return const SvgBlendMode(kCompositeDestinationOut, SVG_FEBLEND_MODE_UNKNOWN);
return const SvgBlendMode(
kCompositeDestinationOut, SVG_FEBLEND_MODE_UNKNOWN);
case ui.BlendMode.dstATop:
return const SvgBlendMode(kCompositeDestinationAtop, SVG_FEBLEND_MODE_UNKNOWN);
return const SvgBlendMode(
kCompositeDestinationAtop, SVG_FEBLEND_MODE_UNKNOWN);
case ui.BlendMode.plus:
return const SvgBlendMode(kCompositeLighter, SVG_FEBLEND_MODE_UNKNOWN);
case ui.BlendMode.src:
Expand All @@ -1271,7 +1280,8 @@ SvgBlendMode? blendModeToSvgEnum(ui.BlendMode? blendMode) {
// Falling back to multiply, ignoring alpha channel.
// TODO(ferhat): only used for debug, find better fallback for web.
case ui.BlendMode.modulate:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_MULTIPLY);
return const SvgBlendMode(
kCompositeSourceOver, SVG_FEBLEND_MODE_MULTIPLY);
case ui.BlendMode.screen:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_SCREEN);
case ui.BlendMode.overlay:
Expand All @@ -1281,32 +1291,40 @@ SvgBlendMode? blendModeToSvgEnum(ui.BlendMode? blendMode) {
case ui.BlendMode.lighten:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_LIGHTEN);
case ui.BlendMode.colorDodge:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_COLOR_DODGE);
return const SvgBlendMode(
kCompositeSourceOver, SVG_FEBLEND_MODE_COLOR_DODGE);
case ui.BlendMode.colorBurn:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_COLOR_BURN);
return const SvgBlendMode(
kCompositeSourceOver, SVG_FEBLEND_MODE_COLOR_BURN);
case ui.BlendMode.hardLight:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_HARD_LIGHT);
return const SvgBlendMode(
kCompositeSourceOver, SVG_FEBLEND_MODE_HARD_LIGHT);
case ui.BlendMode.softLight:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_SOFT_LIGHT);
return const SvgBlendMode(
kCompositeSourceOver, SVG_FEBLEND_MODE_SOFT_LIGHT);
case ui.BlendMode.difference:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_DIFFERENCE);
return const SvgBlendMode(
kCompositeSourceOver, SVG_FEBLEND_MODE_DIFFERENCE);
case ui.BlendMode.exclusion:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_EXCLUSION);
return const SvgBlendMode(
kCompositeSourceOver, SVG_FEBLEND_MODE_EXCLUSION);
case ui.BlendMode.hue:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_HUE);
case ui.BlendMode.saturation:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_SATURATION);
return const SvgBlendMode(
kCompositeSourceOver, SVG_FEBLEND_MODE_SATURATION);
case ui.BlendMode.color:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_COLOR);
case ui.BlendMode.luminosity:
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_LUMINOSITY);
return const SvgBlendMode(
kCompositeSourceOver, SVG_FEBLEND_MODE_LUMINOSITY);
default:
assert(
false,
'Flutter Web does not support the blend mode: $blendMode',
);

return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_NORMAL);
return const SvgBlendMode(kCompositeSourceOver, SVG_FEBLEND_MODE_NORMAL);
}
}

Expand Down Expand Up @@ -1344,8 +1362,8 @@ String stringForStrokeJoin(ui.StrokeJoin strokeJoin) {
/// overflow:hidden with bounds to clip child or sets a clip-path to clip
/// it's contents. The clipping rectangles are nested and returned together
/// with a list of svg elements that provide clip-paths.
List<DomElement> _clipContent(List<SaveClipEntry> clipStack,
DomElement content, ui.Offset offset, Matrix4 currentTransform) {
List<DomElement> _clipContent(List<SaveClipEntry> clipStack, DomElement content,
ui.Offset offset, Matrix4 currentTransform) {
DomElement? root, curElement;
final List<DomElement> clipDefs = <DomElement>[];
final int len = clipStack.length;
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/html/canvas.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import 'dart:typed_data';

import 'package:ui/ui.dart' as ui;

import '../picture.dart';
import '../util.dart';
import '../validators.dart';
import '../vector_math.dart';
import 'painting.dart';
import 'picture.dart';
import 'recording_canvas.dart';
import 'render_vertices.dart';

Expand Down
Loading