Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(263)

Side by Side Diff: third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp

Issue 2387093002: Reflow comments in canvas-related folders (Closed)
Patch Set: More fix Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
3 * All rights reserved.
3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) 4 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 5 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> 7 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org>
7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 8 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved. 9 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved.
9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 10 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
10 * 11 *
11 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 static const char rtl[] = "rtl"; 74 static const char rtl[] = "rtl";
74 static const char ltr[] = "ltr"; 75 static const char ltr[] = "ltr";
75 static const double TryRestoreContextInterval = 0.5; 76 static const double TryRestoreContextInterval = 0.5;
76 static const unsigned MaxTryRestoreContextAttempts = 4; 77 static const unsigned MaxTryRestoreContextAttempts = 4;
77 static const double cDeviceScaleFactor = 1.0; // Canvas is device independent 78 static const double cDeviceScaleFactor = 1.0; // Canvas is device independent
78 79
79 static bool contextLostRestoredEventsEnabled() { 80 static bool contextLostRestoredEventsEnabled() {
80 return RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled(); 81 return RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled();
81 } 82 }
82 83
83 // Drawing methods need to use this instead of SkAutoCanvasRestore in case overd raw 84 // Drawing methods need to use this instead of SkAutoCanvasRestore in case
84 // detection substitutes the recording canvas (to discard overdrawn draw calls). 85 // overdraw detection substitutes the recording canvas (to discard overdrawn
86 // draw calls).
85 class CanvasRenderingContext2DAutoRestoreSkCanvas { 87 class CanvasRenderingContext2DAutoRestoreSkCanvas {
86 STACK_ALLOCATED(); 88 STACK_ALLOCATED();
87 89
88 public: 90 public:
89 explicit CanvasRenderingContext2DAutoRestoreSkCanvas( 91 explicit CanvasRenderingContext2DAutoRestoreSkCanvas(
90 CanvasRenderingContext2D* context) 92 CanvasRenderingContext2D* context)
91 : m_context(context), m_saveCount(0) { 93 : m_context(context), m_saveCount(0) {
92 ASSERT(m_context); 94 ASSERT(m_context);
93 SkCanvas* c = m_context->drawingCanvas(); 95 SkCanvas* c = m_context->drawingCanvas();
94 if (c) { 96 if (c) {
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 223
222 void CanvasRenderingContext2D::dispatchContextLostEvent(TimerBase*) { 224 void CanvasRenderingContext2D::dispatchContextLostEvent(TimerBase*) {
223 if (canvas() && contextLostRestoredEventsEnabled()) { 225 if (canvas() && contextLostRestoredEventsEnabled()) {
224 Event* event = Event::createCancelable(EventTypeNames::contextlost); 226 Event* event = Event::createCancelable(EventTypeNames::contextlost);
225 canvas()->dispatchEvent(event); 227 canvas()->dispatchEvent(event);
226 if (event->defaultPrevented()) { 228 if (event->defaultPrevented()) {
227 m_contextRestorable = false; 229 m_contextRestorable = false;
228 } 230 }
229 } 231 }
230 232
231 // If RealLostContext, it means the context was not lost due to surface failur e 233 // If RealLostContext, it means the context was not lost due to surface
232 // but rather due to a an eviction, which means image buffer exists. 234 // failure but rather due to a an eviction, which means image buffer exists.
233 if (m_contextRestorable && m_contextLostMode == RealLostContext) { 235 if (m_contextRestorable && m_contextLostMode == RealLostContext) {
234 m_tryRestoreContextAttemptCount = 0; 236 m_tryRestoreContextAttemptCount = 0;
235 m_tryRestoreContextEventTimer.startRepeating(TryRestoreContextInterval, 237 m_tryRestoreContextEventTimer.startRepeating(TryRestoreContextInterval,
236 BLINK_FROM_HERE); 238 BLINK_FROM_HERE);
237 } 239 }
238 } 240 }
239 241
240 void CanvasRenderingContext2D::tryRestoreContextEvent(TimerBase* timer) { 242 void CanvasRenderingContext2D::tryRestoreContextEvent(TimerBase* timer) {
241 if (m_contextLostMode == NotLostContext) { 243 if (m_contextLostMode == NotLostContext) {
242 // Canvas was already restored (possibly thanks to a resize), so stop trying . 244 // Canvas was already restored (possibly thanks to a resize), so stop
245 // trying.
243 m_tryRestoreContextEventTimer.stop(); 246 m_tryRestoreContextEventTimer.stop();
244 return; 247 return;
245 } 248 }
246 249
247 DCHECK(m_contextLostMode == RealLostContext); 250 DCHECK(m_contextLostMode == RealLostContext);
248 if (canvas()->hasImageBuffer() && canvas()->buffer()->restoreSurface()) { 251 if (canvas()->hasImageBuffer() && canvas()->buffer()->restoreSurface()) {
249 m_tryRestoreContextEventTimer.stop(); 252 m_tryRestoreContextEventTimer.stop();
250 dispatchContextRestoredEvent(nullptr); 253 dispatchContextRestoredEvent(nullptr);
251 } 254 }
252 255
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 326
324 // Offset by the canvas rect 327 // Offset by the canvas rect
325 LayoutRect pathRect(boundingRect); 328 LayoutRect pathRect(boundingRect);
326 IntRect canvasRect = layoutBox->absoluteContentBox(); 329 IntRect canvasRect = layoutBox->absoluteContentBox();
327 pathRect.moveBy(canvasRect.location()); 330 pathRect.moveBy(canvasRect.location());
328 331
329 renderer->scrollRectToVisible(pathRect, ScrollAlignment::alignCenterAlways, 332 renderer->scrollRectToVisible(pathRect, ScrollAlignment::alignCenterAlways,
330 ScrollAlignment::alignTopAlways); 333 ScrollAlignment::alignTopAlways);
331 334
332 // TODO: should implement "inform the user" that the caret and/or 335 // TODO: should implement "inform the user" that the caret and/or
333 // selection the specified rectangle of the canvas. See http://crbug.com/35798 7 336 // selection the specified rectangle of the canvas. See
337 // http://crbug.com/357987
334 } 338 }
335 339
336 void CanvasRenderingContext2D::clearRect(double x, 340 void CanvasRenderingContext2D::clearRect(double x,
337 double y, 341 double y,
338 double width, 342 double width,
339 double height) { 343 double height) {
340 BaseRenderingContext2D::clearRect(x, y, width, height); 344 BaseRenderingContext2D::clearRect(x, y, width, height);
341 345
342 if (m_hitRegionManager) { 346 if (m_hitRegionManager) {
343 FloatRect rect(x, y, width, height); 347 FloatRect rect(x, y, width, height);
(...skipping 17 matching lines...) Expand all
361 365
362 bool CanvasRenderingContext2D::stateHasFilter() { 366 bool CanvasRenderingContext2D::stateHasFilter() {
363 return state().hasFilter(canvas(), canvas()->size(), this); 367 return state().hasFilter(canvas(), canvas()->size(), this);
364 } 368 }
365 369
366 SkImageFilter* CanvasRenderingContext2D::stateGetFilter() { 370 SkImageFilter* CanvasRenderingContext2D::stateGetFilter() {
367 return state().getFilter(canvas(), canvas()->size(), this); 371 return state().getFilter(canvas(), canvas()->size(), this);
368 } 372 }
369 373
370 void CanvasRenderingContext2D::snapshotStateForFilter() { 374 void CanvasRenderingContext2D::snapshotStateForFilter() {
371 // The style resolution required for fonts is not available in frame-less docu ments. 375 // The style resolution required for fonts is not available in frame-less
376 // documents.
372 if (!canvas()->document().frame()) 377 if (!canvas()->document().frame())
373 return; 378 return;
374 379
375 modifiableState().setFontForFilter(accessFont()); 380 modifiableState().setFontForFilter(accessFont());
376 } 381 }
377 382
378 SkCanvas* CanvasRenderingContext2D::drawingCanvas() const { 383 SkCanvas* CanvasRenderingContext2D::drawingCanvas() const {
379 if (isContextLost()) 384 if (isContextLost())
380 return nullptr; 385 return nullptr;
381 return canvas()->drawingCanvas(); 386 return canvas()->drawingCanvas();
(...skipping 28 matching lines...) Expand all
410 415
411 serializedFont.appendNumber(fontDescription.computedPixelSize()); 416 serializedFont.appendNumber(fontDescription.computedPixelSize());
412 serializedFont.append("px"); 417 serializedFont.append("px");
413 418
414 const FontFamily& firstFontFamily = fontDescription.family(); 419 const FontFamily& firstFontFamily = fontDescription.family();
415 for (const FontFamily* fontFamily = &firstFontFamily; fontFamily; 420 for (const FontFamily* fontFamily = &firstFontFamily; fontFamily;
416 fontFamily = fontFamily->next()) { 421 fontFamily = fontFamily->next()) {
417 if (fontFamily != &firstFontFamily) 422 if (fontFamily != &firstFontFamily)
418 serializedFont.append(','); 423 serializedFont.append(',');
419 424
420 // FIXME: We should append family directly to serializedFont rather than bui lding a temporary string. 425 // FIXME: We should append family directly to serializedFont rather than
426 // building a temporary string.
421 String family = fontFamily->family(); 427 String family = fontFamily->family();
422 if (family.startsWith("-webkit-")) 428 if (family.startsWith("-webkit-"))
423 family = family.substring(8); 429 family = family.substring(8);
424 if (family.contains(' ')) 430 if (family.contains(' '))
425 family = "\"" + family + "\""; 431 family = "\"" + family + "\"";
426 432
427 serializedFont.append(' '); 433 serializedFont.append(' ');
428 serializedFont.append(family); 434 serializedFont.append(family);
429 } 435 }
430 436
431 return serializedFont.toString(); 437 return serializedFont.toString();
432 } 438 }
433 439
434 void CanvasRenderingContext2D::setFont(const String& newFont) { 440 void CanvasRenderingContext2D::setFont(const String& newFont) {
435 // The style resolution required for fonts is not available in frame-less docu ments. 441 // The style resolution required for fonts is not available in frame-less
442 // documents.
436 if (!canvas()->document().frame()) 443 if (!canvas()->document().frame())
437 return; 444 return;
438 445
439 canvas()->document().updateStyleAndLayoutTreeForNode(canvas()); 446 canvas()->document().updateStyleAndLayoutTreeForNode(canvas());
440 447
441 // The following early exit is dependent on the cache not being empty 448 // The following early exit is dependent on the cache not being empty
442 // because an empty cache may indicate that a style change has occured 449 // because an empty cache may indicate that a style change has occured
443 // which would require that the font be re-resolved. This check has to 450 // which would require that the font be re-resolved. This check has to
444 // come after the layout tree update to flush pending style changes. 451 // come after the layout tree update to flush pending style changes.
445 if (newFont == state().unparsedFont() && state().hasRealizedFont() && 452 if (newFont == state().unparsedFont() && state().hasRealizedFont() &&
446 m_fontsResolvedUsingCurrentStyle.size() > 0) 453 m_fontsResolvedUsingCurrentStyle.size() > 0)
447 return; 454 return;
448 455
449 CanvasFontCache* canvasFontCache = canvas()->document().canvasFontCache(); 456 CanvasFontCache* canvasFontCache = canvas()->document().canvasFontCache();
450 457
451 // Map the <canvas> font into the text style. If the font uses keywords like l arger/smaller, these will work 458 // Map the <canvas> font into the text style. If the font uses keywords like
452 // relative to the canvas. 459 // larger/smaller, these will work relative to the canvas.
453 RefPtr<ComputedStyle> fontStyle; 460 RefPtr<ComputedStyle> fontStyle;
454 const ComputedStyle* computedStyle = canvas()->ensureComputedStyle(); 461 const ComputedStyle* computedStyle = canvas()->ensureComputedStyle();
455 if (computedStyle) { 462 if (computedStyle) {
456 HashMap<String, Font>::iterator i = 463 HashMap<String, Font>::iterator i =
457 m_fontsResolvedUsingCurrentStyle.find(newFont); 464 m_fontsResolvedUsingCurrentStyle.find(newFont);
458 if (i != m_fontsResolvedUsingCurrentStyle.end()) { 465 if (i != m_fontsResolvedUsingCurrentStyle.end()) {
459 ASSERT(m_fontLRUList.contains(newFont)); 466 ASSERT(m_fontLRUList.contains(newFont));
460 m_fontLRUList.remove(newFont); 467 m_fontLRUList.remove(newFont);
461 m_fontLRUList.add(newFont); 468 m_fontLRUList.add(newFont);
462 modifiableState().setFont( 469 modifiableState().setFont(
463 i->value, canvas()->document().styleEngine().fontSelector()); 470 i->value, canvas()->document().styleEngine().fontSelector());
464 } else { 471 } else {
465 MutableStylePropertySet* parsedStyle = 472 MutableStylePropertySet* parsedStyle =
466 canvasFontCache->parseFont(newFont); 473 canvasFontCache->parseFont(newFont);
467 if (!parsedStyle) 474 if (!parsedStyle)
468 return; 475 return;
469 fontStyle = ComputedStyle::create(); 476 fontStyle = ComputedStyle::create();
470 FontDescription elementFontDescription( 477 FontDescription elementFontDescription(
471 computedStyle->getFontDescription()); 478 computedStyle->getFontDescription());
472 // Reset the computed size to avoid inheriting the zoom factor from the <c anvas> element. 479 // Reset the computed size to avoid inheriting the zoom factor from the
480 // <canvas> element.
473 elementFontDescription.setComputedSize( 481 elementFontDescription.setComputedSize(
474 elementFontDescription.specifiedSize()); 482 elementFontDescription.specifiedSize());
475 fontStyle->setFontDescription(elementFontDescription); 483 fontStyle->setFontDescription(elementFontDescription);
476 fontStyle->font().update(fontStyle->font().getFontSelector()); 484 fontStyle->font().update(fontStyle->font().getFontSelector());
477 canvas()->document().ensureStyleResolver().computeFont(fontStyle.get(), 485 canvas()->document().ensureStyleResolver().computeFont(fontStyle.get(),
478 *parsedStyle); 486 *parsedStyle);
479 m_fontsResolvedUsingCurrentStyle.add(newFont, fontStyle->font()); 487 m_fontsResolvedUsingCurrentStyle.add(newFont, fontStyle->font());
480 ASSERT(!m_fontLRUList.contains(newFont)); 488 ASSERT(!m_fontLRUList.contains(newFont));
481 m_fontLRUList.add(newFont); 489 m_fontLRUList.add(newFont);
482 pruneLocalFontCache(canvasFontCache->hardMaxFonts()); // hard limit 490 pruneLocalFontCache(canvasFontCache->hardMaxFonts()); // hard limit
483 schedulePruneLocalFontCacheIfNeeded(); // soft limit 491 schedulePruneLocalFontCacheIfNeeded(); // soft limit
484 modifiableState().setFont( 492 modifiableState().setFont(
485 fontStyle->font(), canvas()->document().styleEngine().fontSelector()); 493 fontStyle->font(), canvas()->document().styleEngine().fontSelector());
486 } 494 }
487 } else { 495 } else {
488 Font resolvedFont; 496 Font resolvedFont;
489 if (!canvasFontCache->getFontUsingDefaultStyle(newFont, resolvedFont)) 497 if (!canvasFontCache->getFontUsingDefaultStyle(newFont, resolvedFont))
490 return; 498 return;
491 modifiableState().setFont( 499 modifiableState().setFont(
492 resolvedFont, canvas()->document().styleEngine().fontSelector()); 500 resolvedFont, canvas()->document().styleEngine().fontSelector());
493 } 501 }
494 502
495 // The parse succeeded. 503 // The parse succeeded.
496 String newFontSafeCopy( 504 String newFontSafeCopy(newFont); // Create a string copy since newFont can be
497 newFont); // Create a string copy since newFont can be deleted inside rea lizeSaves. 505 // deleted inside realizeSaves.
498 modifiableState().setUnparsedFont(newFontSafeCopy); 506 modifiableState().setUnparsedFont(newFontSafeCopy);
499 } 507 }
500 508
501 void CanvasRenderingContext2D::schedulePruneLocalFontCacheIfNeeded() { 509 void CanvasRenderingContext2D::schedulePruneLocalFontCacheIfNeeded() {
502 if (m_pruneLocalFontCacheScheduled) 510 if (m_pruneLocalFontCacheScheduled)
503 return; 511 return;
504 m_pruneLocalFontCacheScheduled = true; 512 m_pruneLocalFontCacheScheduled = true;
505 Platform::current()->currentThread()->addTaskObserver(this); 513 Platform::current()->currentThread()->addTaskObserver(this);
506 } 514 }
507 515
508 void CanvasRenderingContext2D::didProcessTask() { 516 void CanvasRenderingContext2D::didProcessTask() {
509 Platform::current()->currentThread()->removeTaskObserver(this); 517 Platform::current()->currentThread()->removeTaskObserver(this);
510 518
511 // This should be the only place where canvas() needs to be checked for nullne ss 519 // This should be the only place where canvas() needs to be checked for
512 // because the circular refence with HTMLCanvasElement mean the canvas and the 520 // nullness because the circular refence with HTMLCanvasElement mean the
513 // context keep each other alive as long as the pair is referenced the task 521 // canvas and the context keep each other alive as long as the pair is
514 // observer is the only persisten refernce to this object that is not traced, 522 // referenced the task observer is the only persisten refernce to this object
515 // so didProcessTask() may be call at a time when the canvas has been garbage 523 // that is not traced, so didProcessTask() may be call at a time when the
516 // collected but not the context. 524 // canvas has been garbage collected but not the context.
517 if (!canvas()) 525 if (!canvas())
518 return; 526 return;
519 527
520 // The rendering surface needs to be prepared now because it will be too late 528 // The rendering surface needs to be prepared now because it will be too late
521 // to create a layer once we are in the paint invalidation phase. 529 // to create a layer once we are in the paint invalidation phase.
522 canvas()->prepareSurfaceForPaintingIfNeeded(); 530 canvas()->prepareSurfaceForPaintingIfNeeded();
523 531
524 pruneLocalFontCache(canvas()->document().canvasFontCache()->maxFonts()); 532 pruneLocalFontCache(canvas()->document().canvasFontCache()->maxFonts());
525 m_pruneLocalFontCacheScheduled = false; 533 m_pruneLocalFontCacheScheduled = false;
526 } 534 }
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 double y, 727 double y,
720 double maxWidth) { 728 double maxWidth) {
721 trackDrawCall(StrokeText); 729 trackDrawCall(StrokeText);
722 drawTextInternal(text, x, y, CanvasRenderingContext2DState::StrokePaintType, 730 drawTextInternal(text, x, y, CanvasRenderingContext2DState::StrokePaintType,
723 &maxWidth); 731 &maxWidth);
724 } 732 }
725 733
726 TextMetrics* CanvasRenderingContext2D::measureText(const String& text) { 734 TextMetrics* CanvasRenderingContext2D::measureText(const String& text) {
727 TextMetrics* metrics = TextMetrics::create(); 735 TextMetrics* metrics = TextMetrics::create();
728 736
729 // The style resolution required for fonts is not available in frame-less docu ments. 737 // The style resolution required for fonts is not available in frame-less
738 // documents.
730 if (!canvas()->document().frame()) 739 if (!canvas()->document().frame())
731 return metrics; 740 return metrics;
732 741
733 canvas()->document().updateStyleAndLayoutTreeForNode(canvas()); 742 canvas()->document().updateStyleAndLayoutTreeForNode(canvas());
734 const Font& font = accessFont(); 743 const Font& font = accessFont();
735 744
736 TextDirection direction; 745 TextDirection direction;
737 if (state().getDirection() == CanvasRenderingContext2DState::DirectionInherit) 746 if (state().getDirection() == CanvasRenderingContext2DState::DirectionInherit)
738 direction = determineDirectionality(text); 747 direction = determineDirectionality(text);
739 else 748 else
(...skipping 15 matching lines...) Expand all
755 const FontMetrics& fontMetrics = font.getFontMetrics(); 764 const FontMetrics& fontMetrics = font.getFontMetrics();
756 const float ascent = fontMetrics.floatAscent(); 765 const float ascent = fontMetrics.floatAscent();
757 const float descent = fontMetrics.floatDescent(); 766 const float descent = fontMetrics.floatDescent();
758 const float baselineY = getFontBaseline(fontMetrics); 767 const float baselineY = getFontBaseline(fontMetrics);
759 768
760 metrics->setFontBoundingBoxAscent(ascent - baselineY); 769 metrics->setFontBoundingBoxAscent(ascent - baselineY);
761 metrics->setFontBoundingBoxDescent(descent + baselineY); 770 metrics->setFontBoundingBoxDescent(descent + baselineY);
762 metrics->setActualBoundingBoxAscent(-textBounds.y() - baselineY); 771 metrics->setActualBoundingBoxAscent(-textBounds.y() - baselineY);
763 metrics->setActualBoundingBoxDescent(textBounds.maxY() + baselineY); 772 metrics->setActualBoundingBoxDescent(textBounds.maxY() + baselineY);
764 773
765 // Note : top/bottom and ascend/descend are currently the same, so there's no difference 774 // Note : top/bottom and ascend/descend are currently the same, so there's no
766 // between the EM box's top and bottom and the font's ascend and descen d 775 // difference between the EM box's top and bottom and the font's ascend and
776 // descend
767 metrics->setEmHeightAscent(0); 777 metrics->setEmHeightAscent(0);
768 metrics->setEmHeightDescent(0); 778 metrics->setEmHeightDescent(0);
769 779
770 metrics->setHangingBaseline(0.8f * ascent - baselineY); 780 metrics->setHangingBaseline(0.8f * ascent - baselineY);
771 metrics->setAlphabeticBaseline(-baselineY); 781 metrics->setAlphabeticBaseline(-baselineY);
772 metrics->setIdeographicBaseline(-descent - baselineY); 782 metrics->setIdeographicBaseline(-descent - baselineY);
773 return metrics; 783 return metrics;
774 } 784 }
775 785
776 void CanvasRenderingContext2D::drawTextInternal( 786 void CanvasRenderingContext2D::drawTextInternal(
777 const String& text, 787 const String& text,
778 double x, 788 double x,
779 double y, 789 double y,
780 CanvasRenderingContext2DState::PaintType paintType, 790 CanvasRenderingContext2DState::PaintType paintType,
781 double* maxWidth) { 791 double* maxWidth) {
782 // The style resolution required for fonts is not available in frame-less docu ments. 792 // The style resolution required for fonts is not available in frame-less
793 // documents.
783 if (!canvas()->document().frame()) 794 if (!canvas()->document().frame())
784 return; 795 return;
785 796
786 // accessFont needs the style to be up to date, but updating style can cause s cript to run, 797 // accessFont needs the style to be up to date, but updating style can cause
787 // (e.g. due to autofocus) which can free the canvas (set size to 0, for examp le), so update 798 // script to run, (e.g. due to autofocus) which can free the canvas (set size
788 // style before grabbing the drawingCanvas. 799 // to 0, for example), so update style before grabbing the drawingCanvas.
789 canvas()->document().updateStyleAndLayoutTreeForNode(canvas()); 800 canvas()->document().updateStyleAndLayoutTreeForNode(canvas());
790 801
791 SkCanvas* c = drawingCanvas(); 802 SkCanvas* c = drawingCanvas();
792 if (!c) 803 if (!c)
793 return; 804 return;
794 805
795 if (!std::isfinite(x) || !std::isfinite(y)) 806 if (!std::isfinite(x) || !std::isfinite(y))
796 return; 807 return;
797 if (maxWidth && (!std::isfinite(*maxWidth) || *maxWidth <= 0)) 808 if (maxWidth && (!std::isfinite(*maxWidth) || *maxWidth <= 0))
798 return; 809 return;
799 810
800 // Currently, SkPictureImageFilter does not support subpixel text anti-aliasin g, which 811 // Currently, SkPictureImageFilter does not support subpixel text
801 // is expected when !creationAttributes().alpha(), so we need to fall out of d isplay 812 // anti-aliasing, which is expected when !creationAttributes().alpha(), so we
802 // list mode when drawing text to an opaque canvas. 813 // need to fall out of display list mode when drawing text to an opaque
803 // crbug.com/583809 814 // canvas. crbug.com/583809
804 if (!creationAttributes().alpha() && !isAccelerated()) 815 if (!creationAttributes().alpha() && !isAccelerated())
805 canvas()->disableDeferral( 816 canvas()->disableDeferral(
806 DisableDeferralReasonSubPixelTextAntiAliasingSupport); 817 DisableDeferralReasonSubPixelTextAntiAliasingSupport);
807 818
808 const Font& font = accessFont(); 819 const Font& font = accessFont();
809 if (!font.primaryFont()) 820 if (!font.primaryFont())
810 return; 821 return;
811 822
812 const FontMetrics& fontMetrics = font.getFontMetrics(); 823 const FontMetrics& fontMetrics = font.getFontMetrics();
813 824
(...skipping 26 matching lines...) Expand all
840 case CenterTextAlign: 851 case CenterTextAlign:
841 location.setX(location.x() - width / 2); 852 location.setX(location.x() - width / 2);
842 break; 853 break;
843 case RightTextAlign: 854 case RightTextAlign:
844 location.setX(location.x() - width); 855 location.setX(location.x() - width);
845 break; 856 break;
846 default: 857 default:
847 break; 858 break;
848 } 859 }
849 860
850 // The slop built in to this mask rect matches the heuristic used in FontCGWin .cpp for GDI text. 861 // The slop built in to this mask rect matches the heuristic used in
862 // FontCGWin.cpp for GDI text.
851 TextRunPaintInfo textRunPaintInfo(textRun); 863 TextRunPaintInfo textRunPaintInfo(textRun);
852 textRunPaintInfo.bounds = 864 textRunPaintInfo.bounds =
853 FloatRect(location.x() - fontMetrics.height() / 2, 865 FloatRect(location.x() - fontMetrics.height() / 2,
854 location.y() - fontMetrics.ascent() - fontMetrics.lineGap(), 866 location.y() - fontMetrics.ascent() - fontMetrics.lineGap(),
855 width + fontMetrics.height(), fontMetrics.lineSpacing()); 867 width + fontMetrics.height(), fontMetrics.lineSpacing());
856 if (paintType == CanvasRenderingContext2DState::StrokePaintType) 868 if (paintType == CanvasRenderingContext2DState::StrokePaintType)
857 inflateStrokeRect(textRunPaintInfo.bounds); 869 inflateStrokeRect(textRunPaintInfo.bounds);
858 870
859 CanvasRenderingContext2DAutoRestoreSkCanvas stateRestorer(this); 871 CanvasRenderingContext2DAutoRestoreSkCanvas stateRestorer(this);
860 if (useMaxWidth) { 872 if (useMaxWidth) {
861 drawingCanvas()->save(); 873 drawingCanvas()->save();
862 drawingCanvas()->translate(location.x(), location.y()); 874 drawingCanvas()->translate(location.x(), location.y());
863 // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) s till work. 875 // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op)
876 // still work.
864 drawingCanvas()->scale((fontWidth > 0 ? (width / fontWidth) : 0), 1); 877 drawingCanvas()->scale((fontWidth > 0 ? (width / fontWidth) : 0), 1);
865 location = FloatPoint(); 878 location = FloatPoint();
866 } 879 }
867 880
868 draw( 881 draw(
869 [&font, this, &textRunPaintInfo, &location]( 882 [&font, this, &textRunPaintInfo, &location](
870 SkCanvas* c, const SkPaint* paint) // draw lambda 883 SkCanvas* c, const SkPaint* paint) // draw lambda
871 { 884 {
872 font.drawBidiText(c, textRunPaintInfo, location, 885 font.drawBidiText(c, textRunPaintInfo, location,
873 Font::UseFallbackIfFontNotReady, cDeviceScaleFactor, 886 Font::UseFallbackIfFontNotReady, cDeviceScaleFactor,
(...skipping 10 matching lines...) Expand all
884 canvas()->document().canvasFontCache()->willUseCurrentFont(); 897 canvas()->document().canvasFontCache()->willUseCurrentFont();
885 return state().font(); 898 return state().font();
886 } 899 }
887 900
888 int CanvasRenderingContext2D::getFontBaseline( 901 int CanvasRenderingContext2D::getFontBaseline(
889 const FontMetrics& fontMetrics) const { 902 const FontMetrics& fontMetrics) const {
890 switch (state().getTextBaseline()) { 903 switch (state().getTextBaseline()) {
891 case TopTextBaseline: 904 case TopTextBaseline:
892 return fontMetrics.ascent(); 905 return fontMetrics.ascent();
893 case HangingTextBaseline: 906 case HangingTextBaseline:
894 // According to http://wiki.apache.org/xmlgraphics-fop/LineLayout/Alignmen tHandling 907 // According to
895 // "FOP (Formatting Objects Processor) puts the hanging baseline at 80% of the ascender height" 908 // http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling
909 // "FOP (Formatting Objects Processor) puts the hanging baseline at 80% of
910 // the ascender height"
896 return (fontMetrics.ascent() * 4) / 5; 911 return (fontMetrics.ascent() * 4) / 5;
897 case BottomTextBaseline: 912 case BottomTextBaseline:
898 case IdeographicTextBaseline: 913 case IdeographicTextBaseline:
899 return -fontMetrics.descent(); 914 return -fontMetrics.descent();
900 case MiddleTextBaseline: 915 case MiddleTextBaseline:
901 return -fontMetrics.descent() + fontMetrics.height() / 2; 916 return -fontMetrics.descent() + fontMetrics.height() / 2;
902 case AlphabeticTextBaseline: 917 case AlphabeticTextBaseline:
903 default: 918 default:
904 // Do nothing. 919 // Do nothing.
905 break; 920 break;
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 1097
1083 unsigned CanvasRenderingContext2D::hitRegionsCount() const { 1098 unsigned CanvasRenderingContext2D::hitRegionsCount() const {
1084 if (m_hitRegionManager) 1099 if (m_hitRegionManager)
1085 return m_hitRegionManager->getHitRegionsCount(); 1100 return m_hitRegionManager->getHitRegionsCount();
1086 1101
1087 return 0; 1102 return 0;
1088 } 1103 }
1089 1104
1090 bool CanvasRenderingContext2D::isAccelerationOptimalForCanvasContent() const { 1105 bool CanvasRenderingContext2D::isAccelerationOptimalForCanvasContent() const {
1091 // Heuristic to determine if the GPU accelerated rendering pipeline is optimal 1106 // Heuristic to determine if the GPU accelerated rendering pipeline is optimal
1092 // for performance based on past usage. It has a bias towards suggesting that the 1107 // for performance based on past usage. It has a bias towards suggesting that
1093 // accelerated pipeline is optimal. 1108 // the accelerated pipeline is optimal.
1094 1109
1095 float acceleratedCost = estimateRenderingCost( 1110 float acceleratedCost = estimateRenderingCost(
1096 ExpensiveCanvasHeuristicParameters::AcceleratedModeIndex); 1111 ExpensiveCanvasHeuristicParameters::AcceleratedModeIndex);
1097 1112
1098 float recordingCost = estimateRenderingCost( 1113 float recordingCost = estimateRenderingCost(
1099 ExpensiveCanvasHeuristicParameters::RecordingModeIndex); 1114 ExpensiveCanvasHeuristicParameters::RecordingModeIndex);
1100 1115
1101 float costDifference = acceleratedCost - recordingCost; 1116 float costDifference = acceleratedCost - recordingCost;
1102 float percentCostReduction = costDifference / acceleratedCost * 100.0; 1117 float percentCostReduction = costDifference / acceleratedCost * 100.0;
1103 float costDifferencePerFrame = 1118 float costDifferencePerFrame =
1104 costDifference / m_usageCounters.numFramesSinceReset; 1119 costDifference / m_usageCounters.numFramesSinceReset;
1105 1120
1106 if (percentCostReduction >= 1121 if (percentCostReduction >=
1107 ExpensiveCanvasHeuristicParameters:: 1122 ExpensiveCanvasHeuristicParameters::
1108 MinPercentageImprovementToSuggestDisableAcceleration && 1123 MinPercentageImprovementToSuggestDisableAcceleration &&
1109 costDifferencePerFrame >= 1124 costDifferencePerFrame >=
1110 ExpensiveCanvasHeuristicParameters:: 1125 ExpensiveCanvasHeuristicParameters::
1111 MinCostPerFrameImprovementToSuggestDisableAcceleration) { 1126 MinCostPerFrameImprovementToSuggestDisableAcceleration) {
1112 return false; 1127 return false;
1113 } 1128 }
1114 return true; 1129 return true;
1115 } 1130 }
1116 1131
1117 void CanvasRenderingContext2D::resetUsageTracking() { 1132 void CanvasRenderingContext2D::resetUsageTracking() {
1118 UsageCounters newCounters; 1133 UsageCounters newCounters;
1119 m_usageCounters = newCounters; 1134 m_usageCounters = newCounters;
1120 } 1135 }
1121 1136
1122 } // namespace blink 1137 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698