morgan pushed to branch base-browser-128.5.0esr-14.0-1 at The Tor Project / Applications / Tor Browser
Commits:
- 
665e7cdd
by Emilio Cobos Álvarez at 2024-12-09T16:54:02+00:00
- 
d7a304c0
by Emilio Cobos Álvarez at 2024-12-09T16:54:02+00:00
9 changed files:
- dom/canvas/CanvasRenderingContext2D.cpp
- servo/components/style/properties/cascade.rs
- servo/components/style/properties/properties.mako.rs
- servo/components/style/values/computed/box.rs
- servo/components/style/values/specified/length.rs
- servo/ports/geckolib/glue.rs
- + testing/web-platform/tests/css/css-viewport/zoom/canvas-ref.html
- + testing/web-platform/tests/css/css-viewport/zoom/canvas.html
- + testing/web-platform/tests/css/css-viewport/zoom/textarea-very-small-zoom-crash.html
Changes:
| ... | ... | @@ -6,6 +6,7 @@ | 
| 6 | 6 |  #include "CanvasRenderingContext2D.h"
 | 
| 7 | 7 | |
| 8 | 8 |  #include "mozilla/gfx/Helpers.h"
 | 
| 9 | +#include "nsCSSValue.h"
 | |
| 9 | 10 |  #include "nsXULElement.h"
 | 
| 10 | 11 | |
| 11 | 12 |  #include "nsMathUtils.h"
 | 
| ... | ... | @@ -2585,14 +2586,8 @@ static already_AddRefed<StyleLockedDeclarationBlock> CreateDeclarationForServo( | 
| 2585 | 2586 |      return nullptr;
 | 
| 2586 | 2587 |    }
 | 
| 2587 | 2588 | |
| 2588 | -  // From canvas spec, force to set line-height property to 'normal' font
 | |
| 2589 | -  // property.
 | |
| 2590 | 2589 |    if (aProperty == eCSSProperty_font) {
 | 
| 2591 | -    const nsCString normalString = "normal"_ns;
 | |
| 2592 | -    Servo_DeclarationBlock_SetPropertyById(
 | |
| 2593 | -        servoDeclarations, eCSSProperty_line_height, &normalString, false,
 | |
| 2594 | -        env.mUrlExtraData, StyleParsingMode::DEFAULT, env.mCompatMode,
 | |
| 2595 | -        env.mLoader, env.mRuleType, {});
 | |
| 2590 | +    Servo_DeclarationBlock_SanitizeForCanvas(servoDeclarations);
 | |
| 2596 | 2591 |    }
 | 
| 2597 | 2592 | |
| 2598 | 2593 |    return servoDeclarations.forget();
 | 
