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

Side by Side Diff: Source/core/rendering/RenderBoxModelObject.cpp

Issue 23241010: Support subpixel values for text-shadow and box-shadow (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: addressed review comments Created 6 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « Source/core/rendering/InlineTextBox.cpp ('k') | Source/core/rendering/style/RenderStyle.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
7 * Copyright (C) 2010 Google Inc. All rights reserved. 7 * Copyright (C) 2010 Google Inc. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 2481 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 bool hasOpaqueBackground = s->visitedDependentColor(CSSPropertyBackgroundCol or).isValid() && s->visitedDependentColor(CSSPropertyBackgroundColor).alpha() == 255; 2492 bool hasOpaqueBackground = s->visitedDependentColor(CSSPropertyBackgroundCol or).isValid() && s->visitedDependentColor(CSSPropertyBackgroundColor).alpha() == 255;
2493 2493
2494 GraphicsContextStateSaver stateSaver(*context, false); 2494 GraphicsContextStateSaver stateSaver(*context, false);
2495 2495
2496 const ShadowList* shadowList = s->boxShadow(); 2496 const ShadowList* shadowList = s->boxShadow();
2497 for (size_t i = shadowList->shadows().size(); i--; ) { 2497 for (size_t i = shadowList->shadows().size(); i--; ) {
2498 const ShadowData& shadow = shadowList->shadows()[i]; 2498 const ShadowData& shadow = shadowList->shadows()[i];
2499 if (shadow.style() != shadowStyle) 2499 if (shadow.style() != shadowStyle)
2500 continue; 2500 continue;
2501 2501
2502 IntSize shadowOffset(shadow.x(), shadow.y()); 2502 FloatSize shadowOffset(shadow.x(), shadow.y());
2503 int shadowBlur = shadow.blur(); 2503 float shadowBlur = shadow.blur();
2504 int shadowSpread = shadow.spread(); 2504 float shadowSpread = shadow.spread();
2505 2505
2506 if (shadowOffset.isZero() && !shadowBlur && !shadowSpread) 2506 if (shadowOffset.isZero() && !shadowBlur && !shadowSpread)
2507 continue; 2507 continue;
2508 2508
2509 const Color& shadowColor = resolveColor(shadow.color()); 2509 const Color& shadowColor = resolveColor(shadow.color());
2510 2510
2511 if (shadow.style() == Normal) { 2511 if (shadow.style() == Normal) {
2512 RoundedRect fillRect = border; 2512 FloatRect fillRect = border.rect();
2513 fillRect.inflate(shadowSpread); 2513 fillRect.inflate(shadowSpread);
2514 if (fillRect.isEmpty()) 2514 if (fillRect.isEmpty())
2515 continue; 2515 continue;
2516 2516
2517 IntRect shadowRect(border.rect()); 2517 FloatRect shadowRect(border.rect());
2518 shadowRect.inflate(shadowBlur + shadowSpread); 2518 shadowRect.inflate(shadowBlur + shadowSpread);
2519 shadowRect.move(shadowOffset); 2519 shadowRect.move(shadowOffset);
2520 2520
2521 // Save the state and clip, if not already done. 2521 // Save the state and clip, if not already done.
2522 // The clip does not depend on any shadow-specific properties. 2522 // The clip does not depend on any shadow-specific properties.
2523 if (!stateSaver.saved()) { 2523 if (!stateSaver.saved()) {
2524 stateSaver.save(); 2524 stateSaver.save();
2525 if (hasBorderRadius) { 2525 if (hasBorderRadius) {
2526 RoundedRect rectToClipOut = border; 2526 RoundedRect rectToClipOut = border;
2527 2527
2528 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time 2528 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time
2529 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the 2529 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the
2530 // corners. Those are avoided by insetting the clipping path by one pixel. 2530 // corners. Those are avoided by insetting the clipping path by one pixel.
2531 if (hasOpaqueBackground) 2531 if (hasOpaqueBackground)
2532 rectToClipOut.inflateWithRadii(-1); 2532 rectToClipOut.inflateWithRadii(-1);
2533 2533
2534 if (!rectToClipOut.isEmpty()) { 2534 if (!rectToClipOut.isEmpty()) {
2535 context->clipOutRoundedRect(rectToClipOut); 2535 context->clipOutRoundedRect(rectToClipOut);
2536 } 2536 }
2537 } else { 2537 } else {
2538 // This IntRect is correct even with fractional shadows, bec ause it is used for the rectangle
2539 // of the box itself, which is always pixel-aligned.
2538 IntRect rectToClipOut = border.rect(); 2540 IntRect rectToClipOut = border.rect();
2539 2541
2540 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time 2542 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time
2541 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the 2543 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the
2542 // edges if they are not pixel-aligned. Those are avoided by insetting the clipping path 2544 // edges if they are not pixel-aligned. Those are avoided by insetting the clipping path
2543 // by one pixel. 2545 // by one pixel.
2544 if (hasOpaqueBackground) { 2546 if (hasOpaqueBackground) {
2545 // FIXME: The function to decide on the policy based on the transform should be a named function. 2547 // FIXME: The function to decide on the policy based on the transform should be a named function.
2546 // FIXME: It's not clear if this check is right. What ab out integral scale factors? 2548 // FIXME: It's not clear if this check is right. What ab out integral scale factors?
2547 AffineTransform transform = context->getCTM(); 2549 AffineTransform transform = context->getCTM();
2548 if (transform.a() != 1 || (transform.d() != 1 && transfo rm.d() != -1) || transform.b() || transform.c()) 2550 if (transform.a() != 1 || (transform.d() != 1 && transfo rm.d() != -1) || transform.b() || transform.c())
2549 rectToClipOut.inflate(-1); 2551 rectToClipOut.inflate(-1);
2550 } 2552 }
2551 2553
2552 if (!rectToClipOut.isEmpty()) { 2554 if (!rectToClipOut.isEmpty()) {
2553 context->clipOut(rectToClipOut); 2555 context->clipOut(rectToClipOut);
2554 } 2556 }
2555 } 2557 }
2556 } 2558 }
2557 2559
2558 // Draw only the shadow. 2560 // Draw only the shadow.
2559 DrawLooper drawLooper; 2561 DrawLooper drawLooper;
2560 drawLooper.addShadow(shadowOffset, shadowBlur, shadowColor, 2562 drawLooper.addShadow(shadowOffset, shadowBlur, shadowColor,
2561 DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresA lpha); 2563 DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresA lpha);
2562 context->setDrawLooper(drawLooper); 2564 context->setDrawLooper(drawLooper);
2563 2565
2564 if (hasBorderRadius) { 2566 if (hasBorderRadius) {
2565 RoundedRect influenceRect(shadowRect, border.radii()); 2567 RoundedRect influenceRect(pixelSnappedIntRect(LayoutRect(shadowR ect)), border.radii());
2566 influenceRect.expandRadii(2 * shadowBlur + shadowSpread); 2568 influenceRect.expandRadii(2 * shadowBlur + shadowSpread);
2567 if (allCornersClippedOut(influenceRect, info.rect)) 2569 if (allCornersClippedOut(influenceRect, info.rect))
2568 context->fillRect(fillRect.rect(), Color::black); 2570 context->fillRect(fillRect, Color::black);
2569 else { 2571 else {
2570 fillRect.expandRadii(shadowSpread); 2572 // TODO: support non-integer shadows - crbug.com/334829
2571 if (!fillRect.isRenderable()) 2573 RoundedRect roundedFillRect = border;
2572 fillRect.adjustRadii(); 2574 roundedFillRect.inflate(shadowSpread);
2573 context->fillRoundedRect(fillRect, Color::black); 2575
2576 roundedFillRect.expandRadii(shadowSpread);
2577 if (!roundedFillRect.isRenderable())
2578 roundedFillRect.adjustRadii();
2579 context->fillRoundedRect(roundedFillRect, Color::black);
2574 } 2580 }
2575 } else { 2581 } else {
2576 context->fillRect(fillRect.rect(), Color::black); 2582 context->fillRect(fillRect, Color::black);
2577 } 2583 }
2578 } else { 2584 } else {
2585 // The inset shadow case.
2579 GraphicsContext::Edges clippedEdges = GraphicsContext::NoEdge; 2586 GraphicsContext::Edges clippedEdges = GraphicsContext::NoEdge;
2580 if (!includeLogicalLeftEdge) { 2587 if (!includeLogicalLeftEdge) {
2581 if (isHorizontal) 2588 if (isHorizontal)
2582 clippedEdges |= GraphicsContext::LeftEdge; 2589 clippedEdges |= GraphicsContext::LeftEdge;
2583 else 2590 else
2584 clippedEdges |= GraphicsContext::TopEdge; 2591 clippedEdges |= GraphicsContext::TopEdge;
2585 } 2592 }
2586 if (!includeLogicalRightEdge) { 2593 if (!includeLogicalRightEdge) {
2587 if (isHorizontal) 2594 if (isHorizontal)
2588 clippedEdges |= GraphicsContext::RightEdge; 2595 clippedEdges |= GraphicsContext::RightEdge;
2589 else 2596 else
2590 clippedEdges |= GraphicsContext::BottomEdge; 2597 clippedEdges |= GraphicsContext::BottomEdge;
2591 } 2598 }
2592 context->drawInnerShadow(border, shadowColor, shadowOffset, shadowBl ur, shadowSpread, clippedEdges); 2599 // TODO: support non-integer shadows - crbug.com/334828
2600 context->drawInnerShadow(border, shadowColor, flooredIntSize(shadowO ffset), shadowBlur, shadowSpread, clippedEdges);
2593 } 2601 }
2594 } 2602 }
2595 } 2603 }
2596 2604
2597 LayoutUnit RenderBoxModelObject::containingBlockLogicalWidthForContent() const 2605 LayoutUnit RenderBoxModelObject::containingBlockLogicalWidthForContent() const
2598 { 2606 {
2599 return containingBlock()->availableLogicalWidth(); 2607 return containingBlock()->availableLogicalWidth();
2600 } 2608 }
2601 2609
2602 RenderBoxModelObject* RenderBoxModelObject::continuation() const 2610 RenderBoxModelObject* RenderBoxModelObject::continuation() const
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2830 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); 2838 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent());
2831 for (RenderObject* child = startChild; child && child != endChild; ) { 2839 for (RenderObject* child = startChild; child && child != endChild; ) {
2832 // Save our next sibling as moveChildTo will clear it. 2840 // Save our next sibling as moveChildTo will clear it.
2833 RenderObject* nextSibling = child->nextSibling(); 2841 RenderObject* nextSibling = child->nextSibling();
2834 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); 2842 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert);
2835 child = nextSibling; 2843 child = nextSibling;
2836 } 2844 }
2837 } 2845 }
2838 2846
2839 } // namespace WebCore 2847 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/InlineTextBox.cpp ('k') | Source/core/rendering/style/RenderStyle.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698