modules/skparagraph/src/ParagraphImpl.cpp
void ParagraphImpl::markLineBreaks() {

    // Find all possible (soft) line breaks
    TextBreaker breaker;
    if (!breaker.initialize(fTextSpan, UBRK_LINE)) {
        return;
    }

    Cluster* current = fClusters.begin();
    while (!breaker.eof() && current < fClusters.end()) {
        size_t currentPos = breaker.next();
        while (current < fClusters.end()) {
            if (current->textRange().end > currentPos) {
                break;
            } else if (current->textRange().end == currentPos) {
                current->setBreakType(breaker.status() == UBRK_LINE_HARD
                                      ? Cluster::BreakType::HardLineBreak
                                      : Cluster::BreakType::SoftLineBreak);
                ++current;
                break;
            }
            ++current;
        }
    }

    // Walk through all the clusters in the direction of input text
    Block* currentStyle = this->fTextStyles.begin();
    SkScalar shift = 0;
    for (auto& cluster : fClusters) {
        auto run = cluster.run();

        // Shift the cluster
        run->shift(&cluster, shift);

        // Synchronize styles (one cluster can be covered by few styles)
        while (!cluster.startsIn(currentStyle->fRange)) {
            currentStyle++;
            SkASSERT(currentStyle != this->fTextStyles.end());
        }

        // Take spacing styles in account
        if (currentStyle->fStyle.getWordSpacing() != 0 &&
            fParagraphStyle.getTextAlign() != TextAlign::kJustify) {
            if (cluster.isWhitespaces() && cluster.isSoftBreak()) {
                shift += run->addSpacesAtTheEnd(currentStyle->fStyle.getWordSpacing(), &cluster);
            }
        }
        if (currentStyle->fStyle.getLetterSpacing() != 0) {
            shift += run->addSpacesEvenly(currentStyle->fStyle.getLetterSpacing(), &cluster);
        }
    }

    fClusters.emplace_back(this, EMPTY_RUN, 0, 0, SkSpan<const char>(), 0, 0);
}
// TODO: we need soft line breaks before for word spacing
we need soft line breaks before for word spacing
we need soft line breaks before for word spacing
void ParagraphImpl::markLineBreaks() {
    TextBreaker breaker;
    if (!breaker.initialize(fTextSpan, UBRK_LINE)) {
        return;
    }
    Cluster* current = fClusters.begin();
    while (!breaker.eof() && current < fClusters.end()) {
        size_t currentPos = breaker.next();
        while (current < fClusters.end()) {
            if (current->textRange().end > currentPos) {
                break;
            } else if (current->textRange().end == currentPos) {
                current->setBreakType(breaker.status() == UBRK_LINE_HARD
                                      ? Cluster::BreakType::HardLineBreak
                                      : Cluster::BreakType::SoftLineBreak);
                ++current;
                break;
            }
            ++current;
        }
    }
    Block* currentStyle = this->fTextStyles.begin();
    SkScalar shift = 0;
    for (auto& cluster : fClusters) {
        auto run = cluster.run();
        run->shift(&cluster, shift);
        while (!cluster.startsIn(currentStyle->fRange)) {
            currentStyle++;
            SkASSERT(currentStyle != this->fTextStyles.end());
        }
        if (currentStyle->fStyle.getWordSpacing() != 0 &&
            fParagraphStyle.getTextAlign() != TextAlign::kJustify) {
            if (cluster.isWhitespaces() && cluster.isSoftBreak()) {
                shift += run->addSpacesAtTheEnd(currentStyle->fStyle.getWordSpacing(), &cluster);
            }
        }
        if (currentStyle->fStyle.getLetterSpacing() != 0) {
            shift += run->addSpacesEvenly(currentStyle->fStyle.getLetterSpacing(), &cluster);
        }
    }
    fClusters.emplace_back(this, EMPTY_RUN, 0, 0, SkSpan<const char>(), 0, 0);
}
void ParagraphImpl :: markLineBreaks ( ) { TextBreaker breaker ; if ( ! breaker . initialize ( fTextSpan , UBRK_LINE ) ) { return ; } Cluster * current = fClusters . begin ( ) ; while ( ! breaker . eof ( ) && current < fClusters . end ( ) ) { size_t currentPos = breaker . next ( ) ; while ( current < fClusters . end ( ) ) { if ( current -> textRange ( ) . end > currentPos ) { break ; } else if ( current -> textRange ( ) . end == currentPos ) { current -> setBreakType ( breaker . status ( ) == UBRK_LINE_HARD ? Cluster :: BreakType :: HardLineBreak : Cluster :: BreakType :: SoftLineBreak ) ; ++ current ; break ; } ++ current ; } } Block * currentStyle = this -> fTextStyles . begin ( ) ; SkScalar shift = 0 ; for ( auto & cluster : fClusters ) { auto run = cluster . run ( ) ; run -> shift ( & cluster , shift ) ; while ( ! cluster . startsIn ( currentStyle -> fRange ) ) { currentStyle ++ ; SkASSERT ( currentStyle != this -> fTextStyles . end ( ) ) ; } if ( currentStyle -> fStyle . getWordSpacing ( ) != 0 && fParagraphStyle . getTextAlign ( ) != TextAlign :: kJustify ) { if ( cluster . isWhitespaces ( ) && cluster . isSoftBreak ( ) ) { shift += run -> addSpacesAtTheEnd ( currentStyle -> fStyle . getWordSpacing ( ) , & cluster ) ; } } if ( currentStyle -> fStyle . getLetterSpacing ( ) != 0 ) { shift += run -> addSpacesEvenly ( currentStyle -> fStyle . getLetterSpacing ( ) , & cluster ) ; } } fClusters . emplace_back ( this , EMPTY_RUN , 0 , 0 , SkSpan < const char > ( ) , 0 , 0 ) ; }
TODO: we need soft line breaks before for word spacing
TODO : we need soft line breaks before for word spacing
// Find all possible (soft) line breaks // Walk through all the clusters in the direction of input text // Shift the cluster // Synchronize styles (one cluster can be covered by few styles) // Take spacing styles in account