| ... | ... | @@ -2657,12 +2652,9 @@ static already_AddRefed<const ComputedStyle> GetFontStyleForServo( | 
| 2657 | 2652 |    // The font-size component must be converted to CSS px for reserialization,
 | 
| 2658 | 2653 |    // so we update the declarations with the value from the computed style.
 | 
| 2659 | 2654 |    if (!sc->StyleFont()->mFont.family.is_system_font) {
 | 
| 2660 | -    nsAutoCString computedFontSize;
 | |
| 2661 | -    sc->GetComputedPropertyValue(eCSSProperty_font_size, computedFontSize);
 | |
| 2662 | -    Servo_DeclarationBlock_SetPropertyById(
 | |
| 2663 | -        declarations, eCSSProperty_font_size, &computedFontSize, false, nullptr,
 | |
| 2664 | -        StyleParsingMode::DEFAULT, eCompatibility_FullStandards, nullptr,
 | |
| 2665 | -        StyleCssRuleType::Style, {});
 | |
| 2655 | +    float px = sc->StyleFont()->mFont.size.ToCSSPixels();
 | |
| 2656 | +    Servo_DeclarationBlock_SetLengthValue(declarations, eCSSProperty_font_size,
 | |
| 2657 | +                                          px, eCSSUnit_Pixel);
 | |
| 2666 | 2658 |    }
 | 
| 2667 | 2659 | |
| 2668 | 2660 |    // The font getter is required to be reserialized based on what we
 | 
| ... | ... | @@ -1247,7 +1247,7 @@ impl<'b> Cascade<'b> { | 
| 1247 | 1247 |          );
 | 
| 1248 | 1248 |          debug_assert!(
 | 
| 1249 | 1249 |              !text_scale.text_zoom_enabled(),
 | 
| 1250 | -            "We only ever disable text zoom (in svg:text), never enable it"
 | |
| 1250 | +            "We only ever disable text zoom never enable it"
 | |
| 1251 | 1251 |          );
 | 
| 1252 | 1252 |          let device = builder.device;
 | 
| 1253 | 1253 |          builder.mutate_font().unzoom_fonts(device);
 | 
| ... | ... | @@ -1257,9 +1257,8 @@ impl<'b> Cascade<'b> { | 
| 1257 | 1257 |          debug_assert!(self.seen.contains(LonghandId::Zoom));
 | 
| 1258 | 1258 |          // NOTE(emilio): Intentionally not using the effective zoom here, since all the inherited
 | 
| 1259 | 1259 |          // zooms are already applied.
 | 
| 1260 | -        let zoom = builder.get_box().clone_zoom();
 | |
| 1261 | 1260 |          let old_size = builder.get_font().clone_font_size();
 | 
| 1262 | -        let new_size = old_size.zoom(zoom);
 | |
| 1261 | +        let new_size = old_size.zoom(builder.resolved_specified_zoom());
 | |
| 1263 | 1262 |          if old_size == new_size {
 | 
| 1264 | 1263 |              return;
 | 
| 1265 | 1264 |          }
 | 
| ... | ... | @@ -2711,6 +2711,19 @@ impl<'a> StyleBuilder<'a> { | 
| 2711 | 2711 |          self.get_box().clone_zoom()
 | 
| 2712 | 2712 |      }
 | 
| 2713 | 2713 | |
| 2714 | +    /// The zoom we need to apply for this element, without including ancestor effective zooms.
 | |
| 2715 | +    pub fn resolved_specified_zoom(&self) -> computed::Zoom {
 | |
| 2716 | +        let zoom = self.specified_zoom();
 | |
| 2717 | +        if zoom.is_document() {
 | |
| 2718 | +            // If our inherited effective zoom has derived to zero, there's not much we can do.
 | |
| 2719 | +            // This value is not exposed to content anyways (it's used for scrollbars and to avoid
 | |
| 2720 | +            // zoom affecting canvas).
 | |
| 2721 | +            self.inherited_effective_zoom().inverted().unwrap_or(computed::Zoom::ONE)
 | |
| 2722 | +        } else {
 | |
| 2723 | +            zoom
 | |
| 2724 | +        }
 | |
| 2725 | +    }
 | |
| 2726 | + | |
| 2714 | 2727 |      /// Inherited zoom.
 | 
| 2715 | 2728 |      pub fn inherited_effective_zoom(&self) -> computed::Zoom {
 | 
| 2716 | 2729 |          self.inherited_style.effective_zoom
 | 
| ... | ... | @@ -2747,7 +2760,7 @@ impl<'a> StyleBuilder<'a> { | 
| 2747 | 2760 |          let lh = device.calc_line_height(&font, writing_mode, None);
 | 
| 2748 | 2761 |          if line_height_base == LineHeightBase::InheritedStyle {
 | 
| 2749 | 2762 |              // Apply our own zoom if our style source is the parent style.
 | 
| 2750 | -            computed::NonNegativeLength::new(self.get_box().clone_zoom().zoom(lh.px()))
 | |
| 2763 | +            computed::NonNegativeLength::new(self.resolved_specified_zoom().zoom(lh.px()))
 | |
| 2751 | 2764 |          } else {
 | 
| 2752 | 2765 |              lh
 | 
| 2753 | 2766 |          }
 | 
| ... | ... | @@ -357,6 +357,21 @@ impl Zoom { | 
| 357 | 357 |          self == Self::ONE
 | 
| 358 | 358 |      }
 | 
| 359 | 359 | |
| 360 | +    /// Returns whether we're the `document` keyword.
 | |
| 361 | +    #[inline]
 | |
| 362 | +    pub fn is_document(self) -> bool {
 | |
| 363 | +        self == Self::DOCUMENT
 | |
| 364 | +    }
 | |
| 365 | + | |
| 366 | +    /// Returns the inverse of our value.
 | |
| 367 | +    #[inline]
 | |
| 368 | +    pub fn inverted(&self) -> Option<Self> {
 | |
| 369 | +        if self.0.value == 0 {
 | |
| 370 | +            return None;
 | |
| 371 | +        }
 | |
| 372 | +        Some(Self(Self::ONE.0 / self.0))
 | |
| 373 | +    }
 | |
| 374 | + | |
| 360 | 375 |      /// Returns the value as a float.
 | 
| 361 | 376 |      #[inline]
 | 
| 362 | 377 |      pub fn value(&self) -> f32 {
 | 
| ... | ... | @@ -103,7 +103,7 @@ impl FontBaseSize { | 
| 103 | 103 |              Self::InheritedStyle => {
 | 
| 104 | 104 |                  // If we're using the size from our inherited style, we still need to apply our
 | 
| 105 | 105 |                  // own zoom.
 | 
| 106 | -                let zoom = style.get_box().clone_zoom();
 | |
| 106 | +                let zoom = style.resolved_specified_zoom();
 | |
| 107 | 107 |                  style.get_parent_font().clone_font_size().zoom(zoom)
 | 
| 108 | 108 |              },
 | 
| 109 | 109 |          }
 | 
| ... | ... | @@ -4972,6 +4972,21 @@ fn set_property( | 
| 4972 | 4972 |      )
 | 
| 4973 | 4973 |  }
 | 
| 4974 | 4974 | |
| 4975 | +#[no_mangle]
 | |
| 4976 | +pub unsafe extern "C" fn Servo_DeclarationBlock_SanitizeForCanvas(
 | |
| 4977 | +    declarations: &LockedDeclarationBlock,
 | |
| 4978 | +) {
 | |
| 4979 | +    use style::properties::PropertyDeclaration;
 | |
| 4980 | +    use style::values::specified::{LineHeight, XTextScale, Zoom};
 | |
| 4981 | +    // From canvas spec, force to set line-height property to 'normal' font property.
 | |
| 4982 | +    // Also, for compat, disable text scaling and CSS zoom.
 | |
| 4983 | +    write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
 | |
| 4984 | +        decls.push(PropertyDeclaration::LineHeight(LineHeight::Normal), Importance::Normal);
 | |
| 4985 | +        decls.push(PropertyDeclaration::Zoom(Zoom::Document), Importance::Normal);
 | |
| 4986 | +        decls.push(PropertyDeclaration::XTextScale(XTextScale::None), Importance::Normal);
 | |
| 4987 | +    });
 | |
| 4988 | +}
 | |
| 4989 | + | |
| 4975 | 4990 |  #[no_mangle]
 | 
| 4976 | 4991 |  pub unsafe extern "C" fn Servo_DeclarationBlock_SetProperty(
 | 
| 4977 | 4992 |      declarations: &LockedDeclarationBlock,
 | 
| 1 | +<!DOCTYPE html>
 | |
| 2 | +<style>
 | |
| 3 | +canvas {
 | |
| 4 | +  width: 600px;
 | |
| 5 | +  height: 200px;
 | |
| 6 | +}
 | |
| 7 | +</style>
 | |
| 8 | +<script>
 | |
| 9 | +document.addEventListener("DOMContentLoaded", () => {
 | |
| 10 | +  const ctx = document.getElementById("canvas").getContext("2d");
 | |
| 11 | +  ctx.font = "48px serif";
 | |
| 12 | +  ctx.fillText(ctx.font, 10, 50);
 | |
| 13 | +});
 | |
| 14 | +</script>
 | |
| 15 | +<canvas id="canvas" width="300" height="100"></canvas> | 
| 1 | +<!DOCTYPE html>
 | |
| 2 | +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1909625">
 | |
| 3 | +<link rel="help" href="https://html.spec.whatwg.org/#dom-context-2d-font">
 | |
| 4 | +<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
 | |
| 5 | +<link rel="author" href="https://mozilla.org" title="Mozilla">
 | |
| 6 | +<link rel="match" href="canvas-ref.html">
 | |
| 7 | +<title>zoom is ignored for canvas</title>
 | |
| 8 | +<style>
 | |
| 9 | +canvas {
 | |
| 10 | +  zoom: 2;
 | |
| 11 | +}
 | |
| 12 | +</style>
 | |
| 13 | +<script>
 | |
| 14 | +document.addEventListener("DOMContentLoaded", () => {
 | |
| 15 | +  const ctx = document.getElementById("canvas").getContext("2d");
 | |
| 16 | +  ctx.font = "48px serif";
 | |
| 17 | +  ctx.fillText(ctx.font, 10, 50);
 | |
| 18 | +});
 | |
| 19 | +</script>
 | |
| 20 | +<canvas id="canvas" width="300" height="100"></canvas> | 
| 1 | +<style>
 | |
| 2 | +*:nth-of-type(1) {
 | |
| 3 | +  zoom: 5%;
 | |
| 4 | +}
 | |
| 5 | +</style>
 | |
| 6 | +<textarea> |