示例#1
0
void CameraController::updateBaseToWorldMatrix()
{
	Vec3d zAt = _testAt - _testBase;

	/* At point与Base point重合 */
	if (zAt.length2() < 1e-10)
	{
		_testBaseEyeToWorldMatrix = _testAtToWorldMatrix;
		_testBaseAtToWorldMatrix = _testAtToWorldMatrix;
		return;
	}

	Vec3d zEye = _testEye - _testBase;

	/* Eye point与Base point重合 */
	if (zEye.length2() < 1e-10)
	{
		_testBaseEyeToWorldMatrix = _testBaseEyeToWorldMatrix;
		
		Vec3d p1 = Vec3d(0, 0, 0);
		Vec3d p2 = Vec3d(1, 0, 0);
		p1 = switchCoordinateSystem_point(p1, _eyeToWorldMatrix, WORLD_MATRIX);	
		p2 = switchCoordinateSystem_point(p2, _eyeToWorldMatrix, WORLD_MATRIX);	

		Matrixd mat1, mat2, mat3, matFinal;
		mat1.makeTranslate(-p1);
		mat2.makeRotate(PI, p2-p1);
		mat3.makeTranslate(p1);
		matFinal = mat1 * mat2 * mat3;

		_testBaseAtToWorldMatrix = _testBaseEyeToWorldMatrix * matFinal;
		return;
	}

	Vec3d yEye;
	Vec3d yAt;
	if (inSameLine(_testEye, _testAt, _testBase)) // eye, at, base 三点共线
	{
		/* y轴以up向量为参照 */
		yEye = _testUp;
		yAt = _testUp;
	}
	else
	{
		/* y轴以视线为参照 */
		Vec3d sight = _testAt - _testEye;
		yEye = zEye ^ sight ^ zEye;
		yAt = zAt ^ sight ^ zAt;
	}

	_testBaseEyeToWorldMatrix = calcMatrixBasedOnAxis(_testBase, yEye, zEye);
	_testBaseAtToWorldMatrix = calcMatrixBasedOnAxis(_testBase, yAt, zAt);
}
TEST_F(VisibleUnitsTest, inSameLine)
{
    const char* bodyContent = "<p id='host'>00<b id='one'>11</b><b id='two'>22</b>33</p>";
    const char* shadowContent = "<div><span id='s4'>44</span><content select=#two></content><br><span id='s5'>55</span><br><content select=#one></content><span id='s6'>66</span></div>";
    setBodyContent(bodyContent);
    RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = setShadowContent(shadowContent);
    updateLayoutAndStyleForPainting();

    RefPtrWillBeRawPtr<Element> body = document().body();
    RefPtrWillBeRawPtr<Element> one = body->querySelector("#one", ASSERT_NO_EXCEPTION);
    RefPtrWillBeRawPtr<Element> two = body->querySelector("#two", ASSERT_NO_EXCEPTION);
    RefPtrWillBeRawPtr<Element> four = shadowRoot->querySelector("#s4", ASSERT_NO_EXCEPTION);
    RefPtrWillBeRawPtr<Element> five = shadowRoot->querySelector("#s5", ASSERT_NO_EXCEPTION);

    EXPECT_TRUE(inSameLine(positionWithAffinityInDOMTree(*one, 0), positionWithAffinityInDOMTree(*two, 0)));
    EXPECT_TRUE(inSameLine(positionWithAffinityInDOMTree(*one->firstChild(), 0), positionWithAffinityInDOMTree(*two->firstChild(), 0)));
    EXPECT_FALSE(inSameLine(positionWithAffinityInDOMTree(*one->firstChild(), 0), positionWithAffinityInDOMTree(*five->firstChild(), 0)));
    EXPECT_FALSE(inSameLine(positionWithAffinityInDOMTree(*two->firstChild(), 0), positionWithAffinityInDOMTree(*four->firstChild(), 0)));

    EXPECT_FALSE(inSameLine(positionWithAffinityInComposedTree(*one, 0), positionWithAffinityInComposedTree(*two, 0)));
    EXPECT_FALSE(inSameLine(positionWithAffinityInComposedTree(*one->firstChild(), 0), positionWithAffinityInComposedTree(*two->firstChild(), 0)));
    EXPECT_FALSE(inSameLine(positionWithAffinityInComposedTree(*one->firstChild(), 0), positionWithAffinityInComposedTree(*five->firstChild(), 0)));
    EXPECT_TRUE(inSameLine(positionWithAffinityInComposedTree(*two->firstChild(), 0), positionWithAffinityInComposedTree(*four->firstChild(), 0)));
}
示例#3
0
VisibleSelection DirectionGranularityStrategy::updateExtent(
    const IntPoint& extentPoint,
    LocalFrame* frame) {
  const VisibleSelection& selection = frame->selection().selection();

  if (m_state == StrategyState::Cleared)
    m_state = StrategyState::Expanding;

  VisiblePosition oldOffsetExtentPosition = selection.visibleExtent();
  IntPoint oldExtentLocation = positionLocation(oldOffsetExtentPosition);

  IntPoint oldOffsetExtentPoint =
      oldExtentLocation + m_diffExtentPointFromExtentPosition;
  IntPoint oldExtentPoint =
      IntPoint(oldOffsetExtentPoint.x() - m_offset, oldOffsetExtentPoint.y());

  // Apply the offset.
  IntPoint newOffsetExtentPoint = extentPoint;
  int dx = extentPoint.x() - oldExtentPoint.x();
  if (m_offset != 0) {
    if (m_offset > 0 && dx > 0)
      m_offset = std::max(0, m_offset - dx);
    else if (m_offset < 0 && dx < 0)
      m_offset = std::min(0, m_offset - dx);
    newOffsetExtentPoint.move(m_offset, 0);
  }

  VisiblePosition newOffsetExtentPosition =
      visiblePositionForContentsPoint(newOffsetExtentPoint, frame);
  IntPoint newOffsetLocation = positionLocation(newOffsetExtentPosition);

  // Reset the offset in case of a vertical change in the location (could be
  // due to a line change or due to an unusual layout, e.g. rotated text).
  bool verticalChange = newOffsetLocation.y() != oldExtentLocation.y();
  if (verticalChange) {
    m_offset = 0;
    m_granularity = CharacterGranularity;
    newOffsetExtentPoint = extentPoint;
    newOffsetExtentPosition =
        visiblePositionForContentsPoint(extentPoint, frame);
  }

  const VisiblePosition base = selection.visibleBase();

  // Do not allow empty selection.
  if (newOffsetExtentPosition.deepEquivalent() == base.deepEquivalent())
    return selection;

  // The direction granularity strategy, particularly the "offset" feature
  // doesn't work with non-horizontal text (e.g. when the text is rotated).
  // So revert to the behavior equivalent to the character granularity
  // strategy if we detect that the text's baseline coordinate changed
  // without a line change.
  if (verticalChange &&
      inSameLine(newOffsetExtentPosition, oldOffsetExtentPosition)) {
    return createVisibleSelection(selection.visibleBase(),
                                  newOffsetExtentPosition);
  }

  int oldExtentBaseOrder = selection.isBaseFirst() ? 1 : -1;

  int newExtentBaseOrder;
  bool thisMoveShrunkSelection;
  if (newOffsetExtentPosition.deepEquivalent() ==
      oldOffsetExtentPosition.deepEquivalent()) {
    if (m_granularity == CharacterGranularity)
      return selection;

    // If we are in Word granularity, we cannot exit here, since we may pass
    // the middle of the word without changing the position (in which case
    // the selection needs to expand).
    thisMoveShrunkSelection = false;
    newExtentBaseOrder = oldExtentBaseOrder;
  } else {
    bool selectionExpanded = arePositionsInSpecifiedOrder(
        newOffsetExtentPosition, oldOffsetExtentPosition, oldExtentBaseOrder);
    bool extentBaseOrderSwitched =
        selectionExpanded
            ? false
            : !arePositionsInSpecifiedOrder(newOffsetExtentPosition, base,
                                            oldExtentBaseOrder);
    newExtentBaseOrder =
        extentBaseOrderSwitched ? -oldExtentBaseOrder : oldExtentBaseOrder;

    // Determine the word boundary, i.e. the boundary extending beyond which
    // should change the granularity to WordGranularity.
    VisiblePosition wordBoundary;
    if (extentBaseOrderSwitched) {
      // Special case.
      // If the extent-base order was switched, then the selection is now
      // expanding in a different direction than before. Therefore we
      // calculate the word boundary in this new direction and based on
      // the |base| position.
      wordBoundary = nextWordBound(base, newExtentBaseOrder > 0
                                             ? SearchDirection::SearchForward
                                             : SearchDirection::SearchBackwards,
                                   BoundAdjust::NextBoundIfOnBound);
      m_granularity = CharacterGranularity;
    } else {
      // Calculate the word boundary based on |oldExtentWithGranularity|.
      // If selection was shrunk in the last update and the extent is now
      // exactly on the word boundary - we need to take the next bound as
      // the bound of the current word.
      wordBoundary = nextWordBound(oldOffsetExtentPosition,
                                   oldExtentBaseOrder > 0
                                       ? SearchDirection::SearchForward
                                       : SearchDirection::SearchBackwards,
                                   m_state == StrategyState::Shrinking
                                       ? BoundAdjust::NextBoundIfOnBound
                                       : BoundAdjust::CurrentPosIfOnBound);
    }

    bool expandedBeyondWordBoundary;
    if (selectionExpanded)
      expandedBeyondWordBoundary = arePositionsInSpecifiedOrder(
          newOffsetExtentPosition, wordBoundary, newExtentBaseOrder);
    else if (extentBaseOrderSwitched)
      expandedBeyondWordBoundary = arePositionsInSpecifiedOrder(
          newOffsetExtentPosition, wordBoundary, newExtentBaseOrder);
    else
      expandedBeyondWordBoundary = false;

    // The selection is shrunk if the extent changes position to be closer to
    // the base, and the extent/base order wasn't switched.
    thisMoveShrunkSelection = !extentBaseOrderSwitched && !selectionExpanded;

    if (expandedBeyondWordBoundary)
      m_granularity = WordGranularity;
    else if (thisMoveShrunkSelection)
      m_granularity = CharacterGranularity;
  }

  VisiblePosition newSelectionExtent = newOffsetExtentPosition;
  if (m_granularity == WordGranularity) {
    // Determine the bounds of the word where the extent is located.
    // Set the selection extent to one of the two bounds depending on
    // whether the extent is passed the middle of the word.
    VisiblePosition boundBeforeExtent =
        nextWordBound(newOffsetExtentPosition, SearchDirection::SearchBackwards,
                      BoundAdjust::CurrentPosIfOnBound);
    VisiblePosition boundAfterExtent =
        nextWordBound(newOffsetExtentPosition, SearchDirection::SearchForward,
                      BoundAdjust::CurrentPosIfOnBound);
    int xMiddleBetweenBounds = (positionLocation(boundAfterExtent).x() +
                                positionLocation(boundBeforeExtent).x()) /
                               2;
    bool offsetExtentBeforeMiddle =
        newOffsetExtentPoint.x() < xMiddleBetweenBounds;
    newSelectionExtent =
        offsetExtentBeforeMiddle ? boundBeforeExtent : boundAfterExtent;
    // Update the offset if selection expanded in word granularity.
    if (newSelectionExtent.deepEquivalent() !=
            selection.visibleExtent().deepEquivalent() &&
        ((newExtentBaseOrder > 0 && !offsetExtentBeforeMiddle) ||
         (newExtentBaseOrder < 0 && offsetExtentBeforeMiddle))) {
      m_offset = positionLocation(newSelectionExtent).x() - extentPoint.x();
    }
  }

  // Only update the state if the selection actually changed as a result of
  // this move.
  if (newSelectionExtent.deepEquivalent() !=
      selection.visibleExtent().deepEquivalent())
    m_state = thisMoveShrunkSelection ? StrategyState::Shrinking
                                      : StrategyState::Expanding;

  m_diffExtentPointFromExtentPosition =
      extentPoint + IntSize(m_offset, 0) - positionLocation(newSelectionExtent);
  VisibleSelection newSelection = selection;
  newSelection.setExtent(newSelectionExtent);
  return newSelection;
}