Пример #1
0
 /**
  * @brief Fill this entire ColumnVector with NULLs.
  **/
 inline void fillWithNulls() {
   DCHECK(null_bitmap_);
   null_bitmap_->setBitRange(0, reserved_length_, true);
   actual_length_ = reserved_length_;
 }
Пример #2
0
void BlockPainter::paintObject(const PaintInfo& paintInfo,
                               const LayoutPoint& paintOffset) {
  const PaintPhase paintPhase = paintInfo.phase;

  if (shouldPaintSelfBlockBackground(paintPhase)) {
    if (m_layoutBlock.style()->visibility() == EVisibility::Visible &&
        m_layoutBlock.hasBoxDecorationBackground())
      m_layoutBlock.paintBoxDecorationBackground(paintInfo, paintOffset);
    // We're done. We don't bother painting any children.
    if (paintPhase == PaintPhaseSelfBlockBackgroundOnly)
      return;
  }

  if (paintInfo.paintRootBackgroundOnly())
    return;

  if (paintPhase == PaintPhaseMask &&
      m_layoutBlock.style()->visibility() == EVisibility::Visible) {
    m_layoutBlock.paintMask(paintInfo, paintOffset);
    return;
  }

  if (paintPhase == PaintPhaseClippingMask &&
      m_layoutBlock.style()->visibility() == EVisibility::Visible) {
    BoxPainter(m_layoutBlock).paintClippingMask(paintInfo, paintOffset);
    return;
  }

  if (paintPhase == PaintPhaseForeground && paintInfo.isPrinting())
    ObjectPainter(m_layoutBlock).addPDFURLRectIfNeeded(paintInfo, paintOffset);

  if (paintPhase != PaintPhaseSelfOutlineOnly) {
    Optional<ScopedPaintChunkProperties> m_scopedScrollProperty;
    Optional<ScrollRecorder> scrollRecorder;
    Optional<PaintInfo> scrolledPaintInfo;
    if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
      const auto* objectProperties = m_layoutBlock.paintProperties();
      if (auto* scroll =
              objectProperties ? objectProperties->scroll() : nullptr) {
        PaintChunkProperties properties(paintInfo.context.getPaintController()
                                            .currentPaintChunkProperties());
        auto* scrollTranslation = objectProperties->scrollTranslation();
        DCHECK(scrollTranslation);
        properties.transform = scrollTranslation;
        properties.scroll = scroll;
        m_scopedScrollProperty.emplace(
            paintInfo.context.getPaintController(), m_layoutBlock,
            DisplayItem::paintPhaseToDrawingType(paintPhase), properties);
        scrolledPaintInfo.emplace(paintInfo);
        scrolledPaintInfo->updateCullRect(
            scrollTranslation->matrix().toAffineTransform());
      }
    } else if (m_layoutBlock.hasOverflowClip()) {
      IntSize scrollOffset = m_layoutBlock.scrolledContentOffset();
      if (m_layoutBlock.layer()->scrollsOverflow() || !scrollOffset.isZero()) {
        scrollRecorder.emplace(paintInfo.context, m_layoutBlock, paintPhase,
                               scrollOffset);
        scrolledPaintInfo.emplace(paintInfo);
        AffineTransform transform;
        transform.translate(-scrollOffset.width(), -scrollOffset.height());
        scrolledPaintInfo->updateCullRect(transform);
      }
    }

    const PaintInfo& contentsPaintInfo =
        scrolledPaintInfo ? *scrolledPaintInfo : paintInfo;

    if (m_layoutBlock.isLayoutBlockFlow()) {
      BlockFlowPainter blockFlowPainter(toLayoutBlockFlow(m_layoutBlock));
      blockFlowPainter.paintContents(contentsPaintInfo, paintOffset);
      if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection ||
          paintPhase == PaintPhaseTextClip)
        blockFlowPainter.paintFloats(contentsPaintInfo, paintOffset);
    } else {
      paintContents(contentsPaintInfo, paintOffset);
    }
  }

  if (shouldPaintSelfOutline(paintPhase))
    ObjectPainter(m_layoutBlock).paintOutline(paintInfo, paintOffset);

  // If the caret's node's layout object's containing block is this block, and
  // the paint action is PaintPhaseForeground, then paint the caret.
  if (paintPhase == PaintPhaseForeground && m_layoutBlock.hasCaret())
    paintCarets(paintInfo, paintOffset);
}
Пример #3
0
// static
bool HTMLIFrameElementPayments::fastHasAttribute(
    const QualifiedName& name,
    const HTMLIFrameElement& element) {
  DCHECK(name == HTMLNames::allowpaymentrequestAttr);
  return element.fastHasAttribute(name);
}
Пример #4
0
bool WebImageDecoder::isFailed() const {
  DCHECK(m_private);
  return m_private->failed();
}
Пример #5
0
WebSize WebImageDecoder::size() const {
  DCHECK(m_private);
  return m_private->size();
}
Пример #6
0
bool SelectionModifier::modify(EAlteration alter,
                               SelectionDirection direction,
                               TextGranularity granularity) {
  DCHECK(!frame()->document()->needsLayoutTreeUpdate());
  DocumentLifecycle::DisallowTransitionScope disallowTransition(
      frame()->document()->lifecycle());

  willBeModified(alter, direction);

  bool wasRange = m_selection.isRange();
  VisiblePosition originalStartPosition = m_selection.visibleStart();
  VisiblePosition position;
  switch (direction) {
    case DirectionRight:
      if (alter == FrameSelection::AlterationMove)
        position = modifyMovingRight(granularity);
      else
        position = modifyExtendingRight(granularity);
      break;
    case DirectionForward:
      if (alter == FrameSelection::AlterationExtend)
        position = modifyExtendingForward(granularity);
      else
        position = modifyMovingForward(granularity);
      break;
    case DirectionLeft:
      if (alter == FrameSelection::AlterationMove)
        position = modifyMovingLeft(granularity);
      else
        position = modifyExtendingLeft(granularity);
      break;
    case DirectionBackward:
      if (alter == FrameSelection::AlterationExtend)
        position = modifyExtendingBackward(granularity);
      else
        position = modifyMovingBackward(granularity);
      break;
  }

  if (position.isNull())
    return false;

  if (isSpatialNavigationEnabled(frame())) {
    if (!wasRange && alter == FrameSelection::AlterationMove &&
        position.deepEquivalent() == originalStartPosition.deepEquivalent())
      return false;
  }

  // Some of the above operations set an xPosForVerticalArrowNavigation.
  // Setting a selection will clear it, so save it to possibly restore later.
  // Note: the START position type is arbitrary because it is unused, it would
  // be the requested position type if there were no
  // xPosForVerticalArrowNavigation set.
  LayoutUnit x = lineDirectionPointForBlockDirectionNavigation(START);
  m_selection.setIsDirectional(shouldAlwaysUseDirectionalSelection(frame()) ||
                               alter == FrameSelection::AlterationExtend);

  switch (alter) {
    case FrameSelection::AlterationMove:
      m_selection = createVisibleSelection(
          SelectionInDOMTree::Builder()
              .collapse(position.toPositionWithAffinity())
              .setIsDirectional(m_selection.isDirectional())
              .build());
      break;
    case FrameSelection::AlterationExtend:

      if (!m_selection.isCaret() && (granularity == WordGranularity ||
                                     granularity == ParagraphGranularity ||
                                     granularity == LineGranularity) &&
          frame() &&
          !frame()
               ->editor()
               .behavior()
               .shouldExtendSelectionByWordOrLineAcrossCaret()) {
        // Don't let the selection go across the base position directly. Needed
        // to match mac behavior when, for instance, word-selecting backwards
        // starting with the caret in the middle of a word and then
        // word-selecting forward, leaving the caret in the same place where it
        // was, instead of directly selecting to the end of the word.
        VisibleSelection newSelection = m_selection;
        newSelection.setExtent(position);
        if (m_selection.isBaseFirst() != newSelection.isBaseFirst())
          position = m_selection.visibleBase();
      }

      // Standard Mac behavior when extending to a boundary is grow the
      // selection rather than leaving the base in place and moving the
      // extent. Matches NSTextView.
      if (!frame() ||
          !frame()
               ->editor()
               .behavior()
               .shouldAlwaysGrowSelectionWhenExtendingToBoundary() ||
          m_selection.isCaret() || !isBoundary(granularity)) {
        m_selection.setExtent(position);
      } else {
        TextDirection textDirection = directionOfEnclosingBlock();
        if (direction == DirectionForward ||
            (textDirection == LTR && direction == DirectionRight) ||
            (textDirection == RTL && direction == DirectionLeft))
          setSelectionEnd(&m_selection, position);
        else
          setSelectionStart(&m_selection, position);
      }
      break;
  }

  if (granularity == LineGranularity || granularity == ParagraphGranularity)
    m_xPosForVerticalArrowNavigation = x;

  return true;
}
Пример #7
0
PointerEvent* PointerEventFactory::create(
    const AtomicString& mouseEventName,
    const PlatformMouseEvent& mouseEvent,
    const Vector<PlatformMouseEvent>& coalescedMouseEvents,
    LocalDOMWindow* view) {
  DCHECK(mouseEventName == EventTypeNames::mousemove ||
         mouseEventName == EventTypeNames::mousedown ||
         mouseEventName == EventTypeNames::mouseup);

  AtomicString pointerEventName =
      pointerEventNameForMouseEventName(mouseEventName);
  DCHECK(pointerEventName == EventTypeNames::pointermove ||
         coalescedMouseEvents.isEmpty());

  unsigned buttons =
      MouseEvent::platformModifiersToButtons(mouseEvent.getModifiers());
  PointerEventInit pointerEventInit;

  setIdTypeButtons(pointerEventInit, mouseEvent.pointerProperties(), buttons);
  setEventSpecificFields(pointerEventInit, pointerEventName);

  if (pointerEventName == EventTypeNames::pointerdown ||
      pointerEventName == EventTypeNames::pointerup) {
    WebPointerProperties::Button button = mouseEvent.pointerProperties().button;
    // TODO(mustaq): Fix when the spec starts supporting hovering erasers.
    if (mouseEvent.pointerProperties().pointerType ==
            WebPointerProperties::PointerType::Eraser &&
        button == WebPointerProperties::Button::Left)
      button = WebPointerProperties::Button::Eraser;
    pointerEventInit.setButton(static_cast<int>(button));
  } else {
    DCHECK(pointerEventName == EventTypeNames::pointermove);
    pointerEventInit.setButton(
        static_cast<int>(WebPointerProperties::Button::NoButton));
  }

  UIEventWithKeyState::setFromPlatformModifiers(pointerEventInit,
                                                mouseEvent.getModifiers());

  // Make sure chorded buttons fire pointermove instead of pointerup/down.
  if ((pointerEventName == EventTypeNames::pointerdown &&
       (buttons &
        ~buttonToButtonsBitfield(mouseEvent.pointerProperties().button)) !=
           0) ||
      (pointerEventName == EventTypeNames::pointerup && buttons != 0))
    pointerEventName = EventTypeNames::pointermove;

  pointerEventInit.setView(view);

  updateMousePointerEventInit(mouseEvent, view, &pointerEventInit);

  // Created coalesced events init structure
  HeapVector<Member<PointerEvent>> coalescedPointerEvents;
  for (const auto& coalescedMouseEvent : coalescedMouseEvents) {
    DCHECK_EQ(mouseEvent.pointerProperties().id,
              coalescedMouseEvent.pointerProperties().id);
    DCHECK_EQ(mouseEvent.pointerProperties().pointerType,
              coalescedMouseEvent.pointerProperties().pointerType);
    PointerEventInit coalescedEventInit = pointerEventInit;
    updateMousePointerEventInit(coalescedMouseEvent, view, &coalescedEventInit);
    coalescedPointerEvents.append(
        PointerEvent::create(pointerEventName, coalescedEventInit));
  }
  pointerEventInit.setCoalescedEvents(coalescedPointerEvents);

  return PointerEvent::create(pointerEventName, pointerEventInit);
}
Пример #8
0
 /**
  * @brief Overwrite the value at the specified position with the supplied
  *        TypedValue.
  * @warning You must call prepareForPositionalWrites() BEFORE calling this
  *          method.
  * @warning Do NOT use positional writes in combination with appends.
  *
  * @param position The position of the value in this IndirectColumnVector to
  *        overwrite.
  * @param value A TypedValue to write into this IndirectColumnVector.
  **/
 inline void positionalWriteTypedValue(const std::size_t position,
                                       TypedValue &&value) {  // NOLINT(whitespace/operators)
   DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
   DCHECK_LT(position, values_.size());
   values_[position] = std::move(value);
 }
