LayoutRect AccessibilityListBoxOption::elementRect() const { LayoutRect rect; if (!m_optionElement) return rect; HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode(); if (!listBoxParentNode) return rect; RenderObject* listBoxRenderer = listBoxParentNode->renderer(); if (!listBoxRenderer) return rect; LayoutRect parentRect = listBoxRenderer->document()->axObjectCache()->getOrCreate(listBoxRenderer)->elementRect(); int index = listBoxOptionIndex(); if (index != -1) rect = toRenderListBox(listBoxRenderer)->itemBoundingBoxRect(parentRect.location(), index); return rect; }
void RenderSVGInlineText::computeNewScaledFontForStyle(const RenderObject& renderer, const RenderStyle& style, float& scalingFactor, FontCascade& scaledFont) { // Alter font-size to the right on-screen value to avoid scaling the glyphs themselves, except when GeometricPrecision is specified scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(renderer); if (!scalingFactor || style.fontDescription().textRenderingMode() == GeometricPrecision) { scalingFactor = 1; scaledFont = style.fontCascade(); return; } auto fontDescription = style.fontDescription(); // FIXME: We need to better handle the case when we compute very small fonts below (below 1pt). fontDescription.setComputedSize(Style::computedFontSizeFromSpecifiedSizeForSVGInlineText(fontDescription.computedSize(), fontDescription.isAbsoluteSize(), scalingFactor, renderer.document())); // SVG controls its own glyph orientation, so don't allow writing-mode // to affect it. if (fontDescription.orientation() != FontOrientation::Horizontal) fontDescription.setOrientation(FontOrientation::Horizontal); scaledFont = FontCascade(fontDescription, 0, 0); scaledFont.update(&renderer.document().fontSelector()); }
VisiblePosition AXObjectCache::visiblePositionForTextMarkerData(TextMarkerData& textMarkerData) { if (!isNodeInUse(textMarkerData.node)) return VisiblePosition(); // FIXME: Accessability should make it clear these are DOM-compliant offsets or store Position objects. VisiblePosition visiblePos = VisiblePosition(createLegacyEditingPosition(textMarkerData.node, textMarkerData.offset), textMarkerData.affinity); Position deepPos = visiblePos.deepEquivalent(); if (deepPos.isNull()) return VisiblePosition(); RenderObject* renderer = deepPos.deprecatedNode()->renderer(); if (!renderer) return VisiblePosition(); AXObjectCache* cache = renderer->document()->axObjectCache(); if (!cache->isIDinUse(textMarkerData.axID)) return VisiblePosition(); if (deepPos.deprecatedNode() != textMarkerData.node || deepPos.deprecatedEditingOffset() != textMarkerData.offset) return VisiblePosition(); return visiblePos; }
void AXObjectCache::textMarkerDataForVisiblePosition(TextMarkerData& textMarkerData, const VisiblePosition& visiblePos) { // This memory must be bzero'd so instances of TextMarkerData can be tested for byte-equivalence. // This also allows callers to check for failure by looking at textMarkerData upon return. memset(&textMarkerData, 0, sizeof(TextMarkerData)); if (visiblePos.isNull()) return; Position deepPos = visiblePos.deepEquivalent(); Node* domNode = deepPos.deprecatedNode(); ASSERT(domNode); if (!domNode) return; if (domNode->isHTMLElement()) { HTMLInputElement* inputElement = domNode->toInputElement(); if (inputElement && inputElement->isPasswordField()) return; } // locate the renderer, which must exist for a visible dom node RenderObject* renderer = domNode->renderer(); ASSERT(renderer); // find or create an accessibility object for this renderer AXObjectCache* cache = renderer->document()->axObjectCache(); RefPtr<AccessibilityObject> obj = cache->getOrCreate(renderer); textMarkerData.axID = obj.get()->axObjectID(); textMarkerData.node = domNode; textMarkerData.offset = deepPos.deprecatedEditingOffset(); textMarkerData.affinity = visiblePos.affinity(); cache->setNodeInUse(domNode); }
int RootInlineBox::verticallyAlignBoxes(int heightOfBlock, GlyphOverflowAndFallbackFontsMap& textBoxDataMap) { #if ENABLE(SVG) // SVG will handle vertical alignment on its own. if (isSVGRootInlineBox()) return 0; #endif int maxPositionTop = 0; int maxPositionBottom = 0; int maxAscent = 0; int maxDescent = 0; // Figure out if we're in strict mode. Note that we can't simply use !style()->htmlHacks(), // because that would match almost strict mode as well. RenderObject* curr = renderer(); while (curr && !curr->node()) curr = curr->container(); bool strictMode = (curr && curr->document()->inStrictMode()); computeLogicalBoxHeights(maxPositionTop, maxPositionBottom, maxAscent, maxDescent, strictMode, textBoxDataMap); if (maxAscent + maxDescent < max(maxPositionTop, maxPositionBottom)) adjustMaxAscentAndDescent(maxAscent, maxDescent, maxPositionTop, maxPositionBottom); int maxHeight = maxAscent + maxDescent; int lineTop = heightOfBlock; int lineBottom = heightOfBlock; placeBoxesVertically(heightOfBlock, maxHeight, maxAscent, strictMode, lineTop, lineBottom); computeVerticalOverflow(lineTop, lineBottom, strictMode, textBoxDataMap); setLineTopBottomPositions(lineTop, lineBottom); heightOfBlock += maxHeight; return heightOfBlock; }
void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit, LayoutUnit) { ASSERT(paintInfo.shouldPaintWithinRoot(renderer())); ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection); ASSERT(truncation() == cNoTruncation); if (renderer()->style()->visibility() != VISIBLE) return; // Note: We're explicitely not supporting composition & custom underlines and custom highlighters - unlike InlineTextBox. // If we ever need that for SVG, it's very easy to refactor and reuse the code. RenderObject* parentRenderer = parent()->renderer(); ASSERT(parentRenderer); bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection; bool hasSelection = !parentRenderer->document().printing() && selectionState() != RenderObject::SelectionNone; if (!hasSelection && paintSelectedTextOnly) return; RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer()); ASSERT(textRenderer); if (!textShouldBePainted(textRenderer)) return; RenderStyle* style = parentRenderer->style(); ASSERT(style); paintDocumentMarkers(paintInfo.context, paintOffset, style, textRenderer->scaledFont(), true); const SVGRenderStyle* svgStyle = style->svgStyle(); ASSERT(svgStyle); bool hasFill = svgStyle->hasFill(); bool hasVisibleStroke = svgStyle->hasVisibleStroke(); RenderStyle* selectionStyle = style; if (hasSelection) { selectionStyle = parentRenderer->getCachedPseudoStyle(SELECTION); if (selectionStyle) { const SVGRenderStyle* svgSelectionStyle = selectionStyle->svgStyle(); ASSERT(svgSelectionStyle); if (!hasFill) hasFill = svgSelectionStyle->hasFill(); if (!hasVisibleStroke) hasVisibleStroke = svgSelectionStyle->hasVisibleStroke(); } else selectionStyle = style; } if (textRenderer->frame() && textRenderer->frame()->view() && textRenderer->frame()->view()->paintBehavior() & PaintBehaviorRenderingSVGMask) { hasFill = true; hasVisibleStroke = false; } AffineTransform fragmentTransform; unsigned textFragmentsSize = m_textFragments.size(); for (unsigned i = 0; i < textFragmentsSize; ++i) { SVGTextFragment& fragment = m_textFragments.at(i); ASSERT(!m_paintingResource); GraphicsContextStateSaver stateSaver(*paintInfo.context, false); fragment.buildFragmentTransform(fragmentTransform); if (!fragmentTransform.isIdentity()) { stateSaver.save(); paintInfo.context->concatCTM(fragmentTransform); } // Spec: All text decorations except line-through should be drawn before the text is filled and stroked; thus, the text is rendered on top of these decorations. unsigned decorations = style->textDecorationsInEffect(); if (decorations & TextDecorationUnderline) paintDecoration(paintInfo.context, TextDecorationUnderline, fragment); if (decorations & TextDecorationOverline) paintDecoration(paintInfo.context, TextDecorationOverline, fragment); for (int i = 0; i < 3; i++) { switch (svgStyle->paintOrderType(i)) { case PT_FILL: // Fill text if (hasFill) { m_paintingResourceMode = ApplyToFillMode | ApplyToTextMode; paintText(paintInfo.context, style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly); } break; case PT_STROKE: // Stroke text if (hasVisibleStroke) { m_paintingResourceMode = ApplyToStrokeMode | ApplyToTextMode; paintText(paintInfo.context, style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly); } break; case PT_MARKERS: // Markers don't apply to text break; default: ASSERT_NOT_REACHED(); break; } } // Spec: Line-through should be drawn after the text is filled and stroked; thus, the line-through is rendered on top of the text. if (decorations & TextDecorationLineThrough) paintDecoration(paintInfo.context, TextDecorationLineThrough, fragment); m_paintingResourceMode = ApplyToDefaultMode; } ASSERT(!m_paintingResource); }
void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo) { ASSERT(paintInfo.shouldPaintWithinRoot(renderer())); ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection); ASSERT(truncation() == cNoTruncation); if (renderer()->style()->visibility() != VISIBLE) return; RenderObject* parentRenderer = parent()->renderer(); ASSERT(parentRenderer); ASSERT(!parentRenderer->document()->printing()); // Determine whether or not we're selected. bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection; bool hasSelection = selectionState() != RenderObject::SelectionNone; if (!hasSelection || paintSelectedTextOnly) return; Color backgroundColor = renderer()->selectionBackgroundColor(); if (!backgroundColor.isValid() || !backgroundColor.alpha()) return; RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer()); ASSERT(textRenderer); if (!textShouldBePainted(textRenderer)) return; RenderStyle* style = parentRenderer->style(); ASSERT(style); RenderStyle* selectionStyle = style; if (hasSelection) { selectionStyle = parentRenderer->getCachedPseudoStyle(SELECTION); if (!selectionStyle) selectionStyle = style; } int startPosition, endPosition; selectionStartEnd(startPosition, endPosition); int fragmentStartPosition = 0; int fragmentEndPosition = 0; AffineTransform fragmentTransform; unsigned textFragmentsSize = m_textFragments.size(); for (unsigned i = 0; i < textFragmentsSize; ++i) { SVGTextFragment& fragment = m_textFragments.at(i); ASSERT(!m_paintingResource); fragmentStartPosition = startPosition; fragmentEndPosition = endPosition; if (!mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition)) continue; GraphicsContextStateSaver stateSaver(*paintInfo.context); fragment.buildFragmentTransform(fragmentTransform); if (!fragmentTransform.isIdentity()) paintInfo.context->concatCTM(fragmentTransform); paintInfo.context->setFillColor(backgroundColor, style->colorSpace()); paintInfo.context->fillRect(selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style), backgroundColor, style->colorSpace()); m_paintingResourceMode = ApplyToDefaultMode; } ASSERT(!m_paintingResource); }
void writeResources(TextStream& ts, const RenderObject& object, int indent) { const RenderStyle* style = object.style(); const SVGRenderStyle* svgStyle = style->svgStyle(); // FIXME: We want to use SVGResourcesCache to determine which resources are present, instead of quering the resource <-> id cache. // For now leave the DRT output as is, but later on we should change this so cycles are properly ignored in the DRT output. RenderObject& renderer = const_cast<RenderObject&>(object); if (!svgStyle->maskerResource().isEmpty()) { if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle->maskerResource())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "masker", svgStyle->maskerResource()); ts << " "; writeStandardPrefix(ts, *masker, 0); ts << " " << masker->resourceBoundingBox(&renderer) << "\n"; } } if (!svgStyle->clipperResource().isEmpty()) { if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object.document(), svgStyle->clipperResource())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "clipPath", svgStyle->clipperResource()); ts << " "; writeStandardPrefix(ts, *clipper, 0); ts << " " << clipper->resourceBoundingBox(&renderer) << "\n"; } } if (!svgStyle->filterResource().isEmpty()) { if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object.document(), svgStyle->filterResource())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "filter", svgStyle->filterResource()); ts << " "; writeStandardPrefix(ts, *filter, 0); ts << " " << filter->resourceBoundingBox(&renderer) << "\n"; } } }
void SVGInlineTextBox::paint(PaintInfo& paintInfo, int, int) { ASSERT(paintInfo.shouldPaintWithinRoot(renderer())); ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection); ASSERT(truncation() == cNoTruncation); if (renderer()->style()->visibility() != VISIBLE) return; // Note: We're explicitely not supporting composition & custom underlines and custom highlighters - unlike InlineTextBox. // If we ever need that for SVG, it's very easy to refactor and reuse the code. RenderObject* parentRenderer = parent()->renderer(); ASSERT(parentRenderer); bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection; bool hasSelection = !parentRenderer->document()->printing() && selectionState() != RenderObject::SelectionNone; if (!hasSelection && paintSelectedTextOnly) return; RenderStyle* style = parentRenderer->style(); ASSERT(style); const SVGRenderStyle* svgStyle = style->svgStyle(); ASSERT(svgStyle); bool hasFill = svgStyle->hasFill(); bool hasStroke = svgStyle->hasStroke(); RenderStyle* selectionStyle = style; if (hasSelection) { selectionStyle = parentRenderer->getCachedPseudoStyle(SELECTION); if (selectionStyle) { const SVGRenderStyle* svgSelectionStyle = selectionStyle->svgStyle(); ASSERT(svgSelectionStyle); if (!hasFill) hasFill = svgSelectionStyle->hasFill(); if (!hasStroke) hasStroke = svgSelectionStyle->hasStroke(); } else selectionStyle = style; } unsigned textFragmentsSize = m_textFragments.size(); for (unsigned i = 0; i < textFragmentsSize; ++i) { SVGTextFragment& fragment = m_textFragments.at(i); ASSERT(!m_paintingResource); paintInfo.context->save(); if (!fragment.transform.isIdentity()) paintInfo.context->concatCTM(fragment.transform); // Spec: All text decorations except line-through should be drawn before the text is filled and stroked; thus, the text is rendered on top of these decorations. int decorations = style->textDecorationsInEffect(); if (decorations & UNDERLINE) paintDecoration(paintInfo.context, UNDERLINE, fragment); if (decorations & OVERLINE) paintDecoration(paintInfo.context, OVERLINE, fragment); // Fill text if (hasFill) { m_paintingResourceMode = ApplyToFillMode | ApplyToTextMode; paintText(paintInfo.context, style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly); } // Stroke text if (hasStroke) { m_paintingResourceMode = ApplyToStrokeMode | ApplyToTextMode; paintText(paintInfo.context, style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly); } // Spec: Line-through should be drawn after the text is filled and stroked; thus, the line-through is rendered on top of the text. if (decorations & LINE_THROUGH) paintDecoration(paintInfo.context, LINE_THROUGH, fragment); m_paintingResourceMode = ApplyToDefaultMode; paintInfo.context->restore(); } ASSERT(!m_paintingResource); }
bool RenderTheme::paintDecorations(const RenderObject& renderer, const PaintInfo& paintInfo, const LayoutRect& rect) { if (paintInfo.context->paintingDisabled()) return false; IntRect integralSnappedRect = pixelSnappedIntRect(rect); FloatRect devicePixelSnappedRect = pixelSnappedForPainting(rect, renderer.document().deviceScaleFactor()); // Call the appropriate paint method based off the appearance value. switch (renderer.style().appearance()) { case MenulistButtonPart: return paintMenuListButtonDecorations(renderer, paintInfo, integralSnappedRect); case TextFieldPart: return paintTextFieldDecorations(renderer, paintInfo, devicePixelSnappedRect); case TextAreaPart: return paintTextAreaDecorations(renderer, paintInfo, devicePixelSnappedRect); case CheckboxPart: return paintCheckboxDecorations(renderer, paintInfo, integralSnappedRect); case RadioPart: return paintRadioDecorations(renderer, paintInfo, integralSnappedRect); case PushButtonPart: return paintPushButtonDecorations(renderer, paintInfo, integralSnappedRect); case SquareButtonPart: return paintSquareButtonDecorations(renderer, paintInfo, integralSnappedRect); case ButtonPart: return paintButtonDecorations(renderer, paintInfo, integralSnappedRect); case MenulistPart: return paintMenuListDecorations(renderer, paintInfo, integralSnappedRect); case SliderThumbHorizontalPart: case SliderThumbVerticalPart: return paintSliderThumbDecorations(renderer, paintInfo, integralSnappedRect); case SearchFieldPart: return paintSearchFieldDecorations(renderer, paintInfo, integralSnappedRect); #if ENABLE(METER_ELEMENT) case MeterPart: case RelevancyLevelIndicatorPart: case ContinuousCapacityLevelIndicatorPart: case DiscreteCapacityLevelIndicatorPart: case RatingLevelIndicatorPart: #endif #if ENABLE(PROGRESS_ELEMENT) case ProgressBarPart: #endif case SliderHorizontalPart: case SliderVerticalPart: case ListboxPart: case DefaultButtonPart: case SearchFieldCancelButtonPart: case SearchFieldDecorationPart: case SearchFieldResultsDecorationPart: case SearchFieldResultsButtonPart: #if ENABLE(INPUT_SPEECH) case InputSpeechButtonPart: #endif #if ENABLE(SERVICE_CONTROLS) case ImageControlsButtonPart: #endif default: break; } return false; }
void writeResources(TextStream& ts, const RenderObject& object, int indent) { const RenderStyle* style = object.style(); const SVGRenderStyle* svgStyle = style->svgStyle(); RenderObject& renderer = const_cast<RenderObject&>(object); if (!svgStyle->maskerResource().isEmpty()) { if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle->maskerResource())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "masker", svgStyle->maskerResource()); ts << " "; writeStandardPrefix(ts, *masker, 0); ts << " " << masker->resourceBoundingBox(&renderer) << "\n"; } } if (!svgStyle->clipperResource().isEmpty()) { if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object.document(), svgStyle->clipperResource())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "clipPath", svgStyle->clipperResource()); ts << " "; writeStandardPrefix(ts, *clipper, 0); ts << " " << clipper->resourceBoundingBox(&renderer) << "\n"; } } #if ENABLE(FILTERS) if (!svgStyle->filterResource().isEmpty()) { if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object.document(), svgStyle->filterResource())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "filter", svgStyle->filterResource()); ts << " "; writeStandardPrefix(ts, *filter, 0); ts << " " << filter->resourceBoundingBox(&renderer) << "\n"; } } #endif }
bool RenderTheme::paint(const RenderObject& o, ControlStates* controlStates, const PaintInfo& paintInfo, const LayoutRect& r) { // If painting is disabled, but we aren't updating control tints, then just bail. // If we are updating control tints, just schedule a repaint if the theme supports tinting // for that control. if (paintInfo.context->updatingControlTints()) { if (controlSupportsTints(o)) o.repaint(); return false; } if (paintInfo.context->paintingDisabled()) return false; ControlPart part = o.style().appearance(); IntRect integralSnappedRect = snappedIntRect(r); FloatRect devicePixelSnappedRect = snapRectToDevicePixels(r, o.document().deviceScaleFactor()); #if USE(NEW_THEME) switch (part) { case CheckboxPart: case RadioPart: case PushButtonPart: case SquareButtonPart: case DefaultButtonPart: case ButtonPart: case InnerSpinButtonPart: updateControlStatesForRenderer(o, controlStates); m_theme->paint(part, controlStates, const_cast<GraphicsContext*>(paintInfo.context), devicePixelSnappedRect, o.style().effectiveZoom(), &o.view().frameView()); return false; default: break; } #else UNUSED_PARAM(controlStates); #endif // Call the appropriate paint method based off the appearance value. switch (part) { #if !USE(NEW_THEME) case CheckboxPart: return paintCheckbox(o, paintInfo, integralSnappedRect); case RadioPart: return paintRadio(o, paintInfo, integralSnappedRect); case PushButtonPart: case SquareButtonPart: case DefaultButtonPart: case ButtonPart: return paintButton(o, paintInfo, integralSnappedRect); case InnerSpinButtonPart: return paintInnerSpinButton(o, paintInfo, integralSnappedRect); #endif case MenulistPart: return paintMenuList(o, paintInfo, devicePixelSnappedRect); #if ENABLE(METER_ELEMENT) case MeterPart: case RelevancyLevelIndicatorPart: case ContinuousCapacityLevelIndicatorPart: case DiscreteCapacityLevelIndicatorPart: case RatingLevelIndicatorPart: return paintMeter(o, paintInfo, integralSnappedRect); #endif case ProgressBarPart: return paintProgressBar(o, paintInfo, integralSnappedRect); case SliderHorizontalPart: case SliderVerticalPart: return paintSliderTrack(o, paintInfo, integralSnappedRect); case SliderThumbHorizontalPart: case SliderThumbVerticalPart: return paintSliderThumb(o, paintInfo, integralSnappedRect); case MediaEnterFullscreenButtonPart: case MediaExitFullscreenButtonPart: return paintMediaFullscreenButton(o, paintInfo, integralSnappedRect); case MediaPlayButtonPart: return paintMediaPlayButton(o, paintInfo, integralSnappedRect); case MediaOverlayPlayButtonPart: return paintMediaOverlayPlayButton(o, paintInfo, integralSnappedRect); case MediaMuteButtonPart: return paintMediaMuteButton(o, paintInfo, integralSnappedRect); case MediaSeekBackButtonPart: return paintMediaSeekBackButton(o, paintInfo, integralSnappedRect); case MediaSeekForwardButtonPart: return paintMediaSeekForwardButton(o, paintInfo, integralSnappedRect); case MediaRewindButtonPart: return paintMediaRewindButton(o, paintInfo, integralSnappedRect); case MediaReturnToRealtimeButtonPart: return paintMediaReturnToRealtimeButton(o, paintInfo, integralSnappedRect); case MediaToggleClosedCaptionsButtonPart: return paintMediaToggleClosedCaptionsButton(o, paintInfo, integralSnappedRect); case MediaSliderPart: return paintMediaSliderTrack(o, paintInfo, integralSnappedRect); case MediaSliderThumbPart: return paintMediaSliderThumb(o, paintInfo, integralSnappedRect); case MediaVolumeSliderMuteButtonPart: return paintMediaMuteButton(o, paintInfo, integralSnappedRect); case MediaVolumeSliderContainerPart: return paintMediaVolumeSliderContainer(o, paintInfo, integralSnappedRect); case MediaVolumeSliderPart: return paintMediaVolumeSliderTrack(o, paintInfo, integralSnappedRect); case MediaVolumeSliderThumbPart: return paintMediaVolumeSliderThumb(o, paintInfo, integralSnappedRect); case MediaFullScreenVolumeSliderPart: return paintMediaFullScreenVolumeSliderTrack(o, paintInfo, integralSnappedRect); case MediaFullScreenVolumeSliderThumbPart: return paintMediaFullScreenVolumeSliderThumb(o, paintInfo, integralSnappedRect); case MediaTimeRemainingPart: return paintMediaTimeRemaining(o, paintInfo, integralSnappedRect); case MediaCurrentTimePart: return paintMediaCurrentTime(o, paintInfo, integralSnappedRect); case MediaControlsBackgroundPart: return paintMediaControlsBackground(o, paintInfo, integralSnappedRect); case MenulistButtonPart: case TextFieldPart: case TextAreaPart: case ListboxPart: return true; case SearchFieldPart: return paintSearchField(o, paintInfo, integralSnappedRect); case SearchFieldCancelButtonPart: return paintSearchFieldCancelButton(o, paintInfo, integralSnappedRect); case SearchFieldDecorationPart: return paintSearchFieldDecorationPart(o, paintInfo, integralSnappedRect); case SearchFieldResultsDecorationPart: return paintSearchFieldResultsDecorationPart(o, paintInfo, integralSnappedRect); case SearchFieldResultsButtonPart: return paintSearchFieldResultsButton(o, paintInfo, integralSnappedRect); case SnapshottedPluginOverlayPart: return paintSnapshottedPluginOverlay(o, paintInfo, integralSnappedRect); #if ENABLE(SERVICE_CONTROLS) case ImageControlsButtonPart: return paintImageControlsButton(o, paintInfo, integralSnappedRect); #endif default: break; } return true; // We don't support the appearance, so let the normal background/border paint. }
void FrameView::layout(bool allowSubtree) { if (d->m_midLayout) return; d->m_layoutTimer.stop(); d->m_delayedLayout = false; // Protect the view from being deleted during layout (in recalcStyle) RefPtr<FrameView> protector(this); if (!m_frame) { // FIXME: Do we need to set m_size.width here? // FIXME: Should we set m_size.height here too? m_size.setWidth(visibleWidth()); return; } // we shouldn't enter layout() while painting ASSERT(!m_frame->isPainting()); if (m_frame->isPainting()) return; if (!allowSubtree && d->m_layoutRoot) { d->m_layoutRoot->markContainingBlocksForLayout(false); d->m_layoutRoot = 0; } ASSERT(m_frame->view() == this); // This early return should be removed when rdar://5598072 is resolved. In the meantime, there is a // gigantic CrashTracer because of this issue, and the early return will hopefully cause graceful // failure instead. if (m_frame->view() != this) return; Document* document = m_frame->document(); if (!document) { // FIXME: Should we set m_size.height here too? m_size.setWidth(visibleWidth()); return; } d->m_layoutSchedulingEnabled = false; if (!d->m_nestedLayoutCount && d->m_postLayoutTasksTimer.isActive()) { // This is a new top-level layout. If there are any remaining tasks from the previous // layout, finish them now. d->m_postLayoutTasksTimer.stop(); performPostLayoutTasks(); } // Viewport-dependent media queries may cause us to need completely different style information. // Check that here. if (document->styleSelector()->affectedByViewportChange()) document->updateStyleSelector(); // Always ensure our style info is up-to-date. This can happen in situations where // the layout beats any sort of style recalc update that needs to occur. if (m_frame->needsReapplyStyles()) m_frame->reapplyStyles(); else if (document->hasChangedChild()) document->recalcStyle(); bool subtree = d->m_layoutRoot; // If there is only one ref to this view left, then its going to be destroyed as soon as we exit, // so there's no point to continuing to layout if (protector->hasOneRef()) return; RenderObject* root = subtree ? d->m_layoutRoot : document->renderer(); if (!root) { // FIXME: Do we need to set m_size here? d->m_layoutSchedulingEnabled = true; return; } d->m_nestedLayoutCount++; ScrollbarMode hMode = d->m_hmode; ScrollbarMode vMode = d->m_vmode; if (!subtree) { RenderObject* rootRenderer = document->documentElement() ? document->documentElement()->renderer() : 0; if (document->isHTMLDocument()) { Node* body = static_cast<HTMLDocument*>(document)->body(); if (body && body->renderer()) { if (body->hasTagName(framesetTag)) { body->renderer()->setChildNeedsLayout(true); vMode = ScrollbarAlwaysOff; hMode = ScrollbarAlwaysOff; } else if (body->hasTagName(bodyTag)) { if (!d->m_firstLayout && m_size.height() != visibleHeight() && static_cast<RenderBox*>(body->renderer())->stretchesToViewHeight()) body->renderer()->setChildNeedsLayout(true); // It's sufficient to just check the X overflow, // since it's illegal to have visible in only one direction. RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE ? body->renderer() : rootRenderer; applyOverflowToViewport(o, hMode, vMode); // Only applies to HTML UAs, not to XML/XHTML UAs } } } else if (rootRenderer) applyOverflowToViewport(rootRenderer, hMode, vMode); // XML/XHTML UAs use the root element. #ifdef INSTRUMENT_LAYOUT_SCHEDULING if (d->m_firstLayout && !document->ownerElement()) OWB_PRINTF("Elapsed time before first layout: %d\n", document->elapsedTime()); #endif } d->m_doFullRepaint = !subtree && (d->m_firstLayout || static_cast<RenderView*>(root)->printing()); if (!subtree) { // Now set our scrollbar state for the layout. ScrollbarMode currentHMode = hScrollbarMode(); ScrollbarMode currentVMode = vScrollbarMode(); if (d->m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) { suppressScrollbars(true); if (d->m_firstLayout) { d->m_firstLayout = false; d->m_firstLayoutCallbackPending = true; d->m_lastLayoutSize = IntSize(width(), height()); d->m_lastZoomFactor = root->style()->zoom(); // Set the initial vMode to AlwaysOn if we're auto. if (vMode == ScrollbarAuto) ScrollView::setVScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear. // Set the initial hMode to AlwaysOff if we're auto. if (hMode == ScrollbarAuto) ScrollView::setHScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear. } if (hMode == vMode) ScrollView::setScrollbarsMode(hMode); else { ScrollView::setHScrollbarMode(hMode); ScrollView::setVScrollbarMode(vMode); } suppressScrollbars(false, true); } IntSize oldSize = m_size; m_size = IntSize(visibleWidth(), visibleHeight()); if (oldSize != m_size) d->m_doFullRepaint = true; } RenderLayer* layer = root->enclosingLayer(); pauseScheduledEvents(); if (subtree) root->view()->pushLayoutState(root); d->m_midLayout = true; beginDeferredRepaints(); root->layout(); endDeferredRepaints(); d->m_midLayout = false; if (subtree) root->view()->popLayoutState(); d->m_layoutRoot = 0; m_frame->invalidateSelection(); d->m_layoutSchedulingEnabled = true; if (!subtree && !static_cast<RenderView*>(root)->printing()) adjustViewSize(); // Now update the positions of all layers. beginDeferredRepaints(); layer->updateLayerPositions(d->m_doFullRepaint); endDeferredRepaints(); d->m_layoutCount++; #if PLATFORM(MAC) if (AXObjectCache::accessibilityEnabled()) root->document()->axObjectCache()->postNotificationToElement(root, "AXLayoutComplete"); #endif #if ENABLE(DASHBOARD_SUPPORT) updateDashboardRegions(); #endif ASSERT(!root->needsLayout()); setStaticBackground(useSlowRepaints()); if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER)) updateOverflowStatus(visibleWidth() < contentsWidth(), visibleHeight() < contentsHeight()); if (!d->m_postLayoutTasksTimer.isActive()) { // Calls resumeScheduledEvents() performPostLayoutTasks(); if (needsLayout()) { // Post-layout widget updates or an event handler made us need layout again. // Lay out again, but this time defer widget updates and event dispatch until after // we return. d->m_postLayoutTasksTimer.startOneShot(0); pauseScheduledEvents(); layout(); } } else { resumeScheduledEvents(); ASSERT(d->m_enqueueEvents); } d->m_nestedLayoutCount--; }
void writeResources(TextStream& ts, const RenderObject& object, int indent) { const RenderStyle* style = object.style(); const SVGRenderStyle* svgStyle = style->svgStyle(); if (!svgStyle->maskElement().isEmpty()) { if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle->maskElement())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "masker", svgStyle->maskElement()); ts << " "; writeStandardPrefix(ts, *masker, 0); ts << " " << masker->resourceBoundingBox(object.objectBoundingBox()) << "\n"; } } if (!svgStyle->clipPath().isEmpty()) { if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object.document(), svgStyle->clipPath())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "clipPath", svgStyle->clipPath()); ts << " "; writeStandardPrefix(ts, *clipper, 0); ts << " " << clipper->resourceBoundingBox(object.objectBoundingBox()) << "\n"; } } // FIXME: Handle other RenderSVGResource* classes here, after converting them from SVGResource*. }