| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. |
| 3 * All rights reserved. |
| 3 * | 4 * |
| 4 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
| 8 * | 9 * |
| 9 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 12 * Library General Public License for more details. | 13 * Library General Public License for more details. |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 (parentStyle.verticalAlign() != VerticalAlignBaseline && | 128 (parentStyle.verticalAlign() != VerticalAlignBaseline && |
| 128 !isRootInlineBox()) || | 129 !isRootInlineBox()) || |
| 129 childStyle.verticalAlign() != VerticalAlignBaseline) | 130 childStyle.verticalAlign() != VerticalAlignBaseline) |
| 130 shouldClearDescendantsHaveSameLineHeightAndBaseline = true; | 131 shouldClearDescendantsHaveSameLineHeightAndBaseline = true; |
| 131 } | 132 } |
| 132 if (childStyle.hasTextCombine() || | 133 if (childStyle.hasTextCombine() || |
| 133 childStyle.getTextEmphasisMark() != TextEmphasisMarkNone) | 134 childStyle.getTextEmphasisMark() != TextEmphasisMarkNone) |
| 134 shouldClearDescendantsHaveSameLineHeightAndBaseline = true; | 135 shouldClearDescendantsHaveSameLineHeightAndBaseline = true; |
| 135 } else { | 136 } else { |
| 136 if (child->getLineLayoutItem().isBR()) { | 137 if (child->getLineLayoutItem().isBR()) { |
| 137 // FIXME: This is dumb. We only turn off because current layout test res
ults expect the <br> to be 0-height on the baseline. | 138 // FIXME: This is dumb. We only turn off because current layout test |
| 138 // Other than making a zillion tests have to regenerate results, there's
no reason to ditch the optimization here. | 139 // results expect the <br> to be 0-height on the baseline. |
| 140 // Other than making a zillion tests have to regenerate results, there's |
| 141 // no reason to ditch the optimization here. |
| 139 shouldClearDescendantsHaveSameLineHeightAndBaseline = true; | 142 shouldClearDescendantsHaveSameLineHeightAndBaseline = true; |
| 140 } else { | 143 } else { |
| 141 ASSERT(isInlineFlowBox()); | 144 ASSERT(isInlineFlowBox()); |
| 142 InlineFlowBox* childFlowBox = toInlineFlowBox(child); | 145 InlineFlowBox* childFlowBox = toInlineFlowBox(child); |
| 143 // Check the child's bit, and then also check for differences in font, l
ine-height, vertical-align | 146 // Check the child's bit, and then also check for differences in font, |
| 147 // line-height, vertical-align |
| 144 if (!childFlowBox->descendantsHaveSameLineHeightAndBaseline() || | 148 if (!childFlowBox->descendantsHaveSameLineHeightAndBaseline() || |
| 145 !parentStyle.font() | 149 !parentStyle.font() |
| 146 .getFontMetrics() | 150 .getFontMetrics() |
| 147 .hasIdenticalAscentDescentAndLineGap( | 151 .hasIdenticalAscentDescentAndLineGap( |
| 148 childStyle.font().getFontMetrics()) || | 152 childStyle.font().getFontMetrics()) || |
| 149 parentStyle.lineHeight() != childStyle.lineHeight() || | 153 parentStyle.lineHeight() != childStyle.lineHeight() || |
| 150 (parentStyle.verticalAlign() != VerticalAlignBaseline && | 154 (parentStyle.verticalAlign() != VerticalAlignBaseline && |
| 151 !isRootInlineBox()) || | 155 !isRootInlineBox()) || |
| 152 childStyle.verticalAlign() != VerticalAlignBaseline || | 156 childStyle.verticalAlign() != VerticalAlignBaseline || |
| 153 childStyle.hasBorder() || childStyle.hasPadding() || | 157 childStyle.hasBorder() || childStyle.hasPadding() || |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 lineBoxes()->attachLineBox(this); | 270 lineBoxes()->attachLineBox(this); |
| 267 } | 271 } |
| 268 | 272 |
| 269 void InlineFlowBox::move(const LayoutSize& delta) { | 273 void InlineFlowBox::move(const LayoutSize& delta) { |
| 270 InlineBox::move(delta); | 274 InlineBox::move(delta); |
| 271 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) { | 275 for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) { |
| 272 if (child->getLineLayoutItem().isOutOfFlowPositioned()) | 276 if (child->getLineLayoutItem().isOutOfFlowPositioned()) |
| 273 continue; | 277 continue; |
| 274 child->move(delta); | 278 child->move(delta); |
| 275 } | 279 } |
| 276 if (m_overflow) | 280 if (m_overflow) { |
| 277 m_overflow->move( | 281 // FIXME: Rounding error here since overflow was pixel snapped, but nobody |
| 278 delta.width(), | 282 // other than list markers passes non-integral values here. |
| 279 delta | 283 m_overflow->move(delta.width(), delta.height()); |
| 280 .height()); // FIXME: Rounding error here since overflow was pixel
snapped, but nobody other than list markers passes non-integral values here. | 284 } |
| 281 } | 285 } |
| 282 | 286 |
| 283 LineBoxList* InlineFlowBox::lineBoxes() const { | 287 LineBoxList* InlineFlowBox::lineBoxes() const { |
| 284 return LineLayoutInline(getLineLayoutItem()).lineBoxes(); | 288 return LineLayoutInline(getLineLayoutItem()).lineBoxes(); |
| 285 } | 289 } |
| 286 | 290 |
| 287 static inline bool isLastChildForLayoutObject(LineLayoutItem ancestor, | 291 static inline bool isLastChildForLayoutObject(LineLayoutItem ancestor, |
| 288 LineLayoutItem child) { | 292 LineLayoutItem child) { |
| 289 if (!child) | 293 if (!child) |
| 290 return false; | 294 return false; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 315 return true; | 319 return true; |
| 316 item = item.parent(); | 320 item = item.parent(); |
| 317 } | 321 } |
| 318 return false; | 322 return false; |
| 319 } | 323 } |
| 320 | 324 |
| 321 void InlineFlowBox::determineSpacingForFlowBoxes( | 325 void InlineFlowBox::determineSpacingForFlowBoxes( |
| 322 bool lastLine, | 326 bool lastLine, |
| 323 bool isLogicallyLastRunWrapped, | 327 bool isLogicallyLastRunWrapped, |
| 324 LineLayoutItem logicallyLastRunLayoutObject) { | 328 LineLayoutItem logicallyLastRunLayoutObject) { |
| 325 // All boxes start off open. They will not apply any margins/border/padding o
n | 329 // All boxes start off open. They will not apply any margins/border/padding |
| 326 // any side. | 330 // on any side. |
| 327 bool includeLeftEdge = false; | 331 bool includeLeftEdge = false; |
| 328 bool includeRightEdge = false; | 332 bool includeRightEdge = false; |
| 329 | 333 |
| 330 // The root inline box never has borders/margins/padding. | 334 // The root inline box never has borders/margins/padding. |
| 331 if (parent()) { | 335 if (parent()) { |
| 332 bool ltr = getLineLayoutItem().style()->isLeftToRightDirection(); | 336 bool ltr = getLineLayoutItem().style()->isLeftToRightDirection(); |
| 333 | 337 |
| 334 // Check to see if all initial lines are unconstructed. If so, then | 338 // Check to see if all initial lines are unconstructed. If so, then |
| 335 // we know the inline began on this line (unless we are a continuation). | 339 // we know the inline began on this line (unless we are a continuation). |
| 336 LineBoxList* lineBoxList = lineBoxes(); | 340 LineBoxList* lineBoxList = lineBoxes(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 349 LineLayoutInline inlineFlow = LineLayoutInline(getLineLayoutItem()); | 353 LineLayoutInline inlineFlow = LineLayoutInline(getLineLayoutItem()); |
| 350 LineLayoutItem logicallyLastRunLayoutItem(logicallyLastRunLayoutObject); | 354 LineLayoutItem logicallyLastRunLayoutItem(logicallyLastRunLayoutObject); |
| 351 bool isLastObjectOnLine = | 355 bool isLastObjectOnLine = |
| 352 !isAncestorAndWithinBlock(getLineLayoutItem(), | 356 !isAncestorAndWithinBlock(getLineLayoutItem(), |
| 353 logicallyLastRunLayoutItem) || | 357 logicallyLastRunLayoutItem) || |
| 354 (isLastChildForLayoutObject(getLineLayoutItem(), | 358 (isLastChildForLayoutObject(getLineLayoutItem(), |
| 355 logicallyLastRunLayoutItem) && | 359 logicallyLastRunLayoutItem) && |
| 356 !isLogicallyLastRunWrapped); | 360 !isLogicallyLastRunWrapped); |
| 357 | 361 |
| 358 // We include the border under these conditions: | 362 // We include the border under these conditions: |
| 359 // (1) The next line was not created, or it is constructed. We check the p
revious line for rtl. | 363 // (1) The next line was not created, or it is constructed. We check the |
| 364 // previous line for rtl. |
| 360 // (2) The logicallyLastRun is not a descendant of this layout object. | 365 // (2) The logicallyLastRun is not a descendant of this layout object. |
| 361 // (3) The logicallyLastRun is a descendant of this layout object, but it
is the last child of this layout object and it does not wrap to the next line. | 366 // (3) The logicallyLastRun is a descendant of this layout object, but it |
| 362 // (4) The decoration break is set to clone therefore there will be border
s on every sides. | 367 // is the last child of this layout object and it does not wrap to the |
| 368 // next line. |
| 369 // (4) The decoration break is set to clone therefore there will be |
| 370 // borders on every sides. |
| 363 if (getLineLayoutItem().style()->boxDecorationBreak() == | 371 if (getLineLayoutItem().style()->boxDecorationBreak() == |
| 364 BoxDecorationBreakClone) { | 372 BoxDecorationBreakClone) { |
| 365 includeLeftEdge = includeRightEdge = true; | 373 includeLeftEdge = includeRightEdge = true; |
| 366 } else if (ltr) { | 374 } else if (ltr) { |
| 367 if (!nextLineBox() && | 375 if (!nextLineBox() && |
| 368 ((lastLine || isLastObjectOnLine) && !inlineFlow.continuation())) | 376 ((lastLine || isLastObjectOnLine) && !inlineFlow.continuation())) |
| 369 includeRightEdge = true; | 377 includeRightEdge = true; |
| 370 } else { | 378 } else { |
| 371 if ((!prevLineBox() || prevLineBox()->isConstructed()) && | 379 if ((!prevLineBox() || prevLineBox()->isConstructed()) && |
| 372 ((lastLine || isLastObjectOnLine) && !inlineFlow.continuation())) | 380 ((lastLine || isLastObjectOnLine) && !inlineFlow.continuation())) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 402 placeBoxRangeInInlineDirection(firstChild(), nullptr, logicalLeft, | 410 placeBoxRangeInInlineDirection(firstChild(), nullptr, logicalLeft, |
| 403 minLogicalLeft, maxLogicalRight, | 411 minLogicalLeft, maxLogicalRight, |
| 404 needsWordSpacing); | 412 needsWordSpacing); |
| 405 | 413 |
| 406 logicalLeft += borderLogicalRight() + paddingLogicalRight(); | 414 logicalLeft += borderLogicalRight() + paddingLogicalRight(); |
| 407 endPlacingBoxRangesInInlineDirection(startLogicalLeft, logicalLeft, | 415 endPlacingBoxRangesInInlineDirection(startLogicalLeft, logicalLeft, |
| 408 minLogicalLeft, maxLogicalRight); | 416 minLogicalLeft, maxLogicalRight); |
| 409 return logicalLeft; | 417 return logicalLeft; |
| 410 } | 418 } |
| 411 | 419 |
| 412 // TODO(wkorman): needsWordSpacing may not need to be a reference in the below.
Seek a test case. | 420 // TODO(wkorman): needsWordSpacing may not need to be a reference in the below. |
| 421 // Seek a test case. |
| 413 void InlineFlowBox::placeBoxRangeInInlineDirection(InlineBox* firstChild, | 422 void InlineFlowBox::placeBoxRangeInInlineDirection(InlineBox* firstChild, |
| 414 InlineBox* lastChild, | 423 InlineBox* lastChild, |
| 415 LayoutUnit& logicalLeft, | 424 LayoutUnit& logicalLeft, |
| 416 LayoutUnit& minLogicalLeft, | 425 LayoutUnit& minLogicalLeft, |
| 417 LayoutUnit& maxLogicalRight, | 426 LayoutUnit& maxLogicalRight, |
| 418 bool& needsWordSpacing) { | 427 bool& needsWordSpacing) { |
| 419 for (InlineBox* curr = firstChild; curr && curr != lastChild; | 428 for (InlineBox* curr = firstChild; curr && curr != lastChild; |
| 420 curr = curr->nextOnLine()) { | 429 curr = curr->nextOnLine()) { |
| 421 if (curr->getLineLayoutItem().isText()) { | 430 if (curr->getLineLayoutItem().isText()) { |
| 422 InlineTextBox* text = toInlineTextBox(curr); | 431 InlineTextBox* text = toInlineTextBox(curr); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 443 if (knownToHaveNoOverflow()) | 452 if (knownToHaveNoOverflow()) |
| 444 maxLogicalRight = std::max(logicalLeft, maxLogicalRight); | 453 maxLogicalRight = std::max(logicalLeft, maxLogicalRight); |
| 445 } else { | 454 } else { |
| 446 if (curr->getLineLayoutItem().isOutOfFlowPositioned()) { | 455 if (curr->getLineLayoutItem().isOutOfFlowPositioned()) { |
| 447 if (curr->getLineLayoutItem() | 456 if (curr->getLineLayoutItem() |
| 448 .parent() | 457 .parent() |
| 449 .style() | 458 .style() |
| 450 ->isLeftToRightDirection()) { | 459 ->isLeftToRightDirection()) { |
| 451 curr->setLogicalLeft(logicalLeft); | 460 curr->setLogicalLeft(logicalLeft); |
| 452 } else { | 461 } else { |
| 453 // Our offset that we cache needs to be from the edge of the right bor
der box and | 462 // Our offset that we cache needs to be from the edge of the right |
| 454 // not the left border box. We have to subtract |x| from the width of
the block | 463 // border box and not the left border box. We have to subtract |x| |
| 455 // (which can be obtained from the root line box). | 464 // from the width of the block (which can be obtained from the root |
| 465 // line box). |
| 456 curr->setLogicalLeft(root().block().logicalWidth() - logicalLeft); | 466 curr->setLogicalLeft(root().block().logicalWidth() - logicalLeft); |
| 457 } | 467 } |
| 458 continue; // The positioned object has no effect on the width. | 468 continue; // The positioned object has no effect on the width. |
| 459 } | 469 } |
| 460 if (curr->getLineLayoutItem().isLayoutInline()) { | 470 if (curr->getLineLayoutItem().isLayoutInline()) { |
| 461 InlineFlowBox* flow = toInlineFlowBox(curr); | 471 InlineFlowBox* flow = toInlineFlowBox(curr); |
| 462 logicalLeft += flow->marginLogicalLeft(); | 472 logicalLeft += flow->marginLogicalLeft(); |
| 463 if (knownToHaveNoOverflow()) | 473 if (knownToHaveNoOverflow()) |
| 464 minLogicalLeft = std::min(logicalLeft, minLogicalLeft); | 474 minLogicalLeft = std::min(logicalLeft, minLogicalLeft); |
| 465 logicalLeft = | 475 logicalLeft = |
| 466 flow->placeBoxesInInlineDirection(logicalLeft, needsWordSpacing); | 476 flow->placeBoxesInInlineDirection(logicalLeft, needsWordSpacing); |
| 467 if (knownToHaveNoOverflow()) | 477 if (knownToHaveNoOverflow()) |
| 468 maxLogicalRight = std::max(logicalLeft, maxLogicalRight); | 478 maxLogicalRight = std::max(logicalLeft, maxLogicalRight); |
| 469 logicalLeft += flow->marginLogicalRight(); | 479 logicalLeft += flow->marginLogicalRight(); |
| 470 } else if (!curr->getLineLayoutItem().isListMarker() || | 480 } else if (!curr->getLineLayoutItem().isListMarker() || |
| 471 LineLayoutListMarker(curr->getLineLayoutItem()).isInside()) { | 481 LineLayoutListMarker(curr->getLineLayoutItem()).isInside()) { |
| 472 // The box can have a different writing-mode than the overall line, so t
his is a bit complicated. | 482 // The box can have a different writing-mode than the overall line, so |
| 473 // Just get all the physical margin and overflow values by hand based of
f |isHorizontal|. | 483 // this is a bit complicated. Just get all the physical margin and |
| 484 // overflow values by hand based off |isHorizontal|. |
| 474 LineLayoutBoxModel box = curr->boxModelObject(); | 485 LineLayoutBoxModel box = curr->boxModelObject(); |
| 475 LayoutUnit logicalLeftMargin; | 486 LayoutUnit logicalLeftMargin; |
| 476 LayoutUnit logicalRightMargin; | 487 LayoutUnit logicalRightMargin; |
| 477 if (isHorizontal()) { | 488 if (isHorizontal()) { |
| 478 logicalLeftMargin = box.marginLeft(); | 489 logicalLeftMargin = box.marginLeft(); |
| 479 logicalRightMargin = box.marginRight(); | 490 logicalRightMargin = box.marginRight(); |
| 480 } else { | 491 } else { |
| 481 logicalLeftMargin = box.marginTop(); | 492 logicalLeftMargin = box.marginTop(); |
| 482 logicalRightMargin = box.marginBottom(); | 493 logicalRightMargin = box.marginBottom(); |
| 483 } | 494 } |
| 484 | 495 |
| 485 logicalLeft += logicalLeftMargin; | 496 logicalLeft += logicalLeftMargin; |
| 486 curr->setLogicalLeft(logicalLeft); | 497 curr->setLogicalLeft(logicalLeft); |
| 487 if (knownToHaveNoOverflow()) | 498 if (knownToHaveNoOverflow()) |
| 488 minLogicalLeft = std::min(logicalLeft, minLogicalLeft); | 499 minLogicalLeft = std::min(logicalLeft, minLogicalLeft); |
| 489 logicalLeft += curr->logicalWidth(); | 500 logicalLeft += curr->logicalWidth(); |
| 490 if (knownToHaveNoOverflow()) | 501 if (knownToHaveNoOverflow()) |
| 491 maxLogicalRight = std::max(logicalLeft, maxLogicalRight); | 502 maxLogicalRight = std::max(logicalLeft, maxLogicalRight); |
| 492 logicalLeft += logicalRightMargin; | 503 logicalLeft += logicalRightMargin; |
| 493 // If we encounter any space after this inline block then ensure it is t
reated as the space between two words. | 504 // If we encounter any space after this inline block then ensure it is |
| 505 // treated as the space between two words. |
| 494 needsWordSpacing = true; | 506 needsWordSpacing = true; |
| 495 } | 507 } |
| 496 } | 508 } |
| 497 } | 509 } |
| 498 } | 510 } |
| 499 | 511 |
| 500 FontBaseline InlineFlowBox::dominantBaseline() const { | 512 FontBaseline InlineFlowBox::dominantBaseline() const { |
| 501 // Use "central" (Ideographic) baseline if writing-mode is vertical-* and text
-orientation is not sideways-*. | 513 // Use "central" (Ideographic) baseline if writing-mode is vertical-* and |
| 514 // text-orientation is not sideways-*. |
| 502 // http://dev.w3.org/csswg/css-writing-modes-3/#text-baselines | 515 // http://dev.w3.org/csswg/css-writing-modes-3/#text-baselines |
| 503 if (!isHorizontal() && | 516 if (!isHorizontal() && |
| 504 getLineLayoutItem() | 517 getLineLayoutItem() |
| 505 .style(isFirstLineStyle()) | 518 .style(isFirstLineStyle()) |
| 506 ->getFontDescription() | 519 ->getFontDescription() |
| 507 .isVerticalAnyUpright()) | 520 .isVerticalAnyUpright()) |
| 508 return IdeographicBaseline; | 521 return IdeographicBaseline; |
| 509 return AlphabeticBaseline; | 522 return AlphabeticBaseline; |
| 510 } | 523 } |
| 511 | 524 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 LayoutUnit& maxPositionTop, | 561 LayoutUnit& maxPositionTop, |
| 549 LayoutUnit& maxPositionBottom, | 562 LayoutUnit& maxPositionBottom, |
| 550 int& maxAscent, | 563 int& maxAscent, |
| 551 int& maxDescent, | 564 int& maxDescent, |
| 552 bool& setMaxAscent, | 565 bool& setMaxAscent, |
| 553 bool& setMaxDescent, | 566 bool& setMaxDescent, |
| 554 bool noQuirksMode, | 567 bool noQuirksMode, |
| 555 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, | 568 GlyphOverflowAndFallbackFontsMap& textBoxDataMap, |
| 556 FontBaseline baselineType, | 569 FontBaseline baselineType, |
| 557 VerticalPositionCache& verticalPositionCache) { | 570 VerticalPositionCache& verticalPositionCache) { |
| 558 // The primary purpose of this function is to compute the maximal ascent and d
escent values for | 571 // The primary purpose of this function is to compute the maximal ascent and |
| 559 // a line. | 572 // descent values for a line. |
| 560 // | 573 // |
| 561 // The maxAscent value represents the distance of the highest point of any box
(typically including line-height) from | 574 // The maxAscent value represents the distance of the highest point of any box |
| 562 // the root box's baseline. The maxDescent value represents the distance of th
e lowest point of any box | 575 // (typically including line-height) from the root box's baseline. The |
| 563 // (also typically including line-height) from the root box baseline. These va
lues can be negative. | 576 // maxDescent value represents the distance of the lowest point of any box |
| 577 // (also typically including line-height) from the root box baseline. These |
| 578 // values can be negative. |
| 564 // | 579 // |
| 565 // A secondary purpose of this function is to store the offset of every box's
baseline from the root box's | 580 // A secondary purpose of this function is to store the offset of every box's |
| 566 // baseline. This information is cached in the logicalTop() of every box. We'r
e effectively just using | 581 // baseline from the root box's baseline. This information is cached in the |
| 567 // the logicalTop() as scratch space. | 582 // logicalTop() of every box. We're effectively just using the logicalTop() as |
| 583 // scratch space. |
| 568 // | 584 // |
| 569 // Because a box can be positioned such that it ends up fully above or fully b
elow the | 585 // Because a box can be positioned such that it ends up fully above or fully |
| 570 // root line box, we only consider it to affect the maxAscent and maxDescent v
alues if some | 586 // below the root line box, we only consider it to affect the maxAscent and |
| 571 // part of the box (EXCLUDING leading) is above (for ascent) or below (for des
cent) the root box's baseline. | 587 // maxDescent values if some part of the box (EXCLUDING leading) is above (for |
| 588 // ascent) or below (for descent) the root box's baseline. |
| 572 bool affectsAscent = false; | 589 bool affectsAscent = false; |
| 573 bool affectsDescent = false; | 590 bool affectsDescent = false; |
| 574 bool checkChildren = !descendantsHaveSameLineHeightAndBaseline(); | 591 bool checkChildren = !descendantsHaveSameLineHeightAndBaseline(); |
| 575 | 592 |
| 576 if (isRootInlineBox()) { | 593 if (isRootInlineBox()) { |
| 577 // Examine our root box. | 594 // Examine our root box. |
| 578 int ascent = 0; | 595 int ascent = 0; |
| 579 int descent = 0; | 596 int descent = 0; |
| 580 rootBox->ascentAndDescentForBox(rootBox, textBoxDataMap, ascent, descent, | 597 rootBox->ascentAndDescentForBox(rootBox, textBoxDataMap, ascent, descent, |
| 581 affectsAscent, affectsDescent); | 598 affectsAscent, affectsDescent); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 598 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { | 615 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { |
| 599 if (curr->getLineLayoutItem().isOutOfFlowPositioned()) | 616 if (curr->getLineLayoutItem().isOutOfFlowPositioned()) |
| 600 continue; // Positioned placeholders don't affect calculations. | 617 continue; // Positioned placeholders don't affect calculations. |
| 601 | 618 |
| 602 InlineFlowBox* inlineFlowBox = | 619 InlineFlowBox* inlineFlowBox = |
| 603 curr->isInlineFlowBox() ? toInlineFlowBox(curr) : nullptr; | 620 curr->isInlineFlowBox() ? toInlineFlowBox(curr) : nullptr; |
| 604 | 621 |
| 605 bool affectsAscent = false; | 622 bool affectsAscent = false; |
| 606 bool affectsDescent = false; | 623 bool affectsDescent = false; |
| 607 | 624 |
| 608 // The verticalPositionForBox function returns the distance between the chil
d box's baseline | 625 // The verticalPositionForBox function returns the distance between the |
| 609 // and the root box's baseline. The value is negative if the child box's ba
seline is above the | 626 // child box's baseline and the root box's baseline. The value is negative |
| 610 // root box's baseline, and it is positive if the child box's baseline is be
low the root box's baseline. | 627 // if the child box's baseline is above the root box's baseline, and it is |
| 628 // positive if the child box's baseline is below the root box's baseline. |
| 611 curr->setLogicalTop( | 629 curr->setLogicalTop( |
| 612 rootBox->verticalPositionForBox(curr, verticalPositionCache)); | 630 rootBox->verticalPositionForBox(curr, verticalPositionCache)); |
| 613 | 631 |
| 614 int ascent = 0; | 632 int ascent = 0; |
| 615 int descent = 0; | 633 int descent = 0; |
| 616 rootBox->ascentAndDescentForBox(curr, textBoxDataMap, ascent, descent, | 634 rootBox->ascentAndDescentForBox(curr, textBoxDataMap, ascent, descent, |
| 617 affectsAscent, affectsDescent); | 635 affectsAscent, affectsDescent); |
| 618 | 636 |
| 619 LayoutUnit boxHeight(ascent + descent); | 637 LayoutUnit boxHeight(ascent + descent); |
| 620 if (curr->verticalAlign() == VerticalAlignTop) { | 638 if (curr->verticalAlign() == VerticalAlignTop) { |
| 621 if (maxPositionTop < boxHeight) | 639 if (maxPositionTop < boxHeight) |
| 622 maxPositionTop = boxHeight; | 640 maxPositionTop = boxHeight; |
| 623 } else if (curr->verticalAlign() == VerticalAlignBottom) { | 641 } else if (curr->verticalAlign() == VerticalAlignBottom) { |
| 624 if (maxPositionBottom < boxHeight) | 642 if (maxPositionBottom < boxHeight) |
| 625 maxPositionBottom = boxHeight; | 643 maxPositionBottom = boxHeight; |
| 626 } else if (!inlineFlowBox || noQuirksMode || | 644 } else if (!inlineFlowBox || noQuirksMode || |
| 627 inlineFlowBox->hasTextChildren() || | 645 inlineFlowBox->hasTextChildren() || |
| 628 (inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() && | 646 (inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() && |
| 629 inlineFlowBox->hasTextDescendants()) || | 647 inlineFlowBox->hasTextDescendants()) || |
| 630 inlineFlowBox->boxModelObject() | 648 inlineFlowBox->boxModelObject() |
| 631 .hasInlineDirectionBordersOrPadding()) { | 649 .hasInlineDirectionBordersOrPadding()) { |
| 632 // Note that these values can be negative. Even though we only affect the
maxAscent and maxDescent values | 650 // Note that these values can be negative. Even though we only affect the |
| 633 // if our box (excluding line-height) was above (for ascent) or below (for
descent) the root baseline, once you factor in line-height | 651 // maxAscent and maxDescent values if our box (excluding line-height) was |
| 634 // the final box can end up being fully above or fully below the root box'
s baseline! This is ok, but what it | 652 // above (for ascent) or below (for descent) the root baseline, once you |
| 635 // means is that ascent and descent (including leading), can end up being
negative. The setMaxAscent and | 653 // factor in line-height the final box can end up being fully above or |
| 636 // setMaxDescent booleans are used to ensure that we're willing to initial
ly set maxAscent/Descent to negative | 654 // fully below the root box's baseline! This is ok, but what it means is |
| 637 // values. | 655 // that ascent and descent (including leading), can end up being negative. |
| 656 // The setMaxAscent and setMaxDescent booleans are used to ensure that |
| 657 // we're willing to initially set maxAscent/Descent to negative values. |
| 638 ascent -= curr->logicalTop().round(); | 658 ascent -= curr->logicalTop().round(); |
| 639 descent += curr->logicalTop().round(); | 659 descent += curr->logicalTop().round(); |
| 640 if (affectsAscent && (maxAscent < ascent || !setMaxAscent)) { | 660 if (affectsAscent && (maxAscent < ascent || !setMaxAscent)) { |
| 641 maxAscent = ascent; | 661 maxAscent = ascent; |
| 642 setMaxAscent = true; | 662 setMaxAscent = true; |
| 643 } | 663 } |
| 644 | 664 |
| 645 if (affectsDescent && (maxDescent < descent || !setMaxDescent)) { | 665 if (affectsDescent && (maxDescent < descent || !setMaxDescent)) { |
| 646 maxDescent = descent; | 666 maxDescent = descent; |
| 647 setMaxDescent = true; | 667 setMaxDescent = true; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 667 bool& setLineTop, | 687 bool& setLineTop, |
| 668 LayoutUnit& lineTopIncludingMargins, | 688 LayoutUnit& lineTopIncludingMargins, |
| 669 LayoutUnit& lineBottomIncludingMargins, | 689 LayoutUnit& lineBottomIncludingMargins, |
| 670 bool& hasAnnotationsBefore, | 690 bool& hasAnnotationsBefore, |
| 671 bool& hasAnnotationsAfter, | 691 bool& hasAnnotationsAfter, |
| 672 FontBaseline baselineType) { | 692 FontBaseline baselineType) { |
| 673 bool isRootBox = isRootInlineBox(); | 693 bool isRootBox = isRootInlineBox(); |
| 674 if (isRootBox) { | 694 if (isRootBox) { |
| 675 const FontMetrics& fontMetrics = | 695 const FontMetrics& fontMetrics = |
| 676 getLineLayoutItem().style(isFirstLineStyle())->getFontMetrics(); | 696 getLineLayoutItem().style(isFirstLineStyle())->getFontMetrics(); |
| 677 // RootInlineBoxes are always placed at pixel boundaries in their logical y
direction. Not doing | 697 // RootInlineBoxes are always placed at pixel boundaries in their logical y |
| 678 // so results in incorrect layout of text decorations, most notably underlin
es. | 698 // direction. Not doing so results in incorrect layout of text decorations, |
| 699 // most notably underlines. |
| 679 setLogicalTop(LayoutUnit( | 700 setLogicalTop(LayoutUnit( |
| 680 roundToInt(top + maxAscent - fontMetrics.ascent(baselineType)))); | 701 roundToInt(top + maxAscent - fontMetrics.ascent(baselineType)))); |
| 681 } | 702 } |
| 682 | 703 |
| 683 LayoutUnit adjustmentForChildrenWithSameLineHeightAndBaseline; | 704 LayoutUnit adjustmentForChildrenWithSameLineHeightAndBaseline; |
| 684 if (descendantsHaveSameLineHeightAndBaseline()) { | 705 if (descendantsHaveSameLineHeightAndBaseline()) { |
| 685 adjustmentForChildrenWithSameLineHeightAndBaseline = logicalTop(); | 706 adjustmentForChildrenWithSameLineHeightAndBaseline = logicalTop(); |
| 686 if (parent()) | 707 if (parent()) |
| 687 adjustmentForChildrenWithSameLineHeightAndBaseline += | 708 adjustmentForChildrenWithSameLineHeightAndBaseline += |
| 688 boxModelObject().borderAndPaddingOver(); | 709 boxModelObject().borderAndPaddingOver(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 if (curr->isInlineFlowBox()) { | 749 if (curr->isInlineFlowBox()) { |
| 729 LineLayoutBoxModel boxObject = | 750 LineLayoutBoxModel boxObject = |
| 730 LineLayoutBoxModel(curr->getLineLayoutItem()); | 751 LineLayoutBoxModel(curr->getLineLayoutItem()); |
| 731 newLogicalTop -= boxObject.borderAndPaddingOver(); | 752 newLogicalTop -= boxObject.borderAndPaddingOver(); |
| 732 borderPaddingHeight = boxObject.borderAndPaddingLogicalHeight(); | 753 borderPaddingHeight = boxObject.borderAndPaddingLogicalHeight(); |
| 733 } | 754 } |
| 734 newLogicalTopIncludingMargins = newLogicalTop; | 755 newLogicalTopIncludingMargins = newLogicalTop; |
| 735 } else if (!curr->getLineLayoutItem().isBR()) { | 756 } else if (!curr->getLineLayoutItem().isBR()) { |
| 736 LineLayoutBox box = LineLayoutBox(curr->getLineLayoutItem()); | 757 LineLayoutBox box = LineLayoutBox(curr->getLineLayoutItem()); |
| 737 newLogicalTopIncludingMargins = newLogicalTop; | 758 newLogicalTopIncludingMargins = newLogicalTop; |
| 738 // TODO(kojii): isHorizontal() does not match to m_layoutObject.isHorizont
alWritingMode(). crbug.com/552954 | 759 // TODO(kojii): isHorizontal() does not match to |
| 739 // ASSERT(curr->isHorizontal() == curr->getLineLayoutItem().style()->isHor
izontalWritingMode()); | 760 // m_layoutObject.isHorizontalWritingMode(). crbug.com/552954 |
| 761 // ASSERT(curr->isHorizontal() == |
| 762 // curr->getLineLayoutItem().style()->isHorizontalWritingMode()); |
| 740 LayoutUnit overSideMargin = | 763 LayoutUnit overSideMargin = |
| 741 curr->isHorizontal() ? box.marginTop() : box.marginRight(); | 764 curr->isHorizontal() ? box.marginTop() : box.marginRight(); |
| 742 LayoutUnit underSideMargin = | 765 LayoutUnit underSideMargin = |
| 743 curr->isHorizontal() ? box.marginBottom() : box.marginLeft(); | 766 curr->isHorizontal() ? box.marginBottom() : box.marginLeft(); |
| 744 newLogicalTop += overSideMargin; | 767 newLogicalTop += overSideMargin; |
| 745 boxHeightIncludingMargins += overSideMargin + underSideMargin; | 768 boxHeightIncludingMargins += overSideMargin + underSideMargin; |
| 746 } | 769 } |
| 747 | 770 |
| 748 curr->setLogicalTop(newLogicalTop); | 771 curr->setLogicalTop(newLogicalTop); |
| 749 | 772 |
| 750 if (childAffectsTopBottomPos) { | 773 if (childAffectsTopBottomPos) { |
| 751 if (curr->getLineLayoutItem().isRubyRun()) { | 774 if (curr->getLineLayoutItem().isRubyRun()) { |
| 752 // Treat the leading on the first and last lines of ruby runs as not bei
ng part of the overall lineTop/lineBottom. | 775 // Treat the leading on the first and last lines of ruby runs as not |
| 753 // Really this is a workaround hack for the fact that ruby should have b
een done as line layout and not done using | 776 // being part of the overall lineTop/lineBottom. |
| 754 // inline-block. | 777 // Really this is a workaround hack for the fact that ruby should have |
| 778 // been done as line layout and not done using inline-block. |
| 755 if (getLineLayoutItem().style()->isFlippedLinesWritingMode() == | 779 if (getLineLayoutItem().style()->isFlippedLinesWritingMode() == |
| 756 (curr->getLineLayoutItem().style()->getRubyPosition() == | 780 (curr->getLineLayoutItem().style()->getRubyPosition() == |
| 757 RubyPositionAfter)) | 781 RubyPositionAfter)) |
| 758 hasAnnotationsBefore = true; | 782 hasAnnotationsBefore = true; |
| 759 else | 783 else |
| 760 hasAnnotationsAfter = true; | 784 hasAnnotationsAfter = true; |
| 761 | 785 |
| 762 LineLayoutRubyRun rubyRun = | 786 LineLayoutRubyRun rubyRun = |
| 763 LineLayoutRubyRun(curr->getLineLayoutItem()); | 787 LineLayoutRubyRun(curr->getLineLayoutItem()); |
| 764 if (LineLayoutRubyBase rubyBase = rubyRun.rubyBase()) { | 788 if (LineLayoutRubyBase rubyBase = rubyRun.rubyBase()) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 } | 832 } |
| 809 selectionBottom = std::max( | 833 selectionBottom = std::max( |
| 810 selectionBottom, newLogicalTop + boxHeight - borderPaddingHeight); | 834 selectionBottom, newLogicalTop + boxHeight - borderPaddingHeight); |
| 811 lineBottom = std::max(lineBottom, newLogicalTop + boxHeight); | 835 lineBottom = std::max(lineBottom, newLogicalTop + boxHeight); |
| 812 lineBottomIncludingMargins = std::max( | 836 lineBottomIncludingMargins = std::max( |
| 813 lineBottom, | 837 lineBottom, |
| 814 std::max(lineBottomIncludingMargins, | 838 std::max(lineBottomIncludingMargins, |
| 815 newLogicalTopIncludingMargins + boxHeightIncludingMargins)); | 839 newLogicalTopIncludingMargins + boxHeightIncludingMargins)); |
| 816 } | 840 } |
| 817 | 841 |
| 818 // Adjust boxes to use their real box y/height and not the logical height (a
s dictated by | 842 // Adjust boxes to use their real box y/height and not the logical height |
| 819 // line-height). | 843 // (as dictated by line-height). |
| 820 if (inlineFlowBox) | 844 if (inlineFlowBox) |
| 821 inlineFlowBox->placeBoxesInBlockDirection( | 845 inlineFlowBox->placeBoxesInBlockDirection( |
| 822 top, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom, | 846 top, maxHeight, maxAscent, noQuirksMode, lineTop, lineBottom, |
| 823 selectionBottom, setLineTop, lineTopIncludingMargins, | 847 selectionBottom, setLineTop, lineTopIncludingMargins, |
| 824 lineBottomIncludingMargins, hasAnnotationsBefore, hasAnnotationsAfter, | 848 lineBottomIncludingMargins, hasAnnotationsBefore, hasAnnotationsAfter, |
| 825 baselineType); | 849 baselineType); |
| 826 } | 850 } |
| 827 | 851 |
| 828 if (isRootBox) { | 852 if (isRootBox) { |
| 829 if (noQuirksMode || hasTextChildren() || | 853 if (noQuirksMode || hasTextChildren() || |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 maxLogicalTop = std::max<LayoutUnit>(maxLogicalTop, curr->y()); | 885 maxLogicalTop = std::max<LayoutUnit>(maxLogicalTop, curr->y()); |
| 862 LayoutUnit localMaxLogicalTop; | 886 LayoutUnit localMaxLogicalTop; |
| 863 if (curr->isInlineFlowBox()) | 887 if (curr->isInlineFlowBox()) |
| 864 toInlineFlowBox(curr)->computeMaxLogicalTop(localMaxLogicalTop); | 888 toInlineFlowBox(curr)->computeMaxLogicalTop(localMaxLogicalTop); |
| 865 maxLogicalTop = std::max<LayoutUnit>(maxLogicalTop, localMaxLogicalTop); | 889 maxLogicalTop = std::max<LayoutUnit>(maxLogicalTop, localMaxLogicalTop); |
| 866 } | 890 } |
| 867 } | 891 } |
| 868 | 892 |
| 869 void InlineFlowBox::flipLinesInBlockDirection(LayoutUnit lineTop, | 893 void InlineFlowBox::flipLinesInBlockDirection(LayoutUnit lineTop, |
| 870 LayoutUnit lineBottom) { | 894 LayoutUnit lineBottom) { |
| 871 // Flip the box on the line such that the top is now relative to the lineBotto
m instead of the lineTop. | 895 // Flip the box on the line such that the top is now relative to the |
| 896 // lineBottom instead of the lineTop. |
| 872 setLogicalTop(lineBottom - (logicalTop() - lineTop) - logicalHeight()); | 897 setLogicalTop(lineBottom - (logicalTop() - lineTop) - logicalHeight()); |
| 873 | 898 |
| 874 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { | 899 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { |
| 875 if (curr->getLineLayoutItem().isOutOfFlowPositioned()) | 900 if (curr->getLineLayoutItem().isOutOfFlowPositioned()) |
| 876 continue; // Positioned placeholders aren't affected here. | 901 continue; // Positioned placeholders aren't affected here. |
| 877 | 902 |
| 878 if (curr->isInlineFlowBox()) | 903 if (curr->isInlineFlowBox()) |
| 879 toInlineFlowBox(curr)->flipLinesInBlockDirection(lineTop, lineBottom); | 904 toInlineFlowBox(curr)->flipLinesInBlockDirection(lineTop, lineBottom); |
| 880 else | 905 else |
| 881 curr->setLogicalTop(lineBottom - (curr->logicalTop() - lineTop) - | 906 curr->setLogicalTop(lineBottom - (curr->logicalTop() - lineTop) - |
| (...skipping 10 matching lines...) Expand all Loading... |
| 892 if (!parent() && | 917 if (!parent() && |
| 893 (!isFirstLineStyle() || &style == getLineLayoutItem().style())) | 918 (!isFirstLineStyle() || &style == getLineLayoutItem().style())) |
| 894 return; | 919 return; |
| 895 | 920 |
| 896 WritingMode writingMode = style.getWritingMode(); | 921 WritingMode writingMode = style.getWritingMode(); |
| 897 ShadowList* boxShadow = style.boxShadow(); | 922 ShadowList* boxShadow = style.boxShadow(); |
| 898 if (!boxShadow) | 923 if (!boxShadow) |
| 899 return; | 924 return; |
| 900 | 925 |
| 901 LayoutRectOutsets outsets(boxShadow->rectOutsetsIncludingOriginal()); | 926 LayoutRectOutsets outsets(boxShadow->rectOutsetsIncludingOriginal()); |
| 902 // Similar to how glyph overflow works, if our lines are flipped, then it's ac
tually the opposite shadow that applies, since | 927 // Similar to how glyph overflow works, if our lines are flipped, then it's |
| 903 // the line is "upside down" in terms of block coordinates. | 928 // actually the opposite shadow that applies, since the line is "upside down" |
| 929 // in terms of block coordinates. |
| 904 LayoutRectOutsets logicalOutsets( | 930 LayoutRectOutsets logicalOutsets( |
| 905 outsets.logicalOutsetsWithFlippedLines(writingMode)); | 931 outsets.logicalOutsetsWithFlippedLines(writingMode)); |
| 906 | 932 |
| 907 LayoutRect shadowBounds(logicalFrameRect()); | 933 LayoutRect shadowBounds(logicalFrameRect()); |
| 908 shadowBounds.expand(logicalOutsets); | 934 shadowBounds.expand(logicalOutsets); |
| 909 logicalVisualOverflow.unite(shadowBounds); | 935 logicalVisualOverflow.unite(shadowBounds); |
| 910 } | 936 } |
| 911 | 937 |
| 912 inline void InlineFlowBox::addBorderOutsetVisualOverflow( | 938 inline void InlineFlowBox::addBorderOutsetVisualOverflow( |
| 913 LayoutRect& logicalVisualOverflow) { | 939 LayoutRect& logicalVisualOverflow) { |
| 914 const ComputedStyle& style = getLineLayoutItem().styleRef(isFirstLineStyle()); | 940 const ComputedStyle& style = getLineLayoutItem().styleRef(isFirstLineStyle()); |
| 915 | 941 |
| 916 // border-image-outset on the block element applies to the block and not to th
e lines, | 942 // border-image-outset on the block element applies to the block and not to |
| 917 // unless it is modified by :first-line pseudo element. | 943 // the lines, unless it is modified by :first-line pseudo element. |
| 918 if (!parent() && | 944 if (!parent() && |
| 919 (!isFirstLineStyle() || &style == getLineLayoutItem().style())) | 945 (!isFirstLineStyle() || &style == getLineLayoutItem().style())) |
| 920 return; | 946 return; |
| 921 | 947 |
| 922 if (!style.hasBorderImageOutsets()) | 948 if (!style.hasBorderImageOutsets()) |
| 923 return; | 949 return; |
| 924 | 950 |
| 925 // Similar to how glyph overflow works, if our lines are flipped, then it's ac
tually the opposite border that applies, since | 951 // Similar to how glyph overflow works, if our lines are flipped, then it's |
| 926 // the line is "upside down" in terms of block coordinates. vertical-rl is the
flipped line mode. | 952 // actually the opposite border that applies, since the line is "upside down" |
| 953 // in terms of block coordinates. vertical-rl is the flipped line mode. |
| 927 LayoutRectOutsets logicalOutsets = | 954 LayoutRectOutsets logicalOutsets = |
| 928 style.borderImageOutsets().logicalOutsetsWithFlippedLines( | 955 style.borderImageOutsets().logicalOutsetsWithFlippedLines( |
| 929 style.getWritingMode()); | 956 style.getWritingMode()); |
| 930 | 957 |
| 931 if (!includeLogicalLeftEdge()) | 958 if (!includeLogicalLeftEdge()) |
| 932 logicalOutsets.setLeft(LayoutUnit()); | 959 logicalOutsets.setLeft(LayoutUnit()); |
| 933 if (!includeLogicalRightEdge()) | 960 if (!includeLogicalRightEdge()) |
| 934 logicalOutsets.setRight(LayoutUnit()); | 961 logicalOutsets.setRight(LayoutUnit()); |
| 935 | 962 |
| 936 LayoutRect borderOutsetBounds(logicalFrameRect()); | 963 LayoutRect borderOutsetBounds(logicalFrameRect()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 textBox->getEmphasisMarkPosition(style, emphasisMarkPosition)) { | 1014 textBox->getEmphasisMarkPosition(style, emphasisMarkPosition)) { |
| 988 float emphasisMarkHeight = | 1015 float emphasisMarkHeight = |
| 989 style.font().emphasisMarkHeight(style.textEmphasisMarkString()); | 1016 style.font().emphasisMarkHeight(style.textEmphasisMarkString()); |
| 990 if ((emphasisMarkPosition == TextEmphasisPositionOver) == | 1017 if ((emphasisMarkPosition == TextEmphasisPositionOver) == |
| 991 (!style.isFlippedLinesWritingMode())) | 1018 (!style.isFlippedLinesWritingMode())) |
| 992 topGlyphOverflow = std::min(topGlyphOverflow, -emphasisMarkHeight); | 1019 topGlyphOverflow = std::min(topGlyphOverflow, -emphasisMarkHeight); |
| 993 else | 1020 else |
| 994 bottomGlyphOverflow = std::max(bottomGlyphOverflow, emphasisMarkHeight); | 1021 bottomGlyphOverflow = std::max(bottomGlyphOverflow, emphasisMarkHeight); |
| 995 } | 1022 } |
| 996 | 1023 |
| 997 // If letter-spacing is negative, we should factor that into right layout over
flow. Even in RTL, letter-spacing is | 1024 // If letter-spacing is negative, we should factor that into right layout |
| 998 // applied to the right, so this is not an issue with left overflow. | 1025 // overflow. Even in RTL, letter-spacing is applied to the right, so this is |
| 1026 // not an issue with left overflow. |
| 999 rightGlyphOverflow -= | 1027 rightGlyphOverflow -= |
| 1000 std::min(0.0f, style.font().getFontDescription().letterSpacing()); | 1028 std::min(0.0f, style.font().getFontDescription().letterSpacing()); |
| 1001 | 1029 |
| 1002 LayoutRectOutsets textShadowLogicalOutsets; | 1030 LayoutRectOutsets textShadowLogicalOutsets; |
| 1003 if (ShadowList* textShadow = style.textShadow()) | 1031 if (ShadowList* textShadow = style.textShadow()) |
| 1004 textShadowLogicalOutsets = | 1032 textShadowLogicalOutsets = |
| 1005 LayoutRectOutsets(textShadow->rectOutsetsIncludingOriginal()) | 1033 LayoutRectOutsets(textShadow->rectOutsetsIncludingOriginal()) |
| 1006 .logicalOutsets(style.getWritingMode()); | 1034 .logicalOutsets(style.getWritingMode()); |
| 1007 | 1035 |
| 1008 // FIXME: This code currently uses negative values for expansion of the top | 1036 // FIXME: This code currently uses negative values for expansion of the top |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 if (logicalVisualOverflow != textBox->logicalFrameRect()) | 1077 if (logicalVisualOverflow != textBox->logicalFrameRect()) |
| 1050 textBox->setLogicalOverflowRect(logicalVisualOverflow); | 1078 textBox->setLogicalOverflowRect(logicalVisualOverflow); |
| 1051 } | 1079 } |
| 1052 | 1080 |
| 1053 inline void InlineFlowBox::addReplacedChildOverflow( | 1081 inline void InlineFlowBox::addReplacedChildOverflow( |
| 1054 const InlineBox* inlineBox, | 1082 const InlineBox* inlineBox, |
| 1055 LayoutRect& logicalLayoutOverflow, | 1083 LayoutRect& logicalLayoutOverflow, |
| 1056 LayoutRect& logicalVisualOverflow) { | 1084 LayoutRect& logicalVisualOverflow) { |
| 1057 LineLayoutBox box = LineLayoutBox(inlineBox->getLineLayoutItem()); | 1085 LineLayoutBox box = LineLayoutBox(inlineBox->getLineLayoutItem()); |
| 1058 | 1086 |
| 1059 // Visual overflow only propagates if the box doesn't have a self-painting lay
er. This rectangle does not include | 1087 // Visual overflow only propagates if the box doesn't have a self-painting |
| 1060 // transforms or relative positioning (since those objects always have self-pa
inting layers), but it does need to be adjusted | 1088 // layer. This rectangle does not include transforms or relative positioning |
| 1061 // for writing-mode differences. | 1089 // (since those objects always have self-painting layers), but it does need to |
| 1090 // be adjusted for writing-mode differences. |
| 1062 if (!box.hasSelfPaintingLayer()) { | 1091 if (!box.hasSelfPaintingLayer()) { |
| 1063 LayoutRect childLogicalVisualOverflow = | 1092 LayoutRect childLogicalVisualOverflow = |
| 1064 box.logicalVisualOverflowRectForPropagation( | 1093 box.logicalVisualOverflowRectForPropagation( |
| 1065 getLineLayoutItem().styleRef()); | 1094 getLineLayoutItem().styleRef()); |
| 1066 childLogicalVisualOverflow.move(inlineBox->logicalLeft(), | 1095 childLogicalVisualOverflow.move(inlineBox->logicalLeft(), |
| 1067 inlineBox->logicalTop()); | 1096 inlineBox->logicalTop()); |
| 1068 logicalVisualOverflow.unite(childLogicalVisualOverflow); | 1097 logicalVisualOverflow.unite(childLogicalVisualOverflow); |
| 1069 } | 1098 } |
| 1070 | 1099 |
| 1071 // Layout overflow internal to the child box only propagates if the child box
doesn't have overflow clip set. | 1100 // Layout overflow internal to the child box only propagates if the child box |
| 1072 // Otherwise the child border box propagates as layout overflow. This rectang
le must include transforms and relative positioning | 1101 // doesn't have overflow clip set. Otherwise the child border box propagates |
| 1073 // and be adjusted for writing-mode differences. | 1102 // as layout overflow. This rectangle must include transforms and relative |
| 1103 // positioning and be adjusted for writing-mode differences. |
| 1074 LayoutRect childLogicalLayoutOverflow = | 1104 LayoutRect childLogicalLayoutOverflow = |
| 1075 box.logicalLayoutOverflowRectForPropagation( | 1105 box.logicalLayoutOverflowRectForPropagation( |
| 1076 getLineLayoutItem().styleRef()); | 1106 getLineLayoutItem().styleRef()); |
| 1077 childLogicalLayoutOverflow.move(inlineBox->logicalLeft(), | 1107 childLogicalLayoutOverflow.move(inlineBox->logicalLeft(), |
| 1078 inlineBox->logicalTop()); | 1108 inlineBox->logicalTop()); |
| 1079 logicalLayoutOverflow.unite(childLogicalLayoutOverflow); | 1109 logicalLayoutOverflow.unite(childLogicalLayoutOverflow); |
| 1080 } | 1110 } |
| 1081 | 1111 |
| 1082 void InlineFlowBox::computeOverflow( | 1112 void InlineFlowBox::computeOverflow( |
| 1083 LayoutUnit lineTop, | 1113 LayoutUnit lineTop, |
| 1084 LayoutUnit lineBottom, | 1114 LayoutUnit lineBottom, |
| 1085 GlyphOverflowAndFallbackFontsMap& textBoxDataMap) { | 1115 GlyphOverflowAndFallbackFontsMap& textBoxDataMap) { |
| 1086 // If we know we have no overflow, we can just bail. | 1116 // If we know we have no overflow, we can just bail. |
| 1087 if (knownToHaveNoOverflow()) { | 1117 if (knownToHaveNoOverflow()) { |
| 1088 ASSERT(!m_overflow); | 1118 ASSERT(!m_overflow); |
| 1089 return; | 1119 return; |
| 1090 } | 1120 } |
| 1091 | 1121 |
| 1092 if (m_overflow) | 1122 if (m_overflow) |
| 1093 m_overflow.reset(); | 1123 m_overflow.reset(); |
| 1094 | 1124 |
| 1095 // Visual overflow just includes overflow for stuff we need to issues paint in
validations for ourselves. Self-painting layers are ignored. | 1125 // Visual overflow just includes overflow for stuff we need to issues paint |
| 1096 // Layout overflow is used to determine scrolling extent, so it still includes
child layers and also factors in | 1126 // invalidations for ourselves. Self-painting layers are ignored. |
| 1097 // transforms, relative positioning, etc. | 1127 // Layout overflow is used to determine scrolling extent, so it still includes |
| 1128 // child layers and also factors in transforms, relative positioning, etc. |
| 1098 LayoutRect logicalLayoutOverflow( | 1129 LayoutRect logicalLayoutOverflow( |
| 1099 logicalFrameRectIncludingLineHeight(lineTop, lineBottom)); | 1130 logicalFrameRectIncludingLineHeight(lineTop, lineBottom)); |
| 1100 LayoutRect logicalVisualOverflow(logicalLayoutOverflow); | 1131 LayoutRect logicalVisualOverflow(logicalLayoutOverflow); |
| 1101 | 1132 |
| 1102 addBoxShadowVisualOverflow(logicalVisualOverflow); | 1133 addBoxShadowVisualOverflow(logicalVisualOverflow); |
| 1103 addBorderOutsetVisualOverflow(logicalVisualOverflow); | 1134 addBorderOutsetVisualOverflow(logicalVisualOverflow); |
| 1104 addOutlineVisualOverflow(logicalVisualOverflow); | 1135 addOutlineVisualOverflow(logicalVisualOverflow); |
| 1105 | 1136 |
| 1106 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { | 1137 for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) { |
| 1107 if (curr->getLineLayoutItem().isOutOfFlowPositioned()) | 1138 if (curr->getLineLayoutItem().isOutOfFlowPositioned()) |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 const HitTestLocation& locationInContainer, | 1214 const HitTestLocation& locationInContainer, |
| 1184 const LayoutPoint& accumulatedOffset, | 1215 const LayoutPoint& accumulatedOffset, |
| 1185 LayoutUnit lineTop, | 1216 LayoutUnit lineTop, |
| 1186 LayoutUnit lineBottom) { | 1217 LayoutUnit lineBottom) { |
| 1187 LayoutRect overflowRect(visualOverflowRect(lineTop, lineBottom)); | 1218 LayoutRect overflowRect(visualOverflowRect(lineTop, lineBottom)); |
| 1188 flipForWritingMode(overflowRect); | 1219 flipForWritingMode(overflowRect); |
| 1189 overflowRect.moveBy(accumulatedOffset); | 1220 overflowRect.moveBy(accumulatedOffset); |
| 1190 if (!locationInContainer.intersects(overflowRect)) | 1221 if (!locationInContainer.intersects(overflowRect)) |
| 1191 return false; | 1222 return false; |
| 1192 | 1223 |
| 1193 // We need to hit test both our inline children (Inline Boxes) and culled inli
nes | 1224 // We need to hit test both our inline children (Inline Boxes) and culled |
| 1194 // (LayoutObjects). We check our inlines in the same order as line layout but | 1225 // inlines (LayoutObjects). We check our inlines in the same order as line |
| 1195 // for each inline we additionally need to hit test its culled inline parents. | 1226 // layout but for each inline we additionally need to hit test its culled |
| 1196 // While hit testing culled inline parents, we can stop once we reach | 1227 // inline parents. While hit testing culled inline parents, we can stop once |
| 1197 // a non-inline parent or a culled inline associated with a different inline b
ox. | 1228 // we reach a non-inline parent or a culled inline associated with a different |
| 1229 // inline box. |
| 1198 InlineBox* prev; | 1230 InlineBox* prev; |
| 1199 for (InlineBox* curr = lastChild(); curr; curr = prev) { | 1231 for (InlineBox* curr = lastChild(); curr; curr = prev) { |
| 1200 prev = curr->prevOnLine(); | 1232 prev = curr->prevOnLine(); |
| 1201 | 1233 |
| 1202 // Layers will handle hit testing themselves. | 1234 // Layers will handle hit testing themselves. |
| 1203 if (!curr->boxModelObject() || | 1235 if (!curr->boxModelObject() || |
| 1204 !curr->boxModelObject().hasSelfPaintingLayer()) { | 1236 !curr->boxModelObject().hasSelfPaintingLayer()) { |
| 1205 if (curr->nodeAtPoint(result, locationInContainer, accumulatedOffset, | 1237 if (curr->nodeAtPoint(result, locationInContainer, accumulatedOffset, |
| 1206 lineTop, lineBottom)) { | 1238 lineTop, lineBottom)) { |
| 1207 getLineLayoutItem().updateHitTestResult( | 1239 getLineLayoutItem().updateHitTestResult( |
| 1208 result, | 1240 result, |
| 1209 locationInContainer.point() - toLayoutSize(accumulatedOffset)); | 1241 locationInContainer.point() - toLayoutSize(accumulatedOffset)); |
| 1210 return true; | 1242 return true; |
| 1211 } | 1243 } |
| 1212 } | 1244 } |
| 1213 | 1245 |
| 1214 // If the current inline box's layout object and the previous inline box's l
ayout object are same, | 1246 // If the current inline box's layout object and the previous inline box's |
| 1215 // we should yield the hit-test to the previous inline box. | 1247 // layout object are same, we should yield the hit-test to the previous |
| 1248 // inline box. |
| 1216 if (prev && curr->getLineLayoutItem() == prev->getLineLayoutItem()) | 1249 if (prev && curr->getLineLayoutItem() == prev->getLineLayoutItem()) |
| 1217 continue; | 1250 continue; |
| 1218 | 1251 |
| 1219 // Hit test the culled inline if necessary. | 1252 // Hit test the culled inline if necessary. |
| 1220 LineLayoutItem currLayoutItem = curr->getLineLayoutItem(); | 1253 LineLayoutItem currLayoutItem = curr->getLineLayoutItem(); |
| 1221 while (true) { | 1254 while (true) { |
| 1222 // If the previous inline box is not a descendant of a current inline's pa
rent, | 1255 // If the previous inline box is not a descendant of a current inline's |
| 1223 // the parent is a culled inline and we hit test it. | 1256 // parent, the parent is a culled inline and we hit test it. |
| 1224 // Otherwise, move to the previous inline box because we hit test first al
l | 1257 // Otherwise, move to the previous inline box because we hit test first |
| 1225 // candidate inline boxes under the parent to take a pre-order tree traver
sal in reverse. | 1258 // all candidate inline boxes under the parent to take a pre-order tree |
| 1259 // traversal in reverse. |
| 1226 bool hasSibling = | 1260 bool hasSibling = |
| 1227 currLayoutItem.previousSibling() || currLayoutItem.nextSibling(); | 1261 currLayoutItem.previousSibling() || currLayoutItem.nextSibling(); |
| 1228 LineLayoutItem culledParent = currLayoutItem.parent(); | 1262 LineLayoutItem culledParent = currLayoutItem.parent(); |
| 1229 ASSERT(culledParent); | 1263 ASSERT(culledParent); |
| 1230 | 1264 |
| 1231 if (culledParent == getLineLayoutItem() || | 1265 if (culledParent == getLineLayoutItem() || |
| 1232 (hasSibling && prev && | 1266 (hasSibling && prev && |
| 1233 prev->getLineLayoutItem().isDescendantOf(culledParent))) | 1267 prev->getLineLayoutItem().isDescendantOf(culledParent))) |
| 1234 break; | 1268 break; |
| 1235 | 1269 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1263 LayoutRect rect = | 1297 LayoutRect rect = |
| 1264 InlineFlowBoxPainter(*this).frameRectClampedToLineTopAndBottomIfNeeded(); | 1298 InlineFlowBoxPainter(*this).frameRectClampedToLineTopAndBottomIfNeeded(); |
| 1265 | 1299 |
| 1266 flipForWritingMode(rect); | 1300 flipForWritingMode(rect); |
| 1267 rect.moveBy(accumulatedOffset); | 1301 rect.moveBy(accumulatedOffset); |
| 1268 | 1302 |
| 1269 // Pixel snap hit testing. | 1303 // Pixel snap hit testing. |
| 1270 rect = LayoutRect(pixelSnappedIntRect(rect)); | 1304 rect = LayoutRect(pixelSnappedIntRect(rect)); |
| 1271 if (visibleToHitTestRequest(result.hitTestRequest()) && | 1305 if (visibleToHitTestRequest(result.hitTestRequest()) && |
| 1272 locationInContainer.intersects(rect)) { | 1306 locationInContainer.intersects(rect)) { |
| 1307 // Don't add in m_topLeft here, we want coords in the containing block's |
| 1308 // coordinate space. |
| 1273 getLineLayoutItem().updateHitTestResult( | 1309 getLineLayoutItem().updateHitTestResult( |
| 1274 result, | 1310 result, flipForWritingMode(locationInContainer.point() - |
| 1275 flipForWritingMode( | 1311 toLayoutSize(accumulatedOffset))); |
| 1276 locationInContainer.point() - | |
| 1277 toLayoutSize( | |
| 1278 accumulatedOffset))); // Don't add in m_topLeft here, we want c
oords in the containing block's space. | |
| 1279 if (result.addNodeToListBasedTestResult(getLineLayoutItem().node(), | 1312 if (result.addNodeToListBasedTestResult(getLineLayoutItem().node(), |
| 1280 locationInContainer, | 1313 locationInContainer, |
| 1281 rect) == StopHitTesting) | 1314 rect) == StopHitTesting) |
| 1282 return true; | 1315 return true; |
| 1283 } | 1316 } |
| 1284 | 1317 |
| 1285 return false; | 1318 return false; |
| 1286 } | 1319 } |
| 1287 | 1320 |
| 1288 void InlineFlowBox::paint(const PaintInfo& paintInfo, | 1321 void InlineFlowBox::paint(const PaintInfo& paintInfo, |
| 1289 const LayoutPoint& paintOffset, | 1322 const LayoutPoint& paintOffset, |
| 1290 LayoutUnit lineTop, | 1323 LayoutUnit lineTop, |
| 1291 LayoutUnit lineBottom) const { | 1324 LayoutUnit lineBottom) const { |
| 1292 InlineFlowBoxPainter(*this).paint(paintInfo, paintOffset, lineTop, | 1325 InlineFlowBoxPainter(*this).paint(paintInfo, paintOffset, lineTop, |
| 1293 lineBottom); | 1326 lineBottom); |
| 1294 } | 1327 } |
| 1295 | 1328 |
| 1296 bool InlineFlowBox::boxShadowCanBeAppliedToBackground( | 1329 bool InlineFlowBox::boxShadowCanBeAppliedToBackground( |
| 1297 const FillLayer& lastBackgroundLayer) const { | 1330 const FillLayer& lastBackgroundLayer) const { |
| 1298 // The checks here match how paintFillLayer() decides whether to clip (if it d
oes, the shadow | 1331 // The checks here match how paintFillLayer() decides whether to clip (if it |
| 1332 // does, the shadow |
| 1299 // would be clipped out, so it has to be drawn separately). | 1333 // would be clipped out, so it has to be drawn separately). |
| 1300 StyleImage* image = lastBackgroundLayer.image(); | 1334 StyleImage* image = lastBackgroundLayer.image(); |
| 1301 bool hasFillImage = image && image->canRender(); | 1335 bool hasFillImage = image && image->canRender(); |
| 1302 return (!hasFillImage && !getLineLayoutItem().style()->hasBorderRadius()) || | 1336 return (!hasFillImage && !getLineLayoutItem().style()->hasBorderRadius()) || |
| 1303 (!prevLineBox() && !nextLineBox()) || !parent(); | 1337 (!prevLineBox() && !nextLineBox()) || !parent(); |
| 1304 } | 1338 } |
| 1305 | 1339 |
| 1306 InlineBox* InlineFlowBox::firstLeafChild() const { | 1340 InlineBox* InlineFlowBox::firstLeafChild() const { |
| 1307 InlineBox* leaf = nullptr; | 1341 InlineBox* leaf = nullptr; |
| 1308 for (InlineBox* child = firstChild(); child && !leaf; | 1342 for (InlineBox* child = firstChild(); child && !leaf; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1333 return true; | 1367 return true; |
| 1334 } | 1368 } |
| 1335 | 1369 |
| 1336 LayoutUnit InlineFlowBox::placeEllipsisBox(bool ltr, | 1370 LayoutUnit InlineFlowBox::placeEllipsisBox(bool ltr, |
| 1337 LayoutUnit blockLeftEdge, | 1371 LayoutUnit blockLeftEdge, |
| 1338 LayoutUnit blockRightEdge, | 1372 LayoutUnit blockRightEdge, |
| 1339 LayoutUnit ellipsisWidth, | 1373 LayoutUnit ellipsisWidth, |
| 1340 LayoutUnit& truncatedWidth, | 1374 LayoutUnit& truncatedWidth, |
| 1341 bool& foundBox) { | 1375 bool& foundBox) { |
| 1342 LayoutUnit result(-1); | 1376 LayoutUnit result(-1); |
| 1343 // We iterate over all children, the foundBox variable tells us when we've fou
nd the | 1377 // We iterate over all children, the foundBox variable tells us when we've |
| 1344 // box containing the ellipsis. All boxes after that one in the flow are hidd
en. | 1378 // found the box containing the ellipsis. All boxes after that one in the |
| 1345 // If our flow is ltr then iterate over the boxes from left to right, otherwis
e iterate | 1379 // flow are hidden. |
| 1346 // from right to left. Varying the order allows us to correctly hide the boxes
following the ellipsis. | 1380 // If our flow is ltr then iterate over the boxes from left to right, |
| 1381 // otherwise iterate from right to left. Varying the order allows us to |
| 1382 // correctly hide the boxes following the ellipsis. |
| 1347 InlineBox* box = ltr ? firstChild() : lastChild(); | 1383 InlineBox* box = ltr ? firstChild() : lastChild(); |
| 1348 | 1384 |
| 1349 // NOTE: these will cross after foundBox = true. | 1385 // NOTE: these will cross after foundBox = true. |
| 1350 int visibleLeftEdge = blockLeftEdge.toInt(); | 1386 int visibleLeftEdge = blockLeftEdge.toInt(); |
| 1351 int visibleRightEdge = blockRightEdge.toInt(); | 1387 int visibleRightEdge = blockRightEdge.toInt(); |
| 1352 | 1388 |
| 1353 while (box) { | 1389 while (box) { |
| 1354 int currResult = | 1390 int currResult = |
| 1355 box->placeEllipsisBox(ltr, LayoutUnit(visibleLeftEdge), | 1391 box->placeEllipsisBox(ltr, LayoutUnit(visibleLeftEdge), |
| 1356 LayoutUnit(visibleRightEdge), ellipsisWidth, | 1392 LayoutUnit(visibleRightEdge), ellipsisWidth, |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1506 } | 1542 } |
| 1507 } | 1543 } |
| 1508 return result; | 1544 return result; |
| 1509 } | 1545 } |
| 1510 | 1546 |
| 1511 void InlineFlowBox::collectLeafBoxesInLogicalOrder( | 1547 void InlineFlowBox::collectLeafBoxesInLogicalOrder( |
| 1512 Vector<InlineBox*>& leafBoxesInLogicalOrder, | 1548 Vector<InlineBox*>& leafBoxesInLogicalOrder, |
| 1513 CustomInlineBoxRangeReverse customReverseImplementation) const { | 1549 CustomInlineBoxRangeReverse customReverseImplementation) const { |
| 1514 InlineBox* leaf = firstLeafChild(); | 1550 InlineBox* leaf = firstLeafChild(); |
| 1515 | 1551 |
| 1516 // FIXME: The reordering code is a copy of parts from BidiResolver::createBidi
RunsForLine, operating directly on InlineBoxes, instead of BidiRuns. | 1552 // FIXME: The reordering code is a copy of parts from BidiResolver:: |
| 1517 // Investigate on how this code could possibly be shared. | 1553 // createBidiRunsForLine, operating directly on InlineBoxes, instead of |
| 1554 // BidiRuns. Investigate on how this code could possibly be shared. |
| 1518 unsigned char minLevel = 128; | 1555 unsigned char minLevel = 128; |
| 1519 unsigned char maxLevel = 0; | 1556 unsigned char maxLevel = 0; |
| 1520 | 1557 |
| 1521 // First find highest and lowest levels, and initialize leafBoxesInLogicalOrde
r with the leaf boxes in visual order. | 1558 // First find highest and lowest levels, and initialize |
| 1559 // leafBoxesInLogicalOrder with the leaf boxes in visual order. |
| 1522 for (; leaf; leaf = leaf->nextLeafChild()) { | 1560 for (; leaf; leaf = leaf->nextLeafChild()) { |
| 1523 minLevel = std::min(minLevel, leaf->bidiLevel()); | 1561 minLevel = std::min(minLevel, leaf->bidiLevel()); |
| 1524 maxLevel = std::max(maxLevel, leaf->bidiLevel()); | 1562 maxLevel = std::max(maxLevel, leaf->bidiLevel()); |
| 1525 leafBoxesInLogicalOrder.append(leaf); | 1563 leafBoxesInLogicalOrder.append(leaf); |
| 1526 } | 1564 } |
| 1527 | 1565 |
| 1528 if (getLineLayoutItem().style()->rtlOrdering() == VisualOrder) | 1566 if (getLineLayoutItem().style()->rtlOrdering() == VisualOrder) |
| 1529 return; | 1567 return; |
| 1530 | 1568 |
| 1531 // Reverse of reordering of the line (L2 according to Bidi spec): | 1569 // Reverse of reordering of the line (L2 according to Bidi spec): |
| 1532 // L2. From the highest level found in the text to the lowest odd level on eac
h line, | 1570 // L2. From the highest level found in the text to the lowest odd level on |
| 1533 // reverse any contiguous sequence of characters that are at that level or hig
her. | 1571 // each line, reverse any contiguous sequence of characters that are at that |
| 1572 // level or higher. |
| 1534 | 1573 |
| 1535 // Reversing the reordering of the line is only done up to the lowest odd leve
l. | 1574 // Reversing the reordering of the line is only done up to the lowest odd |
| 1575 // level. |
| 1536 if (!(minLevel % 2)) | 1576 if (!(minLevel % 2)) |
| 1537 ++minLevel; | 1577 ++minLevel; |
| 1538 | 1578 |
| 1539 Vector<InlineBox*>::iterator end = leafBoxesInLogicalOrder.end(); | 1579 Vector<InlineBox*>::iterator end = leafBoxesInLogicalOrder.end(); |
| 1540 while (minLevel <= maxLevel) { | 1580 while (minLevel <= maxLevel) { |
| 1541 Vector<InlineBox*>::iterator it = leafBoxesInLogicalOrder.begin(); | 1581 Vector<InlineBox*>::iterator it = leafBoxesInLogicalOrder.begin(); |
| 1542 while (it != end) { | 1582 while (it != end) { |
| 1543 while (it != end) { | 1583 while (it != end) { |
| 1544 if ((*it)->bidiLevel() >= minLevel) | 1584 if ((*it)->bidiLevel() >= minLevel) |
| 1545 break; | 1585 break; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1593 ASSERT(child->prevOnLine() == prev); | 1633 ASSERT(child->prevOnLine() == prev); |
| 1594 prev = child; | 1634 prev = child; |
| 1595 } | 1635 } |
| 1596 ASSERT(prev == m_lastChild); | 1636 ASSERT(prev == m_lastChild); |
| 1597 #endif | 1637 #endif |
| 1598 } | 1638 } |
| 1599 | 1639 |
| 1600 #endif | 1640 #endif |
| 1601 | 1641 |
| 1602 } // namespace blink | 1642 } // namespace blink |
| OLD | NEW |