Migrate from ints to unsigneds when referring to indices into strings
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Aug 2016 01:22:55 +0000 (01:22 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Aug 2016 01:22:55 +0000 (01:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=160735

Reviewed by Simon Fraser.

There are a few cases where we use ints to refer to indices into strings:
- A simple historical accident. These were migrated to unsigneds directly.
- Where we use -1 as a sentinal value. These were migrated to Optional<unsigned>.

This patch only modifies rendering code (rather than DOM code). There are a few
places in DOM code (such as Position and Node::maxCharacterOffset()) which also
erroneously use ints; however, I didn't want this change to be observable from
script and I wanted to keep this patch to a reasonable size.

No new tests because there is no behavior change.

* editing/FrameSelection.cpp:
(WebCore::FrameSelection::updateAppearance):
(WebCore::FrameSelection::setCaretVisibility):
* platform/DragImage.cpp:
(WebCore::createDragImageForRange):
* platform/graphics/FontCascade.cpp:
(WebCore::FontCascade::glyphBufferForTextRun):
(WebCore::FontCascade::drawText):
(WebCore::FontCascade::drawEmphasisMarks):
(WebCore::FontCascade::adjustSelectionRectForText):
(WebCore::computeUnderlineType):
(WebCore::FontCascade::getGlyphsAndAdvancesForSimpleText):
(WebCore::FontCascade::drawEmphasisMarksForSimpleText):
(WebCore::FontCascade::drawGlyphBuffer):
(WebCore::offsetToMiddleOfGlyphAtIndex):
(WebCore::FontCascade::adjustSelectionRectForSimpleText):
* platform/graphics/FontCascade.h:
* platform/graphics/GlyphBuffer.h:
(WebCore::GlyphBuffer::size):
(WebCore::GlyphBuffer::glyphs):
(WebCore::GlyphBuffer::advances):
(WebCore::GlyphBuffer::fontAt):
(WebCore::GlyphBuffer::glyphAt):
(WebCore::GlyphBuffer::advanceAt):
(WebCore::GlyphBuffer::offsetAt):
(WebCore::GlyphBuffer::reverse):
(WebCore::GlyphBuffer::offsetInString):
(WebCore::GlyphBuffer::shrink):
(WebCore::GlyphBuffer::swap):
* platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContext::drawText):
(WebCore::GraphicsContext::drawGlyphs):
(WebCore::GraphicsContext::drawEmphasisMarks):
* platform/graphics/GraphicsContext.h:
* platform/graphics/Latin1TextIterator.h:
(WebCore::Latin1TextIterator::Latin1TextIterator):
(WebCore::Latin1TextIterator::currentCharacter):
* platform/graphics/SurrogatePairAwareTextIterator.cpp:
(WebCore::SurrogatePairAwareTextIterator::SurrogatePairAwareTextIterator):
* platform/graphics/SurrogatePairAwareTextIterator.h:
(WebCore::SurrogatePairAwareTextIterator::currentCharacter):
* platform/graphics/WidthIterator.cpp:
(WebCore::WidthIterator::applyFontTransforms):
(WebCore::WidthIterator::advanceInternal):
(WebCore::WidthIterator::advance):
(WebCore::WidthIterator::advanceOneCharacter):
* platform/graphics/WidthIterator.h:
* platform/graphics/cairo/FontCairo.cpp:
(WebCore::drawGlyphsToContext):
(WebCore::drawGlyphsShadow):
(WebCore::FontCascade::drawGlyphs):
* platform/graphics/cairo/FontCairoHarfbuzzNG.cpp:
(WebCore::FontCascade::getGlyphsAndAdvancesForComplexText):
(WebCore::FontCascade::drawEmphasisMarksForComplexText):
(WebCore::FontCascade::adjustSelectionRectForComplexText):
* platform/graphics/cocoa/FontCascadeCocoa.mm:
(WebCore::fillVectorWithHorizontalGlyphPositions):
(WebCore::showLetterpressedGlyphsWithAdvances):
(WebCore::showGlyphsWithAdvances):
(WebCore::FontCascade::drawGlyphs):
(WebCore::FontCascade::dashesForIntersectionsWithRect):
(WebCore::FontCascade::adjustSelectionRectForComplexText):
(WebCore::FontCascade::getGlyphsAndAdvancesForComplexText):
(WebCore::FontCascade::drawEmphasisMarksForComplexText):
* platform/graphics/displaylists/DisplayListRecorder.cpp:
(WebCore::DisplayList::Recorder::drawGlyphs):
* platform/graphics/displaylists/DisplayListRecorder.h:
* platform/graphics/harfbuzz/HarfBuzzShaper.cpp:
(WebCore::HarfBuzzShaper::selectionRect):
* platform/graphics/harfbuzz/HarfBuzzShaper.h:
* platform/graphics/mac/ComplexTextController.h:
* platform/graphics/win/FontCGWin.cpp:
(WebCore::FontCascade::drawGlyphs):
* platform/graphics/win/FontWin.cpp:
(WebCore::FontCascade::adjustSelectionRectForComplexText):
(WebCore::FontCascade::getGlyphsAndAdvancesForComplexText):
(WebCore::FontCascade::drawEmphasisMarksForComplexText):
* rendering/EllipsisBox.cpp:
(WebCore::EllipsisBox::paintSelection):
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::isSelected):
(WebCore::InlineTextBox::selectionState):
(WebCore::InlineTextBox::localSelectionRect):
(WebCore::InlineTextBox::paint):
(WebCore::InlineTextBox::clampedOffset):
(WebCore::InlineTextBox::selectionStartEnd):
(WebCore::InlineTextBox::paintSelection):
(WebCore::InlineTextBox::paintCompositionBackground):
(WebCore::InlineTextBox::paintDocumentMarker):
(WebCore::InlineTextBox::paintTextMatchMarker):
(WebCore::InlineTextBox::positionForOffset):
* rendering/InlineTextBox.h:
(WebCore::InlineTextBox::offsetRun):
(WebCore::InlineTextBox::InlineTextBox): Deleted.
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::localCaretRect):
* rendering/RenderBlock.h:
* rendering/RenderBox.cpp:
(WebCore::RenderBox::localCaretRect):
* rendering/RenderBox.h:
* rendering/RenderInline.cpp:
(WebCore::RenderInline::localCaretRect):
* rendering/RenderInline.h:
* rendering/RenderLineBreak.cpp:
(WebCore::RenderLineBreak::localCaretRect):
* rendering/RenderLineBreak.h:
* rendering/RenderObject.cpp:
(WebCore::RenderObject::selectionStartEnd):
(WebCore::RenderObject::localCaretRect):
* rendering/RenderObject.h:
* rendering/RenderReplaced.cpp:
(WebCore::RenderReplaced::isSelected):
* rendering/RenderText.cpp:
(WebCore::RenderText::localCaretRect):
(WebCore::RenderText::collectSelectionRectsForLineBoxes):
* rendering/RenderText.h:
* rendering/RenderTextLineBoxes.cpp:
(WebCore::RenderTextLineBoxes::setSelectionState):
* rendering/RenderView.cpp:
(WebCore::RenderView::subtreeSelectionBounds):
(WebCore::RenderView::repaintSubtreeSelection):
(WebCore::RenderView::setSelection):
(WebCore::RenderView::splitSelectionBetweenSubtrees):
(WebCore::RenderView::clearSubtreeSelection):
(WebCore::RenderView::applySubtreeSelection):
(WebCore::RenderView::getSelection):
(WebCore::RenderView::clearSelection):
(WebCore::RenderView::RenderView): Deleted.
* rendering/RenderView.h:
* rendering/SelectionSubtreeRoot.cpp:
(WebCore::SelectionSubtreeRoot::adjustForVisibleSelection):
(WebCore::SelectionSubtreeRoot::SelectionSubtreeRoot): Deleted.
* rendering/SelectionSubtreeRoot.h:
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::SelectionSubtreeData):
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStartPos):
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionEndPos):
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionClear):
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStartEndPositions):
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::setSelectionStartPos):
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::setSelectionEndPos):
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::clearSelection):
(WebCore::SelectionSubtreeRoot::OldSelectionData::OldSelectionData): Deleted.
* rendering/TextPainter.cpp:
(WebCore::TextPainter::drawTextOrEmphasisMarks):
(WebCore::TextPainter::paintTextWithShadows):
(WebCore::TextPainter::paintTextAndEmphasisMarksIfNeeded):
(WebCore::TextPainter::paintText):
* rendering/TextPainter.h:
(WebCore::TextPainter::addEmphasis):
* rendering/svg/RenderSVGInlineText.cpp:
(WebCore::RenderSVGInlineText::localCaretRect):
* rendering/svg/RenderSVGInlineText.h:
* rendering/svg/SVGInlineTextBox.cpp:
(WebCore::SVGInlineTextBox::positionForOffset):
(WebCore::SVGInlineTextBox::selectionRectForTextFragment):
(WebCore::SVGInlineTextBox::localSelectionRect):
(WebCore::SVGInlineTextBox::paintSelectionBackground):
(WebCore::SVGInlineTextBox::mapStartEndPositionsIntoFragmentCoordinates):
(WebCore::SVGInlineTextBox::paintTextWithShadows):
(WebCore::SVGInlineTextBox::paintText):
* rendering/svg/SVGInlineTextBox.h:
* rendering/svg/SVGTextQuery.cpp:
(WebCore::SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates):
(WebCore::SVGTextQuery::modifyStartEndPositionsRespectingLigatures):
(WebCore::SVGTextQuery::subStringLengthCallback):
(WebCore::SVGTextQuery::startPositionOfCharacterCallback):
(WebCore::SVGTextQuery::endPositionOfCharacterCallback):
(WebCore::SVGTextQuery::rotationOfCharacterCallback):
(WebCore::calculateGlyphBoundaries):
(WebCore::SVGTextQuery::extentOfCharacterCallback):
(WebCore::SVGTextQuery::characterNumberAtPositionCallback):
* rendering/svg/SVGTextQuery.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@204400 268f45cc-cd09-0410-ab3c-d52691b4dbfc

52 files changed:
Source/WebCore/ChangeLog
Source/WebCore/editing/FrameSelection.cpp
Source/WebCore/platform/DragImage.cpp
Source/WebCore/platform/graphics/FontCascade.cpp
Source/WebCore/platform/graphics/FontCascade.h
Source/WebCore/platform/graphics/GlyphBuffer.h
Source/WebCore/platform/graphics/GraphicsContext.cpp
Source/WebCore/platform/graphics/GraphicsContext.h
Source/WebCore/platform/graphics/Latin1TextIterator.h
Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.cpp
Source/WebCore/platform/graphics/SurrogatePairAwareTextIterator.h
Source/WebCore/platform/graphics/WidthIterator.cpp
Source/WebCore/platform/graphics/WidthIterator.h
Source/WebCore/platform/graphics/cairo/FontCairo.cpp
Source/WebCore/platform/graphics/cairo/FontCairoHarfbuzzNG.cpp
Source/WebCore/platform/graphics/cocoa/FontCascadeCocoa.mm
Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp
Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h
Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp
Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.h
Source/WebCore/platform/graphics/mac/ComplexTextController.h
Source/WebCore/platform/graphics/win/FontCGWin.cpp
Source/WebCore/platform/graphics/win/FontWin.cpp
Source/WebCore/rendering/EllipsisBox.cpp
Source/WebCore/rendering/InlineTextBox.cpp
Source/WebCore/rendering/InlineTextBox.h
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBox.h
Source/WebCore/rendering/RenderInline.cpp
Source/WebCore/rendering/RenderInline.h
Source/WebCore/rendering/RenderLineBreak.cpp
Source/WebCore/rendering/RenderLineBreak.h
Source/WebCore/rendering/RenderObject.cpp
Source/WebCore/rendering/RenderObject.h
Source/WebCore/rendering/RenderReplaced.cpp
Source/WebCore/rendering/RenderText.cpp
Source/WebCore/rendering/RenderText.h
Source/WebCore/rendering/RenderTextLineBoxes.cpp
Source/WebCore/rendering/RenderView.cpp
Source/WebCore/rendering/RenderView.h
Source/WebCore/rendering/SelectionSubtreeRoot.cpp
Source/WebCore/rendering/SelectionSubtreeRoot.h
Source/WebCore/rendering/TextPainter.cpp
Source/WebCore/rendering/TextPainter.h
Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
Source/WebCore/rendering/svg/RenderSVGInlineText.h
Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
Source/WebCore/rendering/svg/SVGInlineTextBox.h
Source/WebCore/rendering/svg/SVGTextQuery.cpp
Source/WebCore/rendering/svg/SVGTextQuery.h

index 8de3427..a0efb71 100644 (file)
@@ -1,3 +1,194 @@
+2016-08-11  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Migrate from ints to unsigneds when referring to indices into strings
+        https://bugs.webkit.org/show_bug.cgi?id=160735
+
+        Reviewed by Simon Fraser.
+
+        There are a few cases where we use ints to refer to indices into strings:
+        - A simple historical accident. These were migrated to unsigneds directly.
+        - Where we use -1 as a sentinal value. These were migrated to Optional<unsigned>.
+
+        This patch only modifies rendering code (rather than DOM code). There are a few
+        places in DOM code (such as Position and Node::maxCharacterOffset()) which also
+        erroneously use ints; however, I didn't want this change to be observable from
+        script and I wanted to keep this patch to a reasonable size.
+
+        No new tests because there is no behavior change.
+
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::updateAppearance):
+        (WebCore::FrameSelection::setCaretVisibility):
+        * platform/DragImage.cpp:
+        (WebCore::createDragImageForRange):
+        * platform/graphics/FontCascade.cpp:
+        (WebCore::FontCascade::glyphBufferForTextRun):
+        (WebCore::FontCascade::drawText):
+        (WebCore::FontCascade::drawEmphasisMarks):
+        (WebCore::FontCascade::adjustSelectionRectForText):
+        (WebCore::computeUnderlineType):
+        (WebCore::FontCascade::getGlyphsAndAdvancesForSimpleText):
+        (WebCore::FontCascade::drawEmphasisMarksForSimpleText):
+        (WebCore::FontCascade::drawGlyphBuffer):
+        (WebCore::offsetToMiddleOfGlyphAtIndex):
+        (WebCore::FontCascade::adjustSelectionRectForSimpleText):
+        * platform/graphics/FontCascade.h:
+        * platform/graphics/GlyphBuffer.h:
+        (WebCore::GlyphBuffer::size):
+        (WebCore::GlyphBuffer::glyphs):
+        (WebCore::GlyphBuffer::advances):
+        (WebCore::GlyphBuffer::fontAt):
+        (WebCore::GlyphBuffer::glyphAt):
+        (WebCore::GlyphBuffer::advanceAt):
+        (WebCore::GlyphBuffer::offsetAt):
+        (WebCore::GlyphBuffer::reverse):
+        (WebCore::GlyphBuffer::offsetInString):
+        (WebCore::GlyphBuffer::shrink):
+        (WebCore::GlyphBuffer::swap):
+        * platform/graphics/GraphicsContext.cpp:
+        (WebCore::GraphicsContext::drawText):
+        (WebCore::GraphicsContext::drawGlyphs):
+        (WebCore::GraphicsContext::drawEmphasisMarks):
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/Latin1TextIterator.h:
+        (WebCore::Latin1TextIterator::Latin1TextIterator):
+        (WebCore::Latin1TextIterator::currentCharacter):
+        * platform/graphics/SurrogatePairAwareTextIterator.cpp:
+        (WebCore::SurrogatePairAwareTextIterator::SurrogatePairAwareTextIterator):
+        * platform/graphics/SurrogatePairAwareTextIterator.h:
+        (WebCore::SurrogatePairAwareTextIterator::currentCharacter):
+        * platform/graphics/WidthIterator.cpp:
+        (WebCore::WidthIterator::applyFontTransforms):
+        (WebCore::WidthIterator::advanceInternal):
+        (WebCore::WidthIterator::advance):
+        (WebCore::WidthIterator::advanceOneCharacter):
+        * platform/graphics/WidthIterator.h:
+        * platform/graphics/cairo/FontCairo.cpp:
+        (WebCore::drawGlyphsToContext):
+        (WebCore::drawGlyphsShadow):
+        (WebCore::FontCascade::drawGlyphs):
+        * platform/graphics/cairo/FontCairoHarfbuzzNG.cpp:
+        (WebCore::FontCascade::getGlyphsAndAdvancesForComplexText):
+        (WebCore::FontCascade::drawEmphasisMarksForComplexText):
+        (WebCore::FontCascade::adjustSelectionRectForComplexText):
+        * platform/graphics/cocoa/FontCascadeCocoa.mm:
+        (WebCore::fillVectorWithHorizontalGlyphPositions):
+        (WebCore::showLetterpressedGlyphsWithAdvances):
+        (WebCore::showGlyphsWithAdvances):
+        (WebCore::FontCascade::drawGlyphs):
+        (WebCore::FontCascade::dashesForIntersectionsWithRect):
+        (WebCore::FontCascade::adjustSelectionRectForComplexText):
+        (WebCore::FontCascade::getGlyphsAndAdvancesForComplexText):
+        (WebCore::FontCascade::drawEmphasisMarksForComplexText):
+        * platform/graphics/displaylists/DisplayListRecorder.cpp:
+        (WebCore::DisplayList::Recorder::drawGlyphs):
+        * platform/graphics/displaylists/DisplayListRecorder.h:
+        * platform/graphics/harfbuzz/HarfBuzzShaper.cpp:
+        (WebCore::HarfBuzzShaper::selectionRect):
+        * platform/graphics/harfbuzz/HarfBuzzShaper.h:
+        * platform/graphics/mac/ComplexTextController.h:
+        * platform/graphics/win/FontCGWin.cpp:
+        (WebCore::FontCascade::drawGlyphs):
+        * platform/graphics/win/FontWin.cpp:
+        (WebCore::FontCascade::adjustSelectionRectForComplexText):
+        (WebCore::FontCascade::getGlyphsAndAdvancesForComplexText):
+        (WebCore::FontCascade::drawEmphasisMarksForComplexText):
+        * rendering/EllipsisBox.cpp:
+        (WebCore::EllipsisBox::paintSelection):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::isSelected):
+        (WebCore::InlineTextBox::selectionState):
+        (WebCore::InlineTextBox::localSelectionRect):
+        (WebCore::InlineTextBox::paint):
+        (WebCore::InlineTextBox::clampedOffset):
+        (WebCore::InlineTextBox::selectionStartEnd):
+        (WebCore::InlineTextBox::paintSelection):
+        (WebCore::InlineTextBox::paintCompositionBackground):
+        (WebCore::InlineTextBox::paintDocumentMarker):
+        (WebCore::InlineTextBox::paintTextMatchMarker):
+        (WebCore::InlineTextBox::positionForOffset):
+        * rendering/InlineTextBox.h:
+        (WebCore::InlineTextBox::offsetRun):
+        (WebCore::InlineTextBox::InlineTextBox): Deleted.
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::localCaretRect):
+        * rendering/RenderBlock.h:
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::localCaretRect):
+        * rendering/RenderBox.h:
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::localCaretRect):
+        * rendering/RenderInline.h:
+        * rendering/RenderLineBreak.cpp:
+        (WebCore::RenderLineBreak::localCaretRect):
+        * rendering/RenderLineBreak.h:
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::selectionStartEnd):
+        (WebCore::RenderObject::localCaretRect):
+        * rendering/RenderObject.h:
+        * rendering/RenderReplaced.cpp:
+        (WebCore::RenderReplaced::isSelected):
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::localCaretRect):
+        (WebCore::RenderText::collectSelectionRectsForLineBoxes):
+        * rendering/RenderText.h:
+        * rendering/RenderTextLineBoxes.cpp:
+        (WebCore::RenderTextLineBoxes::setSelectionState):
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::subtreeSelectionBounds):
+        (WebCore::RenderView::repaintSubtreeSelection):
+        (WebCore::RenderView::setSelection):
+        (WebCore::RenderView::splitSelectionBetweenSubtrees):
+        (WebCore::RenderView::clearSubtreeSelection):
+        (WebCore::RenderView::applySubtreeSelection):
+        (WebCore::RenderView::getSelection):
+        (WebCore::RenderView::clearSelection):
+        (WebCore::RenderView::RenderView): Deleted.
+        * rendering/RenderView.h:
+        * rendering/SelectionSubtreeRoot.cpp:
+        (WebCore::SelectionSubtreeRoot::adjustForVisibleSelection):
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeRoot): Deleted.
+        * rendering/SelectionSubtreeRoot.h:
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::SelectionSubtreeData):
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStartPos):
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionEndPos):
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionClear):
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStartEndPositions):
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::setSelectionStartPos):
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::setSelectionEndPos):
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::clearSelection):
+        (WebCore::SelectionSubtreeRoot::OldSelectionData::OldSelectionData): Deleted.
+        * rendering/TextPainter.cpp:
+        (WebCore::TextPainter::drawTextOrEmphasisMarks):
+        (WebCore::TextPainter::paintTextWithShadows):
+        (WebCore::TextPainter::paintTextAndEmphasisMarksIfNeeded):
+        (WebCore::TextPainter::paintText):
+        * rendering/TextPainter.h:
+        (WebCore::TextPainter::addEmphasis):
+        * rendering/svg/RenderSVGInlineText.cpp:
+        (WebCore::RenderSVGInlineText::localCaretRect):
+        * rendering/svg/RenderSVGInlineText.h:
+        * rendering/svg/SVGInlineTextBox.cpp:
+        (WebCore::SVGInlineTextBox::positionForOffset):
+        (WebCore::SVGInlineTextBox::selectionRectForTextFragment):
+        (WebCore::SVGInlineTextBox::localSelectionRect):
+        (WebCore::SVGInlineTextBox::paintSelectionBackground):
+        (WebCore::SVGInlineTextBox::mapStartEndPositionsIntoFragmentCoordinates):
+        (WebCore::SVGInlineTextBox::paintTextWithShadows):
+        (WebCore::SVGInlineTextBox::paintText):
+        * rendering/svg/SVGInlineTextBox.h:
+        * rendering/svg/SVGTextQuery.cpp:
+        (WebCore::SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates):
+        (WebCore::SVGTextQuery::modifyStartEndPositionsRespectingLigatures):
+        (WebCore::SVGTextQuery::subStringLengthCallback):
+        (WebCore::SVGTextQuery::startPositionOfCharacterCallback):
+        (WebCore::SVGTextQuery::endPositionOfCharacterCallback):
+        (WebCore::SVGTextQuery::rotationOfCharacterCallback):
+        (WebCore::calculateGlyphBoundaries):
+        (WebCore::SVGTextQuery::extentOfCharacterCallback):
+        (WebCore::SVGTextQuery::characterNumberAtPositionCallback):
+        * rendering/svg/SVGTextQuery.h:
+
 2016-08-11  Alex Christensen  <achristensen@webkit.org>
 
         Don't use a NetworkingContext when creating SocketStreamHandles
