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