Commit 8eafe392 authored by Xiaocheng Hu's avatar Xiaocheng Hu Committed by Commit Bot

CanvasRenderingContext2D should update font on demand

CanvasRenderingContext2D stores a font to draw text, but doesn't always
update it when the document's font cache is invalidated. In particular,
it's not notified when @font-face rules are added or removed.

This patch makes CanvasRenderingContext2D to ensure font validity when
using the font, by updating the font if it's invalid.

Bug: 1051715
Change-Id: I29d89a897b9ccaf14848dab0f33b115f4b3eee0c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2053508Reviewed-by: default avatarFernando Serboncini <fserb@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#744363}
parent ee16e6cf
......@@ -459,8 +459,7 @@ String CanvasRenderingContext2D::font() const {
canvas()->GetDocument().GetCanvasFontCache()->WillUseCurrentFont();
StringBuilder serialized_font;
const FontDescription& font_description =
GetState().GetFont().GetFontDescription();
const FontDescription& font_description = GetState().GetFontDescription();
if (font_description.Style() == ItalicSlopeValue())
serialized_font.Append("italic ");
......@@ -933,7 +932,7 @@ const Font& CanvasRenderingContext2D::AccessFont() {
if (!GetState().HasRealizedFont())
setFont(GetState().UnparsedFont());
canvas()->GetDocument().GetCanvasFontCache()->WillUseCurrentFont();
return GetState().GetFont();
return ModifiableState().GetFont();
}
void CanvasRenderingContext2D::SetIsInHiddenPage(bool hidden) {
......
......@@ -262,11 +262,19 @@ void CanvasRenderingContext2DState::SetFont(const Font& font,
selector->RegisterForInvalidationCallbacks(this);
}
const Font& CanvasRenderingContext2DState::GetFont() const {
const Font& CanvasRenderingContext2DState::GetFont() {
DCHECK(realized_font_);
if (!font_.IsFallbackValid())
FontsNeedUpdate(font_.GetFontSelector());
return font_;
}
const FontDescription& CanvasRenderingContext2DState::GetFontDescription()
const {
DCHECK(realized_font_);
return font_.GetFontDescription();
}
void CanvasRenderingContext2DState::SetTransform(
const AffineTransform& transform) {
is_transform_invertible_ = transform.IsInvertible();
......
......@@ -79,7 +79,8 @@ class CanvasRenderingContext2DState final
}
void SetFont(const Font&, FontSelector*);
const Font& GetFont() const;
const Font& GetFont();
const FontDescription& GetFontDescription() const;
bool HasRealizedFont() const { return realized_font_; }
void SetUnparsedFont(const String& font) { unparsed_font_ = font; }
const String& UnparsedFont() const { return unparsed_font_; }
......
......@@ -355,8 +355,7 @@ String OffscreenCanvasRenderingContext2D::font() const {
return kDefaultFont;
StringBuilder serialized_font;
const FontDescription& font_description =
GetState().GetFont().GetFontDescription();
const FontDescription& font_description = GetState().GetFontDescription();
if (font_description.Style() == ItalicSlopeValue())
serialized_font.Append("italic ");
......@@ -606,7 +605,7 @@ TextMetrics* OffscreenCanvasRenderingContext2D::measureText(
const Font& OffscreenCanvasRenderingContext2D::AccessFont() {
if (!GetState().HasRealizedFont())
setFont(GetState().UnparsedFont());
return GetState().GetFont();
return ModifiableState().GetFont();
}
bool OffscreenCanvasRenderingContext2D::IsCanvas2DBufferValid() const {
......
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<canvas id="target"></canvas>
<script>
// https://crbug.com/1051715
test(() => {
const ctx = document.getElementById('target').getContext('2d');
ctx.font = '25px custom-font';
const style = document.createElement('style');
style.textContent = '@font-face { font-family: custom-font; src: url(fake-font.woff); }';
document.body.appendChild(style);
ctx.fillText('foo', 0, 0);
// This is a crash test. Nothing to assert.
}, '@font-face rule changes should not lead to canvas crash');
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment