Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 2464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2475 bool hasOpaqueBackground = s->visitedDependentColor(CSSPropertyBackgroundCol or).isValid() && s->visitedDependentColor(CSSPropertyBackgroundColor).alpha() == 255; | 2475 bool hasOpaqueBackground = s->visitedDependentColor(CSSPropertyBackgroundCol or).isValid() && s->visitedDependentColor(CSSPropertyBackgroundColor).alpha() == 255; |
| 2476 | 2476 |
| 2477 GraphicsContextStateSaver stateSaver(*context, false); | 2477 GraphicsContextStateSaver stateSaver(*context, false); |
| 2478 | 2478 |
| 2479 const ShadowList* shadowList = s->boxShadow(); | 2479 const ShadowList* shadowList = s->boxShadow(); |
| 2480 for (size_t i = shadowList->shadows().size(); i--; ) { | 2480 for (size_t i = shadowList->shadows().size(); i--; ) { |
| 2481 const ShadowData& shadow = shadowList->shadows()[i]; | 2481 const ShadowData& shadow = shadowList->shadows()[i]; |
| 2482 if (shadow.style() != shadowStyle) | 2482 if (shadow.style() != shadowStyle) |
| 2483 continue; | 2483 continue; |
| 2484 | 2484 |
| 2485 IntSize shadowOffset(shadow.x(), shadow.y()); | 2485 LayoutSize shadowOffset(shadow.x(), shadow.y()); |
| 2486 int shadowBlur = shadow.blur(); | 2486 LayoutUnit shadowBlur = shadow.blur(); |
| 2487 int shadowSpread = shadow.spread(); | 2487 LayoutUnit shadowSpread = shadow.spread(); |
| 2488 | 2488 |
| 2489 if (shadowOffset.isZero() && !shadowBlur && !shadowSpread) | 2489 if (shadowOffset.isZero() && !shadowBlur && !shadowSpread) |
| 2490 continue; | 2490 continue; |
| 2491 | 2491 |
| 2492 const Color& shadowColor = resolveColor(shadow.color()); | 2492 const Color& shadowColor = resolveColor(shadow.color()); |
| 2493 | 2493 |
| 2494 if (shadow.style() == Normal) { | 2494 if (shadow.style() == Normal) { |
| 2495 RoundedRect fillRect = border; | 2495 FloatRect fillRect = border.rect(); |
| 2496 fillRect.inflate(shadowSpread); | 2496 fillRect.inflate(shadowSpread); |
| 2497 if (fillRect.isEmpty()) | 2497 if (fillRect.isEmpty()) |
| 2498 continue; | 2498 continue; |
| 2499 | 2499 |
| 2500 IntRect shadowRect(border.rect()); | 2500 LayoutRect shadowRect(border.rect()); |
| 2501 shadowRect.inflate(shadowBlur + shadowSpread); | 2501 shadowRect.inflate(shadowBlur + shadowSpread); |
| 2502 shadowRect.move(shadowOffset); | 2502 shadowRect.move(shadowOffset); |
| 2503 | 2503 |
| 2504 // Save the state and clip, if not already done. | 2504 // Save the state and clip, if not already done. |
| 2505 // The clip does not depend on any shadow-specific properties. | 2505 // The clip does not depend on any shadow-specific properties. |
| 2506 if (!stateSaver.saved()) { | 2506 if (!stateSaver.saved()) { |
| 2507 stateSaver.save(); | 2507 stateSaver.save(); |
| 2508 if (hasBorderRadius) { | 2508 if (hasBorderRadius) { |
| 2509 RoundedRect rectToClipOut = border; | 2509 RoundedRect rectToClipOut = border; |
| 2510 | 2510 |
| 2511 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time | 2511 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time |
| 2512 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the | 2512 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the |
| 2513 // corners. Those are avoided by insetting the clipping path by one pixel. | 2513 // corners. Those are avoided by insetting the clipping path by one pixel. |
| 2514 if (hasOpaqueBackground) | 2514 if (hasOpaqueBackground) |
| 2515 rectToClipOut.inflateWithRadii(-1); | 2515 rectToClipOut.inflateWithRadii(-1); |
| 2516 | 2516 |
| 2517 if (!rectToClipOut.isEmpty()) { | 2517 if (!rectToClipOut.isEmpty()) { |
| 2518 context->clipOutRoundedRect(rectToClipOut); | 2518 context->clipOutRoundedRect(rectToClipOut); |
| 2519 } | 2519 } |
| 2520 } else { | 2520 } else { |
| 2521 // This IntRect is correct even with fractional shadows, bec ause it is used for the rectangle | |
| 2522 // of the box itself, which is always pixel-aligned. | |
| 2521 IntRect rectToClipOut = border.rect(); | 2523 IntRect rectToClipOut = border.rect(); |
| 2522 | 2524 |
| 2523 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time | 2525 // If the box is opaque, it is unnecessary to clip it out. H owever, doing so saves time |
| 2524 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the | 2526 // when painting the shadow. On the other hand, it introduce s subpixel gaps along the |
| 2525 // edges if they are not pixel-aligned. Those are avoided by insetting the clipping path | 2527 // edges if they are not pixel-aligned. Those are avoided by insetting the clipping path |
| 2526 // by one pixel. | 2528 // by one pixel. |
| 2527 if (hasOpaqueBackground) { | 2529 if (hasOpaqueBackground) { |
| 2528 // FIXME: The function to decide on the policy based on the transform should be a named function. | 2530 // FIXME: The function to decide on the policy based on the transform should be a named function. |
| 2529 // FIXME: It's not clear if this check is right. What ab out integral scale factors? | 2531 // FIXME: It's not clear if this check is right. What ab out integral scale factors? |
| 2530 AffineTransform transform = context->getCTM(); | 2532 AffineTransform transform = context->getCTM(); |
| 2531 if (transform.a() != 1 || (transform.d() != 1 && transfo rm.d() != -1) || transform.b() || transform.c()) | 2533 if (transform.a() != 1 || (transform.d() != 1 && transfo rm.d() != -1) || transform.b() || transform.c()) |
| 2532 rectToClipOut.inflate(-1); | 2534 rectToClipOut.inflate(-1); |
| 2533 } | 2535 } |
| 2534 | 2536 |
| 2535 if (!rectToClipOut.isEmpty()) { | 2537 if (!rectToClipOut.isEmpty()) { |
| 2536 context->clipOut(rectToClipOut); | 2538 context->clipOut(rectToClipOut); |
| 2537 } | 2539 } |
| 2538 } | 2540 } |
| 2539 } | 2541 } |
| 2540 | 2542 |
| 2541 // Draw only the shadow. | 2543 // Draw only the shadow. |
| 2542 DrawLooper drawLooper; | 2544 DrawLooper drawLooper; |
| 2543 drawLooper.addShadow(shadowOffset, shadowBlur, shadowColor, | 2545 drawLooper.addShadow(shadowOffset, shadowBlur, shadowColor, |
| 2544 DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresA lpha); | 2546 DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresA lpha); |
| 2545 context->setDrawLooper(drawLooper); | 2547 context->setDrawLooper(drawLooper); |
| 2546 | 2548 |
| 2547 if (hasBorderRadius) { | 2549 if (hasBorderRadius) { |
| 2548 RoundedRect influenceRect(shadowRect, border.radii()); | 2550 // XXX is this IntRect conversion correct? |
|
eae
2013/11/27 23:45:27
Why not use pixelSnappedIntRect instead?
cbiesinger
2013/12/18 02:09:12
Good idea, thanks.
| |
| 2551 RoundedRect influenceRect(IntRect(shadowRect.pixelSnappedLocatio n(), shadowRect.pixelSnappedSize()), border.radii()); | |
| 2549 influenceRect.expandRadii(2 * shadowBlur + shadowSpread); | 2552 influenceRect.expandRadii(2 * shadowBlur + shadowSpread); |
| 2550 if (allCornersClippedOut(influenceRect, info.rect)) | 2553 if (allCornersClippedOut(influenceRect, info.rect)) |
| 2551 context->fillRect(fillRect.rect(), Color::black); | 2554 context->fillRect(fillRect, Color::black); |
| 2552 else { | 2555 else { |
| 2553 fillRect.expandRadii(shadowSpread); | 2556 RoundedRect roundedFillRect = border; |
| 2554 if (!fillRect.isRenderable()) | 2557 roundedFillRect.inflate(shadowSpread); |
| 2555 fillRect.adjustRadii(); | 2558 |
| 2556 context->fillRoundedRect(fillRect, Color::black); | 2559 roundedFillRect.expandRadii(shadowSpread); |
| 2560 if (!roundedFillRect.isRenderable()) | |
| 2561 roundedFillRect.adjustRadii(); | |
| 2562 context->fillRoundedRect(roundedFillRect, Color::black); | |
| 2557 } | 2563 } |
| 2558 } else { | 2564 } else { |
| 2559 context->fillRect(fillRect.rect(), Color::black); | 2565 context->fillRect(fillRect, Color::black); |
| 2560 } | 2566 } |
| 2561 } else { | 2567 } else { |
| 2568 // inset shadow | |
|
eae
2013/11/27 23:45:27
Update comment to be more descriptive or remove it
cbiesinger
2013/12/18 02:09:12
Done.
| |
| 2562 GraphicsContext::Edges clippedEdges = GraphicsContext::NoEdge; | 2569 GraphicsContext::Edges clippedEdges = GraphicsContext::NoEdge; |
| 2563 if (!includeLogicalLeftEdge) { | 2570 if (!includeLogicalLeftEdge) { |
| 2564 if (isHorizontal) | 2571 if (isHorizontal) |
| 2565 clippedEdges |= GraphicsContext::LeftEdge; | 2572 clippedEdges |= GraphicsContext::LeftEdge; |
| 2566 else | 2573 else |
| 2567 clippedEdges |= GraphicsContext::TopEdge; | 2574 clippedEdges |= GraphicsContext::TopEdge; |
| 2568 } | 2575 } |
| 2569 if (!includeLogicalRightEdge) { | 2576 if (!includeLogicalRightEdge) { |
| 2570 if (isHorizontal) | 2577 if (isHorizontal) |
| 2571 clippedEdges |= GraphicsContext::RightEdge; | 2578 clippedEdges |= GraphicsContext::RightEdge; |
| 2572 else | 2579 else |
| 2573 clippedEdges |= GraphicsContext::BottomEdge; | 2580 clippedEdges |= GraphicsContext::BottomEdge; |
| 2574 } | 2581 } |
| 2575 context->drawInnerShadow(border, shadowColor, shadowOffset, shadowBl ur, shadowSpread, clippedEdges); | 2582 // TODO: support non-integer shadows |
| 2583 context->drawInnerShadow(border, shadowColor, IntSize(shadowOffset.w idth(), shadowOffset.height()), shadowBlur, shadowSpread, clippedEdges); | |
|
eae
2013/11/27 23:45:27
do you want to floor or round the offset here? Use
cbiesinger
2013/12/18 02:09:12
Ah, thanks - done. Switched to floored because tha
| |
| 2576 } | 2584 } |
| 2577 } | 2585 } |
| 2578 } | 2586 } |
| 2579 | 2587 |
| 2580 LayoutUnit RenderBoxModelObject::containingBlockLogicalWidthForContent() const | 2588 LayoutUnit RenderBoxModelObject::containingBlockLogicalWidthForContent() const |
| 2581 { | 2589 { |
| 2582 return containingBlock()->availableLogicalWidth(); | 2590 return containingBlock()->availableLogicalWidth(); |
| 2583 } | 2591 } |
| 2584 | 2592 |
| 2585 RenderBoxModelObject* RenderBoxModelObject::continuation() const | 2593 RenderBoxModelObject* RenderBoxModelObject::continuation() const |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2813 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); | 2821 ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent()); |
| 2814 for (RenderObject* child = startChild; child && child != endChild; ) { | 2822 for (RenderObject* child = startChild; child && child != endChild; ) { |
| 2815 // Save our next sibling as moveChildTo will clear it. | 2823 // Save our next sibling as moveChildTo will clear it. |
| 2816 RenderObject* nextSibling = child->nextSibling(); | 2824 RenderObject* nextSibling = child->nextSibling(); |
| 2817 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); | 2825 moveChildTo(toBoxModelObject, child, beforeChild, fullRemoveInsert); |
| 2818 child = nextSibling; | 2826 child = nextSibling; |
| 2819 } | 2827 } |
| 2820 } | 2828 } |
| 2821 | 2829 |
| 2822 } // namespace WebCore | 2830 } // namespace WebCore |
| OLD | NEW |