15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies) 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderDetailsMarker.h" 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 245d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h" 2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Element.h" 26d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/html/HTMLElement.h" 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/PaintInfo.h" 28a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContext.h" 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames; 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 34926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)RenderDetailsMarker::RenderDetailsMarker(Element* element) 358abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) : RenderBlockFlow(element) 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static Path createPath(const FloatPoint* path) 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Path result; 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.moveTo(FloatPoint(path[0].x(), path[0].y())); 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (int i = 1; i < 4; ++i) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.addLineTo(FloatPoint(path[i].x(), path[i].y())); 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static Path createDownArrowPath() 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint points[4] = { FloatPoint(0.0f, 0.07f), FloatPoint(0.5f, 0.93f), FloatPoint(1.0f, 0.07f), FloatPoint(0.0f, 0.07f) }; 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return createPath(points); 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static Path createUpArrowPath() 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint points[4] = { FloatPoint(0.0f, 0.93f), FloatPoint(0.5f, 0.07f), FloatPoint(1.0f, 0.93f), FloatPoint(0.0f, 0.93f) }; 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return createPath(points); 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static Path createLeftArrowPath() 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint points[4] = { FloatPoint(1.0f, 0.0f), FloatPoint(0.14f, 0.5f), FloatPoint(1.0f, 1.0f), FloatPoint(1.0f, 0.0f) }; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return createPath(points); 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static Path createRightArrowPath() 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FloatPoint points[4] = { FloatPoint(0.0f, 0.0f), FloatPoint(0.86f, 0.5f), FloatPoint(0.0f, 1.0f), FloatPoint(0.0f, 0.0f) }; 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return createPath(points); 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderDetailsMarker::Orientation RenderDetailsMarker::orientation() const 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (style()->writingMode()) { 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case TopToBottomWritingMode: 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()->isLeftToRightDirection()) 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isOpen() ? Down : Right; 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isOpen() ? Down : Left; 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case RightToLeftWritingMode: 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()->isLeftToRightDirection()) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isOpen() ? Left : Down; 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isOpen() ? Left : Up; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case LeftToRightWritingMode: 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()->isLeftToRightDirection()) 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isOpen() ? Right : Down; 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isOpen() ? Right : Up; 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case BottomToTopWritingMode: 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style()->isLeftToRightDirection()) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isOpen() ? Up : Right; 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isOpen() ? Up : Left; 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Right; 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Path RenderDetailsMarker::getCanonicalPath() const 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (orientation()) { 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Left: return createLeftArrowPath(); 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Right: return createRightArrowPath(); 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Up: return createUpArrowPath(); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case Down: return createDownArrowPath(); 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return Path(); 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Path RenderDetailsMarker::getPath(const LayoutPoint& origin) const 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Path result = getCanonicalPath(); 110d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) result.transform(AffineTransform().scale(contentWidth().toFloat(), contentHeight().toFloat())); 111d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) result.translate(FloatSize(origin.x().toFloat(), origin.y().toFloat())); 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderDetailsMarker::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (paintInfo.phase != PaintPhaseForeground || style()->visibility() != VISIBLE) { 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderBlock::paint(paintInfo, paintOffset); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutPoint boxOrigin(paintOffset + location()); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LayoutRect overflowRect(visualOverflowRect()); 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) overflowRect.moveBy(boxOrigin); 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!paintInfo.rect.intersects(pixelSnappedIntRect(overflowRect))) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1297757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch const Color color(resolveColor(CSSPropertyColor)); 1305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) paintInfo.context->setStrokeColor(color); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) paintInfo.context->setStrokeStyle(SolidStroke); 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) paintInfo.context->setStrokeThickness(1.0f); 1335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) paintInfo.context->setFillColor(color); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) boxOrigin.move(borderLeft() + paddingLeft(), borderTop() + paddingTop()); 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) paintInfo.context->fillPath(getPath(boxOrigin)); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderDetailsMarker::isOpen() const 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (RenderObject* renderer = parent(); renderer; renderer = renderer->parent()) { 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!renderer->node()) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isHTMLDetailsElement(*renderer->node())) 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !toElement(renderer->node())->getAttribute(openAttr).isNull(); 146d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (isHTMLInputElement(*renderer->node())) 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 154