Example #1
0
void RenderTextTrackCue::repositionCueSnapToLinesSet()
{
    InlineFlowBox* firstLineBox;
    LayoutUnit step;
    LayoutUnit position;
    if (!initializeLayoutParameters(firstLineBox, step, position))
        return;

    bool switched;
    placeBoxInDefaultPosition(position, switched);

    // 11. Step loop: If none of the boxes in boxes would overlap any of the boxes
    // in output and all the boxes in output are within the video's rendering area
    // then jump to the step labeled done positioning.
    while (isOutside() || isOverlapping()) {
        if (!shouldSwitchDirection(firstLineBox, step))
            // 13. Move all the boxes in boxes ...
            // 14. Jump back to the step labeled step loop.
            moveBoxesByStep(step);
        else if (!switchDirection(switched, step))
            break;

        // 19. Jump back to the step labeled step loop.
    }

    // Acommodate extra top and bottom padding, border or margin.
    // Note: this is supported only for internal UA styling, not through the cue selector.
    if (hasInlineDirectionBordersPaddingOrMargin())
        moveIfNecessaryToKeepWithinContainer();
}
Example #2
0
	void Body::update(float mFrameTime)
	{
		onPreUpdate();

		if(_static) { spatialInfo.preUpdate(); return; }
		if(outOfBounds) { onOutOfBounds(); outOfBounds = false; return; }

		oldShape = shape;
		integrate(mFrameTime);
		spatialInfo.preUpdate();
		bodiesToResolve.clear();

		for(const auto& body : spatialInfo.getBodiesToCheck())
		{
			if(body == this || !isOverlapping(shape, body->getShape())) continue;

			auto intersection(getMinIntersection(shape, body->getShape()));

			onDetection({*body, mFrameTime, body->getUserData(), intersection});
			body->onDetection({*this, mFrameTime, userData, -intersection});

			if(!resolve || containsAny(body->getGroups(), getGroupsNoResolve())) continue;
			bodiesToResolve.push_back(body);
		}

		if(!bodiesToResolve.empty()) resolver.resolve(*this, bodiesToResolve);
		if(oldShape != shape) spatialInfo.invalidate();

		spatialInfo.postUpdate();
		onPostUpdate();
	}
