void RenderBlockFlow::layoutBlock(bool relayoutChildren) { ASSERT(needsLayout()); ASSERT(isInlineBlock() || !isInline()); if (!relayoutChildren && simplifiedLayout()) return; SubtreeLayoutScope layoutScope(*this); layoutBlockFlow(relayoutChildren, layoutScope); updateLayerTransformAfterLayout(); // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if // we overflow or not. updateScrollInfoAfterLayout(); if (m_paintInvalidationLogicalTop != m_paintInvalidationLogicalBottom) setShouldInvalidateOverflowForPaint(true); clearNeedsLayout(); }
void BitVector::resizeOutOfLine(size_t numBits) { ASSERT(numBits > maxInlineBits()); OutOfLineBits* newOutOfLineBits = OutOfLineBits::create(numBits); size_t newNumWords = newOutOfLineBits->numWords(); if (isInline()) { // Make sure that all of the bits are zero in case we do a no-op resize. *newOutOfLineBits->bits() = m_bitsOrPointer & ~(static_cast<uintptr_t>(1) << maxInlineBits()); memset(newOutOfLineBits->bits() + 1, 0, (newNumWords - 1) * sizeof(void*)); } else { if (numBits > size()) { size_t oldNumWords = outOfLineBits()->numWords(); memcpy(newOutOfLineBits->bits(), outOfLineBits()->bits(), oldNumWords * sizeof(void*)); memset(newOutOfLineBits->bits() + oldNumWords, 0, (newNumWords - oldNumWords) * sizeof(void*)); } else { memcpy(newOutOfLineBits->bits(), outOfLineBits()->bits(), newOutOfLineBits->numWords() * sizeof(void*)); } OutOfLineBits::destroy(outOfLineBits()); } m_bitsOrPointer = bitwiseCast<uintptr_t>(newOutOfLineBits) >> 1; }
void RenderSVGText::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; ASSERT(needsLayout()); LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(*this)); bool updateCachedBoundariesInParents = false; if (m_needsTransformUpdate) { m_localTransform = textElement().animatedLocalTransform(); m_needsTransformUpdate = false; updateCachedBoundariesInParents = true; } if (!everHadLayout()) { // When laying out initially, collect all layout attributes, build the character data map, // and propogate resulting SVGLayoutAttributes to all RenderSVGInlineText children in the subtree. ASSERT(m_layoutAttributes.isEmpty()); collectLayoutAttributes(this, m_layoutAttributes); updateFontInAllDescendants(this); m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(*this); m_needsReordering = true; m_needsTextMetricsUpdate = false; m_needsPositioningValuesUpdate = false; updateCachedBoundariesInParents = true; } else if (m_needsPositioningValuesUpdate) { // When the x/y/dx/dy/rotate lists change, recompute the layout attributes, and eventually // update the on-screen font objects as well in all descendants. if (m_needsTextMetricsUpdate) { updateFontInAllDescendants(this); m_needsTextMetricsUpdate = false; } m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(*this); m_needsReordering = true; m_needsPositioningValuesUpdate = false; updateCachedBoundariesInParents = true; } else if (m_needsTextMetricsUpdate || SVGRenderSupport::findTreeRootObject(*this).isLayoutSizeChanged()) { // If the root layout size changed (eg. window size changes) or the transform to the root // context has changed then recompute the on-screen font size. updateFontInAllDescendants(this, &m_layoutAttributesBuilder); ASSERT(!m_needsReordering); ASSERT(!m_needsPositioningValuesUpdate); m_needsTextMetricsUpdate = false; updateCachedBoundariesInParents = true; } checkLayoutAttributesConsistency(this, m_layoutAttributes); // Reduced version of RenderBlock::layoutBlock(), which only takes care of SVG text. // All if branches that could cause early exit in RenderBlocks layoutBlock() method are turned into assertions. ASSERT(!isInline()); ASSERT(!simplifiedLayout()); ASSERT(!scrollsOverflow()); ASSERT(!hasControlClip()); ASSERT(!multiColumnFlowThread()); ASSERT(!positionedObjects()); ASSERT(!m_overflow); ASSERT(!isAnonymousBlock()); if (!firstChild()) setChildrenInline(true); // FIXME: We need to find a way to only layout the child boxes, if needed. FloatRect oldBoundaries = objectBoundingBox(); ASSERT(childrenInline()); LayoutUnit repaintLogicalTop = 0; LayoutUnit repaintLogicalBottom = 0; rebuildFloatingObjectSetFromIntrudingFloats(); layoutInlineChildren(true, repaintLogicalTop, repaintLogicalBottom); if (m_needsReordering) m_needsReordering = false; if (!updateCachedBoundariesInParents) updateCachedBoundariesInParents = oldBoundaries != objectBoundingBox(); // Invalidate all resources of this client if our layout changed. if (everHadLayout() && selfNeedsLayout()) SVGResourcesCache::clientLayoutChanged(*this); // If our bounds changed, notify the parents. if (updateCachedBoundariesInParents) RenderSVGBlock::setNeedsBoundariesUpdate(); repainter.repaintAfterLayout(); clearNeedsLayout(); }
DomElement *WPaintedWidget::createDomElement(WApplication *app) { if (isInLayout()) { setLayoutSizeAware(true); setJavaScriptMember(WT_RESIZE_JS, "function(self, w, h) {" """var u = $(self).find('canvas, img');" """if (w >= 0) " "" "u.width(w);" """if (h >= 0) " "" "u.height(h);" "}"); } createPainter(); DomElement *result = DomElement::createNew(domElementType()); setId(result, app); DomElement *wrap = result; if (width().isAuto() && height().isAuto()) { result->setProperty(PropertyStylePosition, "relative"); wrap = DomElement::createNew(DomElement_DIV); wrap->setProperty(PropertyStylePosition, "absolute"); wrap->setProperty(PropertyStyleLeft, "0"); wrap->setProperty(PropertyStyleRight, "0"); } DomElement *canvas = DomElement::createNew(DomElement_DIV); if (!app->environment().agentIsSpiderBot()) canvas->setId('p' + id()); WPaintDevice *device = painter_->getPaintDevice(false); //handle the widget correctly when inline and using VML if (painter_->renderType() == WWidgetPainter::InlineVml && isInline()) { result->setProperty(PropertyStyle, "zoom: 1;"); canvas->setProperty(PropertyStyleDisplay, "inline"); canvas->setProperty(PropertyStyle, "zoom: 1;"); } if (renderWidth_ != 0 && renderHeight_ != 0) { paintEvent(device); #ifdef WT_TARGET_JAVA if (device->painter()) device->painter()->end(); #endif // WT_TARGET_JAVA } painter_->createContents(canvas, device); needRepaint_ = false; wrap->addChild(canvas); if (wrap != result) result->addChild(wrap); updateDom(*result, true); return result; }
void KMMsgPartDialogCompat::applyChanges() { if (!mMsgPart) return; KCursorSaver busy(KBusyPtr::busy()); // apply Content-Disposition: QByteArray cDisp; if ( isInline() ) cDisp = "inline;"; else cDisp = "attachment;"; QString name = fileName(); if ( !name.isEmpty() || !mMsgPart->name().isEmpty()) { mMsgPart->setName( name ); QByteArray encName = KMMsgBase::encodeRFC2231StringAutoDetectCharset( name, mMsgPart->charset() ); cDisp += "\n\tfilename"; if ( name != QString( encName ) ) cDisp += "*=" + encName; else cDisp += "=\"" + encName.replace( '\\', "\\\\" ).replace( '"', "\\\"" ) + '"'; mMsgPart->setContentDisposition( cDisp ); } // apply Content-Description" QString desc = description(); if ( !desc.isEmpty() || !mMsgPart->contentDescription().isEmpty() ) mMsgPart->setContentDescription( desc ); // apply Content-Type: QByteArray type = mimeType().toLatin1(); QByteArray subtype; int idx = type.indexOf('/'); if ( idx < 0 ) subtype = ""; else { subtype = type.mid( idx+1 ); type = type.left( idx ); } mMsgPart->setTypeStr(type); mMsgPart->setSubtypeStr(subtype); // apply Content-Transfer-Encoding: QByteArray cte; if ( subtype == "rfc822" && type == "message" ) { if ( encoding() != SevenBit && encoding() != EightBit ) { kWarning() << "encoding on rfc822/message must be \"7bit\" or \"8bit\""; } } switch ( encoding() ) { case SevenBit: cte = "7bit"; break; case EightBit: cte = "8bit"; break; case QuotedPrintable: cte = "quoted-printable"; break; case Base64: default: cte = "base64"; break; } if ( cte != mMsgPart->cteStr().toLower() ) { QByteArray body = mMsgPart->bodyDecodedBinary(); mMsgPart->setCteStr( cte ); mMsgPart->setBodyEncodedBinary( body ); } }
void RenderSVGText::layout() { ASSERT(needsLayout()); LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); bool updateCachedBoundariesInParents = false; if (m_needsTransformUpdate) { SVGTextElement* text = static_cast<SVGTextElement*>(node()); m_localTransform = text->animatedLocalTransform(); m_needsTransformUpdate = false; updateCachedBoundariesInParents = true; } // If the root layout size changed (eg. window size changes) or the positioning values change, recompute the on-screen font size. if (m_needsPositioningValuesUpdate || SVGRenderSupport::findTreeRootObject(this)->isLayoutSizeChanged()) { recursiveUpdateScaledFont(this); m_needsPositioningValuesUpdate = true; updateCachedBoundariesInParents = true; } if (m_needsPositioningValuesUpdate) { // Perform SVG text layout phase one (see SVGTextLayoutAttributesBuilder for details). SVGTextLayoutAttributesBuilder layoutAttributesBuilder; layoutAttributesBuilder.buildLayoutAttributesForTextSubtree(this); m_needsReordering = true; m_needsPositioningValuesUpdate = false; updateCachedBoundariesInParents = true; } // Reduced version of RenderBlock::layoutBlock(), which only takes care of SVG text. // All if branches that could cause early exit in RenderBlocks layoutBlock() method are turned into assertions. ASSERT(!isInline()); ASSERT(!simplifiedLayout()); ASSERT(!scrollsOverflow()); ASSERT(!hasControlClip()); ASSERT(!hasColumns()); ASSERT(!positionedObjects()); ASSERT(!m_overflow); ASSERT(!isAnonymousBlock()); if (!firstChild()) setChildrenInline(true); // FIXME: We need to find a way to only layout the child boxes, if needed. FloatRect oldBoundaries = objectBoundingBox(); ASSERT(childrenInline()); forceLayoutInlineChildren(); if (m_needsReordering) m_needsReordering = false; if (!updateCachedBoundariesInParents) updateCachedBoundariesInParents = oldBoundaries != objectBoundingBox(); // Invalidate all resources of this client if our layout changed. if (m_everHadLayout && selfNeedsLayout()) SVGResourcesCache::clientLayoutChanged(this); // If our bounds changed, notify the parents. if (updateCachedBoundariesInParents) RenderSVGBlock::setNeedsBoundariesUpdate(); repainter.repaintAfterLayout(); setNeedsLayout(false); }
void BitVector::clearAll() { if (isInline()) m_bitsOrPointer = makeInlineBits(0); else memset(outOfLineBits()->bits(), 0, byteCount(size())); }
DomElementType Widget::domElementType() const { return isInline() ? DomElement_SPAN : DomElement_DIV; }
void WContainerWidget::updateDom(DomElement& element, bool all) { if (all && element.type() == DomElement_LI && isInline()) element.setProperty(PropertyStyleDisplay, "inline"); if (flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED) || all) { AlignmentFlag hAlign = contentAlignment_ & AlignHorizontalMask; bool ltr = WApplication::instance()->layoutDirection() == LeftToRight; switch (hAlign) { case AlignLeft: if (flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED)) element.setProperty(PropertyStyleTextAlign, ltr ? "left" : "right"); break; case AlignRight: element.setProperty(PropertyStyleTextAlign, ltr ? "right" : "left"); break; case AlignCenter: element.setProperty(PropertyStyleTextAlign, "center"); break; case AlignJustify: #ifndef WT_NO_LAYOUT if (!layout_) #endif // WT_NO_LAYOUT element.setProperty(PropertyStyleTextAlign, "justify"); break; default: break; } if (domElementType() == DomElement_TD) { AlignmentFlag vAlign = contentAlignment_ & AlignVerticalMask; switch (vAlign) { case AlignTop: if (flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED)) element.setProperty(PropertyStyleVerticalAlign, "top"); break; case AlignMiddle: element.setProperty(PropertyStyleVerticalAlign, "middle"); break; case AlignBottom: element.setProperty(PropertyStyleVerticalAlign, "bottom"); default: break; } } } if (flags_.test(BIT_ADJUST_CHILDREN_ALIGN) || flags_.test(BIT_CONTENT_ALIGNMENT_CHANGED) || all) { /* * Welcome to CSS hell. * * Apparently, the text-align property only applies to inline elements. * To center non-inline children, the standard says to set its left and * right margin to 'auto'. * * I assume the same applies for aligning to the right ? */ for (unsigned i = 0; i < children_->size(); ++i) { WWidget *child = (*children_)[i]; if (!child->isInline()) { AlignmentFlag ha = contentAlignment_ & AlignHorizontalMask; if (ha == AlignCenter) { if (!child->margin(Left).isAuto()) child->setMargin(WLength::Auto, Left); if (!child->margin(Right).isAuto()) child->setMargin(WLength::Auto, Right); } else if (ha == AlignRight) { if (!child->margin(Left).isAuto()) child->setMargin(WLength::Auto, Left); } } } flags_.reset(BIT_CONTENT_ALIGNMENT_CHANGED); flags_.reset(BIT_ADJUST_CHILDREN_ALIGN); } if (flags_.test(BIT_PADDINGS_CHANGED) || (all && padding_ && !( padding_[0].isAuto() && padding_[1].isAuto() && padding_[2].isAuto() && padding_[3].isAuto()))) { if ((padding_[0] == padding_[1]) && (padding_[0] == padding_[2]) && (padding_[0] == padding_[3])) element.setProperty(PropertyStylePadding, padding_[0].cssText()); else element.setProperty(PropertyStylePadding, padding_[0].cssText() + " " + padding_[1].cssText() + " " + padding_[2].cssText() + " " + padding_[3].cssText()); flags_.reset(BIT_PADDINGS_CHANGED); } WInteractWidget::updateDom(element, all); if (flags_.test(BIT_OVERFLOW_CHANGED) || (all && overflow_ && !(overflow_[0] == OverflowVisible && overflow_[1] == OverflowVisible))) { static const char *cssText[] = { "visible", "auto", "hidden", "scroll" }; element.setProperty(PropertyStyleOverflowX, cssText[overflow_[0]]); element.setProperty(PropertyStyleOverflowY, cssText[overflow_[1]]); flags_.reset(BIT_OVERFLOW_CHANGED); /* If a container widget has overflow, then, if ever something * inside it has position scheme relative/absolute, it will not * scroll properly unless every element up to the container and including * the container itself has overflow: relative. * * The following fixes the common case: * container (overflow) - container - layout */ WApplication *app = WApplication::instance(); if (app->environment().agentIsIE() && (overflow_[0] == OverflowAuto || overflow_[0] == OverflowScroll)) if (positionScheme() == Static) element.setProperty(PropertyStylePosition, "relative"); } }
void LayoutSVGText::layout() { ASSERT(needsLayout()); LayoutAnalyzer::Scope analyzer(*this); subtreeStyleDidChange(); bool updateCachedBoundariesInParents = false; if (m_needsTransformUpdate) { m_localTransform = toSVGTextElement(node())->calculateAnimatedLocalTransform(); m_needsTransformUpdate = false; updateCachedBoundariesInParents = true; } if (!everHadLayout()) { // When laying out initially, collect all layout attributes, build the character data map, // and propogate resulting SVGLayoutAttributes to all LayoutSVGInlineText children in the subtree. ASSERT(m_layoutAttributes.isEmpty()); collectLayoutAttributes(this, m_layoutAttributes); updateFontInAllDescendants(this); m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(*this); m_needsReordering = true; m_needsTextMetricsUpdate = false; m_needsPositioningValuesUpdate = false; updateCachedBoundariesInParents = true; } else if (m_needsPositioningValuesUpdate) { // When the x/y/dx/dy/rotate lists change, recompute the layout attributes, and eventually // update the on-screen font objects as well in all descendants. if (m_needsTextMetricsUpdate) { updateFontInAllDescendants(this); m_needsTextMetricsUpdate = false; } m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(*this); m_needsReordering = true; m_needsPositioningValuesUpdate = false; updateCachedBoundariesInParents = true; } else if (m_needsTextMetricsUpdate || SVGLayoutSupport::findTreeRootObject(this)->isLayoutSizeChanged()) { // If the root layout size changed (eg. window size changes) or the transform to the root // context has changed then recompute the on-screen font size. updateFontInAllDescendants(this, &m_layoutAttributesBuilder); ASSERT(!m_needsReordering); ASSERT(!m_needsPositioningValuesUpdate); m_needsTextMetricsUpdate = false; updateCachedBoundariesInParents = true; } checkLayoutAttributesConsistency(this, m_layoutAttributes); // Reduced version of LayoutBlock::layoutBlock(), which only takes care of SVG text. // All if branches that could cause early exit in LayoutBlocks layoutBlock() method are turned into assertions. ASSERT(!isInline()); ASSERT(!simplifiedLayout()); ASSERT(!scrollsOverflow()); ASSERT(!hasControlClip()); ASSERT(!positionedObjects()); ASSERT(!isAnonymousBlock()); if (!firstChild()) setChildrenInline(true); // FIXME: We need to find a way to only layout the child boxes, if needed. FloatRect oldBoundaries = objectBoundingBox(); ASSERT(childrenInline()); rebuildFloatsFromIntruding(); LayoutUnit beforeEdge = borderBefore() + paddingBefore(); LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight(); setLogicalHeight(beforeEdge); LayoutState state(*this, locationOffset()); LayoutUnit paintInvalidationLogicalTop = 0; LayoutUnit paintInvalidationLogicalBottom = 0; layoutInlineChildren(true, paintInvalidationLogicalTop, paintInvalidationLogicalBottom, afterEdge); if (m_needsReordering) m_needsReordering = false; // If we don't have any line boxes, then make sure the frame rect is still cleared. if (!firstLineBox()) setFrameRect(LayoutRect()); m_overflow.clear(); addVisualEffectOverflow(); if (!updateCachedBoundariesInParents) updateCachedBoundariesInParents = oldBoundaries != objectBoundingBox(); // Invalidate all resources of this client if our layout changed. if (everHadLayout() && selfNeedsLayout()) SVGResourcesCache::clientLayoutChanged(this); // If our bounds changed, notify the parents. if (updateCachedBoundariesInParents) LayoutSVGBlock::setNeedsBoundariesUpdate(); clearNeedsLayout(); }