bool RenderTheme::paintMeter(RenderObject* renderObject, const RenderObject::PaintInfo& paintInfo, const IntRect& rect) { // Some platforms do not have a native gauge widget, so we draw here a default implementation. RenderMeter* renderMeter = toRenderMeter(renderObject); RenderStyle* style = renderObject->style(); int left = style->borderLeft().width() + style->paddingLeft().value(); int top = style->borderTop().width() + style->paddingTop().value(); int right = style->borderRight().width() + style->paddingRight().value(); int bottom = style->borderBottom().width() + style->paddingBottom().value(); FloatRect innerRect(rect.x() + left, rect.y() + top, rect.width() - left - right, rect.height() - top - bottom); HTMLMeterElement* element = static_cast<HTMLMeterElement*>(renderMeter->node()); double min = element->min(); double max = element->max(); double value = element->value(); if (min >= max) { paintInfo.context->fillRect(innerRect, Color::black, style->colorSpace()); return false; } // Paint the background first paintInfo.context->fillRect(innerRect, Color::lightGray, style->colorSpace()); FloatRect valueRect; if (rect.width() < rect.height()) { // Vertical gauge double scale = innerRect.height() / (max - min); valueRect.setLocation(FloatPoint(innerRect.x(), innerRect.y() + narrowPrecisionToFloat((max - value) * scale))); valueRect.setSize(FloatSize(innerRect.width(), narrowPrecisionToFloat((value - min) * scale))); } else if (renderMeter->style()->direction() == RTL) { // right to left horizontal gauge double scale = innerRect.width() / (max - min); valueRect.setLocation(FloatPoint(innerRect.x() + narrowPrecisionToFloat((max - value) * scale), innerRect.y())); valueRect.setSize(FloatSize(narrowPrecisionToFloat((value - min) * scale), innerRect.height())); } else { // left to right horizontal gauge double scale = innerRect.width() / (max - min); valueRect.setLocation(innerRect.location()); valueRect.setSize(FloatSize(narrowPrecisionToFloat((value - min)) * scale, innerRect.height())); } if (!valueRect.isEmpty()) paintInfo.context->fillRect(valueRect, Color::black, style->colorSpace()); return false; }
static bool isDeletableElement(const Node* node) { if (!node || !node->isHTMLElement() || !node->inDocument() || !node->isContentEditable()) return false; // In general we want to only draw the UI arround object of a certain area, but we still keep the min width/height to // make sure we don't end up with very thin or very short elements getting the UI. const int minimumArea = 2500; const int minimumWidth = 48; const int minimumHeight = 16; const unsigned minimumVisibleBorders = 1; RenderObject* renderer = node->renderer(); if (!renderer || !renderer->isBox()) return false; // Disallow the body element since it isn't practical to delete, and the deletion UI would be clipped. if (node->hasTagName(bodyTag)) return false; // Disallow elements with any overflow clip, since the deletion UI would be clipped as well. <rdar://problem/6840161> if (renderer->hasOverflowClip()) return false; // Disallow Mail blockquotes since the deletion UI would get in the way of editing for these. if (isMailBlockquote(node)) return false; RenderBox* box = toRenderBox(renderer); IntRect borderBoundingBox = box->borderBoundingBox(); if (borderBoundingBox.width() < minimumWidth || borderBoundingBox.height() < minimumHeight) return false; if ((borderBoundingBox.width() * borderBoundingBox.height()) < minimumArea) return false; if (renderer->isTable()) return true; if (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->hasTagName(iframeTag)) return true; if (renderer->isPositioned()) return true; if (renderer->isRenderBlock() && !renderer->isTableCell()) { RenderStyle* style = renderer->style(); if (!style) return false; // Allow blocks that have background images if (style->hasBackgroundImage() && style->backgroundImage()->canRender(1.0f)) return true; // Allow blocks with a minimum number of non-transparent borders unsigned visibleBorders = style->borderTop().isVisible() + style->borderBottom().isVisible() + style->borderLeft().isVisible() + style->borderRight().isVisible(); if (visibleBorders >= minimumVisibleBorders) return true; // Allow blocks that have a different background from it's parent Node* parentNode = node->parentNode(); if (!parentNode) return false; RenderObject* parentRenderer = parentNode->renderer(); if (!parentRenderer) return false; RenderStyle* parentStyle = parentRenderer->style(); if (!parentStyle) return false; if (style->hasBackground() && (!parentStyle->hasBackground() || style->backgroundColor() != parentStyle->backgroundColor())) return true; } return false; }
static bool isDeletableElement(const Node* node) { if (!node || !node->isHTMLElement() || !node->inDocument() || !node->isContentEditable()) return false; const int minimumWidth = 25; const int minimumHeight = 25; const unsigned minimumVisibleBorders = 3; RenderObject* renderer = node->renderer(); if (!renderer || renderer->width() < minimumWidth || renderer->height() < minimumHeight) return false; if (renderer->isTable()) return true; if (node->hasTagName(ulTag) || node->hasTagName(olTag)) return true; if (renderer->isPositioned()) return true; // allow block elements (excluding table cells) that have some non-transparent borders if (renderer->isRenderBlock() && !renderer->isTableCell()) { RenderStyle* style = renderer->style(); if (style && style->hasBorder()) { unsigned visibleBorders = style->borderTop().isVisible() + style->borderBottom().isVisible() + style->borderLeft().isVisible() + style->borderRight().isVisible(); if (visibleBorders >= minimumVisibleBorders) return true; } } return false; }