Example #3
0
bool leavesDoNotOverlap(const PointSetArray& pointSet, const vector<shared_ptr<DAGNode>>& nodes) {
	// Find the leaf nodes
	vector<shared_ptr<DAGNode>> leafNodes;

	for (const shared_ptr<DAGNode>& node : nodes) {
		if (node->isLeaf()) {
			leafNodes.push_back(node);
		}
	}

	// Check the leaf nodes never intersect with each other
	for (const shared_ptr<DAGNode>& outerNode : leafNodes) {
		TriRecord outerTri = outerNode->tri_;

		for (const shared_ptr<DAGNode>& innerNode : leafNodes) {
			TriRecord innerTri = innerNode->tri_;

			if (!(outerTri == innerTri) &&
			    isOverlapping(intersectsTriangle(pointSet, outerTri, innerTri))) {
				return false;
			}
		}
	}

	return true;
}
Example #4
0
void RenderVTTCue::repositionCueSnapToLinesSet()
{
    InlineFlowBox* firstLineBox;
    LayoutUnit step;
    LayoutUnit position;

    if (!findFirstLineBox(firstLineBox))
        return;

    if (!initializeLayoutParameters(firstLineBox, step, position))
        return;

    bool switched;
    placeBoxInDefaultPosition(position, switched);

    // 11. Step loop: If none of the boxes in boxes would overlap any of the boxes
    // in output and all the boxes in output are within the video's rendering area
    // then jump to the step labeled done positioning.
    while (isOutside() || isOverlapping()) {
        if (!shouldSwitchDirection(firstLineBox, step)) {
            // 13. Move all the boxes in boxes ...
            // 14. Jump back to the step labeled step loop.
            moveBoxesByStep(step);
        } else if (!switchDirection(switched, step)) {
            break;
        }

        // 19. Jump back to the step labeled step loop.
    }

    // Acommodate extra top and bottom padding, border or margin.
    // Note: this is supported only for internal UA styling, not through the cue selector.
    if (hasInlineDirectionBordersPaddingOrMargin()) {
        IntRect containerRect = containingBlock()->absoluteBoundingBoxRect();
        IntRect cueRect = absoluteBoundingBoxRect();

        int topOverflow = cueRect.y() - containerRect.y();
        int bottomOverflow = containerRect.y() + containerRect.height() - cueRect.y() - cueRect.height();

        int adjustment = 0;
        if (topOverflow < 0)
            adjustment = -topOverflow;
        else if (bottomOverflow < 0)
            adjustment = bottomOverflow;

        if (adjustment)
            setY(y() + adjustment);
    }
}
void FaceDetector::addConsistent(cv::Rect r)
{
    for(int i = 0; i < consistent_rects.size(); i++)
    {
            if(isOverlapping(r, consistent_rects[i].rect))
            {
                consistent_rects[i].rect = r;
                consistent_rects[i].rating += 1.1;
                return;
            }
    }
    ConsistentRect newRect;
    newRect.rect = r;
    newRect.rating = 1.1;
    consistent_rects.push_back(newRect);
}
Example #6
0
static struct psl *getBestMatch(struct pslSets *ps, int iSet, struct psl *psl)
/* Get the best match for a psl in a list of psls from another set. */
{
struct pslRef *pr, *prev;
struct pslRef *bestMatch = NULL, *bestPrev = NULL;
int bestOverlap = 0;
struct psl *bestPsl = NULL;

for (prev = NULL, pr = ps->pending[iSet]; pr != NULL; prev = pr, pr = pr->next)
    {
    if (isOverlapping(psl, pr->psl))
        {
        if (sameBlockStruct(psl, pr->psl))
            {
            bestMatch = pr;
            bestPrev = prev;
            break; /* perfect match */
            }
        else
            {
            int over = overlappedBases(psl, pr->psl);
            if ((bestMatch == NULL) || (over > bestOverlap))
                {
                bestMatch = pr;
                bestPrev = prev;
                bestOverlap = over;
                }
            }
        }
    }
if (bestMatch != NULL)
    {
    bestPsl = bestMatch->psl;
    /* unlink from list and recycle */
    if (bestPrev == NULL)
        ps->pending[iSet] = bestMatch->next;
    else
        bestPrev->next = bestMatch->next;
    pslRefRecycle(ps, bestMatch);
    }
return bestPsl;
}
Example #7
0
bool ofxDeepZoom::shouldSwap(tile &t) {
    vector<list<tile>::iterator> temp;
    
    for (list<tile>::iterator iter=tiles.begin(); iter!=tiles.end(); iter++) {
        if (!iter->bSwap && isOverlapping(iter->rect, t.rect) && (!iter->bInside || iter->state==TILE_STATE_ACTIVE)){
            temp.push_back(iter);
        }
    }
    
    if (!temp.empty()) {
        if (temp.size()==1) {
            return isContaining(temp.front()->rect,t.rect);
        } else {
            float sum = 0;
            for (vector<list<tile>::iterator>::iterator iter=temp.begin();iter!=temp.end();iter++) {
                sum+=(*iter)->rect.width*(*iter)->rect.height;
            }
            return sum>=t.rect.width*t.rect.height;
        }
    }
    return false;
}
Example #8
0
bool CubeWorker::checkAreas(vector<string> &areaIds, vector<PArea> &areas)
{
	const IdentifiersType* dimensions = Context::getContext()->getServer()->lookupDatabase(dbid, false)->lookupCube(cubeid, false)->getDimensions();
	size_t numDimension = dimensions->size();

	size_t num = areas.size();

	for (size_t i = 0; i < num; i++) {
		if (areaIds[i] == "") {
			Logger::error << "name of area is empty" << endl;
			return false;
		}

		if (numDimension != areas[i]->dimCount()) {
			Logger::error << "error in size of dimension elements in AREA: '" << areaIds[i] << "'" << endl;
			return false;
		}
	}

	// check for overlapping areas
	for (size_t i = 0; i < num - 1; i++) {
		for (size_t j = i + 1; j < num; j++) {
			bool overlaps = isOverlapping(areas[i], areas[j]);

			if (overlaps) {
				Logger::error << "error overlapping area '" << areaIds[i] << "' and '" << areaIds[j] << "'" << endl;
				if (isInvestigator) {
					return false;
				} else {
					notifyAreaBuildError(areaIds[i], areaIds[j]);
					throw ErrorException(ErrorException::ERROR_WORKER_MESSAGE, "cannot start worker, overlapping areas");
				}
			}
		}
	}

	return true;
}
Example #9
0
void RenderTextTrackCue::repositionCueSnapToLinesNotSet()
{
    // 3. If none of the boxes in boxes would overlap any of the boxes in output, and all the boxes in
    // output are within the video's rendering area, then jump to the step labeled done positioning below.
    if (!isOutside() && !isOverlapping())
        return;

    // 4. If there is a position to which the boxes in boxes can be moved while maintaining the relative
    // positions of the boxes in boxes to each other such that none of the boxes in boxes would overlap
    // any of the boxes in output, and all the boxes in output would be within the video's rendering area,
    // then move the boxes in boxes to the closest such position to their current position, and then jump
    // to the step labeled done positioning below. If there are multiple such positions that are equidistant
    // from their current position, use the highest one amongst them; if there are several at that height,
    // then use the leftmost one amongst them.
    moveIfNecessaryToKeepWithinContainer();
    int x = 0;
    int y = 0;
    if (!findNonOverlappingPosition(x, y))
        return;

    setX(x);
    setY(y);
}
int validateRectangles(LinkList list)
{
  ListNode * pNode = LinkList_GetNode(list, 0);
  ListNode * pNext;
  RECT * pRect1;
  RECT * pRect2;
  
  while (pNode != NULL)
    {
      pRect1 = (RECT *)(pNode -> p_data);
      if (!isValid(pRect1))
	{
	  return 0;
	}
      pNext = pNode -> p_next;
      while (pNext != NULL)
	{
	  pRect2 = (RECT *)(pNext -> p_data);
	  if (isOverlapping(pRect1, pRect2))
	    {
	      printf("overlap detected:\n");
	      printf("(%d, %d) - [%d x %d]\n", 
		     pRect1 -> x, pRect1 -> y,
		     pRect1 -> width, pRect1 -> height);
	      printf("(%d, %d) - [%d x %d]\n", 
		     pRect2 -> x, pRect2 -> y,
		     pRect2 -> width, pRect2 -> height);
	      return 0;
	    }
	  pNext = pNext -> p_next;
	}
      pNode = pNode -> p_next;
    }

  return 1;
}
Example #11
0
int ConfigDiffTracker<ValType, ShardType>::calculateConfigDiff(
    const std::vector<ChunkType>& chunks) {
    _assertAttached();

    // Apply the chunk changes to the ranges and versions
    //
    // Overall idea here is to work in two steps :
    // 1. For all the new chunks we find, increment the maximum version per-shard and
    //      per-collection, and remove any conflicting chunks from the ranges.
    // 2. For all the new chunks we're interested in (all of them for mongos, just chunks on
    //      the shard for mongod) add them to the ranges.

    std::vector<ChunkType> newTracked;

    // Store epoch now so it doesn't change when we change max
    OID currEpoch = _maxVersion->epoch();

    _validDiffs = 0;

    for (const ChunkType& chunk : chunks) {
        ChunkVersion chunkVersion =
            ChunkVersion::fromBSON(chunk.toBSON(), ChunkType::DEPRECATED_lastmod());

        if (!chunkVersion.isSet() || !chunkVersion.hasEqualEpoch(currEpoch)) {
            warning() << "got invalid chunk version " << chunkVersion << " in document "
                      << chunk.toString() << " when trying to load differing chunks at version "
                      << ChunkVersion(
                          _maxVersion->majorVersion(), _maxVersion->minorVersion(), currEpoch);

            // Don't keep loading, since we know we'll be broken here
            return -1;
        }

        _validDiffs++;

        // Get max changed version and chunk version
        if (chunkVersion > *_maxVersion) {
            *_maxVersion = chunkVersion;
        }

        // Chunk version changes
        ShardType shard = shardFor(chunk.getShard());

        typename MaxChunkVersionMap::const_iterator shardVersionIt = _maxShardVersions->find(shard);
        if (shardVersionIt == _maxShardVersions->end() || shardVersionIt->second < chunkVersion) {
            (*_maxShardVersions)[shard] = chunkVersion;
        }

        // See if we need to remove any chunks we are currently tracking because of this
        // chunk's changes
        removeOverlapping(chunk.getMin(), chunk.getMax());

        // Figure out which of the new chunks we need to track
        // Important - we need to actually own this doc, in case the cursor decides to getMore
        // or unbuffer.
        if (isTracked(chunk)) {
            newTracked.push_back(chunk);
        }
    }

    LOG(3) << "found " << _validDiffs << " new chunks for collection " << _ns << " (tracking "
           << newTracked.size() << "), new version is " << *_maxVersion;

    for (const ChunkType& chunk : newTracked) {
        // Invariant enforced by sharding - it's possible to read inconsistent state due to
        // getMore and yielding, so we want to detect it as early as possible.
        //
        // TODO: This checks for overlap, we also should check for holes here iff we're
        // tracking all chunks.
        if (isOverlapping(chunk.getMin(), chunk.getMax())) {
            return -1;
        }

        _currMap->insert(rangeFor(chunk));
    }

    return _validDiffs;
}
int ConfigDiffTracker<ValType,ShardType>::
calculateConfigDiff( DBClientCursorInterface& diffCursor )
{
    verifyAttached();

    // Apply the chunk changes to the ranges and versions

    //
    // Overall idea here is to work in two steps :
    // 1. For all the new chunks we find, increment the maximum version per-shard and
    //    per-collection, and remove any conflicting chunks from the ranges
    // 2. For all the new chunks we're interested in (all of them for mongos, just chunks on the
    //    shard for mongod) add them to the ranges
    //

    vector<BSONObj> newTracked;
    // Store epoch now so it doesn't change when we change max
    OID currEpoch = _maxVersion->epoch();

    _validDiffs = 0;
    while( diffCursor.more() ) {

        BSONObj diffChunkDoc = diffCursor.next();

        ChunkVersion chunkVersion = ChunkVersion::fromBSON(diffChunkDoc, ChunkType::DEPRECATED_lastmod());

        if( diffChunkDoc[ChunkType::min()].type() != Object ||
                diffChunkDoc[ChunkType::max()].type() != Object ||
                diffChunkDoc[ChunkType::shard()].type() != String )
        {
            warning() << "got invalid chunk document " << diffChunkDoc
                      << " when trying to load differing chunks" << endl;
            continue;
        }

        if( ! chunkVersion.isSet() || ! chunkVersion.hasCompatibleEpoch( currEpoch ) ) {

            warning() << "got invalid chunk version " << chunkVersion << " in document " << diffChunkDoc
                      << " when trying to load differing chunks at version "
                      << ChunkVersion( _maxVersion->toLong(), currEpoch ) << endl;

            // Don't keep loading, since we know we'll be broken here
            return -1;
        }

        _validDiffs++;

        // Get max changed version and chunk version
        if( chunkVersion > *_maxVersion ) *_maxVersion = chunkVersion;

        // Chunk version changes
        ShardType shard = shardFor( diffChunkDoc[ChunkType::shard()].String() );
        typename map<ShardType, ChunkVersion>::iterator shardVersionIt = _maxShardVersions->find( shard );
        if( shardVersionIt == _maxShardVersions->end() || shardVersionIt->second < chunkVersion ) {
            (*_maxShardVersions)[ shard ] = chunkVersion;
        }

        // See if we need to remove any chunks we are currently tracking b/c of this chunk's changes
        removeOverlapping(diffChunkDoc[ChunkType::min()].Obj(),
                          diffChunkDoc[ChunkType::max()].Obj());

        // Figure out which of the new chunks we need to track
        // Important - we need to actually own this doc, in case the cursor decides to getMore or unbuffer
        if( isTracked( diffChunkDoc ) ) newTracked.push_back( diffChunkDoc.getOwned() );
    }

    LOG(3) << "found " << _validDiffs
           << " new chunks for collection " << _ns
           << " (tracking " << newTracked.size()
           << "), new version is " << *_maxVersion
           << endl;

    for( vector<BSONObj>::iterator it = newTracked.begin(); it != newTracked.end(); it++ ) {

        BSONObj chunkDoc = *it;

        // Important - we need to make sure we actually own the min and max here
        BSONObj min = chunkDoc[ChunkType::min()].Obj().getOwned();
        BSONObj max = chunkDoc[ChunkType::max()].Obj().getOwned();

        // Invariant enforced by sharding
        // It's possible to read inconsistent state b/c of getMore() and yielding, so we want
        // to detect as early as possible.
        // TODO: This checks for overlap, we also should check for holes here iff we're tracking
        // all chunks
        if( isOverlapping( min, max ) ) return -1;

        _currMap->insert( rangeFor( chunkDoc, min, max ) );
    }

    return _validDiffs;
}
Example #13
0
void Localization::joinBlobs(vector<observationBlob>& blobs){
  if ( !blobs.empty() ) {
    typedef vector<vector<observationBlob> > group_vector;
    group_vector blobGroup; 
    vector<observationBlob> newBlobs;
    
    // classify blobs together that are overlapping each other
    vector<observationBlob>::iterator iter;
    for ( iter = blobs.begin() ; iter != blobs.end() ; iter++ ) {
      if ( blobGroup.empty() ) {
	vector<observationBlob> t ; 
	t.push_back(*iter); 
	blobGroup.push_back(t); 
      }
      else {
	bool belongs = false; 
	group_vector::iterator iter2; 
	for ( iter2 = blobGroup.begin() ; iter2 != blobGroup.end() ; iter2++ ){
	  vector<observationBlob> tv = *iter2;
	  vector<observationBlob>::iterator iter3; 
	  for ( iter3 = tv.begin(); iter3 != tv.end() ; iter3++ ){
	    if ( isOverlapping( *iter, *iter3 ) ){
	      belongs = true; 
	      iter2->push_back(*iter);
	      break ; 
	    }
	  }
	  if ( belongs )
	    break ; 
	}
	
	// create new blobGroup if the blob doesn't overlap with existing blobs belonging to any group.
	if ( !belongs ) {
	  vector<observationBlob> t2 ; 
	  t2.push_back(*iter); 
	  blobGroup.push_back(t2); 
	}
      }
    }
  
    // join the blobs that belong to the same group
    group_vector::iterator it ; 
    for ( it = blobGroup.begin() ; it != blobGroup.end() ; it++ ){
      vector<observationBlob> group = *it;
      if ( group.size() > 1 ) {
	vector<observationBlob>::iterator it2;
	int minLeft = 1000, maxRight = 0, minTop = 1000, maxBottom = 0; 
	for ( it2 = group.begin(); it2 != group.end(); it2++ ) {
	  if ( it2->Left() < minLeft ) 
	    minLeft = it2->Left(); 
	  if ( it2->Right() > maxRight ) 
	    maxRight = it2->Right(); 
	  if ( it2->Top() < minTop ) 
	    minTop = it2->Top(); 
	  if ( it2->Bottom() > maxBottom )
	    maxBottom = it2->Bottom();
	}
	observationBlob nb(static_cast<int>(group.front().Color()), minLeft, maxRight, minTop, maxBottom, getAngle((minLeft + maxRight) / 2));
	//cout << "new " ; 
	//nb.print();
	newBlobs.push_back(nb); 
      }
      else {
	newBlobs.push_back(group.front()); 
      }
    }
    
    blobs = newBlobs;
  }
}
float			SegmentedShotStrategy::checkHit(const BaseLocalPlayer* tank,
							float position[3]) const
{
  float minTime = Infinity;
  // expired shot can't hit anything
  if (getPath().isExpired()) return minTime;

  float scaleFactor = 1.0f;

  if (tank->getFlag() == Flags::Obesity)   scaleFactor = BZDB.eval(StateDatabase::BZDB_OBESEFACTOR);
  else if (tank->getFlag() == Flags::Tiny) scaleFactor = BZDB.eval(StateDatabase::BZDB_TINYFACTOR);
  else if (tank->getFlag() == Flags::Thief) scaleFactor = BZDB.eval(StateDatabase::BZDB_THIEFTINYFACTOR);

  // get tank radius
  float radius = BZDBCache::tankRadius * scaleFactor;
  const float radius2 = radius * radius;

  // tank is positioned from it's bottom so shift position up by
  // half a tank height.
  Ray tankLastMotionRaw = tank->getLastMotion();
  float lastTankPositionRaw[3];
  lastTankPositionRaw[0] = tankLastMotionRaw.getOrigin()[0];
  lastTankPositionRaw[1] = tankLastMotionRaw.getOrigin()[1];
  lastTankPositionRaw[2] = tankLastMotionRaw.getOrigin()[2] + 0.5f * BZDBCache::tankHeight * scaleFactor;
  Ray tankLastMotion(lastTankPositionRaw, tankLastMotionRaw.getDirection());

  // if bounding box of tank and entire shot doesn't overlap then no hit
  const float (*tankBBox)[3] = tank->getLastMotionBBox();
  if (!isOverlapping(bbox, tankBBox)) return minTime;

  float shotRadius = BZDB.eval(StateDatabase::BZDB_SHOTRADIUS);

  // check each segment in interval (prevTime,currentTime]
  const float dt = currentTime - prevTime;
  const int numSegments = segments.size();
  for (int i = lastSegment; i <= segment && i < numSegments; i++) {
    // can never hit your own first laser segment
    if (i == 0 && getPath().getFlag() == Flags::Laser &&
	getPath().getPlayer() == tank->getId())
      continue;

/*
    // skip segments that don't overlap in time with current interval
    if (segments[i].end <= prevTime) continue;
    if (currentTime <= segments[i].start) break;
*/

    // if shot segment and tank bboxes don't overlap then no hit
    const ShotPathSegment& s = segments[i];
    if (!isOverlapping(s.bbox, tankBBox)) continue;

    // construct relative shot ray:  origin and velocity relative to
    // my tank as a function of time (t=0 is start of the interval).
    Ray relativeRay(rayMinusRay(s.ray, prevTime - s.start, tankLastMotion, 0.0f));

    // get hit time
    float t;
    if (tank->getFlag() == Flags::Narrow) {
      // find closest approach to narrow box around tank.  width of box
      // is shell radius so you can actually hit narrow tank head on.
      static float origin[3] = { 0.0f, 0.0f, 0.0f };
      t = timeRayHitsBlock(relativeRay, origin, tank->getAngle(),
			0.5f * BZDB.eval(StateDatabase::BZDB_TANKLENGTH),
			shotRadius,
			0.5f * BZDBCache::tankHeight);
    }
    else {
      // find time when shot hits sphere around tank
      t = rayAtDistanceFromOrigin(relativeRay, 0.99f * radius);
    }

    // short circuit if time is greater then smallest time so far
    if (t > minTime) continue;

    // make sure time falls within segment
    if (t < 0.0f || t > dt) continue;
    if (t > s.end - prevTime) continue;

    // check if shot hits tank -- get position at time t, see if in radius
    float closestPos[3];
    relativeRay.getPoint(t, closestPos);
    if (closestPos[0] * closestPos[0] +
	closestPos[1] * closestPos[1] +
	closestPos[2] * closestPos[2] < radius2) {
      // save best time so far
      minTime = t;

      // compute location of tank at time of hit
      float tankPos[3];
      tank->getLastMotion().getPoint(t, tankPos);

      // compute position of intersection
      position[0] = tankPos[0] + closestPos[0];
      position[1] = tankPos[1] + closestPos[1];
      position[2] = tankPos[2] + closestPos[2];
      //printf("%u:%u %u:%u\n", tank->getId().port, tank->getId().number, getPath().getPlayer().port, getPath().getPlayer().number);
    }
  }
  return minTime;
}
Example #15
0
void SnapToLinesLayouter::layout()
{
    // http://dev.w3.org/html5/webvtt/#dfn-apply-webvtt-cue-settings
    // Step 13, "If cue's text track cue snap-to-lines flag is set".

    InlineFlowBox* firstLineBox = findFirstLineBox();
    if (!firstLineBox)
        return;

    // Steps 1-3 skipped.
    // 4. Horizontal: Let step be the height of the first line box in boxes.
    //    Vertical: Let step be the width of the first line box in boxes.
    LayoutUnit step = firstLineBox->logicalHeight();

    // 5. If step is zero, then jump to the step labeled done positioning below.
    if (!step)
        return;

    // Steps 6-11.
    LayoutUnit positionAdjustment = computeInitialPositionAdjustment(step);

    // 12. Move all boxes in boxes ...
    // Horizontal: ... down by the distance given by position
    // Vertical: ... right by the distance given by position
    moveBoxesBy(positionAdjustment);

    // 13. Remember the position of all the boxes in boxes as their specified
    // position.
    m_specifiedPosition = m_cueBox.location();

    // 14. Let best position be null. It will hold a position for boxes, much
    // like specified position in the previous step.
    // 15. Let best position score be null.

    // 16. Let switched be false.
    bool switched = false;

    // Step 17 skipped. (margin == 0; title area == video area)

    // 18. Step loop: If none of the boxes in boxes would overlap any of the
    // boxes in output, and all of the boxes in output are entirely within the
    // title area box, then jump to the step labeled done positioning below.
    while (isOutside() || isOverlapping()) {
        // 19. Let current position score be the percentage of the area of the
        // bounding box of the boxes in boxes that is outside the title area
        // box.
        // 20. If best position is null (i.e. this is the first run through
        // this loop, switched is still false, the boxes in boxes are at their
        // specified position, and best position score is still null), or if
        // current position score is a lower percentage than that in best
        // position score, then remember the position of all the boxes in boxes
        // as their best position, and set best position score to current
        // position score.
        if (!shouldSwitchDirection(firstLineBox, step)) {
            // 22. Horizontal: Move all the boxes in boxes down by the distance
            // given by step. (If step is negative, then this will actually
            // result in an upwards movement of the boxes in absolute terms.)
            // Vertical: Move all the boxes in boxes right by the distance
            // given by step. (If step is negative, then this will actually
            // result in a leftwards movement of the boxes in absolute terms.)
            moveBoxesBy(step);

            // 23. Jump back to the step labeled step loop.
            continue;
        }

        // 24. Switch direction: If switched is true, then move all the boxes in
        // boxes back to their best position, and jump to the step labeled done
        // positioning below.

        // 25. Otherwise, move all the boxes in boxes back to their specified
        // position as determined in the earlier step.
        m_cueBox.setLocation(m_specifiedPosition);

        // XX. If switched is true, jump to the step labeled done
        // positioning below.
        if (switched)
            break;

        // 26. Negate step.
        step = -step;

        // 27. Set switched to true.
        switched = true;

        // 28. Jump back to the step labeled step loop.
    }
}