Пример #9
0
bool SVGClipPainter::prepareEffect(const LayoutObject& target,
                                   const FloatRect& targetBoundingBox,
                                   const FloatRect& visualRect,
                                   const FloatPoint& layerPositionOffset,
                                   GraphicsContext& context,
                                   ClipperState& clipperState) {
  DCHECK_EQ(clipperState, ClipperState::NotApplied);
  SECURITY_DCHECK(!m_clip.needsLayout());

  m_clip.clearInvalidationMask();

  if (m_clip.hasCycle())
    return false;

  SVGClipExpansionCycleHelper inClipExpansionChange(m_clip);

  AffineTransform animatedLocalTransform =
      toSVGClipPathElement(m_clip.element())
          ->calculateTransform(SVGElement::IncludeMotionTransform);
  // When drawing a clip for non-SVG elements, the CTM does not include the zoom
  // factor.  In this case, we need to apply the zoom scale explicitly - but
  // only for clips with userSpaceOnUse units (the zoom is accounted for
  // objectBoundingBox-resolved lengths).
  if (!target.isSVG() &&
      m_clip.clipPathUnits() == SVGUnitTypes::kSvgUnitTypeUserspaceonuse) {
    DCHECK(m_clip.style());
    animatedLocalTransform.scale(m_clip.style()->effectiveZoom());
  }

  // First, try to apply the clip as a clipPath.
  Path clipPath;
  if (m_clip.asPath(animatedLocalTransform, targetBoundingBox, clipPath)) {
    AffineTransform positionTransform;
    positionTransform.translate(layerPositionOffset.x(),
                                layerPositionOffset.y());
    clipPath.transform(positionTransform);
    clipperState = ClipperState::AppliedPath;
    context.getPaintController().createAndAppend<BeginClipPathDisplayItem>(
        target, clipPath);
    return true;
  }

  // Fall back to masking.
  clipperState = ClipperState::AppliedMask;

  // Begin compositing the clip mask.
  CompositingRecorder::beginCompositing(context, target, SkBlendMode::kSrcOver,
                                        1, &visualRect);
  {
    if (!drawClipAsMask(context, target, targetBoundingBox, visualRect,
                        animatedLocalTransform, layerPositionOffset)) {
      // End the clip mask's compositor.
      CompositingRecorder::endCompositing(context, target);
      return false;
    }
  }

  // Masked content layer start.
  CompositingRecorder::beginCompositing(context, target, SkBlendMode::kSrcIn, 1,
                                        &visualRect);

  return true;
}
Пример #10
0
 /**
  * @brief Prepare this IndirectColumnVector for positional writes.
  *        Effectively "fills" this IndirectColumnVector with uninitialized
  *        values that will be overwritten with calls to
  *        positionalWriteTypedValue().
  * @warning Do NOT use positional writes in combination with appends.
  **/
 inline void prepareForPositionalWrites() {
   DCHECK(values_.empty());
   values_.resize(reserved_length_);
 }
