Exemple #1
0
// add a word break (possibly for a hyphenated fragment), and add desperate
// breaks if needed (ie when word exceeds current line width)
void LineBreaker::addWordBreak(size_t offset,
                               ParaWidth preBreak,
                               ParaWidth postBreak,
                               size_t preSpaceCount,
                               size_t postSpaceCount,
                               float penalty,
                               HyphenationType hyph) {
  Candidate cand;
  ParaWidth width = mCandidates.back().preBreak;
  if (postBreak - width > currentLineWidth()) {
    // Add desperate breaks.
    // Note: these breaks are based on the shaping of the (non-broken) original
    // text; they are imprecise especially in the presence of kerning,
    // ligatures, and Arabic shaping.
    size_t i = mCandidates.back().offset;
    width += mCharWidths[i++];
    for (; i < offset; i++) {
      float w = mCharWidths[i];
      if (w > 0) {
        cand.offset = i;
        cand.preBreak = width;
        cand.postBreak = width;
        // postSpaceCount doesn't include trailing spaces
        cand.preSpaceCount = postSpaceCount;
        cand.postSpaceCount = postSpaceCount;
        cand.penalty = SCORE_DESPERATE;
        cand.hyphenType = HyphenationType::BREAK_AND_DONT_INSERT_HYPHEN;
#if VERBOSE_DEBUG
        ALOGD("desperate cand: %zd %g:%g", mCandidates.size(), cand.postBreak,
              cand.preBreak);
#endif
        addCandidate(cand);
        width += w;
      }
    }
  }

  cand.offset = offset;
  cand.preBreak = preBreak;
  cand.postBreak = postBreak;
  cand.penalty = penalty;
  cand.preSpaceCount = preSpaceCount;
  cand.postSpaceCount = postSpaceCount;
  cand.hyphenType = hyph;
#if VERBOSE_DEBUG
  ALOGD("cand: %zd %g:%g", mCandidates.size(), cand.postBreak, cand.preBreak);
#endif
  addCandidate(cand);
}
Exemple #2
0
    void R2RegionCoverer::getCovering( const R2Region& region, vector<GeoHash>* cover ) {
        // Strategy: Start with the full plane. Discard any
        // that do not intersect the shape.  Then repeatedly choose the
        // largest cell that intersects the shape and subdivide it.
        //
        // _result contains the cells that will be part of the output, while the
        // queue contains cells that we may still subdivide further.  Cells that
        // are entirely contained within the region are immediately added to the
        // output, while cells that do not intersect the region are immediately
        // discarded. Therefore the queue only contains cells that partially
        // intersect the region. Candidates are prioritized first according to
        // cell size (larger cells first), then by the number of intersecting
        // children they have (fewest children first), and then by the number of
        // fully contained children (fewest children first).

        verify(_minLevel <= _maxLevel);
        dassert(_candidateQueue->empty());
        dassert(_results->empty());
        _region = &region;

        getInitialCandidates();

        while(!_candidateQueue->empty()) {
            Candidate* candidate = _candidateQueue->top().second; // Owned
            _candidateQueue->pop();
            LOG(3) << "Pop: " << candidate->cell;

            // Try to expand this cell into its children
            if (candidate->cell.getBits() < _minLevel ||
                    candidate->numChildren == 1 ||
                    (int)_results->size() +
                    (int)_candidateQueue->size() +
                    candidate->numChildren <= _maxCells) {

                for (int i = 0; i < candidate->numChildren; i++) {
                    addCandidate(candidate->children[i]);
                }
                deleteCandidate(candidate, false);
            } else {
                // Reached max cells. Move all candidates from the queue into results.
                candidate->isTerminal = true;
                addCandidate(candidate);
            }
            LOG(3) << "Queue: " << _candidateQueue->size();
        }

        _region = NULL;
        cover->swap(*_results);
    }