index 33834ad..6e11049 100644 (file)
@@ -2088,8 +2088,11 @@ void FrameSelection::updateAppearance()
     // because we don't yet notify the FrameSelection of text removal.
     if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) {
         RenderObject* startRenderer = startPos.deprecatedNode()->renderer();
+        int startOffset = startPos.deprecatedEditingOffset();
         RenderObject* endRenderer = endPos.deprecatedNode()->renderer();
-        view->setSelection(startRenderer, startPos.deprecatedEditingOffset(), endRenderer, endPos.deprecatedEditingOffset());
+        int endOffset = endPos.deprecatedEditingOffset();
+        ASSERT(startOffset >= 0 && endOffset >= 0);
+        view->setSelection(startRenderer, startOffset, endRenderer, endOffset);
     }
 }
 
@@ -2098,7 +2101,7 @@ void FrameSelection::setCaretVisibility(CaretVisibility visibility)
     if (caretVisibility() == visibility)
         return;
 
-    // FIXME: We shouldn't trigger a synchrnously layout here.
+    // FIXME: We shouldn't trigger a synchronous layout here.
     if (m_frame)
         updateSelectionByUpdatingLayoutOrStyle(*m_frame);
 
index d3cbc1a..5290deb 100644 (file)
@@ -141,8 +141,8 @@ struct ScopedFrameSelectionState {
     const Frame& frame;
     RenderObject* startRenderer;
     RenderObject* endRenderer;
-    int startOffset;
-    int endOffset;
+    Optional<unsigned> startOffset;
+    Optional<unsigned> endOffset;
 };
 
 DragImageRef createDragImageForRange(Frame& frame, Range& range, bool forceBlackText)
@@ -174,7 +174,10 @@ DragImageRef createDragImageForRange(Frame& frame, Range& range, bool forceBlack
         return nullptr;
 
     SnapshotOptions options = SnapshotOptionsPaintSelectionOnly | (forceBlackText ? SnapshotOptionsForceBlackText : SnapshotOptionsNone);
-    view->setSelection(startRenderer, start.deprecatedEditingOffset(), endRenderer, end.deprecatedEditingOffset(), RenderView::RepaintNothing);
+    int startOffset = start.deprecatedEditingOffset();
+    int endOffset = end.deprecatedEditingOffset();
+    ASSERT(startOffset >= 0 && endOffset >= 0);
+    view->setSelection(startRenderer, startOffset, endRenderer, endOffset, RenderView::RepaintNothing);
     // We capture using snapshotFrameRect() because we fake up the selection using
     // FrameView but snapshotSelection() uses the selection from the Frame itself.
     return createDragImageFromSnapshot(snapshotFrameRect(frame, view->selectionBounds(), options), nullptr);
index 4380b5c..3866991 100644 (file)
@@ -294,14 +294,14 @@ void FontCascade::update(RefPtr<FontSelector>&& fontSelector) const
     m_requiresShaping = computeRequiresShaping();
 }
 
-float FontCascade::glyphBufferForTextRun(CodePath codePathToUse, const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer) const
+float FontCascade::glyphBufferForTextRun(CodePath codePathToUse, const TextRun& run, unsigned from, unsigned to, GlyphBuffer& glyphBuffer) const
 {
     if (codePathToUse != Complex)
         return getGlyphsAndAdvancesForSimpleText(run, from, to, glyphBuffer);
     return getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer);
 }
 
