Example #1
0
void
Button::setChildText(Child& child, XmlReader& reader)
{
    std::auto_ptr<Paragraph> paragraph(new Paragraph());
    paragraph->parse(reader);
    resetChild(child, paragraph.release());
}
String TextCheckingHelper::findFirstBadGrammar(GrammarDetail& outGrammarDetail, int& outGrammarPhraseOffset, bool markAll)
{
    // Initialize out parameters; these will be updated if we find something to return.
    outGrammarDetail.location = -1;
    outGrammarDetail.length = 0;
    outGrammarDetail.guesses.clear();
    outGrammarDetail.userDescription = "";
    outGrammarPhraseOffset = 0;

    String firstBadGrammarPhrase;

    // Expand the search range to encompass entire paragraphs, since grammar checking needs that much context.
    // Determine the character offset from the start of the paragraph to the start of the original search range,
    // since we will want to ignore results in this area.
    TextCheckingParagraph paragraph(EphemeralRange(m_start, m_end));

    // Start checking from beginning of paragraph, but skip past results that occur before the start of the original search range.
    int startOffset = 0;
    while (startOffset < paragraph.checkingEnd()) {
        Vector<GrammarDetail> grammarDetails;
        int badGrammarPhraseLocation = -1;
        int badGrammarPhraseLength = 0;
        m_client->textChecker().checkGrammarOfString(paragraph.textSubstring(startOffset), grammarDetails, &badGrammarPhraseLocation, &badGrammarPhraseLength);

        if (!badGrammarPhraseLength) {
            ASSERT(badGrammarPhraseLocation == -1);
            return String();
        }

        ASSERT(badGrammarPhraseLocation >= 0);
        badGrammarPhraseLocation += startOffset;


        // Found some bad grammar. Find the earliest detail range that starts in our search range (if any).
        int badGrammarIndex = findFirstGrammarDetail(grammarDetails, badGrammarPhraseLocation, paragraph.checkingStart(), paragraph.checkingEnd(), markAll);
        if (badGrammarIndex >= 0) {
            ASSERT(static_cast<unsigned>(badGrammarIndex) < grammarDetails.size());
            outGrammarDetail = grammarDetails[badGrammarIndex];
        }

        // If we found a detail in range, then we have found the first bad phrase (unless we found one earlier but
        // kept going so we could mark all instances).
        if (badGrammarIndex >= 0 && firstBadGrammarPhrase.isEmpty()) {
            outGrammarPhraseOffset = badGrammarPhraseLocation - paragraph.checkingStart();
            firstBadGrammarPhrase = paragraph.textSubstring(badGrammarPhraseLocation, badGrammarPhraseLength);

            // Found one. We're done now, unless we're marking each instance.
            if (!markAll)
                break;
        }

        // These results were all between the start of the paragraph and the start of the search range; look
        // beyond this phrase.
        startOffset = badGrammarPhraseLocation + badGrammarPhraseLength;
    }

    return firstBadGrammarPhrase;
}
Example #3
0
Vector<String> TextCheckingHelper::guessesForMisspelledOrUngrammaticalRange(bool checkGrammar, bool& misspelled, bool& ungrammatical) const
{
    if (!unifiedTextCheckerEnabled())
        return Vector<String>();

    Vector<String> guesses;
    misspelled = false;
    ungrammatical = false;
    
    if (!m_client || !m_range || m_range->collapsed(IGNORE_EXCEPTION))
        return guesses;

    // Expand the range to encompass entire paragraphs, since text checking needs that much context.
    TextCheckingParagraph paragraph(m_range);
    if (paragraph.isEmpty())
        return guesses;

    Vector<TextCheckingResult> results;
    TextCheckingTypeMask checkingTypes = checkGrammar ? (TextCheckingTypeSpelling | TextCheckingTypeGrammar) : TextCheckingTypeSpelling;
    checkTextOfParagraph(*m_client->textChecker(), paragraph.text(), checkingTypes, results);
    
    for (unsigned i = 0; i < results.size(); i++) {
        const TextCheckingResult* result = &results[i];
        if (result->type == TextCheckingTypeSpelling && paragraph.checkingRangeMatches(result->location, result->length)) {
            String misspelledWord = paragraph.checkingSubstring();
            ASSERT(misspelledWord.length());
            m_client->textChecker()->getGuessesForWord(misspelledWord, String(), guesses);
            m_client->updateSpellingUIWithMisspelledWord(misspelledWord);
            misspelled = true;
            return guesses;
        }
    }
    
    if (!checkGrammar)
        return guesses;
        
    for (unsigned i = 0; i < results.size(); i++) {
        const TextCheckingResult* result = &results[i];
        if (result->type == TextCheckingTypeGrammar && paragraph.isCheckingRangeCoveredBy(result->location, result->length)) {
            for (unsigned j = 0; j < result->details.size(); j++) {
                const GrammarDetail* detail = &result->details[j];
                ASSERT(detail->length > 0);
                ASSERT(detail->location >= 0);
                if (paragraph.checkingRangeMatches(result->location + detail->location, detail->length)) {
                    String badGrammarPhrase = paragraph.textSubstring(result->location, result->length);
                    ASSERT(badGrammarPhrase.length());
                    for (unsigned k = 0; k < detail->guesses.size(); k++)
                        guesses.append(detail->guesses[k]);
                    m_client->updateSpellingUIWithGrammarString(badGrammarPhrase, *detail);
                    ungrammatical = true;
                    return guesses;
                }
            }
        }
    }
    return guesses;
}
Example #4
0
Vector<String> TextCheckingHelper::guessesForMisspelledOrUngrammaticalRange(bool checkGrammar, bool& misspelled, bool& ungrammatical) const
{
    if (!unifiedTextCheckerEnabled())
        return Vector<String>();

    Vector<String> guesses;
    misspelled = false;
    ungrammatical = false;
    
    if (!m_client || !m_range || m_range->collapsed())
        return guesses;

    // Expand the range to encompass entire paragraphs, since text checking needs that much context.
    TextCheckingParagraph paragraph(m_range);
    if (paragraph.isEmpty())
        return guesses;

    Vector<TextCheckingResult> results;
    TextCheckingTypeMask checkingTypes = checkGrammar ? (TextCheckingTypeSpelling | TextCheckingTypeGrammar) : TextCheckingTypeSpelling;
    VisibleSelection currentSelection;
    if (Frame* frame = m_range->ownerDocument().frame())
        currentSelection = frame->selection().selection();
    checkTextOfParagraph(*m_client->textChecker(), paragraph.text(), checkingTypes, results, currentSelection);

    for (auto& result : results) {
        if (result.type == TextCheckingTypeSpelling && paragraph.checkingRangeMatches(result.location, result.length)) {
            String misspelledWord = paragraph.checkingSubstring();
            ASSERT(misspelledWord.length());
            m_client->textChecker()->getGuessesForWord(misspelledWord, String(), currentSelection, guesses);
            m_client->updateSpellingUIWithMisspelledWord(misspelledWord);
            misspelled = true;
            return guesses;
        }
    }
    
    if (!checkGrammar)
        return guesses;

    for (auto& result : results) {
        if (result.type == TextCheckingTypeGrammar && paragraph.isCheckingRangeCoveredBy(result.location, result.length)) {
            for (auto& detail : result.details) {
                ASSERT(detail.length > 0);
                ASSERT(detail.location >= 0);
                if (paragraph.checkingRangeMatches(result.location + detail.location, detail.length)) {
                    String badGrammarPhrase = paragraph.textSubstring(result.location, result.length);
                    ASSERT(badGrammarPhrase.length());
                    for (auto& guess : detail.guesses)
                        guesses.append(guess);
                    m_client->updateSpellingUIWithGrammarString(badGrammarPhrase, detail);
                    ungrammatical = true;
                    return guesses;
                }
            }
        }
    }
    return guesses;
}
Example #5
0
void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color)
{	
	Paragraph paragraph(wline, color, mTimer.getElapsedTimeF32(), mFont,  (F32)getRect().getWidth() );
	
	mParagraphs.push_back ( paragraph );
	
#if LL_WINDOWS && LL_LCD_COMPILE
	// add to LCD screen
	AddNewDebugConsoleToLCD(wline);
#endif	
}
Example #6
0
void
Document::parse(XmlReader& reader)
{
    XmlReader::AttributeIterator iter(reader);
    while(iter.next()) {
        const char* attribute = (const char*) iter.getName();
        const char* value = (const char*) iter.getValue();

        if(parseAttribute(attribute, value)) {
            continue;
        } else if(style.parseAttribute(attribute, value)) {
            continue;
        } else if(strcmp(attribute, "src") == 0) {
            XmlReader fileReader(value);
            parse(fileReader);
            return;
        } else {
            std::cerr << "Skipping unknown attribute '"
                << attribute << "'.\n";
        }
    }

    int depth = reader.getDepth();
    while(reader.read() && reader.getDepth() > depth) {
        if(reader.getNodeType() == XML_READER_TYPE_ELEMENT) {
            std::string node = (const char*) reader.getName();
            if(node == "p" || node=="Paragraph" || node == "li") {
                std::auto_ptr<Paragraph> paragraph (new Paragraph());
                if(node != "li") {
                    paragraph->parse(reader, style);
                } else {
                    paragraph->parseList(reader, style);
                }
                paragraph->linkClicked.connect(
                    makeCallback(*this, &Document::paragraphLinkClicked));
                addChild(paragraph.release());
            } else if(node == "img") {
                std::auto_ptr<DocumentImage> image (new DocumentImage());
                image->parse(reader, style);
                addChild(image.release());
            } else {
                std::cerr << "Skipping unknown node type '" << node << "'.\n";
                reader.nextNode();
            }
        } else if(reader.getNodeType() == XML_READER_TYPE_TEXT) {
            // TODO create anonymous paragraph...
            std::cerr << "Warning: text outside paragraph not allowed (yet).\n";
        }
    }
}
Example #7
0
//-----------------------------------------------------------------------------
void CompilerInfo::DumpSupportedFeatures()
{
    Features features;

    FillMacros( features );
    FillCxx11Features( features );
    FillCxx14Features( features );
    FillCxx17Features( features );

    std::sort( features.begin(), features.end() );

    ScopedParagraph paragraph( COMPILER_IDENTIFICATION );

    for (const auto& feature : features)
    {
        std::cout << "> " << feature << std::endl;
    }
}
Example #8
0
void KoTextCustomItem::draw(QPainter* p, int _x, int _y, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected )
{
    KoTextZoomHandler *zh=textDocument()->paintingZoomHandler();
    //kdDebug(32500)<<" x :"<<_x<<" y :"<<_y<<" cx :"<<cx<<" cy :"<<cy<<" ch :"<<ch<<" cw :"<<cw<<endl;

    // Calculate index only once
    // Hmm, should pass it to drawCustomItem...
    int charIndex = index();
    KoTextStringChar* stringChar = paragraph()->at( charIndex );

    // Convert x, y, cx, cy, cw and ch from Layout Units to pixels.
    int x = zh->layoutUnitToPixelX(_x) /*+ stringChar->pixelxadj*/;
    int y = zh->layoutUnitToPixelY(_y);
    cx = zh->layoutUnitToPixelX(cx);
    cy = zh->layoutUnitToPixelY(cy);
    cw = zh->layoutUnitToPixelX(_x,cw);
    ch = zh->layoutUnitToPixelY(_y,ch);
    int wpix = zh->layoutUnitToPixelX(_x,width);
    int hpix = zh->layoutUnitToPixelX(_y,height);
    //kdDebug(32500)<<"After  x :"<<x<<" y :"<<y<<" cx :"<<cx<<" cy :"<<cy<<" ch :"<<ch<<" cw :"<<cw<<endl;
    int ascentpix = zh->layoutUnitToPixelY( _y, ascent() );

    KoTextFormat * fmt = stringChar->format();

    //bool forPrint = ( p->device()->devType() == QInternal::Printer );
    p->setFont( fmt->screenFont( zh ) );

    int offset=0;
    if ( fmt->vAlign() == KoTextFormat::AlignSuperScript )
        offset = -( hpix - p->fontMetrics().height() );

    if ( fmt->shadowDistanceX() != 0 || fmt->shadowDistanceY() != 0 ) {
        int sx = fmt->shadowX( zh );
        int sy = fmt->shadowY( zh );
        if ( sx != 0 || sy != 0 )
        {
            p->save();
            p->translate( sx, sy );
            drawCustomItem(p, x, y, wpix, hpix, ascentpix, cx, cy, cw, ch, cg, selected, offset, true);
            p->restore();
        }
    }
    drawCustomItem(p, x, y, wpix, hpix, ascentpix, cx, cy, cw, ch, cg, selected, offset,  false);
}
Example #9
0
File: edit.c Project: vigna/ne
int word_wrap2(buffer * const b) {
	static char avcmd[16];

	if (b->cur_pos > b->cur_line_desc->line_len) return OK;

	bool non_blank_added = false;
	int avshift;
	char * line = b->cur_line_desc->line;
	int64_t pos, original_line;

	/* If the char to our left is a space, we need to insert
	   a non-space to attach our WORDWRAP_BOOKMARK to because
	   spaces at the split point get removed, which effectively
	   leaves our bookmark on the current line. */
	delay_update();
	pos = prev_pos(line, b->cur_pos, b->encoding);
	if (pos >= 0 && (non_blank_added = ne_isspace(get_char(&line[pos], b->encoding), b->encoding))) {
		start_undo_chain(b);
		insert_one_char(b, b->cur_line_desc, b->cur_line, b->cur_pos, 'X');
		line = b->cur_line_desc->line;
		goto_pos(b, next_pos(line, b->cur_pos, b->encoding));
	}
	b->bookmark[WORDWRAP_BOOKMARK].pos   = b->cur_pos;
	b->bookmark[WORDWRAP_BOOKMARK].line  = original_line = b->cur_line;
	b->bookmark[WORDWRAP_BOOKMARK].cur_y = b->cur_y;
	b->bookmark_mask |= (1 << WORDWRAP_BOOKMARK);
	paragraph(b);
	goto_line_pos(b, b->bookmark[WORDWRAP_BOOKMARK].line, b->bookmark[WORDWRAP_BOOKMARK].pos);
	line = b->cur_line_desc->line;
	b->bookmark[WORDWRAP_BOOKMARK].cur_y += b->bookmark[WORDWRAP_BOOKMARK].line - original_line;
	if (avshift = b->cur_y - b->bookmark[WORDWRAP_BOOKMARK].cur_y) {
		snprintf(avcmd, 16, "%c%d", avshift > 0 ? 'T' :'B', avshift > 0 ? avshift : -avshift);
		adjust_view(b, avcmd);
	}
	b->bookmark_mask &= ~(1 << WORDWRAP_BOOKMARK);
	if (non_blank_added) {
		goto_pos(b, prev_pos(b->cur_line_desc->line, b->cur_pos, b->encoding));
		delete_one_char(b, b->cur_line_desc, b->cur_line, b->cur_pos);
		end_undo_chain(b);
	}
	return stop ? STOPPED : OK;
}
Example #10
0
//
//check if there are some messages stored in the buffer
//if yes, output them.
//
void LLConsole::updateBuffer()
{
	BOOL need_clear = FALSE ;

	mMutex.lock() ;
	if(!mLines.empty())
	{				
		S32 end = mLines.size() ;
		LLColor4 color(1.f, 1.f, 1.f, 1.f) ;
		for(S32 i = 0 ; i < end ; i++)
		{
			Paragraph paragraph(mLines[i], color, mAddTimes[i], mFont,  (F32)getRect().getWidth() );
			mParagraphs.push_back ( paragraph );
		}		

		need_clear = TRUE ;		
	}
	mMutex.unlock() ;

	if(need_clear)
	{
		clear() ;
	}
}
Example #11
0
status_t
TextDocument::Insert(int32 textOffset, const BString& text,
	const CharacterStyle& characterStyle, const ParagraphStyle& paragraphStyle)
{
	int32 paragraphOffset;
	int32 index = ParagraphIndexFor(textOffset, paragraphOffset);
	if (index < 0)
		return B_BAD_VALUE;

	textOffset -= paragraphOffset;

	bool hasLineBreaks = text.FindFirst('\n', 0) >= 0;

	if (hasLineBreaks) {
		// Split paragraph at textOffset
		Paragraph paragraph1(ParagraphAt(index).Style());
		Paragraph paragraph2(paragraphStyle);
		const TextSpanList& textSpans = ParagraphAt(index).TextSpans();
		int32 spanCount = textSpans.CountItems();
		for (int32 i = 0; i < spanCount; i++) {
			const TextSpan& span = textSpans.ItemAtFast(i);
			int32 spanLength = span.CountChars();
			if (textOffset >= spanLength) {
				paragraph1.Append(span);
				textOffset -= spanLength;
			} else if (textOffset > 0) {
				paragraph1.Append(
					span.SubSpan(0, textOffset));
				paragraph2.Append(
					span.SubSpan(textOffset, spanLength - textOffset));
				textOffset = 0;
			} else {
				paragraph2.Append(span);
			}
		}

		fParagraphs.Remove(index);

		// Insert TextSpans, splitting 'text' into Paragraphs at line breaks.
		int32 length = text.CountChars();
		int32 chunkStart = 0;
		while (chunkStart < length) {
			int32 chunkEnd = text.FindFirst('\n', chunkStart);
			bool foundLineBreak = chunkEnd >= chunkStart;
			if (foundLineBreak)
				chunkEnd++;
			else
				chunkEnd = length;

			BString chunk;
			text.CopyCharsInto(chunk, chunkStart, chunkEnd - chunkStart);
			TextSpan span(chunk, characterStyle);

			if (foundLineBreak) {
				if (!paragraph1.Append(span))
					return B_NO_MEMORY;
				if (paragraph1.Length() > 0) {
					if (!fParagraphs.Add(paragraph1, index))
						return B_NO_MEMORY;
					index++;
				}
				paragraph1 = Paragraph(paragraphStyle);
			} else {
				if (!paragraph2.Prepend(span))
					return B_NO_MEMORY;
			}

			chunkStart = chunkEnd + 1;
		}

		if (paragraph2.IsEmpty()) {
			// Make sure Paragraph has at least one TextSpan, even
			// if its empty.
			const TextSpanList& spans = paragraph1.TextSpans();
			const TextSpan& span = spans.LastItem();
			paragraph2.Append(TextSpan("", span.Style()));
		}

		if (!fParagraphs.Add(paragraph2, index))
			return B_NO_MEMORY;
	} else {
		Paragraph paragraph(ParagraphAt(index));
		paragraph.Insert(textOffset, TextSpan(text, characterStyle));
		if (!fParagraphs.Replace(index, paragraph))
			return B_NO_MEMORY;
	}

	return B_OK;
}
Example #12
0
KoTextFormat * KoTextCustomItem::format() const
{
    KoTextParag * parag = paragraph();
    //kdDebug(32500) << "KoTextCustomItem::format index=" << index() << " format=" << parag->at( index() )->format() << endl;
    return parag->at( index() )->format();
}
Example #13
0
int KoTextCustomItem::index() const
{
    Q_ASSERT( paragraph() );
    KoTextParag * parag = paragraph();
    return parag->findCustomItem( this );
}
Example #14
0
void SpellChecker::markAndReplaceFor(PassRefPtr<SpellCheckRequest> request, const Vector<TextCheckingResult>& results)
{
    ASSERT(request);

    TextCheckingTypeMask textCheckingOptions = request->data().mask();
    TextCheckingParagraph paragraph(request->checkingRange(), request->paragraphRange());

    bool shouldMarkSpelling = textCheckingOptions & TextCheckingTypeSpelling;
    bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar;

    // Expand the range to encompass entire paragraphs, since text checking needs that much context.
    int selectionOffset = 0;
    int ambiguousBoundaryOffset = -1;
    bool selectionChanged = false;
    bool restoreSelectionAfterChange = false;
    bool adjustSelectionForParagraphBoundaries = false;

    if (shouldMarkSpelling) {
        if (m_frame.selection().isCaret()) {
            // Attempt to save the caret position so we can restore it later if needed
            Position caretPosition = m_frame.selection().end();
            selectionOffset = paragraph.offsetTo(caretPosition, ASSERT_NO_EXCEPTION);
            restoreSelectionAfterChange = true;
            if (selectionOffset > 0 && (static_cast<unsigned>(selectionOffset) > paragraph.text().length() || paragraph.textCharAt(selectionOffset - 1) == newlineCharacter))
                adjustSelectionForParagraphBoundaries = true;
            if (selectionOffset > 0 && static_cast<unsigned>(selectionOffset) <= paragraph.text().length() && isAmbiguousBoundaryCharacter(paragraph.textCharAt(selectionOffset - 1)))
                ambiguousBoundaryOffset = selectionOffset - 1;
        }
    }

    for (unsigned i = 0; i < results.size(); i++) {
        int spellingRangeEndOffset = paragraph.checkingEnd();
        const TextCheckingResult* result = &results[i];
        int resultLocation = result->location + paragraph.checkingStart();
        int resultLength = result->length;
        bool resultEndsAtAmbiguousBoundary = ambiguousBoundaryOffset >= 0 && resultLocation + resultLength == ambiguousBoundaryOffset;

        // Only mark misspelling if:
        // 1. Current text checking isn't done for autocorrection, in which case shouldMarkSpelling is false.
        // 2. Result falls within spellingRange.
        // 3. The word in question doesn't end at an ambiguous boundary. For instance, we would not mark
        //    "wouldn'" as misspelled right after apostrophe is typed.
        if (shouldMarkSpelling && result->decoration == TextDecorationTypeSpelling && resultLocation >= paragraph.checkingStart() && resultLocation + resultLength <= spellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) {
            ASSERT(resultLength > 0 && resultLocation >= 0);
            RefPtr<Range> misspellingRange = paragraph.subrange(resultLocation, resultLength);
            misspellingRange->startContainer()->document().markers().addMarker(misspellingRange.get(), DocumentMarker::Spelling, result->replacement, result->hash);
        } else if (shouldMarkGrammar && result->decoration == TextDecorationTypeGrammar && paragraph.checkingRangeCovers(resultLocation, resultLength)) {
            ASSERT(resultLength > 0 && resultLocation >= 0);
            for (unsigned j = 0; j < result->details.size(); j++) {
                const GrammarDetail* detail = &result->details[j];
                ASSERT(detail->length > 0 && detail->location >= 0);
                if (paragraph.checkingRangeCovers(resultLocation + detail->location, detail->length)) {
                    RefPtr<Range> badGrammarRange = paragraph.subrange(resultLocation + detail->location, detail->length);
                    badGrammarRange->startContainer()->document().markers().addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription, result->hash);
                }
            }
        } else if (result->decoration == TextDecorationTypeInvisibleSpellcheck && resultLocation >= paragraph.checkingStart() && resultLocation + resultLength <= spellingRangeEndOffset) {
            ASSERT(resultLength > 0 && resultLocation >= 0);
            RefPtr<Range> invisibleSpellcheckRange = paragraph.subrange(resultLocation, resultLength);
            invisibleSpellcheckRange->startContainer()->document().markers().addMarker(invisibleSpellcheckRange.get(), DocumentMarker::InvisibleSpellcheck, result->replacement, result->hash);
        }
    }

    if (selectionChanged) {
        TextCheckingParagraph extendedParagraph(paragraph);
        // Restore the caret position if we have made any replacements
        extendedParagraph.expandRangeToNextEnd();
        if (restoreSelectionAfterChange && selectionOffset >= 0 && selectionOffset <= extendedParagraph.rangeLength()) {
            RefPtr<Range> selectionRange = extendedParagraph.subrange(0, selectionOffset);
            m_frame.selection().moveTo(selectionRange->endPosition(), DOWNSTREAM);
            if (adjustSelectionForParagraphBoundaries)
                m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
        } else {
            // If this fails for any reason, the fallback is to go one position beyond the last replacement
            m_frame.selection().moveTo(m_frame.selection().selection().visibleEnd());
            m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
        }
    }
}
Example #15
0
Vector<String> TextCheckingHelper::guessesForMisspelledOrUngrammaticalRange(bool checkGrammar, bool& misspelled, bool& ungrammatical) const
{
#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
    Vector<String> guesses;
    ExceptionCode ec;
    misspelled = false;
    ungrammatical = false;
    
    if (!m_client || !m_range || m_range->collapsed(ec))
        return guesses;

    // Expand the range to encompass entire paragraphs, since text checking needs that much context.
    TextCheckingParagraph paragraph(m_range);
    if (paragraph.isEmpty())
        return guesses;

    Vector<TextCheckingResult> results;
    uint64_t checkingTypes = checkGrammar ? (TextCheckingTypeSpelling | TextCheckingTypeGrammar) : TextCheckingTypeSpelling;
    m_client->checkTextOfParagraph(paragraph.textCharacters(), paragraph.textLength(), checkingTypes, results);
    
    for (unsigned i = 0; i < results.size(); i++) {
        const TextCheckingResult* result = &results[i];
        if (result->type == TextCheckingTypeSpelling && paragraph.checkingRangeMatches(result->location, result->length)) {
            String misspelledWord = paragraph.checkingSubstring();
            ASSERT(misspelledWord.length());
            m_client->getGuessesForWord(misspelledWord, String(), guesses);
            m_client->updateSpellingUIWithMisspelledWord(misspelledWord);
            misspelled = true;
            return guesses;
        }
    }
    
    if (!checkGrammar)
        return guesses;
        
    for (unsigned i = 0; i < results.size(); i++) {
        const TextCheckingResult* result = &results[i];
        if (result->type == TextCheckingTypeGrammar && paragraph.isCheckingRangeCoveredBy(result->location, result->length)) {
            for (unsigned j = 0; j < result->details.size(); j++) {
                const GrammarDetail* detail = &result->details[j];
                ASSERT(detail->length > 0 && detail->location >= 0);
                if (paragraph.checkingRangeMatches(result->location + detail->location, detail->length)) {
                    String badGrammarPhrase = paragraph.textSubstring(result->location, result->length);
                    ASSERT(badGrammarPhrase.length());
                    for (unsigned k = 0; k < detail->guesses.size(); k++)
                        guesses.append(detail->guesses[k]);
                    m_client->updateSpellingUIWithGrammarString(badGrammarPhrase, *detail);
                    ungrammatical = true;
                    return guesses;
                }
            }
        }
    }
    return guesses;
#else
    ASSERT_NOT_REACHED();
    UNUSED_PARAM(checkGrammar);
    UNUSED_PARAM(misspelled);
    UNUSED_PARAM(ungrammatical);
    return Vector<String>();
#endif
}
Example #16
0
string Text_Text::get ()
{
  paragraph ();
  return filter_string_implode (output, "\n");
}