15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderRubyRun.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderRubyBase.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderRubyText.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderText.h" 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 39c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)RenderRubyRun::RenderRubyRun() 428abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) : RenderBlockFlow(0) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setReplaced(true); 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setInline(true); 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderRubyRun::~RenderRubyRun() 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderRubyRun::hasRubyText() const 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The only place where a ruby text can be is in the first position 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: As anonymous blocks, ruby runs do not have ':before' or ':after' content themselves. 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return firstChild() && firstChild()->isRubyText(); 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderRubyRun::hasRubyBase() const 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The only place where a ruby base can be is in the last position 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: As anonymous blocks, ruby runs do not have ':before' or ':after' content themselves. 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return lastChild() && lastChild()->isRubyBase(); 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderRubyText* RenderRubyRun::rubyText() const 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* child = firstChild(); 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If in future it becomes necessary to support floating or positioned ruby text, 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // layout will have to be changed to handle them properly. 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!child || !child->isRubyText() || !child->isFloatingOrOutOfFlowPositioned()); 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return child && child->isRubyText() ? static_cast<RenderRubyText*>(child) : 0; 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderRubyBase* RenderRubyRun::rubyBase() const 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* child = lastChild(); 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return child && child->isRubyBase() ? static_cast<RenderRubyBase*>(child) : 0; 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderRubyBase* RenderRubyRun::rubyBaseSafe() 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyBase* base = rubyBase(); 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!base) { 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) base = createRubyBase(); 8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderBlockFlow::addChild(base); 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return base; 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderRubyRun::isChildAllowed(RenderObject* child, RenderStyle*) const 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return child->isRubyText() || child->isInline(); 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderRubyRun::addChild(RenderObject* child, RenderObject* beforeChild) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(child); 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (child->isRubyText()) { 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!beforeChild) { 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // RenderRuby has already ascertained that we can add the child here. 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!hasRubyText()); 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // prepend ruby texts as first child 10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderBlockFlow::addChild(child, firstChild()); 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (beforeChild->isRubyText()) { 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // New text is inserted just before another. 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // In this case the new text takes the place of the old one, and 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the old text goes into a new run that is inserted as next sibling. 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(beforeChild->parent() == this); 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* ruby = parent(); 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(ruby->isRuby()); 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* newRun = staticCreateRubyRun(ruby); 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ruby->addChild(newRun, nextSibling()); 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Add the new ruby text and move the old one to the new run 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: Doing it in this order and not using RenderRubyRun's methods, 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // in order to avoid automatic removal of the ruby run in case there is no 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // other child besides the old ruby text. 11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderBlockFlow::addChild(child, beforeChild); 12009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderBlockFlow::removeChild(beforeChild); 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newRun->addChild(beforeChild); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (hasRubyBase()) { 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Insertion before a ruby base object. 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // In this case we need insert a new run before the current one and split the base. 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* ruby = parent(); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyRun* newRun = staticCreateRubyRun(ruby); 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ruby->addChild(newRun, this); 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newRun->addChild(child); 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rubyBaseSafe()->moveChildren(newRun->rubyBaseSafe(), beforeChild); 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // child is not a text -> insert it into the base 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // (append it instead if beforeChild is the ruby text) 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (beforeChild && beforeChild->isRubyText()) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) beforeChild = 0; 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rubyBaseSafe()->addChild(child, beforeChild); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderRubyRun::removeChild(RenderObject* child) 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the child is a ruby text, then merge the ruby base with the base of 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // the right sibling run, if possible. 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!beingDestroyed() && !documentBeingDestroyed() && child->isRubyText()) { 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyBase* base = rubyBase(); 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* rightNeighbour = nextSibling(); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (base && rightNeighbour && rightNeighbour->isRubyRun()) { 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Ruby run without a base can happen only at the first run. 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyRun* rightRun = toRenderRubyRun(rightNeighbour); 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rightRun->hasRubyBase()) { 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyBase* rightBase = rightRun->rubyBaseSafe(); 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Collect all children in a single base, then swap the bases. 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightBase->moveChildren(base); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) moveChildTo(rightRun, base); 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rightRun->moveChildTo(this, rightBase); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The now empty ruby base will be removed below. 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!rubyBase()->firstChild()); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderBlockFlow::removeChild(child); 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!beingDestroyed() && !documentBeingDestroyed()) { 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check if our base (if any) is now empty. If so, destroy it. 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock* base = rubyBase(); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (base && !base->firstChild()) { 16809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderBlockFlow::removeChild(base); 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) base->deleteLineBoxTree(); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) base->destroy(); 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If any of the above leaves the run empty, destroy it as well. 174f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (!hasRubyText() && !hasRubyBase()) { 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) deleteLineBoxTree(); 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destroy(); 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderRubyBase* RenderRubyRun::createRubyBase() const 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1838abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) RenderRubyBase* renderer = RenderRubyBase::createAnonymous(&document()); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK); 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newStyle->setTextAlign(CENTER); // FIXME: use WEBKIT_CENTER? 186926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) renderer->setStyle(newStyle.release()); 187926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return renderer; 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderRubyRun* RenderRubyRun::staticCreateRubyRun(const RenderObject* parentRuby) 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(parentRuby && parentRuby->isRuby()); 193f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) RenderRubyRun* rr = new RenderRubyRun(); 1948abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) rr->setDocumentForAnonymous(&parentRuby->document()); 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parentRuby->style(), INLINE_BLOCK); 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rr->setStyle(newStyle.release()); 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return rr; 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 200e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)RenderObject* RenderRubyRun::layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope& layoutScope) 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Don't bother positioning the RenderRubyRun yet. 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyText* rt = rubyText(); 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!rt) 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (relayoutChildren) 207e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) layoutScope.setChildNeedsLayout(rt); 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rt->layoutIfNeeded(); 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return rt; 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderRubyRun::layout() 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 21409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderBlockFlow::layout(); 21502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyText* rt = rubyText(); 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!rt) 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 219926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 220926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) rt->setLogicalLeft(0); 22102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Place the RenderRubyText such that its bottom is flush with the lineTop of the first line of the RenderRubyBase. 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit lastLineRubyTextBottom = rt->logicalHeight(); 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit firstLineRubyTextTop = 0; 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* rootBox = rt->lastRootBox(); 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rootBox) { 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // In order to align, we have to ignore negative leading. 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstLineRubyTextTop = rt->firstRootBox()->logicalTopLayoutOverflow(); 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastLineRubyTextBottom = rootBox->logicalBottomLayoutOverflow(); 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 232926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (style()->isFlippedLinesWritingMode() == (style()->rubyPosition() == RubyPositionAfter)) { 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit firstLineTop = 0; 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderRubyBase* rb = rubyBase()) { 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* rootBox = rb->firstRootBox(); 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rootBox) 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstLineTop = rootBox->logicalTopLayoutOverflow(); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) firstLineTop += rb->logicalTop(); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 24002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rt->setLogicalTop(-lastLineRubyTextBottom + firstLineTop); 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutUnit lastLineBottom = logicalHeight(); 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderRubyBase* rb = rubyBase()) { 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RootInlineBox* rootBox = rb->lastRootBox(); 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (rootBox) 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastLineBottom = rootBox->logicalBottomLayoutOverflow(); 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastLineBottom += rb->logicalTop(); 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) rt->setLogicalTop(-firstLineRubyTextTop + lastLineBottom); 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Update our overflow to account for the new RenderRubyText position. 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeOverflow(clientLogicalBottom()); 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderRubyRun::getOverhang(bool firstLine, RenderObject* startRenderer, RenderObject* endRenderer, int& startOverhang, int& endOverhang) const 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!needsLayout()); 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startOverhang = 0; 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endOverhang = 0; 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyBase* rubyBase = this->rubyBase(); 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderRubyText* rubyText = this->rubyText(); 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!rubyBase || !rubyText) 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!rubyBase->firstRootBox()) 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int logicalWidth = this->logicalWidth(); 275197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch int logicalLeftOverhang = std::numeric_limits<int>::max(); 276197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch int logicalRightOverhang = std::numeric_limits<int>::max(); 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (RootInlineBox* rootInlineBox = rubyBase->firstRootBox(); rootInlineBox; rootInlineBox = rootInlineBox->nextRootBox()) { 278197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch logicalLeftOverhang = std::min<int>(logicalLeftOverhang, rootInlineBox->logicalLeft()); 279197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch logicalRightOverhang = std::min<int>(logicalRightOverhang, logicalWidth - rootInlineBox->logicalRight()); 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startOverhang = style()->isLeftToRightDirection() ? logicalLeftOverhang : logicalRightOverhang; 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endOverhang = style()->isLeftToRightDirection() ? logicalRightOverhang : logicalLeftOverhang; 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!startRenderer || !startRenderer->isText() || startRenderer->style(firstLine)->fontSize() > rubyBase->style(firstLine)->fontSize()) 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startOverhang = 0; 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!endRenderer || !endRenderer->isText() || endRenderer->style(firstLine)->fontSize() > rubyBase->style(firstLine)->fontSize()) 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endOverhang = 0; 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We overhang a ruby only if the neighboring render object is a text. 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We can overhang the ruby by no more than half the width of the neighboring text 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and no more than half the font size. 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int halfWidthOfFontSize = rubyText->style(firstLine)->fontSize() / 2; 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (startOverhang) 296197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch startOverhang = std::min<int>(startOverhang, std::min<int>(toRenderText(startRenderer)->minLogicalWidth(), halfWidthOfFontSize)); 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (endOverhang) 298197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch endOverhang = std::min<int>(endOverhang, std::min<int>(toRenderText(endRenderer)->minLogicalWidth(), halfWidthOfFontSize)); 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 301c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 302