-float FontCascade::drawText(GraphicsContext& context, const TextRun& run, const FloatPoint& point, int from, int to, CustomFontNotReadyAction customFontNotReadyAction) const
+float FontCascade::drawText(GraphicsContext& context, const TextRun& run, const FloatPoint& point, unsigned from, Optional<unsigned> to, CustomFontNotReadyAction customFontNotReadyAction) const
 {
     // Don't draw anything while we are using custom fonts that are in the process of loading,
     // except if the 'force' argument is set to true (in which case it will use a fallback
@@ -309,15 +309,15 @@ float FontCascade::drawText(GraphicsContext& context, const TextRun& run, const
     if (isLoadingCustomFonts() && customFontNotReadyAction == DoNotPaintIfFontNotReady)
         return 0;
 
-    to = (to == -1 ? run.length() : to);
+    unsigned destination = to.valueOr(run.length());
 
     CodePath codePathToUse = codePath(run);
     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
-    if (codePathToUse != Complex && (enableKerning() || requiresShaping()) && (from || static_cast<unsigned>(to) != run.length()))
+    if (codePathToUse != Complex && (enableKerning() || requiresShaping()) && (from || destination != run.length()))
         codePathToUse = Complex;
 
     GlyphBuffer glyphBuffer;
-    float startX = point.x() + glyphBufferForTextRun(codePathToUse, run, from, to, glyphBuffer);
+    float startX = point.x() + glyphBufferForTextRun(codePathToUse, run, from, destination, glyphBuffer);
     // We couldn't generate any glyphs for the run. Give up.
     if (glyphBuffer.isEmpty())
         return 0;
@@ -327,23 +327,22 @@ float FontCascade::drawText(GraphicsContext& context, const TextRun& run, const
     return startPoint.x() - startX;
 }
 
-void FontCascade::drawEmphasisMarks(GraphicsContext& context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+void FontCascade::drawEmphasisMarks(GraphicsContext& context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, unsigned from, Optional<unsigned> to) const
 {
     if (isLoadingCustomFonts())
         return;
 
-    if (to < 0)
-        to = run.length();
+    unsigned destination = to.valueOr(run.length());
 
     CodePath codePathToUse = codePath(run);
     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
-    if (codePathToUse != Complex && (enableKerning() || requiresShaping()) && (from || static_cast<unsigned>(to) != run.length()))
+    if (codePathToUse != Complex && (enableKerning() || requiresShaping()) && (from || destination != run.length()))
         codePathToUse = Complex;
 
     if (codePathToUse != Complex)
-        drawEmphasisMarksForSimpleText(context, run, mark, point, from, to);
+        drawEmphasisMarksForSimpleText(context, run, mark, point, from, destination);
     else
-        drawEmphasisMarksForComplexText(context, run, mark, point, from, to);
+        drawEmphasisMarksForComplexText(context, run, mark, point, from, destination);
 }
 
 float FontCascade::width(const TextRun& run, HashSet<const Font*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
@@ -491,19 +490,19 @@ bool FontCascade::fastAverageCharWidthIfAvailable(float& width) const
     return success;
 }
 
-void FontCascade::adjustSelectionRectForText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
+void FontCascade::adjustSelectionRectForText(const TextRun& run, LayoutRect& selectionRect, unsigned from, Optional<unsigned> to) const
 {
-    to = (to == -1 ? run.length() : to);
+    unsigned destination = to.valueOr(run.length());
 
     CodePath codePathToUse = codePath(run);
     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
-    if (codePathToUse != Complex && (enableKerning() || requiresShaping()) && (from || static_cast<unsigned>(to) != run.length()))
+    if (codePathToUse != Complex && (enableKerning() || requiresShaping()) && (from || destination != run.length()))
         codePathToUse = Complex;
 
     if (codePathToUse != Complex)
-        return adjustSelectionRectForSimpleText(run, selectionRect, from, to);
+        return adjustSelectionRectForSimpleText(run, selectionRect, from, destination);
 
-    return adjustSelectionRectForComplexText(run, selectionRect, from, to);
+    return adjustSelectionRectForComplexText(run, selectionRect, from, destination);
 }
 
 int FontCascade::offsetForPosition(const TextRun& run, float x, bool includePartialGlyphs) const
@@ -1123,7 +1122,7 @@ bool FontCascade::isLoadingCustomFonts() const
     return m_fonts && m_fonts->isLoadingCustomFonts();
 }
     
-GlyphToPathTranslator::GlyphUnderlineType computeUnderlineType(const TextRun& textRun, const GlyphBuffer& glyphBuffer, int index)
+GlyphToPathTranslator::GlyphUnderlineType computeUnderlineType(const TextRun& textRun, const GlyphBuffer& glyphBuffer, unsigned index)
 {
     // In general, we want to skip descenders. However, skipping descenders on CJK characters leads to undesirable renderings,
     // so we want to draw through CJK characters (on a character-by-character basis).
@@ -1238,7 +1237,7 @@ int FontCascade::emphasisMarkHeight(const AtomicString& mark) const
     return markFontData->fontMetrics().height();
 }
 
-float FontCascade::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
+float FontCascade::getGlyphsAndAdvancesForSimpleText(const TextRun& run, unsigned from, unsigned to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
 {
     float initialAdvance;
 
@@ -1268,7 +1267,7 @@ float FontCascade::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int fro
     return initialAdvance;
 }
 
-void FontCascade::drawEmphasisMarksForSimpleText(GraphicsContext& context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+void FontCascade::drawEmphasisMarksForSimpleText(GraphicsContext& context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, unsigned from, unsigned to) const
 {
     GlyphBuffer glyphBuffer;
     float initialAdvance = getGlyphsAndAdvancesForSimpleText(run, from, to, glyphBuffer, ForTextEmphasis);
@@ -1287,8 +1286,8 @@ void FontCascade::drawGlyphBuffer(GraphicsContext& context, const GlyphBuffer& g
     FloatPoint startPoint(point.x(), point.y() - glyphBuffer.initialAdvance().height());
     float nextX = startPoint.x() + glyphBuffer.advanceAt(0).width();
     float nextY = startPoint.y() + glyphBuffer.advanceAt(0).height();
-    int lastFrom = 0;
-    int nextGlyph = 1;
+    unsigned lastFrom = 0;
+    unsigned nextGlyph = 1;
     while (nextGlyph < glyphBuffer.size()) {
         const Font* nextFontData = glyphBuffer.fontAt(nextGlyph);
         FloatSize nextOffset = glyphBuffer.offsetAt(nextGlyph);
@@ -1321,7 +1320,7 @@ inline static float offsetToMiddleOfGlyph(const Font* fontData, Glyph glyph)
     return fontData->widthForGlyph(glyph) / 2;
 }
 
-inline static float offsetToMiddleOfGlyphAtIndex(const GlyphBuffer& glyphBuffer, size_t i)
+inline static float offsetToMiddleOfGlyphAtIndex(const GlyphBuffer& glyphBuffer, unsigned i)
 {
     return offsetToMiddleOfGlyph(glyphBuffer.fontAt(i), glyphBuffer.glyphAt(i));
 }
@@ -1344,7 +1343,7 @@ void FontCascade::drawEmphasisMarks(GraphicsContext& context, const GlyphBuffer&
     FloatPoint startPoint(point.x() + middleOfLastGlyph - offsetToMiddleOfGlyph(markFontData, markGlyph), point.y());
 
     GlyphBuffer markBuffer;
-    for (int i = 0; i + 1 < glyphBuffer.size(); ++i) {
+    for (unsigned i = 0; i + 1 < glyphBuffer.size(); ++i) {
         float middleOfNextGlyph = offsetToMiddleOfGlyphAtIndex(glyphBuffer, i + 1);
         float advance = glyphBuffer.advanceAt(i).width() - middleOfLastGlyph + middleOfNextGlyph;
         markBuffer.add(glyphBuffer.glyphAt(i) ? markGlyph : spaceGlyph, markFontData, advance);
@@ -1371,7 +1370,7 @@ float FontCascade::floatWidthForSimpleText(const TextRun& run, HashSet<const Fon
     return it.m_runWidthSoFar;
 }
 
-void FontCascade::adjustSelectionRectForSimpleText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
+void FontCascade::adjustSelectionRectForSimpleText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
 {
     GlyphBuffer glyphBuffer;
     WidthIterator it(this, run);
index c6d0c25..8bdcca8 100644 (file)
@@ -105,7 +105,7 @@ public:
     virtual void advance() = 0;
     virtual ~GlyphToPathTranslator() { }
 };
-GlyphToPathTranslator::GlyphUnderlineType computeUnderlineType(const TextRun&, const GlyphBuffer&, int index);
+GlyphToPathTranslator::GlyphUnderlineType computeUnderlineType(const TextRun&, const GlyphBuffer&, unsigned index);
 
 class TextLayoutDeleter {
 public:
@@ -133,9 +133,9 @@ public:
     void update(RefPtr<FontSelector>&&) const;
 
     enum CustomFontNotReadyAction { DoNotPaintIfFontNotReady, UseFallbackIfFontNotReady };
-    WEBCORE_EXPORT float drawText(GraphicsContext&, const TextRun&, const FloatPoint&, int from = 0, int to = -1, CustomFontNotReadyAction = DoNotPaintIfFontNotReady) const;
-    static void drawGlyphs(GraphicsContext&, const Font&, const GlyphBuffer&, int from, int numGlyphs, const FloatPoint&, FontSmoothingMode);
-    void drawEmphasisMarks(GraphicsContext&, const TextRun&, const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1) const;
+    WEBCORE_EXPORT float drawText(GraphicsContext&, const TextRun&, const FloatPoint&, unsigned from = 0, Optional<unsigned> to = Nullopt, CustomFontNotReadyAction = DoNotPaintIfFontNotReady) const;
+    static void drawGlyphs(GraphicsContext&, const Font&, const GlyphBuffer&, unsigned from, unsigned numGlyphs, const FloatPoint&, FontSmoothingMode);
+    void drawEmphasisMarks(GraphicsContext&, const TextRun&, const AtomicString& mark, const FloatPoint&, unsigned from = 0, Optional<unsigned> to = Nullopt) const;
 
     DashArray dashesForIntersectionsWithRect(const TextRun&, const FloatPoint& textOrigin, const FloatRect& lineExtents) const;
 
@@ -145,7 +145,7 @@ public:
     static float width(TextLayout&, unsigned from, unsigned len, HashSet<const Font*>* fallbackFonts = 0);
 
     int offsetForPosition(const TextRun&, float position, bool includePartialGlyphs) const;
-    void adjustSelectionRectForText(const TextRun&, LayoutRect& selectionRect, int from = 0, int to = -1) const;
+    void adjustSelectionRectForText(const TextRun&, LayoutRect& selectionRect, unsigned from = 0, Optional<unsigned> to = Nullopt) const;
 
     bool isSmallCaps() const { return m_fontDescription.variantCaps() == FontVariantCaps::Small; }
 
@@ -218,15 +218,15 @@ public:
 private:
     enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis };
 
-    float glyphBufferForTextRun(CodePath, const TextRun&, int from, int to, GlyphBuffer&) const;
+    float glyphBufferForTextRun(CodePath, const TextRun&, unsigned from, unsigned to, GlyphBuffer&) const;
     // Returns the initial in-stream advance.
-    float getGlyphsAndAdvancesForSimpleText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
-    void drawEmphasisMarksForSimpleText(GraphicsContext&, const TextRun&, const AtomicString& mark, const FloatPoint&, int from, int to) const;
+    float getGlyphsAndAdvancesForSimpleText(const TextRun&, unsigned from, unsigned to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
+    void drawEmphasisMarksForSimpleText(GraphicsContext&, const TextRun&, const AtomicString& mark, const FloatPoint&, unsigned from, unsigned to) const;
     void drawGlyphBuffer(GraphicsContext&, const GlyphBuffer&, FloatPoint&) const;
     void drawEmphasisMarks(GraphicsContext&, const GlyphBuffer&, const AtomicString&, const FloatPoint&) const;
     float floatWidthForSimpleText(const TextRun&, HashSet<const Font*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
     int offsetForPositionForSimpleText(const TextRun&, float position, bool includePartialGlyphs) const;
-    void adjustSelectionRectForSimpleText(const TextRun&, LayoutRect& selectionRect, int from, int to) const;
+    void adjustSelectionRectForSimpleText(const TextRun&, LayoutRect& selectionRect, unsigned from, unsigned to) const;
 
     Optional<GlyphData> getEmphasisMarkGlyphData(const AtomicString&) const;
 
@@ -234,11 +234,11 @@ private:
     static bool canExpandAroundIdeographsInComplexText();
 
     // Returns the initial in-stream advance.
-    float getGlyphsAndAdvancesForComplexText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
-    void drawEmphasisMarksForComplexText(GraphicsContext&, const TextRun&, const AtomicString& mark, const FloatPoint&, int from, int to) const;
+    float getGlyphsAndAdvancesForComplexText(const TextRun&, unsigned from, unsigned to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
+    void drawEmphasisMarksForComplexText(GraphicsContext&, const TextRun&, const AtomicString& mark, const FloatPoint&, unsigned from, unsigned to) const;
     float floatWidthForComplexText(const TextRun&, HashSet<const Font*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
     int offsetForPositionForComplexText(const TextRun&, float position, bool includePartialGlyphs) const;
-    void adjustSelectionRectForComplexText(const TextRun&, LayoutRect& selectionRect, int from, int to) const;
+    void adjustSelectionRectForComplexText(const TextRun&, LayoutRect& selectionRect, unsigned from, unsigned to) const;
 
     static std::pair<unsigned, bool> expansionOpportunityCountInternal(const LChar*, size_t length, TextDirection, ExpansionBehavior);
     static std::pair<unsigned, bool> expansionOpportunityCountInternal(const UChar*, size_t length, TextDirection, ExpansionBehavior);
index c82af39..563540c 100644 (file)
@@ -77,7 +77,7 @@ typedef FloatSize GlyphBufferAdvance;
 class GlyphBuffer {
 public:
     bool isEmpty() const { return m_font.isEmpty(); }
-    int size() const { return m_font.size(); }
+    unsigned size() const { return m_font.size(); }
     
     void clear()
     {
@@ -91,12 +91,12 @@ public:
 #endif
     }
 
-    GlyphBufferGlyph* glyphs(int from) { return m_glyphs.data() + from; }
-    GlyphBufferAdvance* advances(int from) { return m_advances.data() + from; }
-    const GlyphBufferGlyph* glyphs(int from) const { return m_glyphs.data() + from; }
-    const GlyphBufferAdvance* advances(int from) const { return m_advances.data() + from; }
+    GlyphBufferGlyph* glyphs(unsigned from) { return m_glyphs.data() + from; }
+    GlyphBufferAdvance* advances(unsigned from) { return m_advances.data() + from; }
+    const GlyphBufferGlyph* glyphs(unsigned from) const { return m_glyphs.data() + from; }
+    const GlyphBufferAdvance* advances(unsigned from) const { return m_advances.data() + from; }
 
-    const Font* fontAt(int index) const { return m_font[index]; }
+    const Font* fontAt(unsigned index) const { return m_font[index]; }
 
     void setInitialAdvance(GlyphBufferAdvance initialAdvance) { m_initialAdvance = initialAdvance; }
     const GlyphBufferAdvance& initialAdvance() const { return m_initialAdvance; }
@@ -104,7 +104,7 @@ public:
     void setLeadingExpansion(float leadingExpansion) { m_leadingExpansion = leadingExpansion; }
     float leadingExpansion() const { return m_leadingExpansion; }
     
-    Glyph glyphAt(int index) const
+    Glyph glyphAt(unsigned index) const
     {
 #if USE(CAIRO)
         return m_glyphs[index].index;
@@ -113,12 +113,12 @@ public:
 #endif
     }
 
-    GlyphBufferAdvance advanceAt(int index) const
+    GlyphBufferAdvance advanceAt(unsigned index) const
     {
         return m_advances[index];
     }
 
-    FloatSize offsetAt(int index) const
+    FloatSize offsetAt(unsigned index) const
     {
 #if PLATFORM(WIN)
         return m_offsets[index];
@@ -180,9 +180,9 @@ public:
     }
 #endif
 
-    void reverse(int from, int length)
+    void reverse(unsigned from, unsigned length)
     {
-        for (int i = from, end = from + length - 1; i < end; ++i, --end)
+        for (unsigned i = from, end = from + length - 1; i < end; ++i, --end)
             swap(i, end);
     }
 
@@ -198,14 +198,13 @@ public:
         m_offsetsInString.reset(new Vector<unsigned, 2048>());
     }
 
-    // FIXME: This converts from an unsigned to an int
-    int offsetInString(int index) const
+    int offsetInString(unsigned index) const
     {
         ASSERT(m_offsetsInString);
         return (*m_offsetsInString)[index];
     }
 
-    void shrink(int truncationPoint)
+    void shrink(unsigned truncationPoint)
     {
         m_font.shrink(truncationPoint);
         m_glyphs.shrink(truncationPoint);
@@ -218,7 +217,7 @@ public:
     }
 
 private:
-    void swap(int index1, int index2)
+    void swap(unsigned index1, unsigned index2)
     {
         const Font* f = m_font[index1];
         m_font[index1] = m_font[index2];
index af19122..edf6053 100644 (file)
@@ -636,7 +636,7 @@ void GraphicsContext::endTransparencyLayer()
     --m_transparencyCount;
 }
 
-float GraphicsContext::drawText(const FontCascade& font, const TextRun& run, const FloatPoint& point, int from, int to)
+float GraphicsContext::drawText(const FontCascade& font, const TextRun& run, const FloatPoint& point, unsigned from, Optional<unsigned> to)
 {
     if (paintingDisabled())
         return 0;
@@ -645,7 +645,7 @@ float GraphicsContext::drawText(const FontCascade& font, const TextRun& run, con
     return font.drawText(*this, run, point, from, to);
 }
 
-void GraphicsContext::drawGlyphs(const FontCascade& fontCascade, const Font& font, const GlyphBuffer& buffer, int from, int numGlyphs, const FloatPoint& point)
+void GraphicsContext::drawGlyphs(const FontCascade& fontCascade, const Font& font, const GlyphBuffer& buffer, unsigned from, unsigned numGlyphs, const FloatPoint& point)
 {
     if (paintingDisabled())
         return;
@@ -658,7 +658,7 @@ void GraphicsContext::drawGlyphs(const FontCascade& fontCascade, const Font& fon
     fontCascade.drawGlyphs(*this, font, buffer, from, numGlyphs, point, fontCascade.fontDescription().fontSmoothing());
 }
 
-void GraphicsContext::drawEmphasisMarks(const FontCascade& font, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to)
+void GraphicsContext::drawEmphasisMarks(const FontCascade& font, const TextRun& run, const AtomicString& mark, const FloatPoint& point, unsigned from, Optional<unsigned> to)
 {
     if (paintingDisabled())
         return;
index 3893406..a6e6fb0 100644 (file)
@@ -381,9 +381,9 @@ public:
     void setTextDrawingMode(TextDrawingModeFlags);
     TextDrawingModeFlags textDrawingMode() const { return m_state.textDrawingMode; }
 
-    float drawText(const FontCascade&, const TextRun&, const FloatPoint&, int from = 0, int to = -1);
-    void drawGlyphs(const FontCascade&, const Font&, const GlyphBuffer&, int from, int numGlyphs, const FloatPoint&);
-    void drawEmphasisMarks(const FontCascade&, const TextRun&, const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1);
+    float drawText(const FontCascade&, const TextRun&, const FloatPoint&, unsigned from = 0, Optional<unsigned> to = Nullopt);
+    void drawGlyphs(const FontCascade&, const Font&, const GlyphBuffer&, unsigned from, unsigned numGlyphs, const FloatPoint&);
+    void drawEmphasisMarks(const FontCascade&, const TextRun&, const AtomicString& mark, const FloatPoint&, unsigned from = 0, Optional<unsigned> to = Nullopt);
     void drawBidiText(const FontCascade&, const TextRun&, const FloatPoint&, FontCascade::CustomFontNotReadyAction = FontCascade::DoNotPaintIfFontNotReady);
 
     void applyState(const GraphicsContextState&);
index c40189b..431d8ff 100644 (file)
@@ -28,18 +28,18 @@ namespace WebCore {
 
 class Latin1TextIterator {
 public:
-    // The passed in LChar pointer starts at 'currentCharacter'. The iterator operates on the range [currentCharacter, lastCharacter].
-    // 'endCharacter' denotes the maximum length of the UChar array, which might exceed 'lastCharacter'.
-    Latin1TextIterator(const LChar* characters, int currentCharacter, int lastCharacter, int /*endCharacter*/)
+    // The passed in LChar pointer starts at 'currentIndex'. The iterator operates on the range [currentIndex, lastIndex].
+    // 'endCharacter' denotes the maximum length of the UChar array, which might exceed 'lastIndex'.
+    Latin1TextIterator(const LChar* characters, unsigned currentIndex, unsigned lastIndex, unsigned /*endCharacter*/)
         : m_characters(characters)
-        , m_currentCharacter(currentCharacter)
-        , m_lastCharacter(lastCharacter)
+        , m_currentIndex(currentIndex)
+        , m_lastIndex(lastIndex)
     {
     }
 
     bool consume(UChar32& character, unsigned& clusterLength)
     {
-        if (m_currentCharacter >= m_lastCharacter)
+        if (m_currentIndex >= m_lastIndex)
             return false;
 
         character = *m_characters;
@@ -50,16 +50,16 @@ public:
     void advance(unsigned advanceLength)
     {
         m_characters += advanceLength;
-        m_currentCharacter += advanceLength;
+        m_currentIndex += advanceLength;
     }
 
-    int currentCharacter() const { return m_currentCharacter; }
+    unsigned currentIndex() const { return m_currentIndex; }
     const LChar* characters() const { return m_characters; }
 
 private:
     const LChar* m_characters;
-    int m_currentCharacter;
-    int m_lastCharacter;
+    unsigned m_currentIndex;
+    unsigned m_lastIndex;
 };
 
 }
index 9155e71..682d98e 100644 (file)
 
 namespace WebCore {
 
-SurrogatePairAwareTextIterator::SurrogatePairAwareTextIterator(const UChar* characters, int currentCharacter, int lastCharacter, int endCharacter)
+SurrogatePairAwareTextIterator::SurrogatePairAwareTextIterator(const UChar* characters, unsigned currentIndex, unsigned lastIndex, unsigned endIndex)
     : m_characters(characters)
-    , m_currentCharacter(currentCharacter)
-    , m_lastCharacter(lastCharacter)
-    , m_endCharacter(endCharacter)
+    , m_currentIndex(currentIndex)
+    , m_lastIndex(lastIndex)
+    , m_endIndex(endIndex)
 {
 }
 
@@ -57,7 +57,7 @@ bool SurrogatePairAwareTextIterator::consumeSlowCase(UChar32& character, unsigne
 
     // Do we have a surrogate pair? If so, determine the full Unicode (32 bit) code point before glyph lookup.
     // Make sure we have another character and it's a low surrogate.
-    if (m_currentCharacter + 1 >= m_endCharacter)
+    if (m_currentIndex + 1 >= m_endIndex)
         return false;
 
     UChar low = m_characters[1];
@@ -74,7 +74,7 @@ UChar32 SurrogatePairAwareTextIterator::normalizeVoicingMarks()
     // According to http://www.unicode.org/Public/UNIDATA/UCD.html#Canonical_Combining_Class_Values
     static const uint8_t hiraganaKatakanaVoicingMarksCombiningClass = 8;
 
-    if (m_currentCharacter + 1 >= m_endCharacter)
+    if (m_currentIndex + 1 >= m_endIndex)
         return 0;
 
     if (u_getCombiningClass(m_characters[1]) == hiraganaKatakanaVoicingMarksCombiningClass) {
index 85c9694..470d14a 100644 (file)
@@ -28,13 +28,13 @@ namespace WebCore {
 
 class SurrogatePairAwareTextIterator {
 public:
-    // The passed in UChar pointer starts at 'currentCharacter'. The iterator operatoes on the range [currentCharacter, lastCharacter].
-    // 'endCharacter' denotes the maximum length of the UChar array, which might exceed 'lastCharacter'.
-    SurrogatePairAwareTextIterator(const UChar*, int currentCharacter, int lastCharacter, int endCharacter);
+    // The passed in UChar pointer starts at 'currentIndex'. The iterator operatoes on the range [currentIndex, lastIndex].
+    // 'endIndex' denotes the maximum length of the UChar array, which might exceed 'lastIndex'.
+    SurrogatePairAwareTextIterator(const UChar*, unsigned currentIndex, unsigned lastIndex, unsigned endIndex);
 
     inline bool consume(UChar32& character, unsigned& clusterLength)
     {
-        if (m_currentCharacter >= m_lastCharacter)
+        if (m_currentIndex >= m_lastIndex)
             return false;
 
         character = *m_characters;
@@ -49,10 +49,10 @@ public:
     void advance(unsigned advanceLength)
     {
         m_characters += advanceLength;
-        m_currentCharacter += advanceLength;
+        m_currentIndex += advanceLength;
     }
 
-    int currentCharacter() const { return m_currentCharacter; }
+    unsigned currentIndex() const { return m_currentIndex; }
     const UChar* characters() const { return m_characters; }
 
 private:
@@ -60,9 +60,9 @@ private:
     UChar32 normalizeVoicingMarks();
 
     const UChar* m_characters;
-    int m_currentCharacter;
-    int m_lastCharacter;
-    int m_endCharacter;
+    unsigned m_currentIndex;
+    unsigned m_lastIndex;
+    unsigned m_endIndex;
 };
 
 }
index 0b9a740..36fba0f 100644 (file)
@@ -81,7 +81,7 @@ static inline bool isSoftBankEmoji(UChar32 codepoint)
     return codepoint >= 0xE001 && codepoint <= 0xE537;
 }
 
-inline auto WidthIterator::shouldApplyFontTransforms(const GlyphBuffer* glyphBuffer, int lastGlyphCount, UChar32 previousCharacter) const -> TransformsType
+inline auto WidthIterator::shouldApplyFontTransforms(const GlyphBuffer* glyphBuffer, unsigned lastGlyphCount, UChar32 previousCharacter) const -> TransformsType
 {
     if (glyphBuffer && glyphBuffer->size() == (lastGlyphCount + 1) && isSoftBankEmoji(previousCharacter))
         return TransformsType::Forced;
@@ -90,14 +90,14 @@ inline auto WidthIterator::shouldApplyFontTransforms(const GlyphBuffer* glyphBuf
     return TransformsType::NotForced;
 }
 
-inline float WidthIterator::applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int& lastGlyphCount, const Font* font, UChar32 previousCharacter, bool force, CharactersTreatedAsSpace& charactersTreatedAsSpace)
+inline float WidthIterator::applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, unsigned& lastGlyphCount, const Font* font, UChar32 previousCharacter, bool force, CharactersTreatedAsSpace& charactersTreatedAsSpace)
 {
     ASSERT_UNUSED(previousCharacter, shouldApplyFontTransforms(glyphBuffer, lastGlyphCount, previousCharacter) != WidthIterator::TransformsType::None);
 
     if (!glyphBuffer)
         return 0;
 
-    int glyphBufferSize = glyphBuffer->size();
+    unsigned glyphBufferSize = glyphBuffer->size();
     if (!force && glyphBufferSize <= lastGlyphCount + 1) {
         lastGlyphCount = glyphBufferSize;
         return 0;
@@ -105,9 +105,10 @@ inline float WidthIterator::applyFontTransforms(GlyphBuffer* glyphBuffer, bool l
 
     GlyphBufferAdvance* advances = glyphBuffer->advances(0);
     float widthDifference = 0;
-    for (int i = lastGlyphCount; i < glyphBufferSize; ++i)
+    for (unsigned i = lastGlyphCount; i < glyphBufferSize; ++i)
         widthDifference -= advances[i].width();
 
+    ASSERT(lastGlyphCount <= glyphBufferSize);
     if (!ltr)
         glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount);
 
@@ -125,7 +126,7 @@ inline float WidthIterator::applyFontTransforms(GlyphBuffer* glyphBuffer, bool l
     }
     charactersTreatedAsSpace.clear();
 
-    for (int i = lastGlyphCount; i < glyphBufferSize; ++i)
+    for (unsigned i = lastGlyphCount; i < glyphBufferSize; ++i)
         widthDifference += advances[i].width();
 
     lastGlyphCount = glyphBufferSize;
@@ -181,7 +182,7 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph
 
     const Font& primaryFont = m_font->primaryFont();
     const Font* lastFontData = &primaryFont;
-    int lastGlyphCount = glyphBuffer ? glyphBuffer->size() : 0;
+    unsigned lastGlyphCount = glyphBuffer ? glyphBuffer->size() : 0;
 
     UChar32 character = 0;
     UChar32 previousCharacter = 0;
@@ -191,7 +192,7 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph
     // We are iterating in string order, not glyph order. Compare this to ComplexTextController::adjustGlyphsAndAdvances()
     while (textIterator.consume(character, clusterLength)) {
         unsigned advanceLength = clusterLength;
-        int currentCharacter = textIterator.currentCharacter();
+        int currentCharacter = textIterator.currentIndex();
         const GlyphData& glyphData = m_font->glyphDataForCharacter(character, rtl);
         Glyph glyph = glyphData.glyph;
         if (!glyph) {
@@ -349,21 +350,21 @@ inline unsigned WidthIterator::advanceInternal(TextIterator& textIterator, Glyph
             glyphBuffer->shrink(lastGlyphCount);
     }
 
-    unsigned consumedCharacters = textIterator.currentCharacter() - m_currentCharacter;
-    m_currentCharacter = textIterator.currentCharacter();
+    unsigned consumedCharacters = textIterator.currentIndex() - m_currentCharacter;
+    m_currentCharacter = textIterator.currentIndex();
     m_runWidthSoFar += widthSinceLastRounding;
     m_finalRoundingWidth = lastRoundingWidth;
     return consumedCharacters;
 }
 
-unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
+unsigned WidthIterator::advance(unsigned offset, GlyphBuffer* glyphBuffer)
 {
-    int length = m_run.length();
+    unsigned length = m_run.length();
 
     if (offset > length)
         offset = length;
 
-    if (m_currentCharacter >= static_cast<unsigned>(offset))
+    if (m_currentCharacter >= offset)
         return 0;
 
     if (m_run.is8Bit()) {
@@ -377,10 +378,10 @@ unsigned WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
 
 bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer& glyphBuffer)
 {
-    int oldSize = glyphBuffer.size();
+    unsigned oldSize = glyphBuffer.size();
     advance(m_currentCharacter + 1, &glyphBuffer);
     float w = 0;
-    for (int i = oldSize; i < glyphBuffer.size(); ++i)
+    for (unsigned i = oldSize; i < glyphBuffer.size(); ++i)
         w += glyphBuffer.advanceAt(i).width();
     width = w;
     return glyphBuffer.size() > oldSize;
index 68fe3f3..c45fdb8 100644 (file)
@@ -42,7 +42,7 @@ struct WidthIterator {
 public:
     WidthIterator(const FontCascade*, const TextRun&, HashSet<const Font*>* fallbackFonts = 0, bool accountForGlyphBounds = false, bool forTextEmphasis = false);
 
-    unsigned advance(int to, GlyphBuffer*);
+    unsigned advance(unsigned to, GlyphBuffer*);
     bool advanceOneCharacter(float& width, GlyphBuffer&);
 
     float maxGlyphBoundingBoxY() const { ASSERT(m_accountForGlyphBounds); return m_maxGlyphBoundingBoxY; }
@@ -70,8 +70,8 @@ private:
     inline unsigned advanceInternal(TextIterator&, GlyphBuffer*);
 
     enum class TransformsType { None, Forced, NotForced };
-    TransformsType shouldApplyFontTransforms(const GlyphBuffer*, int lastGlyphCount, UChar32 previousCharacter) const;
-    float applyFontTransforms(GlyphBuffer*, bool ltr, int& lastGlyphCount, const Font*, UChar32 previousCharacter, bool force, CharactersTreatedAsSpace&);
+    TransformsType shouldApplyFontTransforms(const GlyphBuffer*, unsigned lastGlyphCount, UChar32 previousCharacter) const;
+    float applyFontTransforms(GlyphBuffer*, bool ltr, unsigned& lastGlyphCount, const Font*, UChar32 previousCharacter, bool force, CharactersTreatedAsSpace&);
 
     HashSet<const Font*>* m_fallbackFonts { nullptr };
     bool m_accountForGlyphBounds { false };
index e895f17..9e30801 100644 (file)
@@ -47,7 +47,7 @@
 
 namespace WebCore {
 
-static void drawGlyphsToContext(cairo_t* context, const Font& font, GlyphBufferGlyph* glyphs, int numGlyphs)
+static void drawGlyphsToContext(cairo_t* context, const Font& font, GlyphBufferGlyph* glyphs, unsigned numGlyphs)
 {
     cairo_matrix_t originalTransform;
     float syntheticBoldOffset = font.syntheticBoldOffset();
@@ -66,7 +66,7 @@ static void drawGlyphsToContext(cairo_t* context, const Font& font, GlyphBufferG
         cairo_set_matrix(context, &originalTransform);
 }
 
-static void drawGlyphsShadow(GraphicsContext& graphicsContext, const FloatPoint& point, const Font& font, GlyphBufferGlyph* glyphs, int numGlyphs)
+static void drawGlyphsShadow(GraphicsContext& graphicsContext, const FloatPoint& point, const Font& font, GlyphBufferGlyph* glyphs, unsigned numGlyphs)
 {
     ShadowBlur& shadow = graphicsContext.platformContext()->shadowBlur();
 
@@ -98,7 +98,7 @@ static void drawGlyphsShadow(GraphicsContext& graphicsContext, const FloatPoint&
 }
 
 void FontCascade::drawGlyphs(GraphicsContext& context, const Font& font, const GlyphBuffer& glyphBuffer,
-    int from, int numGlyphs, const FloatPoint& point, FontSmoothingMode)
+    unsigned from, unsigned numGlyphs, const FloatPoint& point, FontSmoothingMode)
 {
     if (!font.platformData().size())
         return;
@@ -106,7 +106,7 @@ void FontCascade::drawGlyphs(GraphicsContext& context, const Font& font, const G
     GlyphBufferGlyph* glyphs = const_cast<GlyphBufferGlyph*>(glyphBuffer.glyphs(from));
 
     float offset = point.x();
-    for (int i = 0; i < numGlyphs; i++) {
+    for (unsigned i = 0; i < numGlyphs; i++) {
         glyphs[i].x = offset;
         glyphs[i].y = point.y();
         offset += glyphBuffer.advanceAt(from + i).width();
@@ -229,7 +229,7 @@ public:
     void advance() final;
 
 private:
-    int m_index;
+    unsigned m_index;
     const TextRun& m_textRun;
     const GlyphBuffer& m_glyphBuffer;
     const Font* m_fontData;
index 216d911..08bae38 100644 (file)
@@ -40,7 +40,7 @@
 
 namespace WebCore {
 
-float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, int, int, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot /* forTextEmphasis */) const
+float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, unsigned, unsigned, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot /* forTextEmphasis */) const
 {
     HarfBuzzShaper shaper(this, run);
     if (!shaper.shape(&glyphBuffer)) {
@@ -52,7 +52,7 @@ float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, int, i
     return 0;
 }
 
-void FontCascade::drawEmphasisMarksForComplexText(GraphicsContext& /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
+void FontCascade::drawEmphasisMarksForComplexText(GraphicsContext& /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, unsigned /* from */, unsigned /* to */) const
 {
     notImplemented();
 }
@@ -85,7 +85,7 @@ int FontCascade::offsetForPositionForComplexText(const TextRun& run, float x, bo
     return 0;
 }
 
-void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
+void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
 {
     HarfBuzzShaper shaper(this, run);
     if (shaper.shape()) {
index 7f564b0..9c1f1da 100644 (file)
@@ -70,11 +70,11 @@ bool FontCascade::canExpandAroundIdeographsInComplexText()
     return true;
 }
 
-static inline void fillVectorWithHorizontalGlyphPositions(Vector<CGPoint, 256>& positions, CGContextRef context, const CGSize* advances, size_t count)
+static inline void fillVectorWithHorizontalGlyphPositions(Vector<CGPoint, 256>& positions, CGContextRef context, const CGSize* advances, unsigned count)
 {
     CGAffineTransform matrix = CGAffineTransformInvert(CGContextGetTextMatrix(context));
     positions[0] = CGPointZero;
-    for (size_t i = 1; i < count; ++i) {
+    for (unsigned i = 1; i < count; ++i) {
         CGSize advance = CGSizeApplyAffineTransform(advances[i - 1], matrix);
         positions[i].x = positions[i - 1].x + advance.width;
         positions[i].y = positions[i - 1].y + advance.height;
@@ -91,7 +91,7 @@ static inline bool shouldUseLetterpressEffect(const GraphicsContext& context)
 #endif
 }
 
-static void showLetterpressedGlyphsWithAdvances(const FloatPoint& point, const Font& font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count)
+static void showLetterpressedGlyphsWithAdvances(const FloatPoint& point, const Font& font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, unsigned count)
 {
 #if ENABLE(LETTERPRESS)
     if (!count)
@@ -158,7 +158,7 @@ private:
 #endif
 };
 
-static void showGlyphsWithAdvances(const FloatPoint& point, const Font& font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count)
+static void showGlyphsWithAdvances(const FloatPoint& point, const Font& font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, unsigned count)
 {
     if (!count)
         return;
@@ -182,7 +182,7 @@ static void showGlyphsWithAdvances(const FloatPoint& point, const Font& font, CG
         CGAffineTransform transform = CGAffineTransformInvert(CGContextGetTextMatrix(context));
 
         CGPoint position = FloatPoint(point.x(), point.y() + font.fontMetrics().floatAscent(IdeographicBaseline) - font.fontMetrics().floatAscent());
-        for (size_t i = 0; i < count; ++i) {
+        for (unsigned i = 0; i < count; ++i) {
             CGSize translation = CGSizeApplyAffineTransform(translations[i], rotateLeftTransform);
             positions[i] = CGPointApplyAffineTransform(CGPointMake(position.x - translation.width, position.y + translation.height), transform);
             position.x += advances[i].width;
@@ -220,7 +220,7 @@ static void setCGFontRenderingMode(GraphicsContext& context)
     CGContextSetShouldSubpixelQuantizeFonts(cgContext, doSubpixelQuantization);
 }
 
-void FontCascade::drawGlyphs(GraphicsContext& context, const Font& font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& anchorPoint, FontSmoothingMode smoothingMode)
+void FontCascade::drawGlyphs(GraphicsContext& context, const Font& font, const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs, const FloatPoint& anchorPoint, FontSmoothingMode smoothingMode)
 {
     const FontPlatformData& platformData = font.platformData();
     if (!platformData.size())
@@ -434,7 +434,7 @@ public:
     void advance() final;
 
 private:
-    int m_index;
+    unsigned m_index;
     const TextRun& m_textRun;
     const GlyphBuffer& m_glyphBuffer;
     const Font* m_fontData;
@@ -488,7 +488,7 @@ DashArray FontCascade::dashesForIntersectionsWithRect(const TextRun& run, const
     FloatPoint origin = FloatPoint(textOrigin.x() + deltaX, textOrigin.y());
     MacGlyphToPathTranslator translator(run, glyphBuffer, origin);
     DashArray result;
-    for (int index = 0; translator.containsMorePaths(); ++index, translator.advance()) {
+    for (unsigned index = 0; translator.containsMorePaths(); ++index, translator.advance()) {
         GlyphIterationState info = GlyphIterationState(CGPointMake(0, 0), CGPointMake(0, 0), lineExtents.y(), lineExtents.y() + lineExtents.height(), lineExtents.x() + lineExtents.width(), lineExtents.x());
         const Font* localFont = glyphBuffer.fontAt(index);
         if (!localFont) {
@@ -527,7 +527,7 @@ bool FontCascade::primaryFontIsSystemFont() const
     return CTFontDescriptorIsSystemUIFont(adoptCF(CTFontCopyFontDescriptor(fontData.platformData().ctFont())).get());
 }
 
-void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
+void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
 {
     ComplexTextController controller(*this, run);
     controller.advance(from);
@@ -542,7 +542,7 @@ void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRe
     selectionRect.setWidth(LayoutUnit::fromFloatCeil(afterWidth - beforeWidth));
 }
 
-float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
+float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, unsigned from, unsigned to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
 {
     float initialAdvance;
 
@@ -565,7 +565,7 @@ float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, int fr
     return initialAdvance;
 }
 
-void FontCascade::drawEmphasisMarksForComplexText(GraphicsContext& context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+void FontCascade::drawEmphasisMarksForComplexText(GraphicsContext& context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, unsigned from, unsigned to) const
 {
     GlyphBuffer glyphBuffer;
     float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis);
index 0bf14be..a224298 100644 (file)
@@ -100,7 +100,7 @@ void Recorder::setMiterLimit(float miterLimit)
     appendItem(SetMiterLimit::create(miterLimit));
 }
 
-void Recorder::drawGlyphs(const Font& font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& startPoint, FontSmoothingMode smoothingMode)
+void Recorder::drawGlyphs(const Font& font, const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs, const FloatPoint& startPoint, FontSmoothingMode smoothingMode)
 {
     DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawGlyphs::create(font, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs, FloatPoint(), toFloatSize(startPoint), smoothingMode)));
     updateItemExtent(newItem);
index eb99a3d..52ea106 100644 (file)
@@ -80,7 +80,7 @@ public:
     void applyFillPattern();
 #endif
 
-    void drawGlyphs(const Font&, const GlyphBuffer&, int from, int numGlyphs, const FloatPoint& anchorPoint, FontSmoothingMode);
+    void drawGlyphs(const Font&, const GlyphBuffer&, unsigned from, unsigned numGlyphs, const FloatPoint& anchorPoint, FontSmoothingMode);
 
     void drawImage(Image&, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions&);
     void drawTiledImage(Image&, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions&);
index 52570ec..ba9e411 100644 (file)
@@ -97,7 +97,7 @@ void HarfBuzzShaper::HarfBuzzRun::setGlyphAndPositions(unsigned index, uint16_t
     m_offsets[index] = FloatPoint(offsetX, offsetY);
 }
 
-int HarfBuzzShaper::HarfBuzzRun::characterIndexForXPosition(float targetX)
+unsigned HarfBuzzShaper::HarfBuzzRun::characterIndexForXPosition(float targetX)
 {
     ASSERT(targetX <= m_width);
     float currentX = 0;
@@ -156,9 +156,9 @@ float HarfBuzzShaper::HarfBuzzRun::xPositionForOffset(unsigned offset)
     return position;
 }
 
-static void normalizeCharacters(const TextRun& run, UChar* destination, int length)
+static void normalizeCharacters(const TextRun& run, UChar* destination, unsigned length)
 {
-    int position = 0;
+    unsigned position = 0;
     bool error = false;
     const UChar* source;
     String stringFor8BitRun;
@@ -170,7 +170,7 @@ static void normalizeCharacters(const TextRun& run, UChar* destination, int leng
 
     while (position < length) {
         UChar32 character;
-        int nextPosition = position;
+        unsigned nextPosition = position;
         U16_NEXT(source, nextPosition, length, character);
         // Don't normalize tabs as they are not treated as spaces for word-end.
         if (FontCascade::treatAsSpace(character) && character != '\t')
@@ -204,14 +204,14 @@ HarfBuzzShaper::~HarfBuzzShaper()
 {
 }
 
-static void normalizeSpacesAndMirrorChars(const UChar* source, UChar* destination, int length, HarfBuzzShaper::NormalizeMode normalizeMode)
+static void normalizeSpacesAndMirrorChars(const UChar* source, UChar* destination, unsigned length, HarfBuzzShaper::NormalizeMode normalizeMode)
 {
-    int position = 0;
+    unsigned position = 0;
     bool error = false;
     // Iterate characters in source and mirror character if needed.
     while (position < length) {
         UChar32 character;
-        int nextPosition = position;
+        unsigned nextPosition = position;
         U16_NEXT(source, nextPosition, length, character);
         // Don't normalize tabs as they are not treated as spaces for word-end
         if (FontCascade::treatAsSpace(character) && character != '\t')
@@ -417,11 +417,11 @@ bool HarfBuzzShaper::collectHarfBuzzRuns()
                 continue;
 
             if (U_GET_GC_MASK(character) & U_GC_M_MASK) {
-                int markLength = clusterLength;
+                unsigned markLength = clusterLength;
                 const UChar* markCharactersEnd = iterator.characters() + clusterLength;
                 while (markCharactersEnd < normalizedBufferEnd) {
                     UChar32 nextCharacter;
-                    int nextCharacterLength = 0;
+                    unsigned nextCharacterLength = 0;
                     U16_NEXT(markCharactersEnd, nextCharacterLength, normalizedBufferEnd - markCharactersEnd, nextCharacter);
                     if (!(U_GET_GC_MASK(nextCharacter) & U_GC_M_MASK))
                         break;
@@ -446,11 +446,11 @@ bool HarfBuzzShaper::collectHarfBuzzRuns()
                 nextScript = currentScript;
             currentCharacterPosition = iterator.characters();
         }
-        unsigned numCharactersOfCurrentRun = iterator.currentCharacter() - startIndexOfCurrentRun;
+        unsigned numCharactersOfCurrentRun = iterator.currentIndex() - startIndexOfCurrentRun;
         hb_script_t script = hb_icu_script_to_script(currentScript);
         m_harfBuzzRuns.append(std::make_unique<HarfBuzzRun>(currentFontData, startIndexOfCurrentRun, numCharactersOfCurrentRun, m_run.direction(), script));
         currentFontData = nextFontData;
-        startIndexOfCurrentRun = iterator.currentCharacter();
+        startIndexOfCurrentRun = iterator.currentIndex();
     } while (iterator.consume(character, clusterLength));
 
     return !m_harfBuzzRuns.isEmpty();
@@ -640,7 +640,7 @@ int HarfBuzzShaper::offsetForPosition(float targetX)
     return charactersSoFar;
 }
 
-FloatRect HarfBuzzShaper::selectionRect(const FloatPoint& point, int height, int from, int to)
+FloatRect HarfBuzzShaper::selectionRect(const FloatPoint& point, int height, unsigned from, unsigned to)
 {
     float currentX = 0;
     float fromX = 0;
@@ -653,18 +653,22 @@ FloatRect HarfBuzzShaper::selectionRect(const FloatPoint& point, int height, int
     for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) {
         if (m_run.rtl())
             currentX -= m_harfBuzzRuns[i]->width();
-        int numCharacters = m_harfBuzzRuns[i]->numCharacters();
-        if (!foundFromX && from >= 0 && from < numCharacters) {
+        unsigned numCharacters = m_harfBuzzRuns[i]->numCharacters();
+        if (!foundFromX && from < numCharacters) {
             fromX = m_harfBuzzRuns[i]->xPositionForOffset(from) + currentX;
             foundFromX = true;
-        } else
+        } else {
+            ASSERT(from >= numCharacters);
             from -= numCharacters;
+        }
 
-        if (!foundToX && to >= 0 && to < numCharacters) {
+        if (!foundToX && to < numCharacters) {
             toX = m_harfBuzzRuns[i]->xPositionForOffset(to) + currentX;
             foundToX = true;
-        } else
+        } else {
+            ASSERT(to >= numCharacters);
             to -= numCharacters;
+        }
 
         if (foundFromX && foundToX)
             break;
index bf76f31..64d40be 100644 (file)
@@ -59,7 +59,7 @@ public:
     FloatPoint adjustStartPoint(const FloatPoint&);
     float totalWidth() { return m_totalWidth; }
     int offsetForPosition(float targetX);
-    FloatRect selectionRect(const FloatPoint&, int height, int from, int to);
+    FloatRect selectionRect(const FloatPoint&, int height, unsigned from, unsigned to);
 
 private:
     class HarfBuzzRun {
@@ -70,7 +70,7 @@ private:
         void setGlyphAndPositions(unsigned index, uint16_t glyphId, float advance, float offsetX, float offsetY);
         void setWidth(float width) { m_width = width; }
 
-        int characterIndexForXPosition(float targetX);
+        unsigned characterIndexForXPosition(float targetX);
         float xPositionForOffset(unsigned offset);
 
         const Font* fontData() { return m_fontData; }
@@ -88,7 +88,7 @@ private:
     private:
         const Font* m_fontData;
         unsigned m_startIndex;
-        size_t m_numCharacters;
+        unsigned m_numCharacters;
         unsigned m_numGlyphs;
         TextDirection m_direction;
         hb_script_t m_script;
index ae96ad1..7df4eff 100644 (file)
@@ -54,7 +54,7 @@ public:
     ComplexTextController(const FontCascade&, const TextRun&, bool mayUseNaturalWritingDirection = false, HashSet<const Font*>* fallbackFonts = 0, bool forTextEmphasis = false);
 
     // Advance and emit glyphs up to the specified character.
-    void advance(unsigned to, GlyphBuffer* = 0, GlyphIterationStyle = IncludePartialGlyphs, HashSet<const Font*>* fallbackFonts = 0);
+    void advance(unsigned to, GlyphBuffer* = nullptr, GlyphIterationStyle = IncludePartialGlyphs, HashSet<const Font*>* fallbackFonts = nullptr);
 
     // Compute the character offset for a given x coordinate.
     int offsetForPosition(float x, bool includePartialGlyphs);
index b5bff27..e8d733a 100644 (file)
@@ -128,7 +128,7 @@ static CGPathRef createPathForGlyph(HDC hdc, Glyph glyph)
 }
 
 void FontCascade::drawGlyphs(GraphicsContext& graphicsContext, const Font& font, const GlyphBuffer& glyphBuffer,
-    int from, int numGlyphs, const FloatPoint& point, FontSmoothingMode smoothingMode)
+    unsigned from, unsigned numGlyphs, const FloatPoint& point, FontSmoothingMode smoothingMode)
 {
     CGContextRef cgContext = graphicsContext.platformContext();
     bool shouldUseFontSmoothing = WebCoreShouldUseFontSmoothing();
index 2396a4d..69fc9cd 100644 (file)
@@ -50,7 +50,7 @@ bool FontCascade::canExpandAroundIdeographsInComplexText()
     return false;
 }
 
-void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
+void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
 {
     UniscribeController it(this, run);
     it.advance(from);
@@ -66,7 +66,7 @@ void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRe
     selectionRect.setWidth(afterWidth - beforeWidth);
 }
 
-float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
+float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, unsigned from, unsigned to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
 {
     if (forTextEmphasis) {
         // FIXME: Add forTextEmphasis paremeter to UniscribeController and use it.
@@ -91,7 +91,7 @@ float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, int fr
     return beforeWidth;
 }
 
-void FontCascade::drawEmphasisMarksForComplexText(GraphicsContext& context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+void FontCascade::drawEmphasisMarksForComplexText(GraphicsContext& context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, unsigned from, unsigned to) const
 {
     GlyphBuffer glyphBuffer;
     float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis);
index 20938b1..45fdd7f 100644 (file)
@@ -136,7 +136,7 @@ void EllipsisBox::paintSelection(GraphicsContext& context, const LayoutPoint& pa
     // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
     LayoutRect selectionRect = LayoutRect(x() + paintOffset.x(), y() + paintOffset.y() + rootBox.selectionTop(), 0, rootBox.selectionHeight());
     TextRun run = RenderBlock::constructTextRun(m_str, style, AllowTrailingExpansion);
-    font.adjustSelectionRectForText(run, selectionRect, 0, -1);
+    font.adjustSelectionRectForText(run, selectionRect);
     context.fillRect(snapRectToDevicePixelsWithWritingDirection(selectionRect, renderer().document().deviceScaleFactor(), run.ltr()), c);
 }
 
index f32a0b3..b8a5a52 100644 (file)
@@ -130,21 +130,26 @@ LayoutUnit InlineTextBox::selectionHeight() const
     return root().selectionHeight();
 }
 
-bool InlineTextBox::isSelected(int startPos, int endPos) const
+bool InlineTextBox::isSelected(unsigned startPos, unsigned endPos) const
 {
-    int sPos = std::max(startPos - m_start, 0);
-    int ePos = std::min(endPos - m_start, static_cast<int>(m_len));
-    return (sPos < ePos);
+    int sPos = clampedOffset(startPos);
+    int ePos = clampedOffset(endPos);
+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=160786
+    // We should only be checking if sPos >= ePos here, because those are the
+    // indices used to actually generate the selection rect. Allowing us past this guard
+    // on any other condition creates zero-width selection rects.
+    return sPos < ePos || (startPos == endPos && startPos >= start() && startPos <= (start() + len()));
 }
 
 RenderObject::SelectionState InlineTextBox::selectionState()
 {
     RenderObject::SelectionState state = renderer().selectionState();
     if (state == RenderObject::SelectionStart || state == RenderObject::SelectionEnd || state == RenderObject::SelectionBoth) {
-        int startPos, endPos;
+        unsigned startPos, endPos;
         renderer().selectionStartEnd(startPos, endPos);
         // The position after a hard line break is considered to be past its end.
-        int lastSelectable = start() + len() - (isLineBreak() ? 1 : 0);
+        ASSERT(start() + len() >= (isLineBreak() ? 1 : 0));
+        unsigned lastSelectable = start() + len() - (isLineBreak() ? 1 : 0);
 
         bool start = (state != RenderObject::SelectionEnd && startPos >= m_start && startPos < m_start + m_len);
         bool end = (state != RenderObject::SelectionStart && endPos > m_start && endPos <= lastSelectable);
@@ -165,8 +170,8 @@ RenderObject::SelectionState InlineTextBox::selectionState()
     if (m_truncation != cNoTruncation && root().ellipsisBox()) {
         EllipsisBox* ellipsis = root().ellipsisBox();
         if (state != RenderObject::SelectionNone) {
-            int selectionStart;
-            int selectionEnd;
+            unsigned selectionStart;
+            unsigned selectionEnd;
             std::tie(selectionStart, selectionEnd) = selectionStartEnd();
             // The ellipsis should be considered to be selected if the end of
             // the selection is past the beginning of the truncation and the
@@ -191,12 +196,16 @@ static const FontCascade& fontToUse(const RenderStyle& style, const RenderText&
     return style.fontCascade();
 }
 
-LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos) const
+LayoutRect InlineTextBox::localSelectionRect(unsigned startPos, unsigned endPos) const
 {
-    int sPos = std::max(startPos - m_start, 0);
-    int ePos = std::min(endPos - m_start, (int)m_len);
-    
-    if (sPos > ePos)
+    unsigned sPos = clampedOffset(startPos);
+    unsigned ePos = clampedOffset(endPos);
+
+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=160786
+    // We should only be checking if sPos >= ePos here, because those are the
+    // indices used to actually generate the selection rect. Allowing us past this guard
+    // on any other condition creates zero-width selection rects.
+    if (sPos >= ePos && !(startPos == endPos && startPos >= start() && startPos <= (start() + len())))
         return LayoutRect();
 
     LayoutUnit selectionTop = this->selectionTop();
@@ -212,7 +221,7 @@ LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos) const
 
     LayoutRect selectionRect = LayoutRect(LayoutPoint(logicalLeft(), selectionTop), LayoutSize(m_logicalWidth, selectionHeight));
     // Avoid computing the font width when the entire line box is selected as an optimization.
-    if (sPos || ePos != static_cast<int>(m_len))
+    if (sPos || ePos != m_len)
         font.adjustSelectionRectForText(textRun, selectionRect, sPos, ePos);
     IntRect snappedSelectionRect = enclosingIntRect(selectionRect);
     LayoutUnit logicalWidth = snappedSelectionRect.width();
@@ -508,18 +517,18 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
     TextRun textRun = constructTextRun(lineStyle, alternateStringToRender);
     unsigned length = textRun.length();
 
-    int selectionStart = 0;
-    int selectionEnd = 0;
+    unsigned selectionStart = 0;
+    unsigned selectionEnd = 0;
     if (haveSelection && (paintSelectedTextOnly || paintSelectedTextSeparately))
         std::tie(selectionStart, selectionEnd) = selectionStartEnd();
 
     if (m_truncation != cNoTruncation) {
-        selectionStart = std::min<int>(selectionStart, m_truncation);
-        selectionEnd = std::min<int>(selectionEnd, m_truncation);
+        selectionStart = std::min(selectionStart, static_cast<unsigned>(m_truncation));
+        selectionEnd = std::min(selectionEnd, static_cast<unsigned>(m_truncation));
         length = m_truncation;
     }
 
-    int emphasisMarkOffset = 0;
+    float emphasisMarkOffset = 0;
     bool emphasisMarkAbove;
     bool hasTextEmphasis = emphasisMarkExistsAndIsAbove(lineStyle, emphasisMarkAbove);
     const AtomicString& emphasisMark = hasTextEmphasis ? lineStyle.textEmphasisMarkString() : nullAtom;
@@ -587,20 +596,25 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
         context.concatCTM(rotation(boxRect, Counterclockwise));
 }
 
-std::pair<int, int> InlineTextBox::selectionStartEnd() const
+unsigned InlineTextBox::clampedOffset(unsigned x) const
+{
+    return std::max(std::min(x, start() + len()), start()) - start();
+}
+
+std::pair<unsigned, unsigned> InlineTextBox::selectionStartEnd() const
 {
     auto selectionState = renderer().selectionState();
     if (selectionState == RenderObject::SelectionInside)
         return { 0, m_len };
     
-    int start;
-    int end;
+    unsigned start;
+    unsigned end;
     renderer().selectionStartEnd(start, end);
     if (selectionState == RenderObject::SelectionStart)
         end = renderer().textLength();
     else if (selectionState == RenderObject::SelectionEnd)
         start = 0;
-    return { std::max(start - m_start, 0), std::min<int>(end - m_start, m_len) };
+    return { clampedOffset(start), clampedOffset(end) };
 }
 
 void InlineTextBox::paintSelection(GraphicsContext& context, const FloatPoint& boxOrigin, const RenderStyle& style, const FontCascade& font, Color textColor)
@@ -610,8 +624,8 @@ void InlineTextBox::paintSelection(GraphicsContext& context, const FloatPoint& b
         return;
 
     // See if we have a selection to paint at all.
-    int selectionStart;
-    int selectionEnd;
+    unsigned selectionStart;
+    unsigned selectionEnd;
     std::tie(selectionStart, selectionEnd) = selectionStartEnd();
     if (selectionStart >= selectionEnd)
         return;
@@ -634,7 +648,7 @@ void InlineTextBox::paintSelection(GraphicsContext& context, const FloatPoint& b
     unsigned length = m_truncation != cNoTruncation ? m_truncation : len();
 
     String hyphenatedString;
-    bool respectHyphen = selectionEnd == static_cast<int>(length) && hasHyphen();
+    bool respectHyphen = selectionEnd == length && hasHyphen();
     if (respectHyphen)
         hyphenatedString = hyphenatedStringForTextRun(style, length);
     TextRun textRun = constructTextRun(style, hyphenatedString, Optional<unsigned>(length));
@@ -660,11 +674,10 @@ void InlineTextBox::paintSelection(GraphicsContext& context, const FloatPoint& b
 #endif
 }
 
-void InlineTextBox::paintCompositionBackground(GraphicsContext& context, const FloatPoint& boxOrigin, const RenderStyle& style, const FontCascade& font, int startPos, int endPos)
+void InlineTextBox::paintCompositionBackground(GraphicsContext& context, const FloatPoint& boxOrigin, const RenderStyle& style, const FontCascade& font, unsigned startPos, unsigned endPos)
 {
-    int offset = m_start;
-    int selectionStart = std::max(startPos - offset, 0);
-    int selectionEnd = std::min<int>(endPos - offset, m_len);
+    unsigned selectionStart = clampedOffset(startPos);
+    unsigned selectionEnd = clampedOffset(endPos);
     if (selectionStart >= selectionEnd)
         return;
 
@@ -756,7 +769,7 @@ void InlineTextBox::paintDocumentMarker(GraphicsContext& context, const FloatPoi
 
     // Determine whether we need to measure text
     bool markerSpansWholeBox = true;
-    if (m_start <= (int)marker.startOffset())
+    if (m_start <= marker.startOffset())
         markerSpansWholeBox = false;
     if ((end() + 1) != marker.endOffset()) // end points at the last char, not past it
         markerSpansWholeBox = false;
@@ -765,11 +778,11 @@ void InlineTextBox::paintDocumentMarker(GraphicsContext& context, const FloatPoi
 
     bool isDictationMarker = marker.type() == DocumentMarker::DictationAlternatives;
     if (!markerSpansWholeBox || grammar || isDictationMarker) {
-        int startPosition = std::max<int>(marker.startOffset() - m_start, 0);
-        int endPosition = std::min<int>(marker.endOffset() - m_start, m_len);
+        unsigned startPosition = clampedOffset(marker.startOffset());
+        unsigned endPosition = clampedOffset(marker.endOffset());
         
         if (m_truncation != cNoTruncation)
-            endPosition = std::min<int>(endPosition, m_truncation);
+            endPosition = std::min(endPosition, static_cast<unsigned>(m_truncation));
 
         // Calculate start & width
         int deltaY = renderer().style().isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
@@ -818,8 +831,8 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext& context, const FloatPo
     LayoutUnit deltaY = renderer().style().isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
     LayoutRect selectionRect = LayoutRect(boxOrigin.x(), boxOrigin.y() - deltaY, 0, this->selectionHeight());
 
-    int sPos = std::max<int>(marker.startOffset() - m_start, 0);
-    int ePos = std::min<int>(marker.endOffset() - m_start, m_len);
+    unsigned sPos = clampedOffset(marker.startOffset());
+    unsigned ePos = clampedOffset(marker.endOffset());
     TextRun run = constructTextRun(style);
     font.adjustSelectionRectForText(run, selectionRect, sPos, ePos);
 
@@ -985,18 +998,18 @@ int InlineTextBox::offsetForPosition(float lineOffset, bool includePartialGlyphs
     return font.offsetForPosition(constructTextRun(lineStyle), lineOffset - logicalLeft(), includePartialGlyphs);
 }
 
-float InlineTextBox::positionForOffset(int offset) const
+float InlineTextBox::positionForOffset(unsigned offset) const
 {
     ASSERT(offset >= m_start);
-    ASSERT(offset <= m_start + m_len);
+    ASSERT(offset <= m_start + len());
 
     if (isLineBreak())
         return logicalLeft();
 
     const RenderStyle& lineStyle = this->lineStyle();
     const FontCascade& font = fontToUse(lineStyle, renderer());
-    int from = !isLeftToRightDirection() ? offset - m_start : 0;
-    int to = !isLeftToRightDirection() ? m_len : offset - m_start;
+    unsigned from = !isLeftToRightDirection() ? clampedOffset(offset) : 0;
+    unsigned to = !isLeftToRightDirection() ? m_len : clampedOffset(offset);
     // FIXME: Do we need to add rightBearing here?
     LayoutRect selectionRect = LayoutRect(logicalLeft(), 0, 0, 0);
     TextRun run = constructTextRun(lineStyle);
index 67b634b..7236f60 100644 (file)
@@ -42,11 +42,6 @@ class InlineTextBox : public InlineBox {
 public:
     explicit InlineTextBox(RenderText& renderer)
         : InlineBox(renderer)
-        , m_prevTextBox(nullptr)
-        , m_nextTextBox(nullptr)
-        , m_start(0)
-        , m_len(0)
-        , m_truncation(cNoTruncation)
     {
         setBehavesLikeText(true);
     }
@@ -69,7 +64,7 @@ public:
     void setStart(unsigned start) { m_start = start; }
     void setLen(unsigned len) { m_len = len; }
 
-    void offsetRun(int d) { ASSERT(!isDirty()); m_start += d; }
+    void offsetRun(int d) { ASSERT(!isDirty()); ASSERT(d > 0 || m_start >= static_cast<unsigned>(-d)); m_start += d; }
 
     unsigned short truncation() const { return m_truncation; }
 
@@ -120,9 +115,9 @@ private:
 public:
     FloatRect calculateBoundaries() const override { return FloatRect(x(), y(), width(), height()); }
 
-    virtual LayoutRect localSelectionRect(int startPos, int endPos) const;
-    bool isSelected(int startPos, int endPos) const;
-    std::pair<int, int> selectionStartEnd() const;
+    virtual LayoutRect localSelectionRect(unsigned startPos, unsigned endPos) const;
+    bool isSelected(unsigned startPos, unsigned endPos) const;
+    std::pair<unsigned, unsigned> selectionStartEnd() const;
 
 protected:
     void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override;
@@ -155,12 +150,13 @@ private:
 
 public:
     virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
-    virtual float positionForOffset(int offset) const;
+    virtual float positionForOffset(unsigned offset) const;
 
 protected:
-    void paintCompositionBackground(GraphicsContext&, const FloatPoint& boxOrigin, const RenderStyle&, const FontCascade&, int startPos, int endPos);
+    void paintCompositionBackground(GraphicsContext&, const FloatPoint& boxOrigin, const RenderStyle&, const FontCascade&, unsigned startPos, unsigned endPos);
     void paintDocumentMarkers(GraphicsContext&, const FloatPoint& boxOrigin, const RenderStyle&, const FontCascade&, bool background);
     void paintCompositionUnderline(GraphicsContext&, const FloatPoint& boxOrigin, const CompositionUnderline&);
+    unsigned clampedOffset(unsigned) const;
 
 private:
     void paintDecoration(GraphicsContext&, const FontCascade&, RenderCombineText*, const TextRun&, const FloatPoint& textOrigin, const FloatRect& boxRect,
@@ -173,15 +169,15 @@ private:
 
     void behavesLikeText() const = delete;
 
-    InlineTextBox* m_prevTextBox; // The previous box that also uses our RenderObject
-    InlineTextBox* m_nextTextBox; // The next box that also uses our RenderObject
+    InlineTextBox* m_prevTextBox { nullptr }; // The previous box that also uses our RenderObject
+    InlineTextBox* m_nextTextBox { nullptr }; // The next box that also uses our RenderObject
 
-    int m_start;
-    unsigned short m_len;
+    unsigned m_start { 0 };
+    unsigned short m_len { 0 };
 
     // Where to truncate when text overflow is applied. We use special constants to
     // denote no truncation (the whole run paints) and full truncation (nothing paints at all).
-    unsigned short m_truncation;
+    unsigned short m_truncation { cNoTruncation };
 };
 
 } // namespace WebCore
index cde607c..d264d2a 100644 (file)
@@ -3489,7 +3489,7 @@ void RenderBlock::updateHitTestResult(HitTestResult& result, const LayoutPoint&
     }
 }
 
-LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine)
+LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine)
 {
     // Do the normal calculation in most cases.
     if (firstChild())
index 3152235..323d170 100644 (file)
@@ -476,7 +476,7 @@ private:
 
     void paintContinuationOutlines(PaintInfo&, const LayoutPoint&);
 
-    LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) final;
+    LayoutRect localCaretRect(InlineBox*, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) final;
     
     // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
     virtual VisiblePosition positionForPointWithInlineChildren(const LayoutPoint&, const RenderRegion*);
index 81b0ad6..eae72ba 100644 (file)
@@ -4383,7 +4383,7 @@ void RenderBox::computePositionedLogicalHeightReplaced(LogicalExtentComputedValu
     computedValues.m_position = logicalTopPos;
 }
 
-LayoutRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, LayoutUnit* extraWidthToEndOfLine)
+LayoutRect RenderBox::localCaretRect(InlineBox* box, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine)
 {
     // VisiblePositions at offsets inside containers either a) refer to the positions before/after
     // those containers (tables and select elements) or b) refer to the position inside an empty block.
index 03830c7..c6017d8 100644 (file)
@@ -481,7 +481,7 @@ public:
     bool hasUnsplittableScrollingOverflow() const;
     bool isUnsplittableForPagination() const;
 
-    LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = nullptr) override;
+    LayoutRect localCaretRect(InlineBox*, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine = nullptr) override;
 
     virtual LayoutRect overflowClipRect(const LayoutPoint& location, RenderRegion*, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize, PaintPhase = PaintPhaseBlockBackground);
     virtual LayoutRect overflowClipRectForChildLayers(const LayoutPoint& location, RenderRegion* region, OverlayScrollbarSizeRelevancy relevancy) { return overflowClipRect(location, region, relevancy); }
index dbb483d..adab648 100644 (file)
@@ -249,7 +249,7 @@ void RenderInline::updateAlwaysCreateLineBoxes(bool fullLayout)
     }
 }
 
-LayoutRect RenderInline::localCaretRect(InlineBox* inlineBox, int, LayoutUnit* extraWidthToEndOfLine)
+LayoutRect RenderInline::localCaretRect(InlineBox* inlineBox, unsigned, LayoutUnit* extraWidthToEndOfLine)
 {
     if (firstChild()) {
         // This condition is possible if the RenderInline is at an editing boundary,
index 5ceafc2..00bc9ec 100644 (file)
@@ -96,7 +96,7 @@ public:
     void setAlwaysCreateLineBoxes() { setRenderInlineAlwaysCreatesLineBoxes(true); }
     void updateAlwaysCreateLineBoxes(bool fullLayout);
 
-    LayoutRect localCaretRect(InlineBox*, int, LayoutUnit* extraWidthToEndOfLine) final;
+    LayoutRect localCaretRect(InlineBox*, unsigned, LayoutUnit* extraWidthToEndOfLine) final;
 
     bool hitTestCulledInline(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset);
 
index 1cd9634..b8c2358 100644 (file)
@@ -166,7 +166,7 @@ void RenderLineBreak::setSelectionState(SelectionState state)
     m_inlineBoxWrapper->root().setHasSelectedChildren(state != SelectionNone);
 }
 
-LayoutRect RenderLineBreak::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine)
+LayoutRect RenderLineBreak::localCaretRect(InlineBox* inlineBox, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine)
 {
     ASSERT_UNUSED(caretOffset, !caretOffset);
     ASSERT_UNUSED(inlineBox, inlineBox == m_inlineBoxWrapper);
index 11fd3bd..9707cd1 100644 (file)
@@ -66,7 +66,7 @@ private:
     int caretMinOffset() const override;
     int caretMaxOffset() const override;
     bool canBeSelectionLeaf() const override;
-    LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine) override;
+    LayoutRect localCaretRect(InlineBox*, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine) override;
     void setSelectionState(SelectionState) override;
 
     LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode) const override;
index 0eb8ad6..ac31226 100644 (file)
@@ -1206,7 +1206,7 @@ SelectionSubtreeRoot& RenderObject::selectionRoot() const
     return view();
 }
 
-void RenderObject::selectionStartEnd(int& spos, int& epos) const
+void RenderObject::selectionStartEnd(unsigned& spos, unsigned& epos) const
 {
     selectionRoot().selectionData().selectionStartEndPositions(spos, epos);
 }
@@ -1377,7 +1377,7 @@ LayoutSize RenderObject::offsetFromAncestorContainer(RenderElement& container) c
     return offset;
 }
 
-LayoutRect RenderObject::localCaretRect(InlineBox*, int, LayoutUnit* extraWidthToEndOfLine)
+LayoutRect RenderObject::localCaretRect(InlineBox*, unsigned, LayoutUnit* extraWidthToEndOfLine)
 {
     if (extraWidthToEndOfLine)
         *extraWidthToEndOfLine = 0;
index c6c6c3f..4116a50 100644 (file)
@@ -749,7 +749,7 @@ public:
      * @param extraWidthToEndOfLine optional out arg to give extra width to end of line -
      * useful for character range rect computations
      */
-    virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = nullptr);
+    virtual LayoutRect localCaretRect(InlineBox*, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine = nullptr);
 
     // When performing a global document tear-down, the renderer of the document is cleared.  We use this
     // as a hook to detect the case of document destruction and don't waste time doing unnecessary work.
@@ -782,7 +782,7 @@ public:
     virtual void imageChanged(WrappedImagePtr, const IntRect* = nullptr) { }
 
     SelectionSubtreeRoot& selectionRoot() const;
-    void selectionStartEnd(int& spos, int& epos) const;
+    void selectionStartEnd(unsigned& spos, unsigned& epos) const;
     
     void removeFromParent();
 
index aa2c34c..0bfb4ba 100644 (file)
@@ -616,18 +616,18 @@ bool RenderReplaced::isSelected() const
     if (s == SelectionInside)
         return true;
 
-    int selectionStart, selectionEnd;
+    unsigned selectionStart, selectionEnd;
     selectionStartEnd(selectionStart, selectionEnd);
     if (s == SelectionStart)
         return selectionStart == 0;
         
-    int end = element()->hasChildNodes() ? element()->countChildNodes() : 1;
+    unsigned end = element()->hasChildNodes() ? element()->countChildNodes() : 1;
     if (s == SelectionEnd)
         return selectionEnd == end;
     if (s == SelectionBoth)
         return selectionStart == 0 && selectionEnd == end;
         
-    ASSERT(0);
+    ASSERT_NOT_REACHED();
     return false;
 }
 
index 02886bb..d3fbe7c 100644 (file)
@@ -442,7 +442,7 @@ VisiblePosition RenderText::positionForPoint(const LayoutPoint& point, const Ren
     return m_lineBoxes.positionForPoint(*this, point);
 }
 
-LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, LayoutUnit* extraWidthToEndOfLine)
+LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine)
 {
     if (!inlineBox)
         return LayoutRect();
@@ -1372,13 +1372,12 @@ LayoutRect RenderText::collectSelectionRectsForLineBoxes(const RenderLayerModelO
 
     if (selectionState() == SelectionNone)
         return LayoutRect();
-    RenderBlock* cb = containingBlock();
-    if (!cb)
+    if (!containingBlock())
         return LayoutRect();
 
     // Now calculate startPos and endPos for painting selection.
     // We include a selection while endPos > 0
-    int startPos, endPos;
+    unsigned startPos, endPos;
     if (selectionState() == SelectionInside) {
         // We are fully selected.
         startPos = 0;
index d63e608..1fc8dc3 100644 (file)
@@ -119,7 +119,7 @@ public:
     bool canBeSelectionLeaf() const override { return true; }
     void setSelectionState(SelectionState) final;
     LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent = true) override;
-    LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) override;
+    LayoutRect localCaretRect(InlineBox*, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) override;
 
     LayoutRect collectSelectionRectsForLineBoxes(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent, Vector<LayoutRect>& rects);
 
index d943f3a..e59f3de 100644 (file)
@@ -445,7 +445,7 @@ void RenderTextLineBoxes::setSelectionState(RenderText& renderer, RenderObject::
         return;
     }
 
-    int start, end;
+    unsigned start, end;
     renderer.selectionStartEnd(start, end);
     if (state == RenderObject::SelectionStart) {
         end = renderer.textLength();
index a8dd718..1e7e2ec 100644 (file)
@@ -118,19 +118,7 @@ private:
 RenderView::RenderView(Document& document, RenderStyle&& style)
     : RenderBlockFlow(document, WTFMove(style))
     , m_frameView(*document.view())
-    , m_selectionUnsplitStart(nullptr)
-    , m_selectionUnsplitEnd(nullptr)
-    , m_selectionUnsplitStartPos(-1)
-    , m_selectionUnsplitEndPos(-1)
     , m_lazyRepaintTimer(*this, &RenderView::lazyRepaintTimerFired)
-    , m_pageLogicalHeight(0)
-    , m_pageLogicalHeightChanged(false)
-    , m_layoutState(nullptr)
-    , m_layoutStateDisableCount(0)
-    , m_renderQuoteHead(nullptr)
-    , m_renderCounterCount(0)
-    , m_selectionWasCaret(false)
-    , m_hasSoftwareFilters(false)
 #if ENABLE(SERVICE_CONTROLS)
     , m_selectionRectGatherer(*this)
 #endif
@@ -772,7 +760,10 @@ LayoutRect RenderView::subtreeSelectionBounds(const SelectionSubtreeRoot& root,
     SelectionMap selectedObjects;
 
     RenderObject* os = root.selectionData().selectionStart();
-    RenderObject* stop = rendererAfterPosition(root.selectionData().selectionEnd(), root.selectionData().selectionEndPos());
+    auto* selectionEnd = root.selectionData().selectionEnd();
+    RenderObject* stop = nullptr;
+    if (selectionEnd)
+        stop = rendererAfterPosition(selectionEnd, root.selectionData().selectionEndPos().value());
     SelectionIterator selectionIterator(os);
     while (os && os != stop) {
         if ((os->canBeSelectionLeaf() || os == root.selectionData().selectionStart() || os == root.selectionData().selectionEnd()) && os->selectionState() != SelectionNone) {
@@ -821,7 +812,10 @@ void RenderView::repaintSubtreeSelection(const SelectionSubtreeRoot& root) const
 {
     HashSet<RenderBlock*> processedBlocks;
 
-    RenderObject* end = rendererAfterPosition(root.selectionData().selectionEnd(), root.selectionData().selectionEndPos());
+    auto* selectionEnd = root.selectionData().selectionEnd();
+    RenderObject* end = nullptr;
+    if (selectionEnd)
+        end = rendererAfterPosition(selectionEnd, root.selectionData().selectionEndPos().value());
     SelectionIterator selectionIterator(root.selectionData().selectionStart());
     for (RenderObject* o = selectionIterator.current(); o && o != end; o = selectionIterator.next()) {
         if (!o->canBeSelectionLeaf() && o != root.selectionData().selectionStart() && o != root.selectionData().selectionEnd())
@@ -840,7 +834,7 @@ void RenderView::repaintSubtreeSelection(const SelectionSubtreeRoot& root) const
     }
 }
 
-void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode blockRepaintMode)
+void RenderView::setSelection(RenderObject* start, Optional<unsigned> startPos, RenderObject* end, Optional<unsigned> endPos, SelectionRepaintMode blockRepaintMode)
 {
     // Make sure both our start and end objects are defined.
     // Check www.msnbc.com and try clicking around to find the case where this happened.
@@ -877,7 +871,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
     splitSelectionBetweenSubtrees(start, startPos, end, endPos, blockRepaintMode);
 }
 
-void RenderView::splitSelectionBetweenSubtrees(const RenderObject* start, int startPos, const RenderObject* end, int endPos, SelectionRepaintMode blockRepaintMode)
+void RenderView::splitSelectionBetweenSubtrees(const RenderObject* start, Optional<unsigned> startPos, const RenderObject* end, Optional<unsigned> endPos, SelectionRepaintMode blockRepaintMode)
 {
     // Compute the visible selection end points for each of the subtrees.
     RenderSubtreesMap renderSubtreesMap;
@@ -902,14 +896,16 @@ void RenderView::splitSelectionBetweenSubtrees(const RenderObject* start, int st
             SelectionSubtreeData selectionData = renderSubtreesMap.get(&root);
             if (selectionData.selectionClear()) {
                 selectionData.setSelectionStart(node->renderer());
-                selectionData.setSelectionStartPos(node == startNode ? startPos : 0);
+                selectionData.setSelectionStartPos(node == startNode ? startPos : Optional<unsigned>(0));
             }
 
             selectionData.setSelectionEnd(node->renderer());
             if (node == endNode)
                 selectionData.setSelectionEndPos(endPos);
-            else
-                selectionData.setSelectionEndPos(node->offsetInCharacters() ? node->maxCharacterOffset() : node->countChildNodes());
+            else {
+                unsigned newEndPos = node->offsetInCharacters() ? node->maxCharacterOffset() : node->countChildNodes();
+                selectionData.setSelectionEndPos(newEndPos);
+            }
 
             renderSubtreesMap.set(&root, selectionData);
         }
@@ -960,7 +956,10 @@ void RenderView::clearSubtreeSelection(const SelectionSubtreeRoot& root, Selecti
     // the union of those rects might remain the same even when changes have occurred.
 
     RenderObject* os = root.selectionData().selectionStart();
-    RenderObject* stop = rendererAfterPosition(root.selectionData().selectionEnd(), root.selectionData().selectionEndPos());
+    auto* selectionEnd = root.selectionData().selectionEnd();
+    RenderObject* stop = nullptr;
+    if (selectionEnd)
+        stop = rendererAfterPosition(selectionEnd, root.selectionData().selectionEndPos().value());
     SelectionIterator selectionIterator(os);
     while (os && os != stop) {
         if (isValidObjectForNewSelection(root, *os)) {
@@ -998,7 +997,10 @@ void RenderView::applySubtreeSelection(const SelectionSubtreeRoot& root, Selecti
     }
 
     RenderObject* selectionStart = root.selectionData().selectionStart();
-    RenderObject* selectionEnd = rendererAfterPosition(root.selectionData().selectionEnd(), root.selectionData().selectionEndPos());
+    auto* selectionDataEnd = root.selectionData().selectionEnd();
+    RenderObject* selectionEnd = nullptr;
+    if (selectionDataEnd)
+        selectionEnd = rendererAfterPosition(selectionDataEnd, root.selectionData().selectionEndPos().value());
     SelectionIterator selectionIterator(selectionStart);
     for (RenderObject* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
         if (currentRenderer == root.selectionData().selectionStart() || currentRenderer == root.selectionData().selectionEnd())
@@ -1089,7 +1091,7 @@ void RenderView::applySubtreeSelection(const SelectionSubtreeRoot& root, Selecti
         selectedBlockInfo.value->repaint();
 }
 
-void RenderView::getSelection(RenderObject*& startRenderer, int& startOffset, RenderObject*& endRenderer, int& endOffset) const
+void RenderView::getSelection(RenderObject*& startRenderer, Optional<unsigned>& startOffset, RenderObject*& endRenderer, Optional<unsigned>& endOffset) const
 {
     startRenderer = m_selectionUnsplitStart;
     startOffset = m_selectionUnsplitStartPos;
@@ -1100,7 +1102,7 @@ void RenderView::getSelection(RenderObject*& startRenderer, int& startOffset, Re
 void RenderView::clearSelection()
 {
     layer()->repaintBlockSelectionGaps();
-    setSelection(nullptr, -1, nullptr, -1, RepaintNewMinusOld);
+    setSelection(nullptr, Nullopt, nullptr, Nullopt, RepaintNewMinusOld);
 }
 
 bool RenderView::printing() const
index c7c9286..5239426 100644 (file)
@@ -85,8 +85,8 @@ public:
     void paintBoxDecorations(PaintInfo&, const LayoutPoint&) override;
 
     enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld, RepaintNothing };
-    void setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode = RepaintNewXOROld);
-    void getSelection(RenderObject*& startRenderer, int& startOffset, RenderObject*& endRenderer, int& endOffset) const;
+    void setSelection(RenderObject* start, Optional<unsigned> startPos, RenderObject* endObject, Optional<unsigned> endPos, SelectionRepaintMode = RepaintNewXOROld);
+    void getSelection(RenderObject*& startRenderer, Optional<unsigned>& startOffset, RenderObject*& endRenderer, Optional<unsigned>& endOffset) const;
     void clearSelection();
     RenderObject* selectionUnsplitStart() const { return m_selectionUnsplitStart; }
     RenderObject* selectionUnsplitEnd() const { return m_selectionUnsplitEnd; }
@@ -307,7 +307,7 @@ private:
 
     bool isScrollableOrRubberbandableBox() const override;
 
-    void splitSelectionBetweenSubtrees(const RenderObject* startRenderer, int startPos, const RenderObject* endRenderer, int endPos, SelectionRepaintMode blockRepaintMode);
+    void splitSelectionBetweenSubtrees(const RenderObject* startRenderer, Optional<unsigned> startPos, const RenderObject* endRenderer, Optional<unsigned> endPos, SelectionRepaintMode blockRepaintMode);
     void clearSubtreeSelection(const SelectionSubtreeRoot&, SelectionRepaintMode, OldSelectionData&) const;
     void updateSelectionForSubtrees(RenderSubtreesMap&, SelectionRepaintMode);
     void applySubtreeSelection(const SelectionSubtreeRoot&, SelectionRepaintMode, const OldSelectionData&);
@@ -317,10 +317,10 @@ private:
 private:
     FrameView& m_frameView;
 
-    RenderObject* m_selectionUnsplitStart;
-    RenderObject* m_selectionUnsplitEnd;
-    int m_selectionUnsplitStartPos;
-    int m_selectionUnsplitEndPos;
+    RenderObject* m_selectionUnsplitStart { nullptr };
+    RenderObject* m_selectionUnsplitEnd { nullptr };
+    Optional<unsigned> m_selectionUnsplitStartPos;
+    Optional<unsigned> m_selectionUnsplitEndPos;
 
     // Include this RenderView.
     uint64_t m_rendererCount { 1 };
@@ -329,18 +329,11 @@ private:
 
     // FIXME: Only used by embedded WebViews inside AppKit NSViews.  Find a way to remove.
     struct LegacyPrinting {
-        LegacyPrinting()
-            : m_bestTruncatedAt(0)
-            , m_truncatedAt(0)
-            , m_truncatorWidth(0)
-            , m_forcedPageBreak(false)
-        { }
-
-        int m_bestTruncatedAt;
-        int m_truncatedAt;
-        int m_truncatorWidth;
+        int m_bestTruncatedAt { 0 };
+        int m_truncatedAt { 0 };
+        int m_truncatorWidth { 0 };
         IntRect m_printRect;
-        bool m_forcedPageBreak;
+        bool m_forcedPageBreak { false };
     };
     LegacyPrinting m_legacyPrinting;
     // End deprecated members.
@@ -354,17 +347,17 @@ private:
 
     std::unique_ptr<ImageQualityController> m_imageQualityController;
     LayoutUnit m_pageLogicalHeight;
-    bool m_pageLogicalHeightChanged;
+    bool m_pageLogicalHeightChanged { false };
     std::unique_ptr<LayoutState> m_layoutState;
-    unsigned m_layoutStateDisableCount;
+    unsigned m_layoutStateDisableCount { 0 };
     std::unique_ptr<RenderLayerCompositor> m_compositor;
     std::unique_ptr<FlowThreadController> m_flowThreadController;
 
-    RenderQuote* m_renderQuoteHead;
-    unsigned m_renderCounterCount;
+    RenderQuote* m_renderQuoteHead { nullptr };
+    unsigned m_renderCounterCount { 0 };
 
-    bool m_selectionWasCaret;
-    bool m_hasSoftwareFilters;
+    bool m_selectionWasCaret { false };
+    bool m_hasSoftwareFilters { false };
     bool m_usesFirstLineRules { false };
     bool m_usesFirstLetterRules { false };
 
index 9f65e94..181e6b5 100644 (file)
@@ -42,19 +42,16 @@ SelectionSubtreeRoot::SelectionSubtreeRoot()
 {
 }
 
-SelectionSubtreeRoot::SelectionSubtreeRoot(RenderObject* selectionStart, int selectionStartPos, RenderObject* selectionEnd, int selectionEndPos)
-    : m_selectionSubtreeData(selectionStart, selectionStartPos, selectionEnd, selectionEndPos)
-{
-}
-
 void SelectionSubtreeRoot::adjustForVisibleSelection(Document& document)
 {
     if (m_selectionSubtreeData.selectionClear())
         return;
 
     // Create a range based on the cached end points
-    Position startPosition = createLegacyEditingPosition(m_selectionSubtreeData.selectionStart()->node(), m_selectionSubtreeData.selectionStartPos());
-    Position endPosition = createLegacyEditingPosition(m_selectionSubtreeData.selectionEnd()->node(), m_selectionSubtreeData.selectionEndPos());
+    auto selectionStart = m_selectionSubtreeData.selectionStartPos().value();
+    auto selectionEnd = m_selectionSubtreeData.selectionEndPos().value();
+    Position startPosition = createLegacyEditingPosition(m_selectionSubtreeData.selectionStart()->node(), selectionStart);
+    Position endPosition = createLegacyEditingPosition(m_selectionSubtreeData.selectionEnd()->node(), selectionEnd);
 
     RefPtr<Range> range = Range::create(document, startPosition.parentAnchoredEquivalent(), endPosition.parentAnchoredEquivalent());
     VisibleSelection selection(*range);
@@ -82,10 +79,13 @@ void SelectionSubtreeRoot::adjustForVisibleSelection(Document& document)
     if (&startPos.deprecatedNode()->renderer()->selectionRoot() != this)
         return;
 
+    auto newStartPos = startPos.deprecatedEditingOffset();
+    auto newEndPos = endPos.deprecatedEditingOffset();
+    ASSERT(newStartPos >= 0 && newEndPos >= 0);
     m_selectionSubtreeData.setSelectionStart(startPos.deprecatedNode()->renderer());
-    m_selectionSubtreeData.setSelectionStartPos(startPos.deprecatedEditingOffset());
+    m_selectionSubtreeData.setSelectionStartPos(newStartPos);
     m_selectionSubtreeData.setSelectionEnd(endPos.deprecatedNode()->renderer());
-    m_selectionSubtreeData.setSelectionEndPos(endPos.deprecatedEditingOffset());
+    m_selectionSubtreeData.setSelectionEndPos(newEndPos);
 }
 
 } // namespace WebCore
index dd19197..a821211 100644 (file)
@@ -45,28 +45,20 @@ public:
 
     struct OldSelectionData {
         OldSelectionData()
-            : selectionStartPos(-1)
-            , selectionEndPos(-1)
         {
         }
 
-        int selectionStartPos;
-        int selectionEndPos;
+        Optional<unsigned> selectionStartPos;
+        Optional<unsigned> selectionEndPos;
         SelectedObjectMap selectedObjects;
         SelectedBlockMap selectedBlocks;
     };
 
     class SelectionSubtreeData {
     public:
-        SelectionSubtreeData()
-            : m_selectionStart(nullptr)
-            , m_selectionStartPos(-1)
-            , m_selectionEnd(nullptr)
-            , m_selectionEndPos(-1)
-        {
-        }
+        SelectionSubtreeData() = default;
 
-        SelectionSubtreeData(RenderObject* selectionStart, int selectionStartPos, RenderObject* selectionEnd, int selectionEndPos)
+        SelectionSubtreeData(RenderObject* selectionStart, Optional<unsigned> selectionStartPos, RenderObject* selectionEnd, Optional<unsigned> selectionEndPos)
             : m_selectionStart(selectionStart)
             , m_selectionStartPos(selectionStartPos)
             , m_selectionEnd(selectionEnd)
@@ -75,46 +67,45 @@ public:
         }
 
         RenderObject* selectionStart() const { return m_selectionStart; }
-        int selectionStartPos() const { return m_selectionStartPos; }
+        Optional<unsigned> selectionStartPos() const { return m_selectionStartPos; }
         RenderObject* selectionEnd() const { return m_selectionEnd; }
-        int selectionEndPos() const { return m_selectionEndPos; }
+        Optional<unsigned> selectionEndPos() const { return m_selectionEndPos; }
         bool selectionClear() const
         {
             return !m_selectionStart
-            && (m_selectionStartPos == -1)
+            && (!m_selectionStartPos)
             && !m_selectionEnd
-            && (m_selectionEndPos == -1);
+            && (!m_selectionEndPos);
         }
 
-        void selectionStartEndPositions(int& startPos, int& endPos) const
+        void selectionStartEndPositions(unsigned& startPos, unsigned& endPos) const
         {
-            startPos = m_selectionStartPos;
-            endPos = m_selectionEndPos;
+            startPos = m_selectionStartPos.value();
+            endPos = m_selectionEndPos.value();
         }
         void setSelectionStart(RenderObject* selectionStart) { m_selectionStart = selectionStart; }
-        void setSelectionStartPos(int selectionStartPos) { m_selectionStartPos = selectionStartPos; }
+        void setSelectionStartPos(Optional<unsigned> selectionStartPos) { m_selectionStartPos = selectionStartPos;}
         void setSelectionEnd(RenderObject* selectionEnd) { m_selectionEnd = selectionEnd; }
-        void setSelectionEndPos(int selectionEndPos) { m_selectionEndPos = selectionEndPos; }
+        void setSelectionEndPos(Optional<unsigned> selectionEndPos) { m_selectionEndPos = selectionEndPos;}
         void clearSelection()
         {
             m_selectionStart = nullptr;
-            m_selectionStartPos = -1;
+            m_selectionStartPos = Nullopt;
             m_selectionEnd = nullptr;
-            m_selectionEndPos = -1;
+            m_selectionEndPos = Nullopt;
         }
 
     private:
-        RenderObject* m_selectionStart;
-        int m_selectionStartPos;
-        RenderObject* m_selectionEnd;
-        int m_selectionEndPos;
+        RenderObject* m_selectionStart { nullptr };
+        Optional<unsigned> m_selectionStartPos;
+        RenderObject* m_selectionEnd { nullptr };
+        Optional<unsigned> m_selectionEndPos;
     };
 
     typedef HashMap<SelectionSubtreeRoot*, SelectionSubtreeData> RenderSubtreesMap;
     typedef HashMap<const SelectionSubtreeRoot*, std::unique_ptr<OldSelectionData>> SubtreeOldSelectionDataMap;
 
     SelectionSubtreeRoot();
-    SelectionSubtreeRoot(RenderObject* selectionStart, int selectionStartPos, RenderObject* selectionEnd, int selectionEndPos);
 
     SelectionSubtreeData& selectionData() { return m_selectionSubtreeData; }
     const SelectionSubtreeData& selectionData() const { return m_selectionSubtreeData; }
index 8d3597f..6e5ecc2 100644 (file)
@@ -84,17 +84,17 @@ TextPainter::TextPainter(GraphicsContext& context)
 }
 
 void TextPainter::drawTextOrEmphasisMarks(const FontCascade& font, const TextRun& textRun, const AtomicString& emphasisMark,
-    int emphasisMarkOffset, const FloatPoint& textOrigin, int startOffset, int endOffset)
+    float emphasisMarkOffset, const FloatPoint& textOrigin, unsigned startOffset, unsigned endOffset)
 {
     ASSERT(startOffset < endOffset);
     if (emphasisMark.isEmpty())
         m_context.drawText(font, textRun, textOrigin, startOffset, endOffset);
     else
-        m_context.drawEmphasisMarks(font, textRun, emphasisMark, textOrigin + IntSize(0, emphasisMarkOffset), startOffset, endOffset);
+        m_context.drawEmphasisMarks(font, textRun, emphasisMark, textOrigin + FloatSize(0, emphasisMarkOffset), startOffset, endOffset);
 }
 
 void TextPainter::paintTextWithShadows(const ShadowData* shadow, const FontCascade& font, const TextRun& textRun, const FloatRect& boxRect, const FloatPoint& textOrigin,
-    int startOffset, int endOffset, const AtomicString& emphasisMark, int emphasisMarkOffset, bool stroked)
+    unsigned startOffset, unsigned endOffset, const AtomicString& emphasisMark, float emphasisMarkOffset, bool stroked)
 {
     if (!shadow) {
         drawTextOrEmphasisMarks(font, textRun, emphasisMark, emphasisMarkOffset, textOrigin, startOffset, endOffset);
@@ -120,7 +120,7 @@ void TextPainter::paintTextWithShadows(const ShadowData* shadow, const FontCasca
     }
 }
 
-void TextPainter::paintTextAndEmphasisMarksIfNeeded(const TextRun& textRun, const FloatRect& boxRect, const FloatPoint& textOrigin, int startOffset, int endOffset,
+void TextPainter::paintTextAndEmphasisMarksIfNeeded(const TextRun& textRun, const FloatRect& boxRect, const FloatPoint& textOrigin, unsigned startOffset, unsigned endOffset,
     const TextPaintStyle& paintStyle, const ShadowData* shadow)
 {
     // FIXME: Truncate right-to-left text correctly.
@@ -145,7 +145,7 @@ void TextPainter::paintTextAndEmphasisMarksIfNeeded(const TextRun& textRun, cons
         m_context.concatCTM(rotation(boxRect, Counterclockwise));
 }
     
-void TextPainter::paintText(const TextRun& textRun, int length, const FloatRect& boxRect, const FloatPoint& textOrigin, int selectionStart, int selectionEnd,
+void TextPainter::paintText(const TextRun& textRun, unsigned length, const FloatRect& boxRect, const FloatPoint& textOrigin, unsigned selectionStart, unsigned selectionEnd,
     bool paintSelectedTextOnly, bool paintSelectedTextSeparately)
 {
     ASSERT(m_font);
index e4b5b18..2e167fb 100644 (file)
@@ -54,18 +54,18 @@ public:
     void setSelectionPaintStyle(const TextPaintStyle& selectionPaintStyle) { m_selectionPaintStyle = selectionPaintStyle; }
     void setIsHorizontal(bool isHorizontal) { m_textBoxIsHorizontal = isHorizontal; }
     void setFont(const FontCascade& font) { m_font = &font; }
-    void addEmphasis(const AtomicString& emphasisMark, int emphasisMarkOffset, RenderCombineText*);
+    void addEmphasis(const AtomicString& emphasisMark, float emphasisMarkOffset, RenderCombineText*);
     void addTextShadow(const ShadowData* textShadow, const ShadowData* selectionShadow);
 
-    void paintText(const TextRun&, int length, const FloatRect& boxRect, const FloatPoint& textOrigin,
-        int selectionStart = 0, int selectionEnd = 0, bool paintSelectedTextOnly = false, bool paintSelectedTextSeparately = false);
+    void paintText(const TextRun&, unsigned length, const FloatRect& boxRect, const FloatPoint& textOrigin,
+        unsigned selectionStart = 0, unsigned selectionEnd = 0, bool paintSelectedTextOnly = false, bool paintSelectedTextSeparately = false);
 
 private:
-    void drawTextOrEmphasisMarks(const FontCascade&, const TextRun&, const AtomicString& emphasisMark, int emphasisMarkOffset,
-        const FloatPoint& textOrigin, int startOffset, int endOffset);
+    void drawTextOrEmphasisMarks(const FontCascade&, const TextRun&, const AtomicString& emphasisMark, float emphasisMarkOffset,
+        const FloatPoint& textOrigin, unsigned startOffset, unsigned endOffset);
     void paintTextWithShadows(const ShadowData*, const FontCascade&, const TextRun&, const FloatRect& boxRect, const FloatPoint& textOrigin,
-        int startOffset, int endOffset, const AtomicString& emphasisMark, int emphasisMarkOffset, bool stroked);
-    void paintTextAndEmphasisMarksIfNeeded(const TextRun&, const FloatRect& boxRect, const FloatPoint& textOrigin, int startOffset, int endOffset,
+        unsigned startOffset, unsigned endOffset, const AtomicString& emphasisMark, float emphasisMarkOffset, bool stroked);
+    void paintTextAndEmphasisMarksIfNeeded(const TextRun&, const FloatRect& boxRect, const FloatPoint& textOrigin, unsigned startOffset, unsigned endOffset,
         const TextPaintStyle&, const ShadowData*);
 
     GraphicsContext& m_context;
@@ -76,11 +76,11 @@ private:
     const ShadowData* m_selectionShadow { nullptr };
     AtomicString m_emphasisMark;
     RenderCombineText* m_combinedText { nullptr };
-    int m_emphasisMarkOffset { 0 };
+    float m_emphasisMarkOffset { 0 };
     bool m_textBoxIsHorizontal { true };
 };
 
-inline void TextPainter::addEmphasis(const AtomicString& emphasisMark, int emphasisMarkOffset, RenderCombineText* combinedText)
+inline void TextPainter::addEmphasis(const AtomicString& emphasisMark, float emphasisMarkOffset, RenderCombineText* combinedText)
 {
     m_emphasisMark = emphasisMark;
     m_emphasisMarkOffset = emphasisMarkOffset;
index 97133e1..c6ebaf3 100644 (file)
@@ -116,17 +116,17 @@ std::unique_ptr<InlineTextBox> RenderSVGInlineText::createTextBox()
     return WTFMove(box);
 }
 
-LayoutRect RenderSVGInlineText::localCaretRect(InlineBox* box, int caretOffset, LayoutUnit*)
+LayoutRect RenderSVGInlineText::localCaretRect(InlineBox* box, unsigned caretOffset, LayoutUnit*)
 {
     if (!is<InlineTextBox>(box))
         return LayoutRect();
 
     auto& textBox = downcast<InlineTextBox>(*box);
-    if (static_cast<unsigned>(caretOffset) < textBox.start() || static_cast<unsigned>(caretOffset) > textBox.start() + textBox.len())
+    if (caretOffset < textBox.start() || caretOffset > textBox.start() + textBox.len())
         return LayoutRect();
 
     // Use the edge of the selection rect to determine the caret rect.
-    if (static_cast<unsigned>(caretOffset) < textBox.start() + textBox.len()) {
+    if (caretOffset < textBox.start() + textBox.len()) {
         LayoutRect rect = textBox.localSelectionRect(caretOffset, caretOffset + 1);
         LayoutUnit x = textBox.isLeftToRightDirection() ? rect.x() : rect.maxX();
         return LayoutRect(x, rect.y(), caretWidth, rect.height());
index 746773b..9998fe1 100644 (file)
@@ -60,7 +60,7 @@ private:
     bool isSVGInlineText() const override { return true; }
 
     VisiblePosition positionForPoint(const LayoutPoint&, const RenderRegion*) override;
-    LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) override;
+    LayoutRect localCaretRect(InlineBox*, unsigned caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) override;
     IntRect linesBoundingBox() const override;
     std::unique_ptr<InlineTextBox> createTextBox() override;
 
index a4f419f..75155c8 100644 (file)
@@ -100,14 +100,14 @@ int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
     return fragment.characterOffset - start() + renderer().scaledFont().offsetForPosition(textRun, position * scalingFactor, includePartialGlyphs);
 }
 
-float SVGInlineTextBox::positionForOffset(int) const
+float SVGInlineTextBox::positionForOffset(unsigned) const
 {
     // SVG doesn't use the offset <-> position selection system. 
     ASSERT_NOT_REACHED();
     return 0;
 }
 
-FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment& fragment, int startPosition, int endPosition, const RenderStyle* style) const
+FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment& fragment, unsigned startPosition, unsigned endPosition, const RenderStyle* style) const
 {
     ASSERT_WITH_SECURITY_IMPLICATION(startPosition < endPosition);
     ASSERT(style);
@@ -134,11 +134,10 @@ FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment&
     return snappedSelectionRect;
 }
 
-LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPosition) const
+LayoutRect SVGInlineTextBox::localSelectionRect(unsigned startPosition, unsigned endPosition) const
 {
-    int boxStart = start();
-    startPosition = std::max(startPosition - boxStart, 0);
-    endPosition = std::min(endPosition - boxStart, static_cast<int>(len()));
+    startPosition = clampedOffset(startPosition);
+    endPosition = clampedOffset(endPosition);
     if (startPosition >= endPosition)
         return LayoutRect();
 
@@ -146,8 +145,8 @@ LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPositi
 
     AffineTransform fragmentTransform;
     FloatRect selectionRect;
-    int fragmentStartPosition = 0;
-    int fragmentEndPosition = 0;
+    unsigned fragmentStartPosition = 0;
+    unsigned fragmentEndPosition = 0;
 
     unsigned textFragmentsSize = m_textFragments.size();
     for (unsigned i = 0; i < textFragmentsSize; ++i) {
@@ -203,12 +202,12 @@ void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo)
 
     auto& style = parentRenderer.style();
 
-    int startPosition;
-    int endPosition;
+    unsigned startPosition;
+    unsigned endPosition;
     std::tie(startPosition, endPosition) = selectionStartEnd();
 
-    int fragmentStartPosition = 0;
-    int fragmentEndPosition = 0;
+    unsigned fragmentStartPosition = 0;
+    unsigned fragmentEndPosition = 0;
     AffineTransform fragmentTransform;
     unsigned textFragmentsSize = m_textFragments.size();
     for (unsigned i = 0; i < textFragmentsSize; ++i) {
@@ -407,21 +406,24 @@ TextRun SVGInlineTextBox::constructTextRun(const RenderStyle* style, const SVGTe
     return run;
 }
 
-bool SVGInlineTextBox::mapStartEndPositionsIntoFragmentCoordinates(const SVGTextFragment& fragment, int& startPosition, int& endPosition) const
+bool SVGInlineTextBox::mapStartEndPositionsIntoFragmentCoordinates(const SVGTextFragment& fragment, unsigned& startPosition, unsigned& endPosition) const
 {
     if (startPosition >= endPosition)
         return false;
 
-    int offset = static_cast<int>(fragment.characterOffset) - start();
-    int length = static_cast<int>(fragment.length);
+    ASSERT(fragment.characterOffset >= start());
+    unsigned offset = fragment.characterOffset - start();
+    unsigned length = fragment.length;
 
     if (startPosition >= offset + length || endPosition <= offset)
         return false;
 
     if (startPosition < offset)
         startPosition = 0;
-    else
+    else {
+        ASSERT(startPosition >= offset);
         startPosition -= offset;
+    }
 
     if (endPosition > offset + length)
         endPosition = length;
@@ -540,7 +542,7 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext& context, TextDe
         releasePaintingResource(contextPtr, &path);
 }
 
-void SVGInlineTextBox::paintTextWithShadows(GraphicsContext& context, const RenderStyle* style, TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int endPosition)
+void SVGInlineTextBox::paintTextWithShadows(GraphicsContext& context, const RenderStyle* style, TextRun& textRun, const SVGTextFragment& fragment, unsigned startPosition, unsigned endPosition)
 {
     float scalingFactor = renderer().scalingFactor();
     ASSERT(scalingFactor);
@@ -590,8 +592,8 @@ void SVGInlineTextBox::paintText(GraphicsContext& context, const RenderStyle* st
     ASSERT(style);
     ASSERT(selectionStyle);
 
-    int startPosition = 0;
-    int endPosition = 0;
+    unsigned startPosition = 0;
+    unsigned endPosition = 0;
     if (hasSelection) {
         std::tie(startPosition, endPosition) = selectionStartEnd();
         hasSelection = mapStartEndPositionsIntoFragmentCoordinates(fragment, startPosition, endPosition);
@@ -618,7 +620,7 @@ void SVGInlineTextBox::paintText(GraphicsContext& context, const RenderStyle* st
         SVGResourcesCache::clientStyleChanged(parent()->renderer(), StyleDifferenceRepaint, *style);
 
     // Eventually draw text using regular style from the end position of the selection to the end of the current chunk part
-    if (endPosition < static_cast<int>(fragment.length) && !paintSelectedTextOnly)
+    if (endPosition < fragment.length && !paintSelectedTextOnly)
         paintTextWithShadows(context, style, textRun, fragment, endPosition, fragment.length);
 }
 
index c8fd148..1e32a42 100644 (file)
@@ -43,13 +43,13 @@ public:
     int selectionTop() { return top(); }
     int selectionHeight() { return static_cast<int>(ceilf(m_logicalHeight)); }
     int offsetForPosition(float x, bool includePartialGlyphs = true) const override;
-    float positionForOffset(int offset) const override;
+    float positionForOffset(unsigned offset) const override;
 
     void paintSelectionBackground(PaintInfo&);
     void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override;
-    LayoutRect localSelectionRect(int startPosition, int endPosition) const override;
+    LayoutRect localSelectionRect(unsigned startPosition, unsigned endPosition) const override;
 
-    bool mapStartEndPositionsIntoFragmentCoordinates(const SVGTextFragment&, int& startPosition, int& endPosition) const;
+    bool mapStartEndPositionsIntoFragmentCoordinates(const SVGTextFragment&, unsigned& startPosition, unsigned& endPosition) const;
 
     FloatRect calculateBoundaries() const override;
 
@@ -64,7 +64,7 @@ public:
     void setStartsNewTextChunk(bool newTextChunk) { m_startsNewTextChunk = newTextChunk; }
 
     int offsetForPositionInFragment(const SVGTextFragment&, float position, bool includePartialGlyphs) const;
-    FloatRect selectionRectForTextFragment(const SVGTextFragment&, int fragmentStartPosition, int fragmentEndPosition, const RenderStyle*) const;
+    FloatRect selectionRectForTextFragment(const SVGTextFragment&, unsigned fragmentStartPosition, unsigned fragmentEndPosition, const RenderStyle*) const;
 
 private:
     bool isSVGInlineTextBox() const override { return true; }
@@ -79,7 +79,7 @@ private:
 
     void paintDecoration(GraphicsContext&, TextDecoration, const SVGTextFragment&);
     void paintDecorationWithStyle(GraphicsContext&, TextDecoration, const SVGTextFragment&, RenderBoxModelObject& decorationRenderer);
-    void paintTextWithShadows(GraphicsContext&, const RenderStyle*, TextRun&, const SVGTextFragment&, int startPosition, int endPosition);
+    void paintTextWithShadows(GraphicsContext&, const RenderStyle*, TextRun&, const SVGTextFragment&, unsigned startPosition, unsigned endPosition);
     void paintText(GraphicsContext&, const RenderStyle*, const RenderStyle* selectionStyle, const SVGTextFragment&, bool hasSelection, bool paintSelectedTextOnly);
 
     bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom, HitTestAction) override;
index ff36677..9330aaa 100644 (file)
@@ -134,13 +134,15 @@ bool SVGTextQuery::executeQuery(Data* queryData, ProcessTextFragmentCallback fra
     return false;
 }
 
-bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData, const SVGTextFragment& fragment, int& startPosition, int& endPosition) const
+bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData, const SVGTextFragment& fragment, unsigned& startPosition, unsigned& endPosition) const
 {
     // Reuse the same logic used for text selection & painting, to map our query start/length into start/endPositions of the current text fragment.
+    ASSERT(startPosition >= queryData->processedCharacters);
+    ASSERT(endPosition >= queryData->processedCharacters);
     startPosition -= queryData->processedCharacters;
     endPosition -= queryData->processedCharacters;
 
-    if (startPosition >= endPosition || startPosition < 0 || endPosition < 0)
+    if (startPosition >= endPosition)
         return false;
 
     modifyStartEndPositionsRespectingLigatures(queryData, startPosition, endPosition);
@@ -151,7 +153,7 @@ bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData,
     return true;
 }
 
-void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, int& startPosition, int& endPosition) const
+void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, unsigned& startPosition, unsigned& endPosition) const
 {
     SVGTextLayoutAttributes* layoutAttributes = queryData->textRenderer->layoutAttributes();
     Vector<SVGTextMetrics>& textMetricsValues = layoutAttributes->textMetricsValues();
@@ -167,7 +169,7 @@ void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, i
     bool alterStartPosition = true;
     bool alterEndPosition = true;
 
-    int lastPositionOffset = -1;
+    Optional<unsigned> lastPositionOffset;
     for (; textMetricsOffset < textMetricsSize && positionOffset < positionSize; ++textMetricsOffset) {
         SVGTextMetrics& metrics = textMetricsValues[textMetricsOffset];
 
@@ -182,21 +184,21 @@ void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, i
             break;
 
         // If the start position maps to a character in the metrics list, we don't need to modify it.
-        if (startPosition == static_cast<int>(positionOffset))
+        if (startPosition == positionOffset)
             alterStartPosition = false;
 
         // If the start position maps to a character in the metrics list, we don't need to modify it.
-        if (endPosition == static_cast<int>(positionOffset))
+        if (endPosition == positionOffset)
             alterEndPosition = false;
 
         // Detect ligatures.
-        if (lastPositionOffset != -1 && lastPositionOffset - positionOffset > 1) {
-            if (alterStartPosition && startPosition > lastPositionOffset && startPosition < static_cast<int>(positionOffset)) {
-                startPosition = lastPositionOffset;
+        if (lastPositionOffset && lastPositionOffset.value() - positionOffset > 1) {
+            if (alterStartPosition && startPosition > lastPositionOffset.value() && startPosition < positionOffset) {
+                startPosition = lastPositionOffset.value();
                 alterStartPosition = false;
             }
 
-            if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset)) {
+            if (alterEndPosition && endPosition > lastPositionOffset.value() && endPosition < positionOffset) {
                 endPosition = positionOffset;
                 alterEndPosition = false;
             }
@@ -212,11 +214,11 @@ void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, i
     if (!alterStartPosition && !alterEndPosition)
         return;
 
-    if (lastPositionOffset != -1 && lastPositionOffset - positionOffset > 1) {
-        if (alterStartPosition && startPosition > lastPositionOffset && startPosition < static_cast<int>(positionOffset))
-            startPosition = lastPositionOffset;
+    if (lastPositionOffset && lastPositionOffset.value() - positionOffset > 1) {
+        if (alterStartPosition && startPosition > lastPositionOffset.value() && startPosition < positionOffset)
+            startPosition = lastPositionOffset.value();
 
-        if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset))
+        if (alterEndPosition && endPosition > lastPositionOffset.value() && endPosition < positionOffset)
             endPosition = positionOffset;
     }
 }
@@ -284,8 +286,8 @@ bool SVGTextQuery::subStringLengthCallback(Data* queryData, const SVGTextFragmen
 {
     SubStringLengthData* data = static_cast<SubStringLengthData*>(queryData);
 
-    int startPosition = data->startPosition;
-    int endPosition = startPosition + data->length;
+    unsigned startPosition = data->startPosition;
+    unsigned endPosition = startPosition + data->length;
     if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition))
         return false;
 
@@ -319,8 +321,8 @@ bool SVGTextQuery::startPositionOfCharacterCallback(Data* queryData, const SVGTe
 {
     StartPositionOfCharacterData* data = static_cast<StartPositionOfCharacterData*>(queryData);
 
-    int startPosition = data->position;
-    int endPosition = startPosition + 1;
+    unsigned startPosition = data->position;
+    unsigned endPosition = startPosition + 1;
     if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition))
         return false;
 
@@ -368,8 +370,8 @@ bool SVGTextQuery::endPositionOfCharacterCallback(Data* queryData, const SVGText
 {
     EndPositionOfCharacterData* data = static_cast<EndPositionOfCharacterData*>(queryData);
 
-    int startPosition = data->position;
-    int endPosition = startPosition + 1;
+    unsigned startPosition = data->position;
+    unsigned endPosition = startPosition + 1;
     if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition))
         return false;
 
@@ -416,8 +418,8 @@ bool SVGTextQuery::rotationOfCharacterCallback(Data* queryData, const SVGTextFra
 {
     RotationOfCharacterData* data = static_cast<RotationOfCharacterData*>(queryData);
 
-    int startPosition = data->position;
-    int endPosition = startPosition + 1;
+    unsigned startPosition = data->position;
+    unsigned endPosition = startPosition + 1;
     if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition))
         return false;
 
@@ -454,7 +456,7 @@ struct ExtentOfCharacterData : SVGTextQuery::Data {
     FloatRect extent;
 };
 
-static inline void calculateGlyphBoundaries(SVGTextQuery::Data* queryData, const SVGTextFragment& fragment, int startPosition, FloatRect& extent)
+static inline void calculateGlyphBoundaries(SVGTextQuery::Data* queryData, const SVGTextFragment& fragment, unsigned startPosition, FloatRect& extent)
 {
     float scalingFactor = queryData->textRenderer->scalingFactor();
     ASSERT(scalingFactor);
@@ -484,8 +486,8 @@ bool SVGTextQuery::extentOfCharacterCallback(Data* queryData, const SVGTextFragm
 {
     ExtentOfCharacterData* data = static_cast<ExtentOfCharacterData*>(queryData);
 
-    int startPosition = data->position;
-    int endPosition = startPosition + 1;
+    unsigned startPosition = data->position;
+    unsigned endPosition = startPosition + 1;
     if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition))
         return false;
 
@@ -519,8 +521,8 @@ bool SVGTextQuery::characterNumberAtPositionCallback(Data* queryData, const SVGT
 
     FloatRect extent;
     for (unsigned i = 0; i < fragment.length; ++i) {
-        int startPosition = data->processedCharacters + i;
-        int endPosition = startPosition + 1;
+        unsigned startPosition = data->processedCharacters + i;
+        unsigned endPosition = startPosition + 1;
         if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition))
             continue;
 
index 721b2df..38730a3 100644 (file)
@@ -52,8 +52,8 @@ private:
     bool executeQuery(Data*, ProcessTextFragmentCallback) const;
 
     void collectTextBoxesInFlowBox(InlineFlowBox*);
-    bool mapStartEndPositionsIntoFragmentCoordinates(Data*, const SVGTextFragment&, int& startPosition, int& endPosition) const;
-    void modifyStartEndPositionsRespectingLigatures(Data*, int& startPosition, int& endPosition) const;
+    bool mapStartEndPositionsIntoFragmentCoordinates(Data*, const SVGTextFragment&, unsigned& startPosition, unsigned& endPosition) const;
+    void modifyStartEndPositionsRespectingLigatures(Data*, unsigned& startPosition, unsigned& endPosition) const;
 
 private:
     bool numberOfCharactersCallback(Data*, const SVGTextFragment&) const;