Пример #11
0
 /**
  * @brief Overwrite the value at the specified position with the supplied
  *        TypedValue.
  * @warning You must call prepareForPositionalWrites() BEFORE calling this
  *          method.
  * @warning Do NOT use positional writes in combination with appends.
  *
  * @param position The position of the value in this IndirectColumnVector to
  *        overwrite.
  * @param value A TypedValue to write into this IndirectColumnVector.
  **/
 inline void positionalWriteTypedValue(const std::size_t position,
                                       const TypedValue &value) {
   DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
   DCHECK_LT(position, values_.size());
   values_[position] = value;
 }
Пример #12
0
 /**
  * @brief Fill this entire ColumnVector with copies of value.
  *
  * @param value A value to fill this ColumnVector with.
  **/
 inline void fillWithValue(const TypedValue &value) {
   DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
   values_.assign(reserved_length_, value);
 }
Пример #13
0
 /**
  * @brief Append a TypedValue to this IndirectColumnVector.
  *
  * @param value A value to append to this NativeColumnVector.
  **/
 inline void appendTypedValue(TypedValue &&value) {
   DCHECK(value.isPlausibleInstanceOf(type_.getSignature()));
   DCHECK_LT(values_.size(), reserved_length_);
   values_.emplace_back(std::move(value));
 }