static void fillSurfaceWeightPattern (OTGrammarTableau me, long numberOfSyllables, int stress [],
	int footedToTheLeft [], int footedToTheRight [], int underlyingWeightPattern [],
	int overtFormsHaveSecondaryStress)
{
	int surfaceWeightPattern [1+7], minSurfaceWeight [1+7], maxSurfaceWeight [1+7];
	int weight1, weight2, weight3, weight4, weight5;
	for (long isyll = 1; isyll <= numberOfSyllables; isyll ++) {
		if (underlyingWeightPattern [isyll] < 3) {
			minSurfaceWeight [isyll] = maxSurfaceWeight [isyll] = underlyingWeightPattern [isyll];   /* L -> L; H -> H */
		} else {
			minSurfaceWeight [isyll] = 3, maxSurfaceWeight [isyll] = 4;   /* C -> { J, K } */ 
		}
	}
	surfaceWeightPattern [6] = surfaceWeightPattern [7] = 1;   /* Constant L. */
	for (weight1 = minSurfaceWeight [1]; weight1 <= maxSurfaceWeight [1]; weight1 ++) {
		surfaceWeightPattern [1] = weight1;
		for (weight2 = minSurfaceWeight [2]; weight2 <= maxSurfaceWeight [2]; weight2 ++) {
			surfaceWeightPattern [2] = weight2;
			if (numberOfSyllables == 2) {
				addCandidate (me, 2, stress, footedToTheLeft, footedToTheRight, surfaceWeightPattern, overtFormsHaveSecondaryStress);
			} else for (weight3 = minSurfaceWeight [3]; weight3 <= maxSurfaceWeight [3]; weight3 ++) {
				surfaceWeightPattern [3] = weight3;
				if (numberOfSyllables == 3) {
					addCandidate (me, 3, stress, footedToTheLeft, footedToTheRight, surfaceWeightPattern, overtFormsHaveSecondaryStress);
				} else for (weight4 = minSurfaceWeight [4]; weight4 <= maxSurfaceWeight [4]; weight4 ++) {
					surfaceWeightPattern [4] = weight4;
					if (numberOfSyllables == 4) {
						addCandidate (me, 4, stress, footedToTheLeft, footedToTheRight, surfaceWeightPattern, overtFormsHaveSecondaryStress);
					} else for (weight5 = minSurfaceWeight [5]; weight5 <= maxSurfaceWeight [5]; weight5 ++) {
						surfaceWeightPattern [5] = weight5;
						addCandidate (me, numberOfSyllables, stress, footedToTheLeft, footedToTheRight, surfaceWeightPattern, overtFormsHaveSecondaryStress);
					}
				}
			}
		}
	}
}
Exemple #4
0
    // Takes ownership of "candidate"
    void R2RegionCoverer::addCandidate( Candidate* candidate ) {
        if (candidate == NULL) return;

        if (candidate->isTerminal) {
            _results->push_back(candidate->cell);
            deleteCandidate(candidate, true);
            return;
        }

        verify(candidate->numChildren == 0);

        // Expand children
        int numTerminals = expandChildren(candidate);

        if (candidate->numChildren == 0) {
            deleteCandidate(candidate, true);
        } else if (numTerminals == 4 && candidate->cell.getBits() >= _minLevel) {
            // Optimization: add the parent cell rather than all of its children.
            candidate->isTerminal = true;
            addCandidate(candidate);
        } else {
            // Add the cell into the priority queue for further subdivision.
            //
            // We negate the priority so that smaller absolute priorities are returned
            // first.  The heuristic is designed to refine the largest cells first,
            // since those are where we have the largest potential gain.  Among cells
            // at the same level, we prefer the cells with the smallest number of
            // intersecting children.  Finally, we prefer cells that have the smallest
            // number of children that cannot be refined any further.
            int priority = -((((candidate->cell.getBits() << 4)
                              + candidate->numChildren) << 4)
                              + numTerminals);
            _candidateQueue->push(make_pair(priority, candidate)); // queue owns candidate
            LOG(3) << "Push: " << candidate->cell << " (" << priority << ") ";
        }
    }
Exemple #5
0
 void R2RegionCoverer::getInitialCandidates() {
     // Add the full plane
     // TODO a better initialization.
     addCandidate(newCandidate(GeoHash()));
 }
// for merging candidate sets:
CandidateSet& CandidateSet::operator+=(const CandidateSet& rhs) {
	for (int i=0; i < rhs.getSize(); ++i) {
		addCandidate(rhs[i]);
	}
	return *this;
}