| 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 Apple Inc. All rights reserved. | 6 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y())); | 269 LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y())); |
| 270 while (child) { | 270 while (child) { |
| 271 child->layoutIfNeeded(); | 271 child->layoutIfNeeded(); |
| 272 ASSERT(!child->needsLayout()); | 272 ASSERT(!child->needsLayout()); |
| 273 child = child->nextSibling(); | 273 child = child->nextSibling(); |
| 274 } | 274 } |
| 275 statePusher.pop(); | 275 statePusher.pop(); |
| 276 setNeedsLayout(false); | 276 setNeedsLayout(false); |
| 277 } | 277 } |
| 278 | 278 |
| 279 int RenderBox::offsetLeft() const | |
| 280 { | |
| 281 RenderBox* offsetPar = offsetParent(); | |
| 282 if (!offsetPar) | |
| 283 return 0; | |
| 284 int xPos = x() - offsetPar->borderLeft(); | |
| 285 if (!isPositioned()) { | |
| 286 if (isRelPositioned()) | |
| 287 xPos += relativePositionOffsetX(); | |
| 288 RenderObject* curr = parent(); | |
| 289 while (curr && curr != offsetPar) { | |
| 290 // FIXME: What are we supposed to do inside SVG content? | |
| 291 if (curr->isBox() && !curr->isTableRow()) | |
| 292 xPos += toRenderBox(curr)->x(); | |
| 293 curr = curr->parent(); | |
| 294 } | |
| 295 if (offsetPar->isBody() && !offsetPar->isRelPositioned() && !offsetPar->
isPositioned()) | |
| 296 xPos += offsetPar->x(); | |
| 297 } | |
| 298 return xPos; | |
| 299 } | |
| 300 | |
| 301 int RenderBox::offsetTop() const | |
| 302 { | |
| 303 RenderBox* offsetPar = offsetParent(); | |
| 304 if (!offsetPar) | |
| 305 return 0; | |
| 306 int yPos = y() - offsetPar->borderTop(); | |
| 307 if (!isPositioned()) { | |
| 308 if (isRelPositioned()) | |
| 309 yPos += relativePositionOffsetY(); | |
| 310 RenderObject* curr = parent(); | |
| 311 while (curr && curr != offsetPar) { | |
| 312 // FIXME: What are we supposed to do inside SVG content? | |
| 313 if (curr->isBox() && !curr->isTableRow()) | |
| 314 yPos += toRenderBox(curr)->y(); | |
| 315 curr = curr->parent(); | |
| 316 } | |
| 317 if (offsetPar->isBody() && !offsetPar->isRelPositioned() && !offsetPar->
isPositioned()) | |
| 318 yPos += offsetPar->y(); | |
| 319 } | |
| 320 return yPos; | |
| 321 } | |
| 322 | |
| 323 RenderBox* RenderBox::offsetParent() const | |
| 324 { | |
| 325 // FIXME: It feels like this function could almost be written using containi
ng blocks. | |
| 326 if (isBody()) | |
| 327 return 0; | |
| 328 | |
| 329 bool skipTables = isPositioned() || isRelPositioned(); | |
| 330 float currZoom = style()->effectiveZoom(); | |
| 331 RenderObject* curr = parent(); | |
| 332 while (curr && (!curr->element() || | |
| 333 (!curr->isPositioned() && !curr->isRelPositioned() && !curr-
>isBody()))) { | |
| 334 Node* element = curr->element(); | |
| 335 if (!skipTables && element) { | |
| 336 bool isTableElement = element->hasTagName(tableTag) || | |
| 337 element->hasTagName(tdTag) || | |
| 338 element->hasTagName(thTag); | |
| 339 | |
| 340 #if ENABLE(WML) | |
| 341 if (!isTableElement && element->isWMLElement()) | |
| 342 isTableElement = element->hasTagName(WMLNames::tableTag) || | |
| 343 element->hasTagName(WMLNames::tdTag); | |
| 344 #endif | |
| 345 | |
| 346 if (isTableElement) | |
| 347 break; | |
| 348 } | |
| 349 | |
| 350 float newZoom = curr->style()->effectiveZoom(); | |
| 351 if (currZoom != newZoom) | |
| 352 break; | |
| 353 currZoom = newZoom; | |
| 354 curr = curr->parent(); | |
| 355 } | |
| 356 return curr && curr->isBox() ? toRenderBox(curr) : 0; | |
| 357 } | |
| 358 | |
| 359 // More IE extensions. clientWidth and clientHeight represent the interior of a
n object | 279 // More IE extensions. clientWidth and clientHeight represent the interior of a
n object |
| 360 // excluding border and scrollbar. | 280 // excluding border and scrollbar. |
| 361 int RenderBox::clientWidth() const | 281 int RenderBox::clientWidth() const |
| 362 { | 282 { |
| 363 return width() - borderLeft() - borderRight() - verticalScrollbarWidth(); | 283 return width() - borderLeft() - borderRight() - verticalScrollbarWidth(); |
| 364 } | 284 } |
| 365 | 285 |
| 366 int RenderBox::clientHeight() const | 286 int RenderBox::clientHeight() const |
| 367 { | 287 { |
| 368 return height() - borderTop() - borderBottom() - horizontalScrollbarHeight()
; | 288 return height() - borderTop() - borderBottom() - horizontalScrollbarHeight()
; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 if (hasOverflowClip()) | 321 if (hasOverflowClip()) |
| 402 layer()->scrollToXOffset(newLeft); | 322 layer()->scrollToXOffset(newLeft); |
| 403 } | 323 } |
| 404 | 324 |
| 405 void RenderBox::setScrollTop(int newTop) | 325 void RenderBox::setScrollTop(int newTop) |
| 406 { | 326 { |
| 407 if (hasOverflowClip()) | 327 if (hasOverflowClip()) |
| 408 layer()->scrollToYOffset(newTop); | 328 layer()->scrollToYOffset(newTop); |
| 409 } | 329 } |
| 410 | 330 |
| 411 int RenderBox::paddingTop(bool) const | |
| 412 { | |
| 413 int w = 0; | |
| 414 Length padding = style()->paddingTop(); | |
| 415 if (padding.isPercent()) | |
| 416 w = containingBlock()->availableWidth(); | |
| 417 return padding.calcMinValue(w); | |
| 418 } | |
| 419 | |
| 420 int RenderBox::paddingBottom(bool) const | |
| 421 { | |
| 422 int w = 0; | |
| 423 Length padding = style()->paddingBottom(); | |
| 424 if (padding.isPercent()) | |
| 425 w = containingBlock()->availableWidth(); | |
| 426 return padding.calcMinValue(w); | |
| 427 } | |
| 428 | |
| 429 int RenderBox::paddingLeft(bool) const | |
| 430 { | |
| 431 int w = 0; | |
| 432 Length padding = style()->paddingLeft(); | |
| 433 if (padding.isPercent()) | |
| 434 w = containingBlock()->availableWidth(); | |
| 435 return padding.calcMinValue(w); | |
| 436 } | |
| 437 | |
| 438 int RenderBox::paddingRight(bool) const | |
| 439 { | |
| 440 int w = 0; | |
| 441 Length padding = style()->paddingRight(); | |
| 442 if (padding.isPercent()) | |
| 443 w = containingBlock()->availableWidth(); | |
| 444 return padding.calcMinValue(w); | |
| 445 } | |
| 446 | |
| 447 void RenderBox::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool) | 331 void RenderBox::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool) |
| 448 { | 332 { |
| 449 rects.append(IntRect(tx, ty, width(), height())); | 333 rects.append(IntRect(tx, ty, width(), height())); |
| 450 } | 334 } |
| 451 | 335 |
| 452 void RenderBox::absoluteQuads(Vector<FloatQuad>& quads, bool) | 336 void RenderBox::absoluteQuads(Vector<FloatQuad>& quads, bool) |
| 453 { | 337 { |
| 454 quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height()))); | 338 quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height()))); |
| 455 } | 339 } |
| 456 | 340 |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 paintFillLayers(paintInfo, c, fillLayer->next(), clipY, clipH, tx, ty, width
, height, op); | 758 paintFillLayers(paintInfo, c, fillLayer->next(), clipY, clipH, tx, ty, width
, height, op); |
| 875 paintFillLayer(paintInfo, c, fillLayer, clipY, clipH, tx, ty, width, height,
op); | 759 paintFillLayer(paintInfo, c, fillLayer, clipY, clipH, tx, ty, width, height,
op); |
| 876 } | 760 } |
| 877 | 761 |
| 878 void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const
FillLayer* fillLayer, | 762 void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const
FillLayer* fillLayer, |
| 879 int clipY, int clipH, int tx, int ty, int width,
int height, CompositeOperator op) | 763 int clipY, int clipH, int tx, int ty, int width,
int height, CompositeOperator op) |
| 880 { | 764 { |
| 881 paintFillLayerExtended(paintInfo, c, fillLayer, clipY, clipH, tx, ty, width,
height, 0, op); | 765 paintFillLayerExtended(paintInfo, c, fillLayer, clipY, clipH, tx, ty, width,
height, 0, op); |
| 882 } | 766 } |
| 883 | 767 |
| 884 IntSize RenderBox::calculateBackgroundSize(const FillLayer* bgLayer, int scaledW
idth, int scaledHeight) const | |
| 885 { | |
| 886 StyleImage* bg = bgLayer->image(); | |
| 887 bg->setImageContainerSize(IntSize(scaledWidth, scaledHeight)); // Use the bo
x established by background-origin. | |
| 888 | |
| 889 if (bgLayer->isSizeSet()) { | |
| 890 int w = scaledWidth; | |
| 891 int h = scaledHeight; | |
| 892 Length bgWidth = bgLayer->size().width(); | |
| 893 Length bgHeight = bgLayer->size().height(); | |
| 894 | |
| 895 if (bgWidth.isFixed()) | |
| 896 w = bgWidth.value(); | |
| 897 else if (bgWidth.isPercent()) | |
| 898 w = bgWidth.calcValue(scaledWidth); | |
| 899 | |
| 900 if (bgHeight.isFixed()) | |
| 901 h = bgHeight.value(); | |
| 902 else if (bgHeight.isPercent()) | |
| 903 h = bgHeight.calcValue(scaledHeight); | |
| 904 | |
| 905 // If one of the values is auto we have to use the appropriate | |
| 906 // scale to maintain our aspect ratio. | |
| 907 if (bgWidth.isAuto() && !bgHeight.isAuto()) | |
| 908 w = bg->imageSize(this, style()->effectiveZoom()).width() * h / bg->
imageSize(this, style()->effectiveZoom()).height(); | |
| 909 else if (!bgWidth.isAuto() && bgHeight.isAuto()) | |
| 910 h = bg->imageSize(this, style()->effectiveZoom()).height() * w / bg-
>imageSize(this, style()->effectiveZoom()).width(); | |
| 911 else if (bgWidth.isAuto() && bgHeight.isAuto()) { | |
| 912 // If both width and height are auto, we just want to use the image'
s | |
| 913 // intrinsic size. | |
| 914 w = bg->imageSize(this, style()->effectiveZoom()).width(); | |
| 915 h = bg->imageSize(this, style()->effectiveZoom()).height(); | |
| 916 } | |
| 917 | |
| 918 return IntSize(max(1, w), max(1, h)); | |
| 919 } else | |
| 920 return bg->imageSize(this, style()->effectiveZoom()); | |
| 921 } | |
| 922 | |
| 923 void RenderBox::imageChanged(WrappedImagePtr image, const IntRect*) | 768 void RenderBox::imageChanged(WrappedImagePtr image, const IntRect*) |
| 924 { | 769 { |
| 925 if (!parent()) | 770 if (!parent()) |
| 926 return; | 771 return; |
| 927 | 772 |
| 928 if (isRenderInline() || style()->borderImage().image() && style()->borderIma
ge().image()->data() == image || | 773 if (style()->borderImage().image() && style()->borderImage().image()->data()
== image || |
| 929 style()->maskBoxImage().image() && style()->maskBoxImage().image()->data
() == image) { | 774 style()->maskBoxImage().image() && style()->maskBoxImage().image()->data
() == image) { |
| 930 repaint(); | 775 repaint(); |
| 931 return; | 776 return; |
| 932 } | 777 } |
| 933 | 778 |
| 934 bool didFullRepaint = repaintLayerRectsForImage(image, style()->backgroundLa
yers(), true); | 779 bool didFullRepaint = repaintLayerRectsForImage(image, style()->backgroundLa
yers(), true); |
| 935 if (!didFullRepaint) { | 780 if (!didFullRepaint) |
| 936 repaintLayerRectsForImage(image, style()->maskLayers(), false); | 781 repaintLayerRectsForImage(image, style()->maskLayers(), false); |
| 937 } | |
| 938 } | 782 } |
| 939 | 783 |
| 940 bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer
* layers, bool drawingBackground) | 784 bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer
* layers, bool drawingBackground) |
| 941 { | 785 { |
| 942 IntRect rendererRect; | 786 IntRect rendererRect; |
| 943 RenderBox* layerRenderer = 0; | 787 RenderBox* layerRenderer = 0; |
| 944 | 788 |
| 945 for (const FillLayer* curLayer = layers; curLayer; curLayer = curLayer->next
()) { | 789 for (const FillLayer* curLayer = layers; curLayer; curLayer = curLayer->next
()) { |
| 946 if (curLayer->image() && image == curLayer->image()->data() && curLayer-
>image()->canRender(style()->effectiveZoom())) { | 790 if (curLayer->image() && image == curLayer->image()->data() && curLayer-
>image()->canRender(style()->effectiveZoom())) { |
| 947 // Now that we know this image is being used, compute the renderer a
nd the rect | 791 // Now that we know this image is being used, compute the renderer a
nd the rect |
| (...skipping 28 matching lines...) Expand all Loading... |
| 976 IntSize tileSize; | 820 IntSize tileSize; |
| 977 layerRenderer->calculateBackgroundImageGeometry(curLayer, rendererRe
ct.x(), rendererRect.y(), rendererRect.width(), rendererRect.height(), repaintRe
ct, phase, tileSize); | 821 layerRenderer->calculateBackgroundImageGeometry(curLayer, rendererRe
ct.x(), rendererRect.y(), rendererRect.width(), rendererRect.height(), repaintRe
ct, phase, tileSize); |
| 978 layerRenderer->repaintRectangle(repaintRect); | 822 layerRenderer->repaintRectangle(repaintRect); |
| 979 if (repaintRect == rendererRect) | 823 if (repaintRect == rendererRect) |
| 980 return true; | 824 return true; |
| 981 } | 825 } |
| 982 } | 826 } |
| 983 return false; | 827 return false; |
| 984 } | 828 } |
| 985 | 829 |
| 986 void RenderBox::calculateBackgroundImageGeometry(const FillLayer* bgLayer, int t
x, int ty, int w, int h, IntRect& destRect, IntPoint& phase, IntSize& tileSize) | |
| 987 { | |
| 988 int pw; | |
| 989 int ph; | |
| 990 int left = 0; | |
| 991 int right = 0; | |
| 992 int top = 0; | |
| 993 int bottom = 0; | |
| 994 int cx; | |
| 995 int cy; | |
| 996 int rw = 0; | |
| 997 int rh = 0; | |
| 998 | |
| 999 // CSS2 chapter 14.2.1 | |
| 1000 | |
| 1001 if (bgLayer->attachment()) { | |
| 1002 // Scroll | |
| 1003 if (bgLayer->origin() != BorderFillBox) { | |
| 1004 left = borderLeft(); | |
| 1005 right = borderRight(); | |
| 1006 top = borderTop(); | |
| 1007 bottom = borderBottom(); | |
| 1008 if (bgLayer->origin() == ContentFillBox) { | |
| 1009 left += paddingLeft(); | |
| 1010 right += paddingRight(); | |
| 1011 top += paddingTop(); | |
| 1012 bottom += paddingBottom(); | |
| 1013 } | |
| 1014 } | |
| 1015 | |
| 1016 // The background of the box generated by the root element covers the en
tire canvas including | |
| 1017 // its margins. Since those were added in already, we have to factor th
em out when computing the | |
| 1018 // box used by background-origin/size/position. | |
| 1019 if (isRoot()) { | |
| 1020 rw = width() - left - right; | |
| 1021 rh = height() - top - bottom; | |
| 1022 left += marginLeft(); | |
| 1023 right += marginRight(); | |
| 1024 top += marginTop(); | |
| 1025 bottom += marginBottom(); | |
| 1026 } | |
| 1027 cx = tx; | |
| 1028 cy = ty; | |
| 1029 pw = w - left - right; | |
| 1030 ph = h - top - bottom; | |
| 1031 } else { | |
| 1032 // Fixed | |
| 1033 IntRect vr = viewRect(); | |
| 1034 cx = vr.x(); | |
| 1035 cy = vr.y(); | |
| 1036 pw = vr.width(); | |
| 1037 ph = vr.height(); | |
| 1038 } | |
| 1039 | |
| 1040 int sx = 0; | |
| 1041 int sy = 0; | |
| 1042 int cw; | |
| 1043 int ch; | |
| 1044 | |
| 1045 IntSize scaledImageSize; | |
| 1046 if (isRoot() && bgLayer->attachment()) | |
| 1047 scaledImageSize = calculateBackgroundSize(bgLayer, rw, rh); | |
| 1048 else | |
| 1049 scaledImageSize = calculateBackgroundSize(bgLayer, pw, ph); | |
| 1050 | |
| 1051 int scaledImageWidth = scaledImageSize.width(); | |
| 1052 int scaledImageHeight = scaledImageSize.height(); | |
| 1053 | |
| 1054 EFillRepeat backgroundRepeat = bgLayer->repeat(); | |
| 1055 | |
| 1056 int xPosition; | |
| 1057 if (isRoot() && bgLayer->attachment()) | |
| 1058 xPosition = bgLayer->xPosition().calcMinValue(rw - scaledImageWidth, tru
e); | |
| 1059 else | |
| 1060 xPosition = bgLayer->xPosition().calcMinValue(pw - scaledImageWidth, tru
e); | |
| 1061 if (backgroundRepeat == RepeatFill || backgroundRepeat == RepeatXFill) { | |
| 1062 cw = pw + left + right; | |
| 1063 sx = scaledImageWidth ? scaledImageWidth - (xPosition + left) % scaledIm
ageWidth : 0; | |
| 1064 } else { | |
| 1065 cx += max(xPosition + left, 0); | |
| 1066 sx = -min(xPosition + left, 0); | |
| 1067 cw = scaledImageWidth + min(xPosition + left, 0); | |
| 1068 } | |
| 1069 | |
| 1070 int yPosition; | |
| 1071 if (isRoot() && bgLayer->attachment()) | |
| 1072 yPosition = bgLayer->yPosition().calcMinValue(rh - scaledImageHeight, tr
ue); | |
| 1073 else | |
| 1074 yPosition = bgLayer->yPosition().calcMinValue(ph - scaledImageHeight, tr
ue); | |
| 1075 if (backgroundRepeat == RepeatFill || backgroundRepeat == RepeatYFill) { | |
| 1076 ch = ph + top + bottom; | |
| 1077 sy = scaledImageHeight ? scaledImageHeight - (yPosition + top) % scaledI
mageHeight : 0; | |
| 1078 } else { | |
| 1079 cy += max(yPosition + top, 0); | |
| 1080 sy = -min(yPosition + top, 0); | |
| 1081 ch = scaledImageHeight + min(yPosition + top, 0); | |
| 1082 } | |
| 1083 | |
| 1084 if (!bgLayer->attachment()) { | |
| 1085 sx += max(tx - cx, 0); | |
| 1086 sy += max(ty - cy, 0); | |
| 1087 } | |
| 1088 | |
| 1089 destRect = IntRect(cx, cy, cw, ch); | |
| 1090 destRect.intersect(IntRect(tx, ty, w, h)); | |
| 1091 phase = IntPoint(sx, sy); | |
| 1092 tileSize = IntSize(scaledImageWidth, scaledImageHeight); | |
| 1093 } | |
| 1094 | |
| 1095 void RenderBox::paintFillLayerExtended(const PaintInfo& paintInfo, const Color&
c, const FillLayer* bgLayer, int clipY, int clipH, | |
| 1096 int tx, int ty, int w, int h, InlineFlowB
ox* box, CompositeOperator op) | |
| 1097 { | |
| 1098 GraphicsContext* context = paintInfo.context; | |
| 1099 bool includeLeftEdge = box ? box->includeLeftEdge() : true; | |
| 1100 bool includeRightEdge = box ? box->includeRightEdge() : true; | |
| 1101 int bLeft = includeLeftEdge ? borderLeft() : 0; | |
| 1102 int bRight = includeRightEdge ? borderRight() : 0; | |
| 1103 int pLeft = includeLeftEdge ? paddingLeft() : 0; | |
| 1104 int pRight = includeRightEdge ? paddingRight() : 0; | |
| 1105 | |
| 1106 bool clippedToBorderRadius = false; | |
| 1107 if (style()->hasBorderRadius() && (includeLeftEdge || includeRightEdge)) { | |
| 1108 context->save(); | |
| 1109 context->addRoundedRectClip(IntRect(tx, ty, w, h), | |
| 1110 includeLeftEdge ? style()->borderTopLeftRadius() : IntSize(), | |
| 1111 includeRightEdge ? style()->borderTopRightRadius() : IntSize(), | |
| 1112 includeLeftEdge ? style()->borderBottomLeftRadius() : IntSize(), | |
| 1113 includeRightEdge ? style()->borderBottomRightRadius() : IntSize()); | |
| 1114 clippedToBorderRadius = true; | |
| 1115 } | |
| 1116 | |
| 1117 if (bgLayer->clip() == PaddingFillBox || bgLayer->clip() == ContentFillBox)
{ | |
| 1118 // Clip to the padding or content boxes as necessary. | |
| 1119 bool includePadding = bgLayer->clip() == ContentFillBox; | |
| 1120 int x = tx + bLeft + (includePadding ? pLeft : 0); | |
| 1121 int y = ty + borderTop() + (includePadding ? paddingTop() : 0); | |
| 1122 int width = w - bLeft - bRight - (includePadding ? pLeft + pRight : 0); | |
| 1123 int height = h - borderTop() - borderBottom() - (includePadding ? paddin
gTop() + paddingBottom() : 0); | |
| 1124 context->save(); | |
| 1125 context->clip(IntRect(x, y, width, height)); | |
| 1126 } else if (bgLayer->clip() == TextFillBox) { | |
| 1127 // We have to draw our text into a mask that can then be used to clip ba
ckground drawing. | |
| 1128 // First figure out how big the mask has to be. It should be no bigger
than what we need | |
| 1129 // to actually render, so we should intersect the dirty rect with the bo
rder box of the background. | |
| 1130 IntRect maskRect(tx, ty, w, h); | |
| 1131 maskRect.intersect(paintInfo.rect); | |
| 1132 | |
| 1133 // Now create the mask. | |
| 1134 auto_ptr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), f
alse); | |
| 1135 if (!maskImage.get()) | |
| 1136 return; | |
| 1137 | |
| 1138 GraphicsContext* maskImageContext = maskImage->context(); | |
| 1139 maskImageContext->translate(-maskRect.x(), -maskRect.y()); | |
| 1140 | |
| 1141 // Now add the text to the clip. We do this by painting using a special
paint phase that signals to | |
| 1142 // InlineTextBoxes that they should just add their contents to the clip. | |
| 1143 PaintInfo info(maskImageContext, maskRect, PaintPhaseTextClip, true, 0,
0); | |
| 1144 if (box) | |
| 1145 box->paint(info, tx - box->xPos(), ty - box->yPos()); | |
| 1146 else | |
| 1147 paint(info, tx, ty); | |
| 1148 | |
| 1149 // The mask has been created. Now we just need to clip to it. | |
| 1150 context->save(); | |
| 1151 context->clipToImageBuffer(maskRect, maskImage.get()); | |
| 1152 } | |
| 1153 | |
| 1154 StyleImage* bg = bgLayer->image(); | |
| 1155 bool shouldPaintBackgroundImage = bg && bg->canRender(style()->effectiveZoom
()); | |
| 1156 Color bgColor = c; | |
| 1157 | |
| 1158 // When this style flag is set, change existing background colors and images
to a solid white background. | |
| 1159 // If there's no bg color or image, leave it untouched to avoid affecting tr
ansparency. | |
| 1160 // We don't try to avoid loading the background images, because this style f
lag is only set | |
| 1161 // when printing, and at that point we've already loaded the background imag
es anyway. (To avoid | |
| 1162 // loading the background images we'd have to do this check when applying st
yles rather than | |
| 1163 // while rendering.) | |
| 1164 if (style()->forceBackgroundsToWhite()) { | |
| 1165 // Note that we can't reuse this variable below because the bgColor migh
t be changed | |
| 1166 bool shouldPaintBackgroundColor = !bgLayer->next() && bgColor.isValid()
&& bgColor.alpha() > 0; | |
| 1167 if (shouldPaintBackgroundImage || shouldPaintBackgroundColor) { | |
| 1168 bgColor = Color::white; | |
| 1169 shouldPaintBackgroundImage = false; | |
| 1170 } | |
| 1171 } | |
| 1172 | |
| 1173 // Only fill with a base color (e.g., white) if we're the root document, sin
ce iframes/frames with | |
| 1174 // no background in the child document should show the parent's background. | |
| 1175 bool isTransparent = false; | |
| 1176 if (!bgLayer->next() && isRoot() && !(bgColor.isValid() && bgColor.alpha() >
0) && view()->frameView()) { | |
| 1177 Node* elt = document()->ownerElement(); | |
| 1178 if (elt) { | |
| 1179 if (!elt->hasTagName(frameTag)) { | |
| 1180 // Locate the <body> element using the DOM. This is easier than
trying | |
| 1181 // to crawl around a render tree with potential :before/:after c
ontent and | |
| 1182 // anonymous blocks created by inline <body> tags etc. We can l
ocate the <body> | |
| 1183 // render object very easily via the DOM. | |
| 1184 HTMLElement* body = document()->body(); | |
| 1185 isTransparent = !body || !body->hasLocalName(framesetTag); // Ca
n't scroll a frameset document anyway. | |
| 1186 } | |
| 1187 } else | |
| 1188 isTransparent = view()->frameView()->isTransparent(); | |
| 1189 | |
| 1190 // FIXME: This needs to be dynamic. We should be able to go back to bli
tting if we ever stop being transparent. | |
| 1191 if (isTransparent) | |
| 1192 view()->frameView()->setUseSlowRepaints(); // The parent must show b
ehind the child. | |
| 1193 } | |
| 1194 | |
| 1195 // Paint the color first underneath all images. | |
| 1196 if (!bgLayer->next()) { | |
| 1197 IntRect rect(tx, clipY, w, clipH); | |
| 1198 // If we have an alpha and we are painting the root element, go ahead an
d blend with the base background color. | |
| 1199 if (isRoot() && (!bgColor.isValid() || bgColor.alpha() < 0xFF) && !isTra
nsparent) { | |
| 1200 Color baseColor = view()->frameView()->baseBackgroundColor(); | |
| 1201 if (baseColor.alpha() > 0) { | |
| 1202 context->save(); | |
| 1203 context->setCompositeOperation(CompositeCopy); | |
| 1204 context->fillRect(rect, baseColor); | |
| 1205 context->restore(); | |
| 1206 } else | |
| 1207 context->clearRect(rect); | |
| 1208 } | |
| 1209 | |
| 1210 if (bgColor.isValid() && bgColor.alpha() > 0) | |
| 1211 context->fillRect(rect, bgColor); | |
| 1212 } | |
| 1213 | |
| 1214 // no progressive loading of the background image | |
| 1215 if (shouldPaintBackgroundImage) { | |
| 1216 IntRect destRect; | |
| 1217 IntPoint phase; | |
| 1218 IntSize tileSize; | |
| 1219 | |
| 1220 calculateBackgroundImageGeometry(bgLayer, tx, ty, w, h, destRect, phase,
tileSize); | |
| 1221 if (!destRect.isEmpty()) { | |
| 1222 CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer-
>composite() : op; | |
| 1223 context->drawTiledImage(bg->image(this, tileSize), destRect, phase,
tileSize, compositeOp); | |
| 1224 } | |
| 1225 } | |
| 1226 | |
| 1227 if (bgLayer->clip() != BorderFillBox) | |
| 1228 // Undo the background clip | |
| 1229 context->restore(); | |
| 1230 | |
| 1231 if (clippedToBorderRadius) | |
| 1232 // Undo the border radius clip | |
| 1233 context->restore(); | |
| 1234 } | |
| 1235 | |
| 1236 #if PLATFORM(MAC) | 830 #if PLATFORM(MAC) |
| 1237 | 831 |
| 1238 void RenderBox::paintCustomHighlight(int tx, int ty, const AtomicString& type, b
ool behindText) | 832 void RenderBox::paintCustomHighlight(int tx, int ty, const AtomicString& type, b
ool behindText) |
| 1239 { | 833 { |
| 1240 Frame* frame = document()->frame(); | 834 Frame* frame = document()->frame(); |
| 1241 if (!frame) | 835 if (!frame) |
| 1242 return; | 836 return; |
| 1243 Page* page = frame->page(); | 837 Page* page = frame->page(); |
| 1244 if (!page) | 838 if (!page) |
| 1245 return; | 839 return; |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1955 | 1549 |
| 1956 return max(minW, min(width, maxW)); | 1550 return max(minW, min(width, maxW)); |
| 1957 } | 1551 } |
| 1958 | 1552 |
| 1959 int RenderBox::calcReplacedWidthUsing(Length width) const | 1553 int RenderBox::calcReplacedWidthUsing(Length width) const |
| 1960 { | 1554 { |
| 1961 switch (width.type()) { | 1555 switch (width.type()) { |
| 1962 case Fixed: | 1556 case Fixed: |
| 1963 return calcContentBoxWidth(width.value()); | 1557 return calcContentBoxWidth(width.value()); |
| 1964 case Percent: { | 1558 case Percent: { |
| 1965 const int cw = isPositioned() ? containingBlockWidthForPositioned(co
ntainer()) : containingBlockWidth(); | 1559 const int cw = isPositioned() ? containingBlockWidthForPositioned(to
RenderBoxModelObject(container())) : containingBlockWidth(); |
| 1966 if (cw > 0) | 1560 if (cw > 0) |
| 1967 return calcContentBoxWidth(width.calcMinValue(cw)); | 1561 return calcContentBoxWidth(width.calcMinValue(cw)); |
| 1968 } | 1562 } |
| 1969 // fall through | 1563 // fall through |
| 1970 default: | 1564 default: |
| 1971 return intrinsicSize().width(); | 1565 return intrinsicSize().width(); |
| 1972 } | 1566 } |
| 1973 } | 1567 } |
| 1974 | 1568 |
| 1975 int RenderBox::calcReplacedHeight() const | 1569 int RenderBox::calcReplacedHeight() const |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1997 if (cb->isPositioned() && cb->style()->height().isAuto() && !(cb->st
yle()->top().isAuto() || cb->style()->bottom().isAuto())) { | 1591 if (cb->isPositioned() && cb->style()->height().isAuto() && !(cb->st
yle()->top().isAuto() || cb->style()->bottom().isAuto())) { |
| 1998 ASSERT(cb->isRenderBlock()); | 1592 ASSERT(cb->isRenderBlock()); |
| 1999 RenderBlock* block = toRenderBlock(cb); | 1593 RenderBlock* block = toRenderBlock(cb); |
| 2000 int oldHeight = block->height(); | 1594 int oldHeight = block->height(); |
| 2001 block->calcHeight(); | 1595 block->calcHeight(); |
| 2002 int newHeight = block->calcContentBoxHeight(block->contentHeight
()); | 1596 int newHeight = block->calcContentBoxHeight(block->contentHeight
()); |
| 2003 block->setHeight(oldHeight); | 1597 block->setHeight(oldHeight); |
| 2004 return calcContentBoxHeight(height.calcValue(newHeight)); | 1598 return calcContentBoxHeight(height.calcValue(newHeight)); |
| 2005 } | 1599 } |
| 2006 | 1600 |
| 2007 int availableHeight = isPositioned() ? containingBlockHeightForPosit
ioned(cb) : toRenderBox(cb)->availableHeight(); | 1601 int availableHeight = isPositioned() ? containingBlockHeightForPosit
ioned(toRenderBoxModelObject(cb)) : toRenderBox(cb)->availableHeight(); |
| 2008 | 1602 |
| 2009 // It is necessary to use the border-box to match WinIE's broken | 1603 // It is necessary to use the border-box to match WinIE's broken |
| 2010 // box model. This is essential for sizing inside | 1604 // box model. This is essential for sizing inside |
| 2011 // table cells using percentage heights. | 1605 // table cells using percentage heights. |
| 2012 if (cb->isTableCell() && (cb->style()->height().isAuto() || cb->styl
e()->height().isPercent())) { | 1606 if (cb->isTableCell() && (cb->style()->height().isAuto() || cb->styl
e()->height().isPercent())) { |
| 2013 // Don't let table cells squeeze percent-height replaced element
s | 1607 // Don't let table cells squeeze percent-height replaced element
s |
| 2014 // <http://bugs.webkit.org/show_bug.cgi?id=15359> | 1608 // <http://bugs.webkit.org/show_bug.cgi?id=15359> |
| 2015 availableHeight = max(availableHeight, intrinsicSize().height())
; | 1609 availableHeight = max(availableHeight, intrinsicSize().height())
; |
| 2016 return height.calcValue(availableHeight - (borderTop() + borderB
ottom() | 1610 return height.calcValue(availableHeight - (borderTop() + borderB
ottom() |
| 2017 + paddingTop() + paddingBottom())); | 1611 + paddingTop() + paddingBottom())); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2067 } | 1661 } |
| 2068 | 1662 |
| 2069 // margins are calculated with respect to the _width_ of | 1663 // margins are calculated with respect to the _width_ of |
| 2070 // the containing block (8.3) | 1664 // the containing block (8.3) |
| 2071 int cw = containingBlock()->contentWidth(); | 1665 int cw = containingBlock()->contentWidth(); |
| 2072 | 1666 |
| 2073 m_marginTop = style()->marginTop().calcMinValue(cw); | 1667 m_marginTop = style()->marginTop().calcMinValue(cw); |
| 2074 m_marginBottom = style()->marginBottom().calcMinValue(cw); | 1668 m_marginBottom = style()->marginBottom().calcMinValue(cw); |
| 2075 } | 1669 } |
| 2076 | 1670 |
| 2077 int RenderBox::containingBlockWidthForPositioned(const RenderObject* containingB
lock) const | 1671 int RenderBox::containingBlockWidthForPositioned(const RenderBoxModelObject* con
tainingBlock) const |
| 2078 { | 1672 { |
| 2079 if (containingBlock->isRenderInline()) { | 1673 if (containingBlock->isBox()) { |
| 2080 ASSERT(containingBlock->isRelPositioned()); | 1674 const RenderBox* containingBlockBox = toRenderBox(containingBlock); |
| 1675 return containingBlockBox->width() - containingBlockBox->borderLeft() -
containingBlockBox->borderRight() - containingBlockBox->verticalScrollbarWidth()
; |
| 1676 } |
| 1677 |
| 1678 ASSERT(containingBlock->isRenderInline() && containingBlock->isRelPositioned
()); |
| 2081 | 1679 |
| 2082 const RenderInline* flow = toRenderInline(containingBlock); | 1680 const RenderInline* flow = toRenderInline(containingBlock); |
| 2083 InlineFlowBox* first = flow->firstLineBox(); | 1681 InlineFlowBox* first = flow->firstLineBox(); |
| 2084 InlineFlowBox* last = flow->lastLineBox(); | 1682 InlineFlowBox* last = flow->lastLineBox(); |
| 2085 | 1683 |
| 2086 // If the containing block is empty, return a width of 0. | 1684 // If the containing block is empty, return a width of 0. |
| 2087 if (!first || !last) | 1685 if (!first || !last) |
| 2088 return 0; | 1686 return 0; |
| 2089 | 1687 |
| 2090 int fromLeft; | 1688 int fromLeft; |
| 2091 int fromRight; | 1689 int fromRight; |
| 2092 if (containingBlock->style()->direction() == LTR) { | 1690 if (containingBlock->style()->direction() == LTR) { |
| 2093 fromLeft = first->xPos() + first->borderLeft(); | 1691 fromLeft = first->xPos() + first->borderLeft(); |
| 2094 fromRight = last->xPos() + last->width() - last->borderRight(); | 1692 fromRight = last->xPos() + last->width() - last->borderRight(); |
| 2095 } else { | 1693 } else { |
| 2096 fromRight = first->xPos() + first->width() - first->borderRight(); | 1694 fromRight = first->xPos() + first->width() - first->borderRight(); |
| 2097 fromLeft = last->xPos() + last->borderLeft(); | 1695 fromLeft = last->xPos() + last->borderLeft(); |
| 2098 } | |
| 2099 | |
| 2100 return max(0, (fromRight - fromLeft)); | |
| 2101 } | 1696 } |
| 2102 | 1697 |
| 2103 const RenderBox* containingBlockBox = toRenderBox(containingBlock); | 1698 return max(0, (fromRight - fromLeft)); |
| 2104 return containingBlockBox->width() - containingBlockBox->borderLeft() - cont
ainingBlockBox->borderRight() - containingBlockBox->verticalScrollbarWidth(); | |
| 2105 } | 1699 } |
| 2106 | 1700 |
| 2107 int RenderBox::containingBlockHeightForPositioned(const RenderObject* containing
Block) const | 1701 int RenderBox::containingBlockHeightForPositioned(const RenderBoxModelObject* co
ntainingBlock) const |
| 2108 { | 1702 { |
| 2109 const RenderBox* containingBlockBox = toRenderBox(containingBlock); | 1703 int heightResult = 0; |
| 2110 | 1704 if (containingBlock->isBox()) |
| 2111 int heightResult; | 1705 heightResult = toRenderBox(containingBlock)->height(); |
| 2112 if (containingBlock->isRenderInline()) { | 1706 else if (containingBlock->isRenderInline()) { |
| 2113 ASSERT(containingBlock->isRelPositioned()); | 1707 ASSERT(containingBlock->isRelPositioned()); |
| 2114 heightResult = toRenderInline(containingBlock)->linesBoundingBox().heigh
t(); | 1708 heightResult = toRenderInline(containingBlock)->linesBoundingBox().heigh
t(); |
| 2115 } else | 1709 } |
| 2116 heightResult = containingBlockBox->height(); | 1710 return heightResult - containingBlock->borderTop() - containingBlock->border
Bottom(); |
| 2117 | |
| 2118 return heightResult - containingBlockBox->borderTop() - containingBlockBox->
borderBottom(); | |
| 2119 } | 1711 } |
| 2120 | 1712 |
| 2121 void RenderBox::calcAbsoluteHorizontal() | 1713 void RenderBox::calcAbsoluteHorizontal() |
| 2122 { | 1714 { |
| 2123 if (isReplaced()) { | 1715 if (isReplaced()) { |
| 2124 calcAbsoluteHorizontalReplaced(); | 1716 calcAbsoluteHorizontalReplaced(); |
| 2125 return; | 1717 return; |
| 2126 } | 1718 } |
| 2127 | 1719 |
| 2128 // QUESTIONS | 1720 // QUESTIONS |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2145 | 1737 |
| 2146 // The following is based off of the W3C Working Draft from April 11, 2006 o
f | 1738 // The following is based off of the W3C Working Draft from April 11, 2006 o
f |
| 2147 // CSS 2.1: Section 10.3.7 "Absolutely positioned, non-replaced elements" | 1739 // CSS 2.1: Section 10.3.7 "Absolutely positioned, non-replaced elements" |
| 2148 // <http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width> | 1740 // <http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width> |
| 2149 // (block-style-comments in this function and in calcAbsoluteHorizontalValue
s() | 1741 // (block-style-comments in this function and in calcAbsoluteHorizontalValue
s() |
| 2150 // correspond to text from the spec) | 1742 // correspond to text from the spec) |
| 2151 | 1743 |
| 2152 | 1744 |
| 2153 // We don't use containingBlock(), since we may be positioned by an enclosin
g | 1745 // We don't use containingBlock(), since we may be positioned by an enclosin
g |
| 2154 // relative positioned inline. | 1746 // relative positioned inline. |
| 2155 const RenderBox* containerBlock = toRenderBox(container()); | 1747 const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(containe
r()); |
| 2156 | 1748 |
| 2157 const int containerWidth = containingBlockWidthForPositioned(containerBlock)
; | 1749 const int containerWidth = containingBlockWidthForPositioned(containerBlock)
; |
| 2158 | 1750 |
| 2159 // To match WinIE, in quirks mode use the parent's 'direction' property | 1751 // To match WinIE, in quirks mode use the parent's 'direction' property |
| 2160 // instead of the the container block's. | 1752 // instead of the the container block's. |
| 2161 TextDirection containerDirection = (style()->htmlHacks()) ? parent()->style(
)->direction() : containerBlock->style()->direction(); | 1753 TextDirection containerDirection = (style()->htmlHacks()) ? parent()->style(
)->direction() : containerBlock->style()->direction(); |
| 2162 | 1754 |
| 2163 const int bordersPlusPadding = borderLeft() + borderRight() + paddingLeft()
+ paddingRight(); | 1755 const int bordersPlusPadding = borderLeft() + borderRight() + paddingLeft()
+ paddingRight(); |
| 2164 const Length marginLeft = style()->marginLeft(); | 1756 const Length marginLeft = style()->marginLeft(); |
| 2165 const Length marginRight = style()->marginRight(); | 1757 const Length marginRight = style()->marginRight(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2189 * viewport, and all scrollable boxes should be assumed to be scrolled to th
eir | 1781 * viewport, and all scrollable boxes should be assumed to be scrolled to th
eir |
| 2190 * origin. | 1782 * origin. |
| 2191 \*--------------------------------------------------------------------------
-*/ | 1783 \*--------------------------------------------------------------------------
-*/ |
| 2192 | 1784 |
| 2193 // see FIXME 2 | 1785 // see FIXME 2 |
| 2194 // Calculate the static distance if needed. | 1786 // Calculate the static distance if needed. |
| 2195 if (left.isAuto() && right.isAuto()) { | 1787 if (left.isAuto() && right.isAuto()) { |
| 2196 if (containerDirection == LTR) { | 1788 if (containerDirection == LTR) { |
| 2197 // 'staticX' should already have been set through layout of the pare
nt. | 1789 // 'staticX' should already have been set through layout of the pare
nt. |
| 2198 int staticPosition = layer()->staticX() - containerBlock->borderLeft
(); | 1790 int staticPosition = layer()->staticX() - containerBlock->borderLeft
(); |
| 2199 for (RenderBox* po = parentBox(); po && po != containerBlock; po = p
o->parentBox()) | 1791 for (RenderObject* po = parent(); po && po != containerBlock; po = p
o->parent()) { |
| 2200 staticPosition += po->x(); | 1792 if (po->isBox()) |
| 1793 staticPosition += toRenderBox(po)->x(); |
| 1794 } |
| 2201 left.setValue(Fixed, staticPosition); | 1795 left.setValue(Fixed, staticPosition); |
| 2202 } else { | 1796 } else { |
| 2203 RenderBox* po = parentBox(); | 1797 RenderObject* po = parent(); |
| 2204 // 'staticX' should already have been set through layout of the pare
nt. | 1798 // 'staticX' should already have been set through layout of the pare
nt. |
| 2205 int staticPosition = layer()->staticX() + containerWidth + container
Block->borderRight() - po->width(); | 1799 int staticPosition = layer()->staticX() + containerWidth + container
Block->borderRight(); |
| 2206 for (; po && po != containerBlock; po = po->parentBox()) | 1800 if (po->isBox()) |
| 2207 staticPosition -= po->x(); | 1801 staticPosition -= toRenderBox(po)->width(); |
| 1802 for (; po && po != containerBlock; po = po->parent()) { |
| 1803 if (po->isBox()) |
| 1804 staticPosition -= toRenderBox(po)->x(); |
| 1805 } |
| 2208 right.setValue(Fixed, staticPosition); | 1806 right.setValue(Fixed, staticPosition); |
| 2209 } | 1807 } |
| 2210 } | 1808 } |
| 2211 | 1809 |
| 2212 // Calculate constraint equation values for 'width' case. | 1810 // Calculate constraint equation values for 'width' case. |
| 2213 int widthResult; | 1811 int widthResult; |
| 2214 int xResult; | 1812 int xResult; |
| 2215 calcAbsoluteHorizontalValues(style()->width(), containerBlock, containerDire
ction, | 1813 calcAbsoluteHorizontalValues(style()->width(), containerBlock, containerDire
ction, |
| 2216 containerWidth, bordersPlusPadding, | 1814 containerWidth, bordersPlusPadding, |
| 2217 left, right, marginLeft, marginRight, | 1815 left, right, marginLeft, marginRight, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2265 left, right, marginLeft, marginRight, | 1863 left, right, marginLeft, marginRight, |
| 2266 widthResult, m_marginLeft, m_marginRight, x
Result); | 1864 widthResult, m_marginLeft, m_marginRight, x
Result); |
| 2267 setWidth(widthResult); | 1865 setWidth(widthResult); |
| 2268 setX(xResult); | 1866 setX(xResult); |
| 2269 } | 1867 } |
| 2270 | 1868 |
| 2271 // Put width() into correct form. | 1869 // Put width() into correct form. |
| 2272 setWidth(width() + bordersPlusPadding); | 1870 setWidth(width() + bordersPlusPadding); |
| 2273 } | 1871 } |
| 2274 | 1872 |
| 2275 void RenderBox::calcAbsoluteHorizontalValues(Length width, const RenderBox* cont
ainerBlock, TextDirection containerDirection, | 1873 void RenderBox::calcAbsoluteHorizontalValues(Length width, const RenderBoxModelO
bject* containerBlock, TextDirection containerDirection, |
| 2276 const int containerWidth, const int
bordersPlusPadding, | 1874 const int containerWidth, const int
bordersPlusPadding, |
| 2277 const Length left, const Length rig
ht, const Length marginLeft, const Length marginRight, | 1875 const Length left, const Length rig
ht, const Length marginLeft, const Length marginRight, |
| 2278 int& widthValue, int& marginLeftVal
ue, int& marginRightValue, int& xPos) | 1876 int& widthValue, int& marginLeftVal
ue, int& marginRightValue, int& xPos) |
| 2279 { | 1877 { |
| 2280 // 'left' and 'right' cannot both be 'auto' because one would of been | 1878 // 'left' and 'right' cannot both be 'auto' because one would of been |
| 2281 // converted to the static postion already | 1879 // converted to the static postion already |
| 2282 ASSERT(!(left.isAuto() && right.isAuto())); | 1880 ASSERT(!(left.isAuto() && right.isAuto())); |
| 2283 | 1881 |
| 2284 int leftValue = 0; | 1882 int leftValue = 0; |
| 2285 | 1883 |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2452 } | 2050 } |
| 2453 | 2051 |
| 2454 // The following is based off of the W3C Working Draft from April 11, 2006 o
f | 2052 // The following is based off of the W3C Working Draft from April 11, 2006 o
f |
| 2455 // CSS 2.1: Section 10.6.4 "Absolutely positioned, non-replaced elements" | 2053 // CSS 2.1: Section 10.6.4 "Absolutely positioned, non-replaced elements" |
| 2456 // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-non-replace
d-height> | 2054 // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-non-replace
d-height> |
| 2457 // (block-style-comments in this function and in calcAbsoluteVerticalValues(
) | 2055 // (block-style-comments in this function and in calcAbsoluteVerticalValues(
) |
| 2458 // correspond to text from the spec) | 2056 // correspond to text from the spec) |
| 2459 | 2057 |
| 2460 | 2058 |
| 2461 // We don't use containingBlock(), since we may be positioned by an enclosin
g relpositioned inline. | 2059 // We don't use containingBlock(), since we may be positioned by an enclosin
g relpositioned inline. |
| 2462 const RenderBox* containerBlock = toRenderBox(container()); | 2060 const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(containe
r()); |
| 2463 | 2061 |
| 2464 const int containerHeight = containingBlockHeightForPositioned(containerBloc
k); | 2062 const int containerHeight = containingBlockHeightForPositioned(containerBloc
k); |
| 2465 | 2063 |
| 2466 const int bordersPlusPadding = borderTop() + borderBottom() + paddingTop() +
paddingBottom(); | 2064 const int bordersPlusPadding = borderTop() + borderBottom() + paddingTop() +
paddingBottom(); |
| 2467 const Length marginTop = style()->marginTop(); | 2065 const Length marginTop = style()->marginTop(); |
| 2468 const Length marginBottom = style()->marginBottom(); | 2066 const Length marginBottom = style()->marginBottom(); |
| 2469 Length top = style()->top(); | 2067 Length top = style()->top(); |
| 2470 Length bottom = style()->bottom(); | 2068 Length bottom = style()->bottom(); |
| 2471 | 2069 |
| 2472 /*--------------------------------------------------------------------------
-*\ | 2070 /*--------------------------------------------------------------------------
-*\ |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2484 * For the purposes of calculating the static position, the containing block | 2082 * For the purposes of calculating the static position, the containing block |
| 2485 * of fixed positioned elements is the initial containing block instead of | 2083 * of fixed positioned elements is the initial containing block instead of |
| 2486 * the viewport. | 2084 * the viewport. |
| 2487 \*--------------------------------------------------------------------------
-*/ | 2085 \*--------------------------------------------------------------------------
-*/ |
| 2488 | 2086 |
| 2489 // see FIXME 2 | 2087 // see FIXME 2 |
| 2490 // Calculate the static distance if needed. | 2088 // Calculate the static distance if needed. |
| 2491 if (top.isAuto() && bottom.isAuto()) { | 2089 if (top.isAuto() && bottom.isAuto()) { |
| 2492 // staticY should already have been set through layout of the parent() | 2090 // staticY should already have been set through layout of the parent() |
| 2493 int staticTop = layer()->staticY() - containerBlock->borderTop(); | 2091 int staticTop = layer()->staticY() - containerBlock->borderTop(); |
| 2494 for (RenderBox* po = parentBox(); po && po != containerBlock; po = po->p
arentBox()) { | 2092 for (RenderObject* po = parent(); po && po != containerBlock; po = po->p
arent()) { |
| 2495 if (!po->isTableRow()) | 2093 if (po->isBox() && !po->isTableRow()) |
| 2496 staticTop += po->y(); | 2094 staticTop += toRenderBox(po)->y(); |
| 2497 } | 2095 } |
| 2498 top.setValue(Fixed, staticTop); | 2096 top.setValue(Fixed, staticTop); |
| 2499 } | 2097 } |
| 2500 | 2098 |
| 2501 | 2099 |
| 2502 int h; // Needed to compute overflow. | 2100 int h; // Needed to compute overflow. |
| 2503 int y; | 2101 int y; |
| 2504 | 2102 |
| 2505 // Calculate constraint equation values for 'height' case. | 2103 // Calculate constraint equation values for 'height' case. |
| 2506 calcAbsoluteVerticalValues(style()->height(), containerBlock, containerHeigh
t, bordersPlusPadding, | 2104 calcAbsoluteVerticalValues(style()->height(), containerBlock, containerHeigh
t, bordersPlusPadding, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2546 m_marginTop = minMarginTop; | 2144 m_marginTop = minMarginTop; |
| 2547 m_marginBottom = minMarginBottom; | 2145 m_marginBottom = minMarginBottom; |
| 2548 m_frameRect.setY(minYPos); | 2146 m_frameRect.setY(minYPos); |
| 2549 } | 2147 } |
| 2550 } | 2148 } |
| 2551 | 2149 |
| 2552 // Set final height value. | 2150 // Set final height value. |
| 2553 setHeight(h + bordersPlusPadding); | 2151 setHeight(h + bordersPlusPadding); |
| 2554 } | 2152 } |
| 2555 | 2153 |
| 2556 void RenderBox::calcAbsoluteVerticalValues(Length h, const RenderBox* containerB
lock, | 2154 void RenderBox::calcAbsoluteVerticalValues(Length h, const RenderBoxModelObject*
containerBlock, |
| 2557 const int containerHeight, const int
bordersPlusPadding, | 2155 const int containerHeight, const int
bordersPlusPadding, |
| 2558 const Length top, const Length bottom
, const Length marginTop, const Length marginBottom, | 2156 const Length top, const Length bottom
, const Length marginTop, const Length marginBottom, |
| 2559 int& heightValue, int& marginTopValue
, int& marginBottomValue, int& yPos) | 2157 int& heightValue, int& marginTopValue
, int& marginBottomValue, int& yPos) |
| 2560 { | 2158 { |
| 2561 // 'top' and 'bottom' cannot both be 'auto' because 'top would of been | 2159 // 'top' and 'bottom' cannot both be 'auto' because 'top would of been |
| 2562 // converted to the static position in calcAbsoluteVertical() | 2160 // converted to the static position in calcAbsoluteVertical() |
| 2563 ASSERT(!(top.isAuto() && bottom.isAuto())); | 2161 ASSERT(!(top.isAuto() && bottom.isAuto())); |
| 2564 | 2162 |
| 2565 int contentHeight = height() - bordersPlusPadding; | 2163 int contentHeight = height() - bordersPlusPadding; |
| 2566 | 2164 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2675 void RenderBox::calcAbsoluteHorizontalReplaced() | 2273 void RenderBox::calcAbsoluteHorizontalReplaced() |
| 2676 { | 2274 { |
| 2677 // The following is based off of the W3C Working Draft from April 11, 2006 o
f | 2275 // The following is based off of the W3C Working Draft from April 11, 2006 o
f |
| 2678 // CSS 2.1: Section 10.3.8 "Absolutly positioned, replaced elements" | 2276 // CSS 2.1: Section 10.3.8 "Absolutly positioned, replaced elements" |
| 2679 // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-wi
dth> | 2277 // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-wi
dth> |
| 2680 // (block-style-comments in this function correspond to text from the spec a
nd | 2278 // (block-style-comments in this function correspond to text from the spec a
nd |
| 2681 // the numbers correspond to numbers in spec) | 2279 // the numbers correspond to numbers in spec) |
| 2682 | 2280 |
| 2683 // We don't use containingBlock(), since we may be positioned by an enclosin
g | 2281 // We don't use containingBlock(), since we may be positioned by an enclosin
g |
| 2684 // relative positioned inline. | 2282 // relative positioned inline. |
| 2685 const RenderBox* containerBlock = toRenderBox(container()); | 2283 const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(containe
r()); |
| 2686 | 2284 |
| 2687 const int containerWidth = containingBlockWidthForPositioned(containerBlock)
; | 2285 const int containerWidth = containingBlockWidthForPositioned(containerBlock)
; |
| 2688 | 2286 |
| 2689 // To match WinIE, in quirks mode use the parent's 'direction' property | 2287 // To match WinIE, in quirks mode use the parent's 'direction' property |
| 2690 // instead of the the container block's. | 2288 // instead of the the container block's. |
| 2691 TextDirection containerDirection = (style()->htmlHacks()) ? parent()->style(
)->direction() : containerBlock->style()->direction(); | 2289 TextDirection containerDirection = (style()->htmlHacks()) ? parent()->style(
)->direction() : containerBlock->style()->direction(); |
| 2692 | 2290 |
| 2693 // Variables to solve. | 2291 // Variables to solve. |
| 2694 Length left = style()->left(); | 2292 Length left = style()->left(); |
| 2695 Length right = style()->right(); | 2293 Length right = style()->right(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2711 * 2. If both 'left' and 'right' have the value 'auto', then if 'direction' | 2309 * 2. If both 'left' and 'right' have the value 'auto', then if 'direction' |
| 2712 * of the containing block is 'ltr', set 'left' to the static position; | 2310 * of the containing block is 'ltr', set 'left' to the static position; |
| 2713 * else if 'direction' is 'rtl', set 'right' to the static position. | 2311 * else if 'direction' is 'rtl', set 'right' to the static position. |
| 2714 \*-----------------------------------------------------------------------*/ | 2312 \*-----------------------------------------------------------------------*/ |
| 2715 // see FIXME 2 | 2313 // see FIXME 2 |
| 2716 if (left.isAuto() && right.isAuto()) { | 2314 if (left.isAuto() && right.isAuto()) { |
| 2717 // see FIXME 1 | 2315 // see FIXME 1 |
| 2718 if (containerDirection == LTR) { | 2316 if (containerDirection == LTR) { |
| 2719 // 'staticX' should already have been set through layout of the pare
nt. | 2317 // 'staticX' should already have been set through layout of the pare
nt. |
| 2720 int staticPosition = layer()->staticX() - containerBlock->borderLeft
(); | 2318 int staticPosition = layer()->staticX() - containerBlock->borderLeft
(); |
| 2721 for (RenderBox* po = parentBox(); po && po != containerBlock; po = p
o->parentBox()) | 2319 for (RenderObject* po = parent(); po && po != containerBlock; po = p
o->parent()) { |
| 2722 staticPosition += po->x(); | 2320 if (po->isBox()) |
| 2321 staticPosition += toRenderBox(po)->x(); |
| 2322 } |
| 2723 left.setValue(Fixed, staticPosition); | 2323 left.setValue(Fixed, staticPosition); |
| 2724 } else { | 2324 } else { |
| 2725 RenderBox* po = parentBox(); | 2325 RenderObject* po = parent(); |
| 2726 // 'staticX' should already have been set through layout of the pare
nt. | 2326 // 'staticX' should already have been set through layout of the pare
nt. |
| 2727 int staticPosition = layer()->staticX() + containerWidth + container
Block->borderRight() - po->width(); | 2327 int staticPosition = layer()->staticX() + containerWidth + toRenderB
oxModelObject(containerBlock)->borderRight(); |
| 2728 for (; po && po != containerBlock; po = po->parentBox()) | 2328 if (po->isBox()) |
| 2729 staticPosition -= po->x(); | 2329 po -= toRenderBox(po)->width(); |
| 2330 for ( ; po && po != containerBlock; po = po->parent()) { |
| 2331 if (po->isBox()) |
| 2332 staticPosition += toRenderBox(po)->x(); |
| 2333 } |
| 2730 right.setValue(Fixed, staticPosition); | 2334 right.setValue(Fixed, staticPosition); |
| 2731 } | 2335 } |
| 2732 } | 2336 } |
| 2733 | 2337 |
| 2734 /*-----------------------------------------------------------------------*\ | 2338 /*-----------------------------------------------------------------------*\ |
| 2735 * 3. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left' | 2339 * 3. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left' |
| 2736 * or 'margin-right' with '0'. | 2340 * or 'margin-right' with '0'. |
| 2737 \*-----------------------------------------------------------------------*/ | 2341 \*-----------------------------------------------------------------------*/ |
| 2738 if (left.isAuto() || right.isAuto()) { | 2342 if (left.isAuto() || right.isAuto()) { |
| 2739 if (marginLeft.isAuto()) | 2343 if (marginLeft.isAuto()) |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2848 | 2452 |
| 2849 void RenderBox::calcAbsoluteVerticalReplaced() | 2453 void RenderBox::calcAbsoluteVerticalReplaced() |
| 2850 { | 2454 { |
| 2851 // The following is based off of the W3C Working Draft from April 11, 2006 o
f | 2455 // The following is based off of the W3C Working Draft from April 11, 2006 o
f |
| 2852 // CSS 2.1: Section 10.6.5 "Absolutly positioned, replaced elements" | 2456 // CSS 2.1: Section 10.6.5 "Absolutly positioned, replaced elements" |
| 2853 // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-he
ight> | 2457 // <http://www.w3.org/TR/2005/WD-CSS21-20050613/visudet.html#abs-replaced-he
ight> |
| 2854 // (block-style-comments in this function correspond to text from the spec a
nd | 2458 // (block-style-comments in this function correspond to text from the spec a
nd |
| 2855 // the numbers correspond to numbers in spec) | 2459 // the numbers correspond to numbers in spec) |
| 2856 | 2460 |
| 2857 // We don't use containingBlock(), since we may be positioned by an enclosin
g relpositioned inline. | 2461 // We don't use containingBlock(), since we may be positioned by an enclosin
g relpositioned inline. |
| 2858 const RenderBox* containerBlock = toRenderBox(container()); | 2462 const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(containe
r()); |
| 2859 | 2463 |
| 2860 const int containerHeight = containingBlockHeightForPositioned(containerBloc
k); | 2464 const int containerHeight = containingBlockHeightForPositioned(containerBloc
k); |
| 2861 | 2465 |
| 2862 // Variables to solve. | 2466 // Variables to solve. |
| 2863 Length top = style()->top(); | 2467 Length top = style()->top(); |
| 2864 Length bottom = style()->bottom(); | 2468 Length bottom = style()->bottom(); |
| 2865 Length marginTop = style()->marginTop(); | 2469 Length marginTop = style()->marginTop(); |
| 2866 Length marginBottom = style()->marginBottom(); | 2470 Length marginBottom = style()->marginBottom(); |
| 2867 | 2471 |
| 2868 | 2472 |
| 2869 /*-----------------------------------------------------------------------*\ | 2473 /*-----------------------------------------------------------------------*\ |
| 2870 * 1. The used value of 'height' is determined as for inline replaced | 2474 * 1. The used value of 'height' is determined as for inline replaced |
| 2871 * elements. | 2475 * elements. |
| 2872 \*-----------------------------------------------------------------------*/ | 2476 \*-----------------------------------------------------------------------*/ |
| 2873 // NOTE: This value of height is FINAL in that the min/max height calculatio
ns | 2477 // NOTE: This value of height is FINAL in that the min/max height calculatio
ns |
| 2874 // are dealt with in calcReplacedHeight(). This means that the steps to pro
duce | 2478 // are dealt with in calcReplacedHeight(). This means that the steps to pro
duce |
| 2875 // correct max/min in the non-replaced version, are not necessary. | 2479 // correct max/min in the non-replaced version, are not necessary. |
| 2876 setHeight(calcReplacedHeight() + borderTop() + borderBottom() + paddingTop()
+ paddingBottom()); | 2480 setHeight(calcReplacedHeight() + borderTop() + borderBottom() + paddingTop()
+ paddingBottom()); |
| 2877 const int availableSpace = containerHeight - height(); | 2481 const int availableSpace = containerHeight - height(); |
| 2878 | 2482 |
| 2879 /*-----------------------------------------------------------------------*\ | 2483 /*-----------------------------------------------------------------------*\ |
| 2880 * 2. If both 'top' and 'bottom' have the value 'auto', replace 'top' | 2484 * 2. If both 'top' and 'bottom' have the value 'auto', replace 'top' |
| 2881 * with the element's static position. | 2485 * with the element's static position. |
| 2882 \*-----------------------------------------------------------------------*/ | 2486 \*-----------------------------------------------------------------------*/ |
| 2883 // see FIXME 2 | 2487 // see FIXME 2 |
| 2884 if (top.isAuto() && bottom.isAuto()) { | 2488 if (top.isAuto() && bottom.isAuto()) { |
| 2885 // staticY should already have been set through layout of the parent(). | 2489 // staticY should already have been set through layout of the parent(). |
| 2886 int staticTop = layer()->staticY() - containerBlock->borderTop(); | 2490 int staticTop = layer()->staticY() - containerBlock->borderTop(); |
| 2887 for (RenderBox* po = parentBox(); po && po != containerBlock; po = po->p
arentBox()) { | 2491 for (RenderObject* po = parent(); po && po != containerBlock; po = po->p
arent()) { |
| 2888 if (!po->isTableRow()) | 2492 if (po->isBox() && !po->isTableRow()) |
| 2889 staticTop += po->y(); | 2493 staticTop += toRenderBox(po)->y(); |
| 2890 } | 2494 } |
| 2891 top.setValue(Fixed, staticTop); | 2495 top.setValue(Fixed, staticTop); |
| 2892 } | 2496 } |
| 2893 | 2497 |
| 2894 /*-----------------------------------------------------------------------*\ | 2498 /*-----------------------------------------------------------------------*\ |
| 2895 * 3. If 'bottom' is 'auto', replace any 'auto' on 'margin-top' or | 2499 * 3. If 'bottom' is 'auto', replace any 'auto' on 'margin-top' or |
| 2896 * 'margin-bottom' with '0'. | 2500 * 'margin-bottom' with '0'. |
| 2897 \*-----------------------------------------------------------------------*/ | 2501 \*-----------------------------------------------------------------------*/ |
| 2898 // FIXME: The spec. says that this step should only be taken when bottom is | 2502 // FIXME: The spec. says that this step should only be taken when bottom is |
| 2899 // auto, but if only top is auto, this makes step 4 impossible. | 2503 // auto, but if only top is auto, this makes step 4 impossible. |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3085 for (RenderObject* renderObject = firstChild(); renderObject; renderObject =
renderObject->nextSibling()) { | 2689 for (RenderObject* renderObject = firstChild(); renderObject; renderObject =
renderObject->nextSibling()) { |
| 3086 if (!renderObject->firstChild() && !renderObject->isInline() && !renderO
bject->isBlockFlow() | 2690 if (!renderObject->firstChild() && !renderObject->isInline() && !renderO
bject->isBlockFlow() |
| 3087 || renderObject->style()->visibility() != VISIBLE) | 2691 || renderObject->style()->visibility() != VISIBLE) |
| 3088 continue; | 2692 continue; |
| 3089 | 2693 |
| 3090 if (!renderObject->isBox()) | 2694 if (!renderObject->isBox()) |
| 3091 continue; | 2695 continue; |
| 3092 | 2696 |
| 3093 RenderBox* renderer = toRenderBox(renderObject); | 2697 RenderBox* renderer = toRenderBox(renderObject); |
| 3094 | 2698 |
| 3095 int top = borderTop() + paddingTop() + (isTableRow() ? 0 : renderer->y()
); | 2699 int top = renderer->borderTop() + renderer->paddingTop() + (isTableRow()
? 0 : renderer->y()); |
| 3096 int bottom = top + renderer->contentHeight(); | 2700 int bottom = top + renderer->contentHeight(); |
| 3097 int left = borderLeft() + paddingLeft() + (isTableRow() ? 0 : renderer->
x()); | 2701 int left = renderer->borderLeft() + renderer->paddingLeft() + (isTableRo
w() ? 0 : renderer->x()); |
| 3098 int right = left + renderer->contentWidth(); | 2702 int right = left + renderer->contentWidth(); |
| 3099 | 2703 |
| 3100 if (xPos <= right && xPos >= left && yPos <= top && yPos >= bottom) { | 2704 if (xPos <= right && xPos >= left && yPos <= top && yPos >= bottom) { |
| 3101 if (renderer->isTableRow()) | 2705 if (renderer->isTableRow()) |
| 3102 return renderer->positionForCoordinates(xPos + newX - renderer->
x(), yPos + newY - renderer->y()); | 2706 return renderer->positionForCoordinates(xPos + newX - renderer->
x(), yPos + newY - renderer->y()); |
| 3103 return renderer->positionForCoordinates(xPos - renderer->x(), yPos -
renderer->y()); | 2707 return renderer->positionForCoordinates(xPos - renderer->x(), yPos -
renderer->y()); |
| 3104 } | 2708 } |
| 3105 | 2709 |
| 3106 // Find the distance from (x, y) to the box. Split the space around the
box into 8 pieces | 2710 // Find the distance from (x, y) to the box. Split the space around the
box into 8 pieces |
| 3107 // and use a different compare depending on which piece (x, y) is in. | 2711 // and use a different compare depending on which piece (x, y) is in. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3146 #if ENABLE(SVG) | 2750 #if ENABLE(SVG) |
| 3147 | 2751 |
| 3148 TransformationMatrix RenderBox::localTransform() const | 2752 TransformationMatrix RenderBox::localTransform() const |
| 3149 { | 2753 { |
| 3150 return TransformationMatrix(1, 0, 0, 1, x(), y()); | 2754 return TransformationMatrix(1, 0, 0, 1, x(), y()); |
| 3151 } | 2755 } |
| 3152 | 2756 |
| 3153 #endif | 2757 #endif |
| 3154 | 2758 |
| 3155 } // namespace WebCore | 2759 } // namespace WebCore |
| OLD | NEW |