Пример #14
0
 /**
  * @brief Overwrite the value at the specified position with a NULL value.
  * @warning You must call prepareForPositionalWrites() BEFORE calling this
  *          method.
  * @warning Do NOT use positional writes in combination with appends.
  * @warning It is intended that this and other positional write methods
  *          should be called exactly once for each position (if this is
  *          violated, NULLs may not be tracked properly).
  *
  * @param position The position of the value in this NativeColumnVector to
  *        overwrite with a NULL value.
  **/
 inline void positionalWriteNullValue(const std::size_t position) {
   DCHECK_LT(position, actual_length_);
   DCHECK(null_bitmap_);
   null_bitmap_->setBit(position, true);
 }
Пример #15
0
bool CSSStyleSheet::sheetLoaded() {
  DCHECK(m_ownerNode);
  setLoadCompleted(m_ownerNode->sheetLoaded());
  return m_loadCompleted;
}
Пример #16
0
void RangeInputType::handleKeydownEvent(KeyboardEvent* event) {
  if (element().isDisabledOrReadOnly())
    return;

  const String& key = event->key();

  const Decimal current = parseToNumberOrNaN(element().value());
  DCHECK(current.isFinite());

  StepRange stepRange(createStepRange(RejectAny));

  // FIXME: We can't use stepUp() for the step value "any". So, we increase
  // or decrease the value by 1/100 of the value range. Is it reasonable?
  const Decimal step =
      equalIgnoringCase(element().fastGetAttribute(stepAttr), "any")
          ? (stepRange.maximum() - stepRange.minimum()) / 100
          : stepRange.step();
  const Decimal bigStep =
      std::max((stepRange.maximum() - stepRange.minimum()) / 10, step);

  TextDirection dir = LTR;
  bool isVertical = false;
  if (element().layoutObject()) {
    dir = computedTextDirection();
    ControlPart part = element().layoutObject()->style()->appearance();
    isVertical = part == SliderVerticalPart;
  }

  Decimal newValue;
  if (key == "ArrowUp")
    newValue = current + step;
  else if (key == "ArrowDown")
    newValue = current - step;
  else if (key == "ArrowLeft")
    newValue = (isVertical || dir == RTL) ? current + step : current - step;
  else if (key == "ArrowRight")
    newValue = (isVertical || dir == RTL) ? current - step : current + step;
  else if (key == "PageUp")
    newValue = current + bigStep;
  else if (key == "PageDown")
    newValue = current - bigStep;
  else if (key == "Home")
    newValue = isVertical ? stepRange.maximum() : stepRange.minimum();
  else if (key == "End")
    newValue = isVertical ? stepRange.minimum() : stepRange.maximum();
  else
    return;  // Did not match any key binding.

  newValue = stepRange.clampValue(newValue);

  if (newValue != current) {
    EventQueueScope scope;
    TextFieldEventBehavior eventBehavior = DispatchInputAndChangeEvent;
    setValueAsDecimal(newValue, eventBehavior, IGNORE_EXCEPTION);

    if (AXObjectCache* cache = element().document().existingAXObjectCache())
      cache->handleValueChanged(&element());
  }

  event->setDefaultHandled();
}
Пример #17
0
CSSStyleSheet* CSSStyleSheet::createInline(StyleSheetContents* sheet,
                                           Node& ownerNode,
                                           const TextPosition& startPosition) {
  DCHECK(sheet);
  return new CSSStyleSheet(sheet, ownerNode, true, startPosition);
}
Пример #18
0
    void OutputWidget::addChild(FastoObject* child)
    {
        DCHECK(child->parent());

        FastoObjectCommand* command = dynamic_cast<FastoObjectCommand*>(child);
        if(command){
            return;
        }

        command = dynamic_cast<FastoObjectCommand*>(child->parent());
        if(command){

            void* parentinner = command->parent();

            QModelIndex parent;
            bool isFound = commonModel_->findItem(parentinner, parent);
            if(!isFound){
                return;
            }

            fastoredis::FastoCommonItem* par = NULL;
            if(!parent.isValid()){
                par = static_cast<fastoredis::FastoCommonItem*>(commonModel_->root());
            }
            else{
                par = common::utils_qt::item<fastoredis::FastoCommonItem*>(parent);
            }

            DCHECK(par);
            if(!par){
                return;
            }

            const QString key = common::convertFromString<QString>(command->inputArgs());

            fastoredis::FastoCommonItem* comChild = createItem(par, key, child);
            comChild->setChangeCommand(command->oppositeCommand());
            commonModel_->insertItem(parent, comChild);
        }
        else{
            FastoObjectArray* arr = dynamic_cast<FastoObjectArray*>(child->parent());
            if(arr){
                QModelIndex parent;
                bool isFound = commonModel_->findItem(arr, parent);
                if(!isFound){
                    return;
                }

                fastoredis::FastoCommonItem* par = NULL;
                if(!parent.isValid()){
                    par = static_cast<fastoredis::FastoCommonItem*>(commonModel_->root());
                }
                else{
                    par = common::utils_qt::item<fastoredis::FastoCommonItem*>(parent);
                }

                DCHECK(par);
                if(!par){
                    return;
                }

                fastoredis::FastoCommonItem* comChild = createItem(par, QString(), child);
                commonModel_->insertItem(parent, comChild);
            }
            else{
                NOTREACHED();
            }
        }
    }
