+2014-06-20 Myles C. Maxfield <mmaxfield@apple.com>
+
+ Use unsigneds instead of ints for indexes into a string in text layout code
+ https://bugs.webkit.org/show_bug.cgi?id=133592
+
+ Reviewed by Zalan Bujtas.
+
+ Migrate much of the text-handling code to use unsigneds for indexes into a string.
+
+ No new tests because there is no behavior change.
+
+ * WebCore.exp.in:
+ * platform/graphics/Font.cpp:
+ (WebCore::Font::drawText):
+ (WebCore::Font::drawEmphasisMarks):
+ (WebCore::Font::adjustSelectionRectForText):
+ (WebCore::computeUnderlineType):
+ * platform/graphics/Font.h:
+ * platform/graphics/FontFastPath.cpp:
+ (WebCore::Font::getGlyphsAndAdvancesForSimpleText):
+ (WebCore::Font::drawSimpleText):
+ (WebCore::Font::drawEmphasisMarksForSimpleText):
+ (WebCore::Font::drawGlyphBuffer):
+ (WebCore::Font::drawEmphasisMarks):
+ (WebCore::Font::adjustSelectionRectForSimpleText):
+ * platform/graphics/GlyphBuffer.h:
+ (WebCore::GlyphBuffer::size):
+ (WebCore::GlyphBuffer::glyphs):
+ (WebCore::GlyphBuffer::advances):
+ (WebCore::GlyphBuffer::fontDataAt):
+ (WebCore::GlyphBuffer::advanceAt):
+ (WebCore::GlyphBuffer::offsetAt):
+ (WebCore::GlyphBuffer::reverse):
+ (WebCore::GlyphBuffer::offsetInString):
+ (WebCore::GlyphBuffer::swap):
+ * platform/graphics/GraphicsContext.cpp:
+ (WebCore::TextRunIterator::atEnd):
+ * platform/graphics/Latin1TextIterator.h:
+ (WebCore::Latin1TextIterator::Latin1TextIterator):
+ (WebCore::Latin1TextIterator::currentCharacter):
+ * platform/graphics/SimpleFontData.h:
+ * platform/graphics/SurrogatePairAwareTextIterator.cpp:
+ (WebCore::SurrogatePairAwareTextIterator::SurrogatePairAwareTextIterator):
+ * platform/graphics/SurrogatePairAwareTextIterator.h:
+ (WebCore::SurrogatePairAwareTextIterator::currentCharacter):
+ * platform/graphics/TextRun.h:
+ (WebCore::TextRun::length):
+ (WebCore::TextRun::charactersLength):
+ * platform/graphics/WidthIterator.cpp:
+ (WebCore::WidthIterator::glyphDataForCharacter):
+ (WebCore::applyFontTransforms):
+ (WebCore::WidthIterator::advanceInternal):
+ (WebCore::WidthIterator::advance):
+ (WebCore::WidthIterator::advanceOneCharacter):
+ * platform/graphics/WidthIterator.h:
+ * platform/graphics/cairo/FontCairo.cpp:
+ (WebCore::Font::drawGlyphs):
+ * platform/graphics/cairo/FontCairoHarfbuzzNG.cpp:
+ (WebCore::Font::drawComplexText):
+ (WebCore::Font::drawEmphasisMarksForComplexText):
+ (WebCore::Font::adjustSelectionRectForComplexText):
+ * platform/graphics/harfbuzz/HarfBuzzShaper.cpp:
+ (WebCore::HarfBuzzShaper::setNormalizedBuffer):
+ * platform/graphics/mac/FontComplexTextMac.cpp:
+ (WebCore::Font::adjustSelectionRectForComplexText):
+ (WebCore::Font::getGlyphsAndAdvancesForComplexText):
+ (WebCore::Font::drawComplexText):
+ (WebCore::Font::drawEmphasisMarksForComplexText):
+ * platform/graphics/mac/FontMac.mm:
+ (WebCore::Font::drawGlyphs):
+ * platform/graphics/win/FontCGWin.cpp:
+ (WebCore::Font::drawGlyphs):
+ * platform/graphics/win/FontWin.cpp:
+ (WebCore::Font::adjustSelectionRectForComplexText):
+ (WebCore::Font::getGlyphsAndAdvancesForComplexText):
+ (WebCore::Font::drawComplexText):
+ (WebCore::Font::drawEmphasisMarksForComplexText):
+ * platform/graphics/wince/FontWinCE.cpp:
+ (WebCore::Font::drawGlyphs):
+ (WebCore::Font::drawComplexText):
+ (WebCore::Font::drawEmphasisMarksForComplexText):
+ (WebCore::Font::selectionRectForComplexText):
+ * rendering/InlineTextBox.cpp:
+ (WebCore::InlineTextBox::isSelected):
+ (WebCore::InlineTextBox::selectionState):
+ (WebCore::adjustCharactersAndLengthForHyphen):
+ (WebCore::InlineTextBox::localSelectionRect):
+ (WebCore::InlineTextBox::paint):
+ (WebCore::InlineTextBox::selectionStartEnd):
+ (WebCore::InlineTextBox::paintSelection):
+ (WebCore::InlineTextBox::paintCompositionBackground):
+ (WebCore::InlineTextBox::paintDocumentMarker):
+ (WebCore::InlineTextBox::paintTextMatchMarker):
+ (WebCore::InlineTextBox::computeRectForReplacementMarker):
+ (WebCore::InlineTextBox::paintCompositionUnderline):
+ (WebCore::InlineTextBox::positionForOffset):
+ (WebCore::InlineTextBox::constructTextRun):
+ * rendering/InlineTextBox.h:
+ * rendering/RenderCombineText.cpp:
+ (WebCore::RenderCombineText::getStringToRender):
+ * rendering/RenderCombineText.h:
+ * rendering/svg/SVGInlineFlowBox.cpp:
+ (WebCore::SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer):
+ * rendering/svg/SVGInlineTextBox.cpp:
+ (WebCore::SVGInlineTextBox::positionForOffset):
+ (WebCore::SVGInlineTextBox::localSelectionRect):
+ (WebCore::SVGInlineTextBox::paintSelectionBackground):
+ (WebCore::SVGInlineTextBox::mapStartEndPositionsIntoFragmentCoordinates):
+ (WebCore::SVGInlineTextBox::paintText):
+ * rendering/svg/SVGInlineTextBox.h:
+ * rendering/svg/SVGTextMetricsBuilder.cpp:
+ (WebCore::SVGTextMetricsBuilder::currentCharacterStartsSurrogatePair):
+ (WebCore::SVGTextMetricsBuilder::advance):
+ * rendering/svg/SVGTextQuery.cpp:
+ (WebCore::SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates):
+ (WebCore::SVGTextQuery::modifyStartEndPositionsRespectingLigatures):
+ (WebCore::SVGTextQuery::subStringLengthCallback):
+ (WebCore::SVGTextQuery::startPositionOfCharacterCallback):
+ (WebCore::SVGTextQuery::endPositionOfCharacterCallback):
+ (WebCore::SVGTextQuery::rotationOfCharacterCallback):
+ (WebCore::SVGTextQuery::extentOfCharacterCallback):
+ (WebCore::SVGTextQuery::characterNumberAtPositionCallback):
+ * rendering/svg/SVGTextQuery.h:
+ * rendering/svg/SVGTextRunRenderingContext.cpp:
+ (WebCore::SVGGlyphToPathTranslator::SVGGlyphToPathTranslator):
+ (WebCore::SVGTextRunRenderingContext::glyphDataForCharacter):
+ * rendering/svg/SVGTextRunRenderingContext.h:
+ * svg/SVGFontData.cpp:
+ (WebCore::SVGFontData::applySVGGlyphSelection):
+ * svg/SVGFontData.h:
+
2014-06-24 Eric Carlson <eric.carlson@apple.com>
Unreviewed build fix.
__ZNK7WebCore3URL8protocolEv
__ZNK7WebCore3URLcvP5NSURLEv
__ZNK7WebCore4Font5widthERKNS_7TextRunEPN3WTF7HashSetIPKNS_14SimpleFontDataENS4_7PtrHashIS8_EENS4_10HashTraitsIS8_EEEEPNS_13GlyphOverflowE
-__ZNK7WebCore4Font8drawTextEPNS_15GraphicsContextERKNS_7TextRunERKNS_10FloatPointEiiNS0_24CustomFontNotReadyActionE
+__ZNK7WebCore4Font8drawTextEPNS_15GraphicsContextERKNS_7TextRunERKNS_10FloatPointEjiNS0_24CustomFontNotReadyActionE
__ZNK7WebCore4FonteqERKS0_
__ZNK7WebCore4Node11textContentEb
__ZNK7WebCore4Node13ownerDocumentEv
m_typesettingFeatures = computeTypesettingFeatures();
}
-float Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to, CustomFontNotReadyAction customFontNotReadyAction) const
+float Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, unsigned from, int initialTo, 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
if (loadingCustomFonts() && customFontNotReadyAction == DoNotPaintIfFontNotReady)
return 0;
- to = (to == -1 ? run.length() : to);
+ unsigned to = initialTo < 0 ? run.length() : initialTo;
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
return drawComplexText(context, run, point, from, to);
}
-void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, unsigned from, int initialTo) const
{
if (loadingCustomFonts())
return;
-
- if (to < 0)
- to = run.length();
+
+ unsigned to = initialTo < 0 ? run.length() : initialTo;
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
return success;
}
-void Font::adjustSelectionRectForText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
+void Font::adjustSelectionRectForText(const TextRun& run, LayoutRect& selectionRect, unsigned from, int initialTo) const
{
- to = (to == -1 ? run.length() : to);
+ unsigned to = initialTo < 0 ? run.length() : initialTo;
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
return true;
}
-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).
UChar32 baseCharacter;
- int offsetInString = glyphBuffer.offsetInString(index);
+ int initialOffsetInString = glyphBuffer.offsetInString(index);
- if (offsetInString == GlyphBuffer::kNoOffset) {
+ if (initialOffsetInString == GlyphBuffer::kNoOffset) {
// We have no idea which character spawned this glyph. Bail.
return GlyphToPathTranslator::GlyphUnderlineType::DrawOverGlyph;
}
+ ASSERT(initialOffsetInString >= 0);
+ unsigned offsetInString = static_cast<unsigned>(initialOffsetInString);
+
if (textRun.is8Bit())
baseCharacter = textRun.characters8()[offsetInString];
- else {
+ else
U16_NEXT(textRun.characters16(), offsetInString, textRun.length(), baseCharacter);
- }
// u_getIntPropertyValue with UCHAR_IDEOGRAPHIC doesn't return true for Japanese or Korean codepoints.
// Instead, we can use the "Unicode allocation block" for the character.
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 Font {
public:
void update(PassRefPtr<FontSelector>) const;
enum CustomFontNotReadyAction { DoNotPaintIfFontNotReady, UseFallbackIfFontNotReady };
- float drawText(GraphicsContext*, const TextRun&, const FloatPoint&, int from = 0, int to = -1, CustomFontNotReadyAction = DoNotPaintIfFontNotReady) const;
- void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int numGlyphs, const FloatPoint&) const;
- void drawEmphasisMarks(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1) const;
+ float drawText(GraphicsContext*, const TextRun&, const FloatPoint&, unsigned from = 0, int to = -1, CustomFontNotReadyAction = DoNotPaintIfFontNotReady) const;
+ void drawGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, unsigned from, unsigned numGlyphs, const FloatPoint&) const;
+ void drawEmphasisMarks(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, unsigned from = 0, int to = -1) const;
DashArray dashesForIntersectionsWithRect(const TextRun&, const FloatPoint& textOrigin, const FloatRect& lineExtents) const;
static float width(TextLayout&, unsigned from, unsigned len, HashSet<const SimpleFontData*>* 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, int to = -1) const;
bool isSmallCaps() const { return m_fontDescription.smallCaps(); }
enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis };
// Returns the initial in-stream advance.
- float getGlyphsAndAdvancesForSimpleText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
- float drawSimpleText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) 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;
+ float drawSimpleText(GraphicsContext*, const TextRun&, const FloatPoint&, unsigned from, unsigned to) const;
+ void drawEmphasisMarksForSimpleText(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, unsigned from, unsigned to) const;
void drawGlyphBuffer(GraphicsContext*, const TextRun&, const GlyphBuffer&, FloatPoint&) const;
void drawEmphasisMarks(GraphicsContext*, const TextRun&, const GlyphBuffer&, const AtomicString&, const FloatPoint&) const;
float floatWidthForSimpleText(const TextRun&, HashSet<const SimpleFontData*>* 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;
bool getEmphasisMarkGlyphData(const AtomicString&, GlyphData&) const;
static bool canExpandAroundIdeographsInComplexText();
// Returns the initial in-stream advance.
- float getGlyphsAndAdvancesForComplexText(const TextRun&, int from, int to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const;
- float drawComplexText(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) 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;
+ float drawComplexText(GraphicsContext*, const TextRun&, const FloatPoint&, unsigned from, unsigned to) const;
+ void drawEmphasisMarksForComplexText(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, unsigned from, unsigned to) const;
float floatWidthForComplexText(const TextRun&, HashSet<const SimpleFontData*>* 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;
friend struct WidthIterator;
friend class SVGTextRunRenderingContext;
return markFontData->fontMetrics().height();
}
-float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
+float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, unsigned from, unsigned to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
{
float initialAdvance;
return initialAdvance;
}
-float Font::drawSimpleText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
+float Font::drawSimpleText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, unsigned from, unsigned to) const
{
// This glyph buffer holds our glyphs+advances+font data for each glyph.
GlyphBuffer glyphBuffer;
return startPoint.x() - startX;
}
-void Font::drawEmphasisMarksForSimpleText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+void Font::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);
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;
#if ENABLE(SVG_FONTS)
TextRun::RenderingContext* renderingContext = run.renderingContext();
#endif
renderingContext->drawSVGGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint);
else
#endif
+ {
+ ASSERT(nextGlyph >= lastFrom);
drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint);
+ }
lastFrom = nextGlyph;
fontData = nextFontData;
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);
return it.m_runWidthSoFar;
}
-void Font::adjustSelectionRectForSimpleText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
+void Font::adjustSelectionRectForSimpleText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
{
GlyphBuffer glyphBuffer;
WidthIterator it(this, run);
class GlyphBuffer {
public:
bool isEmpty() const { return m_fontData.isEmpty(); }
- int size() const { return m_fontData.size(); }
+ unsigned size() const { return m_fontData.size(); }
void clear()
{
#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 SimpleFontData* fontDataAt(int index) const { return m_fontData[index]; }
+ const SimpleFontData* fontDataAt(unsigned index) const { return m_fontData[index]; }
void setInitialAdvance(GlyphBufferAdvance initialAdvance) { m_initialAdvance = initialAdvance; }
const GlyphBufferAdvance& initialAdvance() const { return m_initialAdvance; }
#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];
}
#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)
swap(i, end);
m_offsetsInString.reset(new Vector<int, 2048>());
}
- int offsetInString(int index) const
+ int offsetInString(unsigned index) const
{
ASSERT(m_offsetsInString);
return (*m_offsetsInString)[index];
}
private:
- void swap(int index1, int index2)
+ void swap(unsigned index1, unsigned index2)
{
const SimpleFontData* f = m_fontData[index1];
m_fontData[index1] = m_fontData[index2];
private:
const TextRun* m_textRun;
- int m_offset;
+ unsigned m_offset;
};
class InterpolationQualityMaintainer {
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*/)
+ Latin1TextIterator(const LChar* characters, unsigned currentCharacter, unsigned lastCharacter, unsigned /*endCharacter*/)
: m_characters(characters)
, m_currentCharacter(currentCharacter)
, m_lastCharacter(lastCharacter)
m_currentCharacter += advanceLength;
}
- int currentCharacter() const { return m_currentCharacter; }
+ unsigned currentCharacter() const { return m_currentCharacter; }
const LChar* characters() const { return m_characters; }
private:
const LChar* m_characters;
- int m_currentCharacter;
- int m_lastCharacter;
+ unsigned m_currentCharacter;
+ unsigned m_lastCharacter;
};
}
virtual void initializeFontData(SimpleFontData*, float fontSize) = 0;
virtual float widthForSVGGlyph(Glyph, float fontSize) const = 0;
virtual bool fillSVGGlyphPage(GlyphPage*, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData*) const = 0;
- virtual bool applySVGGlyphSelection(WidthIterator&, GlyphData&, bool mirror, int currentCharacter, unsigned& advanceLength) const = 0;
+ virtual bool applySVGGlyphSelection(WidthIterator&, GlyphData&, bool mirror, unsigned currentCharacter, unsigned& advanceLength) const = 0;
};
// Used to create platform fonts.
namespace WebCore {
-SurrogatePairAwareTextIterator::SurrogatePairAwareTextIterator(const UChar* characters, int currentCharacter, int lastCharacter, int endCharacter)
+SurrogatePairAwareTextIterator::SurrogatePairAwareTextIterator(const UChar* characters, unsigned currentCharacter, unsigned lastCharacter, unsigned endCharacter)
: m_characters(characters)
, m_currentCharacter(currentCharacter)
, m_lastCharacter(lastCharacter)
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);
+ SurrogatePairAwareTextIterator(const UChar*, unsigned currentCharacter, unsigned lastCharacter, unsigned endCharacter);
inline bool consume(UChar32& character, unsigned& clusterLength)
{
m_currentCharacter += advanceLength;
}
- int currentCharacter() const { return m_currentCharacter; }
+ unsigned currentCharacter() const { return m_currentCharacter; }
const UChar* characters() const { return m_characters; }
private:
UChar32 normalizeVoicingMarks();
const UChar* m_characters;
- int m_currentCharacter;
- int m_lastCharacter;
- int m_endCharacter;
+ unsigned m_currentCharacter;
+ unsigned m_lastCharacter;
+ unsigned m_endCharacter;
};
}
const UChar* characters16() const { ASSERT(!is8Bit()); return m_data.characters16; }
bool is8Bit() const { return m_is8Bit; }
- int length() const { return m_len; }
- int charactersLength() const { return m_charactersLength; }
+ unsigned length() const { return m_len; }
+ unsigned charactersLength() const { return m_charactersLength; }
String string() const
{
if (is8Bit())
virtual ~RenderingContext() { }
#if ENABLE(SVG_FONTS)
- virtual GlyphData glyphDataForCharacter(const Font&, WidthIterator&, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength) = 0;
+ virtual GlyphData glyphDataForCharacter(const Font&, WidthIterator&, UChar32 character, bool mirror, unsigned currentCharacter, unsigned& advanceLength) = 0;
virtual void drawSVGGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const = 0;
virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int& charsConsumed, String& glyphName) const = 0;
virtual bool applySVGKerning(const SimpleFontData*, WidthIterator&, GlyphBuffer*, int from) const = 0;
}
}
-GlyphData WidthIterator::glyphDataForCharacter(UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength)
+GlyphData WidthIterator::glyphDataForCharacter(UChar32 character, bool mirror, unsigned currentCharacter, unsigned& advanceLength)
{
ASSERT(m_font);
typedef Vector<std::pair<int, OriginalAdvancesForCharacterTreatedAsSpace>, 64> CharactersTreatedAsSpace;
-static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int& lastGlyphCount, const SimpleFontData* fontData, WidthIterator& iterator, TypesettingFeatures typesettingFeatures, CharactersTreatedAsSpace& charactersTreatedAsSpace)
+static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, unsigned& lastGlyphCount, const SimpleFontData* fontData, WidthIterator& iterator, TypesettingFeatures typesettingFeatures, CharactersTreatedAsSpace& charactersTreatedAsSpace)
{
ASSERT(typesettingFeatures & (Kerning | Ligatures));
const SimpleFontData* primaryFont = m_font->primaryFont();
const SimpleFontData* lastFontData = primaryFont;
- int lastGlyphCount = glyphBuffer ? glyphBuffer->size() : 0;
+ unsigned lastGlyphCount = glyphBuffer ? glyphBuffer->size() : 0;
UChar32 character = 0;
unsigned clusterLength = 0;
CharactersTreatedAsSpace charactersTreatedAsSpace;
while (textIterator.consume(character, clusterLength)) {
unsigned advanceLength = clusterLength;
- int currentCharacter = textIterator.currentCharacter();
+ unsigned currentCharacter = textIterator.currentCharacter();
const GlyphData& glyphData = glyphDataForCharacter(character, rtl, currentCharacter, advanceLength);
Glyph glyph = glyphData.glyph;
const SimpleFontData* fontData = glyphData.fontData;
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()) {
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;
public:
WidthIterator(const Font*, const TextRun&, HashSet<const SimpleFontData*>* 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; }
#endif
private:
- GlyphData glyphDataForCharacter(UChar32, bool mirror, int currentCharacter, unsigned& advanceLength);
+ GlyphData glyphDataForCharacter(UChar32, bool mirror, unsigned currentCharacter, unsigned& advanceLength);
template <typename TextIterator>
inline unsigned advanceInternal(TextIterator&, GlyphBuffer*);
}
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
- int from, int numGlyphs, const FloatPoint& point) const
+ unsigned from, unsigned numGlyphs, const FloatPoint& point) const
{
if (!font->platformData().size())
return;
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();
namespace WebCore {
-float Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int, int) const
+float Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, unsigned, unsigned) const
{
GlyphBuffer glyphBuffer;
HarfBuzzShaper shaper(this, run);
return 0;
}
-void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, unsigned /* from */, unsigned /* to */) const
{
notImplemented();
}
return 0;
}
-void Font::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
+void Font::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
{
HarfBuzzShaper shaper(this, run);
if (shaper.shape()) {
} else
runCharacters = m_run.characters16();
- for (int i = 0; i < m_run.length(); ++i) {
+ for (unsigned i = 0; i < m_run.length(); ++i) {
UChar ch = runCharacters[i];
if (::ublock_getCode(ch) == UBLOCK_COMBINING_DIACRITICAL_MARKS) {
icu::Normalizer::normalize(icu::UnicodeString(runCharacters,
namespace WebCore {
-void Font::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
+void Font::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
{
ComplexTextController controller(this, run);
controller.advance(from);
selectionRect.setWidth(afterWidth - beforeWidth);
}
-float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
+float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, unsigned from, unsigned to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
{
float initialAdvance;
return initialAdvance;
}
-float Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
+float Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, unsigned from, unsigned to) const
{
// This glyph buffer holds our glyphs + advances + font data for each glyph.
GlyphBuffer glyphBuffer;
return startPoint.x() - startX;
}
-void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+void Font::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);
}
}
-void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& anchorPoint) const
+void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs, const FloatPoint& anchorPoint) const
{
const FontPlatformData& platformData = font->platformData();
if (!platformData.size())
virtual void advance() override;
void moveToNextValidGlyph();
- int m_index;
+ unsigned m_index;
const TextRun& m_textRun;
const GlyphBuffer& m_glyphBuffer;
const SimpleFontData* m_fontData;
}
void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
- int from, int numGlyphs, const FloatPoint& point) const
+ unsigned from, unsigned numGlyphs, const FloatPoint& point) const
{
CGContextRef cgContext = graphicsContext->platformContext();
bool shouldUseFontSmoothing = WebCoreShouldUseFontSmoothing();
return false;
}
-void Font::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
+void Font::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
{
UniscribeController it(this, run);
it.advance(from);
selectionRect.setWidth(afterWidth - beforeWidth);
}
-float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
+float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, unsigned from, unsigned to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
{
if (forTextEmphasis) {
// FIXME: Add forTextEmphasis paremeter to UniscribeController and use it.
return beforeWidth;
}
-float Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
+float Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, unsigned from, unsigned to) const
{
// This glyph buffer holds our glyphs + advances + font data for each glyph.
GlyphBuffer glyphBuffer;
return startPoint.x() - startX;
}
-void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
+void Font::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);
ScreenDcReleaser releaseScreenDc;
void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer,
- int from, int numGlyphs, const FloatPoint& point) const
+ unsigned from, unsigned numGlyphs, const FloatPoint& point) const
{
graphicsContext->drawText(fontData, glyphBuffer, from, numGlyphs, point);
}
return offset;
}
-float Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
+float Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, unsigned from, unsigned to) const
{
if (to < 0)
to = run.length();
return widthOfDrawnText;
}
-void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const
+void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, unsigned /* from */, unsigned /* to */) const
{
notImplemented();
}
}
FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& pt,
- int h, int from, int to) const
+ int h, unsigned from, unsigned to) const
{
TextRunComponents components;
int w = generateComponents(&components, *this, run);
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);
+ unsigned sPos = startPos > m_start ? startPos - m_start : 0;
+ if (endPos <= m_start)
+ return false;
+ unsigned ePos = std::min(endPos - m_start, static_cast<unsigned>(m_len));
+ return sPos < ePos;
}
RenderObject::SelectionState InlineTextBox::selectionState()
{
RenderObject::SelectionState state = renderer().selectionState();
if (state == RenderObject::SelectionStart || state == RenderObject::SelectionEnd || state == RenderObject::SelectionBoth) {
- int startPos, endPos;
- renderer().selectionStartEnd(startPos, endPos);
+ int initialStartPos, initialEndPos;
+ renderer().selectionStartEnd(initialStartPos, initialEndPos);
+ ASSERT(initialStartPos >= 0 && initialEndPos >= 0);
+ unsigned startPos = initialStartPos;
+ unsigned endPos = initialEndPos;
// The position after a hard line break is considered to be past its end.
- int lastSelectable = 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);
if (m_truncation != cNoTruncation && root().ellipsisBox()) {
EllipsisBox* ellipsis = root().ellipsisBox();
if (state != RenderObject::SelectionNone) {
- int start, end;
+ unsigned start, end;
selectionStartEnd(start, end);
// The ellipsis should be considered to be selected if the end of
// the selection is past the beginning of the truncation and the
return state;
}
-static void adjustCharactersAndLengthForHyphen(BufferForAppendingHyphen& charactersWithHyphen, const RenderStyle& style, String& string, int& length)
+static void adjustCharactersAndLengthForHyphen(BufferForAppendingHyphen& charactersWithHyphen, const RenderStyle& style, String& string, unsigned& length)
{
const AtomicString& hyphenString = style.hyphenString();
charactersWithHyphen.reserveCapacity(length + hyphenString.length());
return style.font();
}
-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);
+ unsigned sPos = startPos > m_start ? startPos - m_start : 0;
+
+ if (endPos < m_start)
+ return LayoutRect();
+
+ unsigned ePos = std::min(endPos - m_start, static_cast<unsigned>(m_len));
if (sPos > ePos)
return LayoutRect();
BufferForAppendingHyphen charactersWithHyphen;
bool respectHyphen = ePos == m_len && hasHyphen();
TextRun textRun = constructTextRun(lineStyle, font, respectHyphen ? &charactersWithHyphen : 0);
- if (respectHyphen)
- endPos = textRun.length();
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();
}
// 2. Now paint the foreground, including text and decorations like underline/overline (in quirks mode only).
- int length = m_len;
- int maximumLength;
+ unsigned length = m_len;
+ unsigned maximumLength;
String string;
if (!combinedText) {
string = renderer().text();
- if (static_cast<unsigned>(length) != string.length() || m_start) {
- ASSERT_WITH_SECURITY_IMPLICATION(static_cast<unsigned>(m_start + length) <= string.length());
+ if (length != string.length() || m_start) {
+ ASSERT_WITH_SECURITY_IMPLICATION(m_start + length <= string.length());
string = string.substringSharingImpl(m_start, length);
}
+ ASSERT(renderer().textLength() >= m_start);
maximumLength = renderer().textLength() - m_start;
} else {
combinedText->getStringToRender(m_start, string, length);
if (hasHyphen())
length = textRun.length();
- int sPos = 0;
- int ePos = 0;
+ unsigned sPos = 0;
+ unsigned ePos = 0;
if (haveSelection && (paintSelectedTextOnly || paintSelectedTextSeparately))
selectionStartEnd(sPos, ePos);
if (m_truncation != cNoTruncation) {
- sPos = std::min<int>(sPos, m_truncation);
- ePos = std::min<int>(ePos, m_truncation);
+ sPos = std::min(sPos, static_cast<unsigned>(m_truncation));
+ ePos = std::min(ePos, static_cast<unsigned>(m_truncation));
length = m_truncation;
}
context->concatCTM(rotation(boxRect, Counterclockwise));
}
-void InlineTextBox::selectionStartEnd(int& sPos, int& ePos)
+void InlineTextBox::selectionStartEnd(unsigned& sPos, unsigned& ePos)
{
- int startPos, endPos;
+ unsigned startPos, endPos;
if (renderer().selectionState() == RenderObject::SelectionInside) {
startPos = 0;
endPos = renderer().textLength();
} else {
- renderer().selectionStartEnd(startPos, endPos);
+ int originalStartPos, originalEndPos;
+ renderer().selectionStartEnd(originalStartPos, originalEndPos);
+ ASSERT(originalStartPos >= 0 && originalEndPos >= 0);
+ startPos = originalStartPos;
+ endPos = originalEndPos;
if (renderer().selectionState() == RenderObject::SelectionStart)
endPos = renderer().textLength();
else if (renderer().selectionState() == RenderObject::SelectionEnd)
startPos = 0;
}
-
- sPos = std::max(startPos - m_start, 0);
- ePos = std::min(endPos - m_start, (int)m_len);
+
+ sPos = startPos > m_start ? startPos - m_start : 0;
+ ePos = endPos > m_start ? endPos - m_start : 0;
+ ePos = std::min(ePos, static_cast<unsigned>(m_len));
}
void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& boxOrigin, const RenderStyle& style, const Font& font, Color textColor)
return;
// See if we have a selection to paint at all.
- int sPos, ePos;
+ unsigned sPos, ePos;
selectionStartEnd(sPos, ePos);
if (sPos >= ePos)
return;
// If the text is truncated, let the thing being painted in the truncation
// draw its own highlight.
- int length = m_truncation != cNoTruncation ? m_truncation : m_len;
+ unsigned length = m_truncation != cNoTruncation ? m_truncation : m_len;
String string = renderer().text();
if (string.length() != static_cast<unsigned>(length) || m_start) {
BufferForAppendingHyphen charactersWithHyphen;
bool respectHyphen = ePos == length && hasHyphen();
+ ASSERT(renderer().textLength() >= m_start);
TextRun textRun = constructTextRun(style, font, string, renderer().textLength() - m_start, respectHyphen ? &charactersWithHyphen : 0);
if (respectHyphen)
ePos = textRun.length();
#endif
}
-void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const FloatPoint& boxOrigin, const RenderStyle& style, const Font& font, int startPos, int endPos)
+void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const FloatPoint& boxOrigin, const RenderStyle& style, const Font& font, unsigned startPos, unsigned endPos)
{
- int offset = m_start;
- int sPos = std::max(startPos - offset, 0);
- int ePos = std::min(endPos - offset, (int)m_len);
+ unsigned offset = m_start;
+ unsigned sPos = startPos > offset ? startPos - offset : 0;
+ ASSERT(endPos >= offset);
+ unsigned ePos = std::min(endPos - offset, static_cast<unsigned>(m_len));
if (sPos >= ePos)
return;
// 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;
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 = marker->startOffset() > m_start ? marker->startOffset() - m_start : 0;
+ ASSERT(marker->endOffset() >= m_start);
+ unsigned endPosition = std::min(marker->endOffset() - m_start, static_cast<unsigned>(m_len));
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();
{
LayoutUnit selectionHeight = this->selectionHeight();
- int sPos = std::max(marker->startOffset() - m_start, (unsigned)0);
- int ePos = std::min(marker->endOffset() - m_start, (unsigned)m_len);
+ unsigned sPos = marker->startOffset() > m_start ? marker->startOffset() - m_start : 0;
+ ASSERT(marker->endOffset() >= m_start);
+ unsigned ePos = std::min(marker->endOffset() - m_start, static_cast<unsigned>(m_len));
TextRun run = constructTextRun(style, font);
// Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
LayoutUnit top = selectionTop();
LayoutUnit h = selectionHeight();
- int sPos = std::max(marker->startOffset() - m_start, (unsigned)0);
- int ePos = std::min(marker->endOffset() - m_start, (unsigned)m_len);
+ unsigned sPos = marker->startOffset() > m_start ? marker->startOffset() - m_start : 0;
+ ASSERT(marker->endOffset() >= m_start);
+ unsigned ePos = std::min(marker->endOffset() - m_start, (unsigned)m_len);
TextRun run = constructTextRun(style, font);
// Compute and store the rect associated with this marker.
start = renderer().width(m_start, paintStart - m_start, textPos(), isFirstLine());
}
if (paintEnd != underline.endOffset) { // end points at the last char, not past it
- paintEnd = std::min(paintEnd, (unsigned)underline.endOffset);
+ paintEnd = std::min(paintEnd, underline.endOffset);
useWholeWidth = false;
}
if (m_truncation != cNoTruncation) {
- paintEnd = std::min(paintEnd, (unsigned)m_start + m_truncation);
+ paintEnd = std::min(paintEnd, m_start + m_truncation);
useWholeWidth = false;
}
if (!useWholeWidth) {
return font.offsetForPosition(constructTextRun(lineStyle, font), 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);
const RenderStyle& lineStyle = this->lineStyle();
const Font& font = fontToUse(lineStyle, renderer());
- int from = !isLeftToRightDirection() ? offset - m_start : 0;
- int to = !isLeftToRightDirection() ? m_len : offset - m_start;
+ unsigned from = !isLeftToRightDirection() ? offset - m_start : 0;
+ unsigned to = !isLeftToRightDirection() ? m_len : offset - m_start;
// FIXME: Do we need to add rightBearing here?
LayoutRect selectionRect = LayoutRect(logicalLeft(), 0, 0, 0);
TextRun run = constructTextRun(lineStyle, font);
if (string.length() != length || startPos)
string = string.substringSharingImpl(startPos, length);
-
+
+ ASSERT(renderer().textLength() >= startPos);
return constructTextRun(style, font, string, renderer().textLength() - startPos, charactersWithHyphen);
}
-TextRun InlineTextBox::constructTextRun(const RenderStyle& style, const Font& font, String string, int maximumLength, BufferForAppendingHyphen* charactersWithHyphen) const
+TextRun InlineTextBox::constructTextRun(const RenderStyle& style, const Font& font, String string, unsigned maximumLength, BufferForAppendingHyphen* charactersWithHyphen) const
{
- int length = string.length();
+ unsigned length = string.length();
if (charactersWithHyphen) {
adjustCharactersAndLengthForHyphen(*charactersWithHyphen, style, string, length);
LayoutUnit selectionBottom() const;
LayoutUnit selectionHeight() const;
- TextRun constructTextRun(const RenderStyle&, const Font&, BufferForAppendingHyphen* = 0) const;
- TextRun constructTextRun(const RenderStyle&, const Font&, String, int maximumLength, BufferForAppendingHyphen* = 0) const;
+ TextRun constructTextRun(const RenderStyle&, const Font&, BufferForAppendingHyphen* = nullptr) const;
+ TextRun constructTextRun(const RenderStyle&, const Font&, String, unsigned maximumLength, BufferForAppendingHyphen* = nullptr) const;
public:
virtual FloatRect calculateBoundaries() const { return FloatRect(x(), y(), width(), height()); }
- virtual LayoutRect localSelectionRect(int startPos, int endPos) const;
- bool isSelected(int startPos, int endPos) const;
- void selectionStartEnd(int& sPos, int& ePos);
+ virtual LayoutRect localSelectionRect(unsigned startPos, unsigned endPos) const;
+ bool isSelected(unsigned startPos, unsigned endPos) const;
+ void selectionStartEnd(unsigned& sPos, unsigned& ePos);
protected:
virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
public:
virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
- virtual float positionForOffset(int offset) const;
+ virtual float positionForOffset(unsigned offset) const;
// Needs to be public, so the static paintTextWithShadows() function can use it.
static FloatSize applyShadowToGraphicsContext(GraphicsContext*, const ShadowData*, const FloatRect& textRect, bool stroked, bool opaque, bool horizontal);
protected:
- void paintCompositionBackground(GraphicsContext*, const FloatPoint& boxOrigin, const RenderStyle&, const Font&, int startPos, int endPos);
+ void paintCompositionBackground(GraphicsContext*, const FloatPoint& boxOrigin, const RenderStyle&, const Font&, unsigned startPos, unsigned endPos);
void paintDocumentMarkers(GraphicsContext*, const FloatPoint& boxOrigin, const RenderStyle&, const Font&, bool background);
void paintCompositionUnderline(GraphicsContext*, const FloatPoint& boxOrigin, const CompositionUnderline&);
InlineTextBox* m_prevTextBox; // The previous box that also uses our RenderObject
InlineTextBox* m_nextTextBox; // The next box that also uses our RenderObject
- int m_start;
+ unsigned m_start;
unsigned short m_len;
// Where to truncate when text overflow is applied. We use special constants to
textOrigin.move(boxRect.height() / 2 - ceilf(m_combinedTextWidth) / 2, style().font().pixelSize());
}
-void RenderCombineText::getStringToRender(int start, String& string, int& length) const
+void RenderCombineText::getStringToRender(unsigned start, String& string, unsigned& length) const
{
- ASSERT(start >= 0);
if (m_isCombined) {
string = originalText();
length = string.length();
}
string = text();
- string = string.substringSharingImpl(static_cast<unsigned>(start), length);
+ string = string.substringSharingImpl(start, length);
}
void RenderCombineText::combineText()
void combineText();
void adjustTextOrigin(FloatPoint& textOrigin, const FloatRect& boxRect) const;
- void getStringToRender(int, String& string, int& length) const;
+ void getStringToRender(unsigned, String&, unsigned& length) const;
bool isCombined() const { return m_isCombined; }
float combinedTextWidth(const Font& font) const { return font.size(); }
const Font& originalFont() const { return parent()->style().font(); }
if (markerStartPosition >= markerEndPosition)
continue;
- int fragmentStartPosition = 0;
- int fragmentEndPosition = 0;
+ unsigned fragmentStartPosition = 0;
+ unsigned fragmentEndPosition = 0;
const Vector<SVGTextFragment>& fragments = textBox->textFragments();
unsigned textFragmentsSize = fragments.size();
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 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()));
+ unsigned boxStart = start();
+ startPosition = startPosition > boxStart ? startPosition - boxStart : 0;
+
+ if (endPosition < boxStart)
+ return LayoutRect();
+
+ endPosition = std::min(endPosition - boxStart, len());
if (startPosition >= endPosition)
return LayoutRect();
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) {
selectionStyle = &style;
}
- int startPosition, endPosition;
+ unsigned startPosition, endPosition;
selectionStartEnd(startPosition, endPosition);
- 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) {
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;
ASSERT(style);
ASSERT(selectionStyle);
- int startPosition = 0;
- int endPosition = 0;
+ unsigned startPosition = 0;
+ unsigned endPosition = 0;
if (hasSelection) {
selectionStartEnd(startPosition, endPosition);
hasSelection = mapStartEndPositionsIntoFragmentCoordinates(fragment, startPosition, endPosition);
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);
}
virtual int selectionTop() { return top(); }
virtual int selectionHeight() { return static_cast<int>(ceilf(m_logicalHeight)); }
virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
- virtual float positionForOffset(int offset) const;
+ virtual float positionForOffset(unsigned offset) const;
void paintSelectionBackground(PaintInfo&);
virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
- virtual LayoutRect localSelectionRect(int startPosition, int endPosition) const override;
+ virtual 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;
virtual FloatRect calculateBoundaries() const;
inline bool SVGTextMetricsBuilder::currentCharacterStartsSurrogatePair() const
{
- return U16_IS_LEAD(m_run[m_textPosition]) && int(m_textPosition + 1) < m_run.charactersLength() && U16_IS_TRAIL(m_run[m_textPosition + 1]);
+ return U16_IS_LEAD(m_run[m_textPosition]) && m_textPosition + 1 < m_run.charactersLength() && U16_IS_TRAIL(m_run[m_textPosition + 1]);
}
bool SVGTextMetricsBuilder::advance()
{
m_textPosition += m_currentMetrics.length();
- if (int(m_textPosition) >= m_run.charactersLength())
+ if (m_textPosition >= m_run.charactersLength())
return false;
if (m_isComplexText)
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);
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();
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)) {
+ if (alterStartPosition && startPosition > static_cast<unsigned>(lastPositionOffset) && startPosition < positionOffset) {
startPosition = lastPositionOffset;
alterStartPosition = false;
}
- if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset)) {
+ if (alterEndPosition && endPosition > static_cast<unsigned>(lastPositionOffset) && endPosition < positionOffset) {
endPosition = positionOffset;
alterEndPosition = false;
}
return;
if (lastPositionOffset != -1 && lastPositionOffset - positionOffset > 1) {
- if (alterStartPosition && startPosition > lastPositionOffset && startPosition < static_cast<int>(positionOffset)) {
+ if (alterStartPosition && startPosition > static_cast<unsigned>(lastPositionOffset) && startPosition < positionOffset) {
startPosition = lastPositionOffset;
alterStartPosition = false;
}
- if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset)) {
+ if (alterEndPosition && endPosition > static_cast<unsigned>(lastPositionOffset) && endPosition < positionOffset) {
endPosition = positionOffset;
alterEndPosition = false;
}
{
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;
{
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;
{
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;
{
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;
{
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;
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;
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;
class SVGGlyphToPathTranslator final : public GlyphToPathTranslator {
public:
- SVGGlyphToPathTranslator(const TextRun* const, const GlyphBuffer&, const FloatPoint&, const SVGFontData&, SVGFontElement&, const int from, const int numGlyphs, float scale, bool isVerticalText);
+ SVGGlyphToPathTranslator(const TextRun* const, const GlyphBuffer&, const FloatPoint&, const SVGFontData&, SVGFontElement&, unsigned from, unsigned numGlyphs, float scale, bool isVerticalText);
private:
virtual bool containsMorePaths() override
{
FloatPoint m_currentPoint;
FloatPoint m_glyphOrigin;
SVGGlyph m_svgGlyph;
- int m_index;
+ unsigned m_index;
Glyph m_glyph;
SVGFontElement& m_fontElement;
- const float m_stoppingPoint;
+ const unsigned m_stoppingPoint;
const float m_scale;
const bool m_isVerticalText;
};
-SVGGlyphToPathTranslator::SVGGlyphToPathTranslator(const TextRun* const textRun, const GlyphBuffer& glyphBuffer, const FloatPoint& point, const SVGFontData& svgFontData, SVGFontElement& fontElement, const int from, const int numGlyphs, float scale, bool isVerticalText)
+SVGGlyphToPathTranslator::SVGGlyphToPathTranslator(const TextRun* const textRun, const GlyphBuffer& glyphBuffer, const FloatPoint& point, const SVGFontData& svgFontData, SVGFontElement& fontElement, unsigned from, unsigned numGlyphs, float scale, bool isVerticalText)
: m_textRun(textRun)
, m_glyphBuffer(glyphBuffer)
, m_svgFontData(svgFontData)
}
}
-GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, WidthIterator& iterator, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength)
+GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, WidthIterator& iterator, UChar32 character, bool mirror, unsigned currentCharacter, unsigned& advanceLength)
{
const SimpleFontData* primaryFont = font.primaryFont();
ASSERT(primaryFont);
RenderSVGResource* activePaintingResource() const { return m_activePaintingResource; }
void setActivePaintingResource(RenderSVGResource* object) { m_activePaintingResource = object; }
- virtual GlyphData glyphDataForCharacter(const Font&, WidthIterator&, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength) override;
+ virtual GlyphData glyphDataForCharacter(const Font&, WidthIterator&, UChar32 character, bool mirror, unsigned currentCharacter, unsigned& advanceLength) override;
virtual void drawSVGGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const override;
virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int& charsConsumed, String& glyphName) const override;
virtual bool applySVGKerning(const SimpleFontData*, WidthIterator&, GlyphBuffer*, int from) const override;
return svgGlyph.horizontalAdvanceX * scaleEmToUnits(fontSize, svgFontFaceElement->unitsPerEm());
}
-bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& glyphData, bool mirror, int currentCharacter, unsigned& advanceLength) const
+bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& glyphData, bool mirror, unsigned currentCharacter, unsigned& advanceLength) const
{
const TextRun& run = iterator.run();
Vector<SVGGlyph::ArabicForm>& arabicForms = iterator.arabicForms();
- ASSERT(int(run.charactersLength()) >= currentCharacter);
+ ASSERT(run.charactersLength() >= currentCharacter);
// Associate text with arabic forms, if needed.
String remainingTextInRun;
virtual void initializeFontData(SimpleFontData*, float fontSize) override;
virtual float widthForSVGGlyph(Glyph, float fontSize) const override;
virtual bool fillSVGGlyphPage(GlyphPage*, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData*) const override;
- virtual bool applySVGGlyphSelection(WidthIterator&, GlyphData&, bool mirror, int currentCharacter, unsigned& advanceLength) const override;
+ virtual bool applySVGGlyphSelection(WidthIterator&, GlyphData&, bool mirror, unsigned currentCharacter, unsigned& advanceLength) const override;
SVGFontFaceElement* svgFontFaceElement() const { return m_svgFontFaceElement; }