Пример #19
0
bool SelectionModifier::modifyWithPageGranularity(EAlteration alter,
                                                  unsigned verticalDistance,
                                                  VerticalDirection direction) {
  if (!verticalDistance)
    return false;

  DCHECK(!frame()->document()->needsLayoutTreeUpdate());
  DocumentLifecycle::DisallowTransitionScope disallowTransition(
      frame()->document()->lifecycle());

  willBeModified(alter, direction == FrameSelection::DirectionUp
                            ? DirectionBackward
                            : DirectionForward);

  VisiblePosition pos;
  LayoutUnit xPos;
  switch (alter) {
    case FrameSelection::AlterationMove:
      pos = createVisiblePosition(direction == FrameSelection::DirectionUp
                                      ? m_selection.start()
                                      : m_selection.end(),
                                  m_selection.affinity());
      xPos = lineDirectionPointForBlockDirectionNavigation(
          direction == FrameSelection::DirectionUp ? START : END);
      m_selection.setAffinity(direction == FrameSelection::DirectionUp
                                  ? TextAffinity::Upstream
                                  : TextAffinity::Downstream);
      break;
    case FrameSelection::AlterationExtend:
      pos = createVisiblePosition(m_selection.extent(), m_selection.affinity());
      xPos = lineDirectionPointForBlockDirectionNavigation(EXTENT);
      m_selection.setAffinity(TextAffinity::Downstream);
      break;
  }

  int startY;
  if (!absoluteCaretY(pos, startY))
    return false;
  if (direction == FrameSelection::DirectionUp)
    startY = -startY;
  int lastY = startY;

  VisiblePosition result;
  VisiblePosition next;
  for (VisiblePosition p = pos;; p = next) {
    if (direction == FrameSelection::DirectionUp)
      next = previousLinePosition(p, xPos);
    else
      next = nextLinePosition(p, xPos);

    if (next.isNull() || next.deepEquivalent() == p.deepEquivalent())
      break;
    int nextY;
    if (!absoluteCaretY(next, nextY))
      break;
    if (direction == FrameSelection::DirectionUp)
      nextY = -nextY;
    if (nextY - startY > static_cast<int>(verticalDistance))
      break;
    if (nextY >= lastY) {
      lastY = nextY;
      result = next;
    }
  }

  if (result.isNull())
    return false;

  switch (alter) {
    case FrameSelection::AlterationMove:
      m_selection = createVisibleSelection(
          SelectionInDOMTree::Builder()
              .collapse(result.toPositionWithAffinity())
              .setIsDirectional(m_selection.isDirectional())
              .build());
      break;
    case FrameSelection::AlterationExtend:
      m_selection.setExtent(result);
      break;
  }

  m_selection.setIsDirectional(shouldAlwaysUseDirectionalSelection(frame()) ||
                               alter == FrameSelection::AlterationExtend);

  return true;
}
Пример #20
0
static void sortBlock(unsigned from,
                      unsigned to,
                      HeapVector<NodeSetVector>& parentMatrix,
                      bool mayContainAttributeNodes) {
  // Should not call this function with less that two nodes to sort.
  DCHECK_LT(from + 1, to);
  unsigned minDepth = UINT_MAX;
  for (unsigned i = from; i < to; ++i) {
    unsigned depth = parentMatrix[i].size() - 1;
    if (minDepth > depth)
      minDepth = depth;
  }

  // Find the common ancestor.
  unsigned commonAncestorDepth = minDepth;
  Node* commonAncestor;
  while (true) {
    commonAncestor = parentWithDepth(commonAncestorDepth, parentMatrix[from]);
    if (commonAncestorDepth == 0)
      break;

    bool allEqual = true;
    for (unsigned i = from + 1; i < to; ++i) {
      if (commonAncestor !=
          parentWithDepth(commonAncestorDepth, parentMatrix[i])) {
        allEqual = false;
        break;
      }
    }
    if (allEqual)
      break;

    --commonAncestorDepth;
  }

  if (commonAncestorDepth == minDepth) {
    // One of the nodes is the common ancestor => it is the first in
    // document order. Find it and move it to the beginning.
    for (unsigned i = from; i < to; ++i) {
      if (commonAncestor == parentMatrix[i][0]) {
        parentMatrix[i].swap(parentMatrix[from]);
        if (from + 2 < to)
          sortBlock(from + 1, to, parentMatrix, mayContainAttributeNodes);
        return;
      }
    }
  }

  if (mayContainAttributeNodes && commonAncestor->isElementNode()) {
    // The attribute nodes and namespace nodes of an element occur before
    // the children of the element. The namespace nodes are defined to occur
    // before the attribute nodes. The relative order of namespace nodes is
    // implementation-dependent. The relative order of attribute nodes is
    // implementation-dependent.
    unsigned sortedEnd = from;
    // FIXME: namespace nodes are not implemented.
    for (unsigned i = sortedEnd; i < to; ++i) {
      Node* n = parentMatrix[i][0];
      if (n->isAttributeNode() && toAttr(n)->ownerElement() == commonAncestor)
        parentMatrix[i].swap(parentMatrix[sortedEnd++]);
    }
    if (sortedEnd != from) {
      if (to - sortedEnd > 1)
        sortBlock(sortedEnd, to, parentMatrix, mayContainAttributeNodes);
      return;
    }
  }

  // Children nodes of the common ancestor induce a subdivision of our
  // node-set. Sort it according to this subdivision, and recursively sort
  // each group.
  HeapHashSet<Member<Node>> parentNodes;
  for (unsigned i = from; i < to; ++i)
    parentNodes.add(parentWithDepth(commonAncestorDepth + 1, parentMatrix[i]));

  unsigned previousGroupEnd = from;
  unsigned groupEnd = from;
  for (Node* n = commonAncestor->firstChild(); n; n = n->nextSibling()) {
    // If parentNodes contains the node, perform a linear search to move its
    // children in the node-set to the beginning.
    if (parentNodes.contains(n)) {
      for (unsigned i = groupEnd; i < to; ++i) {
        if (parentWithDepth(commonAncestorDepth + 1, parentMatrix[i]) == n)
          parentMatrix[i].swap(parentMatrix[groupEnd++]);
      }

      if (groupEnd - previousGroupEnd > 1)
        sortBlock(previousGroupEnd, groupEnd, parentMatrix,
                  mayContainAttributeNodes);

      DCHECK_NE(previousGroupEnd, groupEnd);
      previousGroupEnd = groupEnd;
#if DCHECK_IS_ON()
      parentNodes.remove(n);
#endif
    }
  }

  DCHECK(parentNodes.isEmpty());
}
Пример #21
0
void WebImageDecoder::setData(const WebData& data, bool allDataReceived) {
  DCHECK(m_private);
  m_private->setData(PassRefPtr<SharedBuffer>(data).get(), allDataReceived);
}
Пример #22
0
TypedValue TypedValue::ReconstructFromProto(const serialization::TypedValue &proto) {
  DCHECK(ProtoIsValid(proto))
      << "Attempted to create TypedValue from an invalid proto description:\n"
      << proto.DebugString();

  switch (proto.type_id()) {
    case serialization::Type::INT:
      return proto.has_int_value() ?
          TypedValue(static_cast<int>(proto.int_value())) :
          TypedValue(kInt);
    case serialization::Type::LONG:
      return proto.has_long_value() ?
          TypedValue(static_cast<std::int64_t>(proto.long_value())) :
          TypedValue(kLong);
    case serialization::Type::FLOAT:
      return proto.has_float_value() ?
          TypedValue(static_cast<float>(proto.float_value())) :
          TypedValue(kFloat);
    case serialization::Type::DOUBLE:
      return proto.has_double_value() ?
          TypedValue(static_cast<double>(proto.double_value())) :
          TypedValue(kDouble);
    case serialization::Type::DATETIME:
      if (proto.has_datetime_value()) {
        DatetimeLit datetime;
        datetime.ticks = proto.datetime_value();
        return TypedValue(datetime);
      } else {
        return TypedValue(kDatetime);
      }
    case serialization::Type::DATETIME_INTERVAL:
      if (proto.has_datetime_interval_value()) {
        DatetimeIntervalLit interval;
        interval.interval_ticks = proto.datetime_interval_value();
        return TypedValue(interval);
      } else {
        return TypedValue(kDatetimeInterval);
      }
    case serialization::Type::YEAR_MONTH_INTERVAL:
      if (proto.has_year_month_interval_value()) {
        YearMonthIntervalLit interval;
        interval.months = proto.year_month_interval_value();
        return TypedValue(interval);
      } else {
        return TypedValue(kYearMonthInterval);
      }
    case serialization::Type::CHAR:
      return proto.has_out_of_line_data() ?
          TypedValue(kChar,
                     static_cast<const void*>(proto.out_of_line_data().c_str()),
                     proto.out_of_line_data().size()).ensureNotReference() :
          TypedValue(kChar);
    case serialization::Type::VAR_CHAR:
      return proto.has_out_of_line_data() ?
          TypedValue(kVarChar,
                     static_cast<const void*>(proto.out_of_line_data().c_str()),
                     proto.out_of_line_data().size()).ensureNotReference() :
          TypedValue(kVarChar);
    case serialization::Type::NULL_TYPE:
      return TypedValue(kNullType);
    default:
      FATAL_ERROR("Unrecognized TypeID in TypedValue::ReconstructFromProto");
  }
}
Пример #23
0
bool WebImageDecoder::isSizeAvailable() const {
  DCHECK(m_private);
  return m_private->isSizeAvailable();
}
Пример #24
0
serialization::TypedValue TypedValue::getProto() const {
  serialization::TypedValue proto;

  // NOTE(chasseur): To represent a NULL value, only the 'type_id' field of the
  // proto is filled in, and all the optional value fields are omitted.
  switch (getTypeID()) {
    case kInt:
      proto.set_type_id(serialization::Type::INT);
      if (!isNull()) {
        proto.set_int_value(getLiteral<int>());
      }
      break;
    case kLong:
      proto.set_type_id(serialization::Type::LONG);
      if (!isNull()) {
        proto.set_long_value(getLiteral<std::int64_t>());
      }
      break;
    case kFloat:
      proto.set_type_id(serialization::Type::FLOAT);
      if (!isNull()) {
        proto.set_float_value(getLiteral<float>());
      }
      break;
    case kDouble:
      proto.set_type_id(serialization::Type::DOUBLE);
      if (!isNull()) {
        proto.set_double_value(getLiteral<double>());
      }
      break;
    case kDatetime:
      proto.set_type_id(serialization::Type::DATETIME);
      if (!isNull()) {
        proto.set_datetime_value(value_union_.datetime_value.ticks);
      }
      break;
    case kDatetimeInterval:
      proto.set_type_id(serialization::Type::DATETIME_INTERVAL);
      if (!isNull()) {
        proto.set_datetime_interval_value(value_union_.datetime_interval_value.interval_ticks);
      }
      break;
    case kYearMonthInterval:
      proto.set_type_id(serialization::Type::YEAR_MONTH_INTERVAL);
      if (!isNull()) {
        proto.set_year_month_interval_value(value_union_.year_month_interval_value.months);
      }
      break;
    case kChar:
      proto.set_type_id(serialization::Type::CHAR);
      if (!isNull()) {
        proto.set_out_of_line_data(static_cast<const char*>(getOutOfLineData()), getDataSize());
      }
      break;
    case kVarChar:
      proto.set_type_id(serialization::Type::VAR_CHAR);
      if (!isNull()) {
        proto.set_out_of_line_data(static_cast<const char*>(getOutOfLineData()), getDataSize());
      }
      break;
    case kNullType:
      proto.set_type_id(serialization::Type::NULL_TYPE);
      DCHECK(isNull());
      break;
    default:
      FATAL_ERROR("Unrecognized TypeID in TypedValue::getProto");
  }

  return proto;
}
Пример #25
0
size_t WebImageDecoder::frameCount() const {
  DCHECK(m_private);
  return m_private->frameCount();
}
Пример #26
0
void ViewPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo) {
  if (paintInfo.skipRootBackground())
    return;

  // This function overrides background painting for the LayoutView.
  // View background painting is special in the following ways:
  // 1. The view paints background for the root element, the background
  //    positioning respects the positioning and transformation of the root
  //    element.
  // 2. CSS background-clip is ignored, the background layers always expand to
  //    cover the whole canvas. None of the stacking context effects (except
  //    transformation) on the root element affects the background.
  // 3. The main frame is also responsible for painting the user-agent-defined
  //    base background color. Conceptually it should be painted by the embedder
  //    but painting it here allows culling and pre-blending optimization when
  //    possible.

  GraphicsContext& context = paintInfo.context;
  if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
          context, m_layoutView, DisplayItem::kDocumentBackground))
    return;

  // The background fill rect is the size of the LayoutView's main
  // GraphicsLayer.
  IntRect backgroundRect =
      pixelSnappedIntRect(m_layoutView.layer()->boundingBoxForCompositing());
  const Document& document = m_layoutView.document();
  const FrameView& frameView = *m_layoutView.frameView();
  bool isMainFrame = document.isInMainFrame();
  bool paintsBaseBackground = isMainFrame && !frameView.isTransparent();
  bool shouldClearCanvas =
      paintsBaseBackground &&
      (document.settings() &&
       document.settings()->shouldClearDocumentBackground());
  Color baseBackgroundColor =
      paintsBaseBackground ? frameView.baseBackgroundColor() : Color();
  Color rootBackgroundColor =
      m_layoutView.style()->visitedDependentColor(CSSPropertyBackgroundColor);
  const LayoutObject* rootObject =
      document.documentElement() ? document.documentElement()->layoutObject()
                                 : nullptr;

  LayoutObjectDrawingRecorder recorder(
      context, m_layoutView, DisplayItem::kDocumentBackground, backgroundRect);

  // Special handling for print economy mode.
  bool forceBackgroundToWhite =
      BoxPainter::shouldForceWhiteBackgroundForPrintEconomy(
          m_layoutView.styleRef(), document);
  if (forceBackgroundToWhite) {
    // If for any reason the view background is not transparent, paint white
    // instead, otherwise keep transparent as is.
    if (paintsBaseBackground || rootBackgroundColor.alpha() ||
        m_layoutView.style()->backgroundLayers().image())
      context.fillRect(backgroundRect, Color::white, SkBlendMode::kSrc);
    return;
  }

  // Compute the enclosing rect of the view, in root element space.
  //
  // For background colors we can simply paint the document rect in the default
  // space.  However for background image, the root element transform applies.
  // The strategy is to apply root element transform on the context and issue
  // draw commands in the local space, therefore we need to apply inverse
  // transform on the document rect to get to the root element space.
  bool backgroundRenderable = true;
  TransformationMatrix transform;
  IntRect paintRect = backgroundRect;
  if (!rootObject || !rootObject->isBox()) {
    backgroundRenderable = false;
  } else if (rootObject->hasLayer()) {
    const PaintLayer& rootLayer = *toLayoutBoxModelObject(rootObject)->layer();
    LayoutPoint offset;
    rootLayer.convertToLayerCoords(nullptr, offset);
    transform.translate(offset.x(), offset.y());
    transform.multiply(
        rootLayer.renderableTransform(paintInfo.getGlobalPaintFlags()));

    if (!transform.isInvertible()) {
      backgroundRenderable = false;
    } else {
      bool isClamped;
      paintRect = transform.inverse()
                      .projectQuad(FloatQuad(backgroundRect), &isClamped)
                      .enclosingBoundingBox();
      backgroundRenderable = !isClamped;
    }
  }

  if (!backgroundRenderable) {
    if (baseBackgroundColor.alpha()) {
      context.fillRect(
          backgroundRect, baseBackgroundColor,
          shouldClearCanvas ? SkBlendMode::kSrc : SkBlendMode::kSrcOver);
    } else if (shouldClearCanvas) {
      context.fillRect(backgroundRect, Color(), SkBlendMode::kClear);
    }
    return;
  }

  BoxPainter::FillLayerOcclusionOutputList reversedPaintList;
  bool shouldDrawBackgroundInSeparateBuffer =
      BoxPainter(m_layoutView)
          .calculateFillLayerOcclusionCulling(
              reversedPaintList, m_layoutView.style()->backgroundLayers());
  DCHECK(reversedPaintList.size());

  // If the root background color is opaque, isolation group can be skipped
  // because the canvas
  // will be cleared by root background color.
  if (!rootBackgroundColor.hasAlpha())
    shouldDrawBackgroundInSeparateBuffer = false;

  // We are going to clear the canvas with transparent pixels, isolation group
  // can be skipped.
  if (!baseBackgroundColor.alpha() && shouldClearCanvas)
    shouldDrawBackgroundInSeparateBuffer = false;

  if (shouldDrawBackgroundInSeparateBuffer) {
    if (baseBackgroundColor.alpha()) {
      context.fillRect(
          backgroundRect, baseBackgroundColor,
          shouldClearCanvas ? SkBlendMode::kSrc : SkBlendMode::kSrcOver);
    }
    context.beginLayer();
  }

  Color combinedBackgroundColor =
      shouldDrawBackgroundInSeparateBuffer
          ? rootBackgroundColor
          : baseBackgroundColor.blend(rootBackgroundColor);
  if (combinedBackgroundColor.alpha()) {
    if (!combinedBackgroundColor.hasAlpha() &&
        RuntimeEnabledFeatures::slimmingPaintV2Enabled())
      recorder.setKnownToBeOpaque();
    context.fillRect(backgroundRect, combinedBackgroundColor,
                     (shouldDrawBackgroundInSeparateBuffer || shouldClearCanvas)
                         ? SkBlendMode::kSrc
                         : SkBlendMode::kSrcOver);
  } else if (shouldClearCanvas && !shouldDrawBackgroundInSeparateBuffer) {
    context.fillRect(backgroundRect, Color(), SkBlendMode::kClear);
  }

  for (auto it = reversedPaintList.rbegin(); it != reversedPaintList.rend();
       ++it) {
    DCHECK((*it)->clip() == BorderFillBox);

    bool shouldPaintInViewportSpace =
        (*it)->attachment() == FixedBackgroundAttachment;
    if (shouldPaintInViewportSpace) {
      BoxPainter::paintFillLayer(m_layoutView, paintInfo, Color(), **it,
                                 LayoutRect(LayoutRect::infiniteIntRect()),
                                 BackgroundBleedNone);
    } else {
      context.save();
      // TODO(trchen): We should be able to handle 3D-transformed root
      // background with slimming paint by using transform display items.
      context.concatCTM(transform.toAffineTransform());
      BoxPainter::paintFillLayer(m_layoutView, paintInfo, Color(), **it,
                                 LayoutRect(paintRect), BackgroundBleedNone);
      context.restore();
    }
  }

  if (shouldDrawBackgroundInSeparateBuffer)
    context.endLayer();
}
Пример #27
0
void BlockPainter::paintContents(const PaintInfo& paintInfo,
                                 const LayoutPoint& paintOffset) {
  DCHECK(!m_layoutBlock.childrenInline());
  PaintInfo paintInfoForDescendants = paintInfo.forDescendants();
  m_layoutBlock.paintChildren(paintInfoForDescendants, paintOffset);
}
Пример #28
0
void CSSStyleSheet::didMutateRules() {
  DCHECK(m_contents->isMutable());
  DCHECK_LE(m_contents->clientSize(), 1u);

  didMutate(PartialRuleUpdate);
}
Пример #29
0
// static
void HTMLIFrameElementPayments::setBooleanAttribute(const QualifiedName& name,
                                                    HTMLIFrameElement& element,
                                                    bool value) {
  DCHECK(name == HTMLNames::allowpaymentrequestAttr);
  element.setBooleanAttribute(name, value);
}
Пример #30
0
 /**
  * @brief Append a NULL value to this NativeColumnVector.
  * @warning Appending a new value must not cause the number of values in this
  *          NativeColumnVector to exceed the reserved length supplied to the
  *          constructor.
  **/
 inline void appendNullValue() {
   DCHECK_LT(actual_length_, reserved_length_);
   DCHECK(null_bitmap_);
   null_bitmap_->setBit(actual_length_, true);
   ++actual_length_;
 }