diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp')
-rw-r--r-- | Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp | 150 |
1 files changed, 75 insertions, 75 deletions
diff --git a/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp b/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp index d4985c7a2..9e6f44867 100644 --- a/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp +++ b/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp @@ -31,17 +31,15 @@ #include "config.h" #include "HarfBuzzShaper.h" -#include "Font.h" +#include "FontCascade.h" #include "HarfBuzzFace.h" #include "SurrogatePairAwareTextIterator.h" -#include "TextRun.h" -#include "hb-icu.h" +#include <hb-icu.h> #include <unicode/normlzr.h> #include <unicode/uchar.h> #include <wtf/MathExtras.h> #include <wtf/StdLibExtras.h> -#include <wtf/Vector.h> -#include <wtf/unicode/Unicode.h> +#include <wtf/text/StringView.h> namespace WebCore { @@ -73,7 +71,7 @@ static inline float harfBuzzPositionToFloat(hb_position_t value) return static_cast<float>(value) / (1 << 16); } -HarfBuzzShaper::HarfBuzzRun::HarfBuzzRun(const SimpleFontData* fontData, unsigned startIndex, unsigned numCharacters, TextDirection direction, hb_script_t script) +HarfBuzzShaper::HarfBuzzRun::HarfBuzzRun(const Font* fontData, unsigned startIndex, unsigned numCharacters, TextDirection direction, hb_script_t script) : m_fontData(fontData) , m_startIndex(startIndex) , m_numCharacters(numCharacters) @@ -85,6 +83,11 @@ HarfBuzzShaper::HarfBuzzRun::HarfBuzzRun(const SimpleFontData* fontData, unsigne void HarfBuzzShaper::HarfBuzzRun::applyShapeResult(hb_buffer_t* harfBuzzBuffer) { m_numGlyphs = hb_buffer_get_length(harfBuzzBuffer); + if (!m_numGlyphs) { + // HarfBuzzShaper::fillGlyphBuffer gets offsets()[0] + m_offsets.resize(1); + return; + } m_glyphs.resize(m_numGlyphs); m_advances.resize(m_numGlyphs); m_glyphToCharacterIndexes.resize(m_numGlyphs); @@ -98,7 +101,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; @@ -157,9 +160,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; @@ -171,12 +174,12 @@ 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 (Font::treatAsSpace(character) && character != '\t') + if (FontCascade::treatAsSpace(character) && character != '\t') character = ' '; - else if (Font::treatAsZeroWidthSpaceInComplexScript(character)) + else if (FontCascade::treatAsZeroWidthSpaceInComplexScript(character)) character = zeroWidthSpace; U16_APPEND(destination, position, length, character, error); ASSERT_UNUSED(error, !error); @@ -184,7 +187,7 @@ static void normalizeCharacters(const TextRun& run, UChar* destination, int leng } } -HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run) +HarfBuzzShaper::HarfBuzzShaper(const FontCascade* font, const TextRun& run) : m_font(font) , m_normalizedBufferLength(0) , m_run(run) @@ -193,8 +196,6 @@ HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run) , m_padPerWordBreak(0) , m_padError(0) , m_letterSpacing(font->letterSpacing()) - , m_fromIndex(0) - , m_toIndex(m_run.length()) { m_normalizedBuffer = std::make_unique<UChar[]>(m_run.length() + 1); m_normalizedBufferLength = m_run.length(); @@ -207,19 +208,19 @@ 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 (Font::treatAsSpace(character) && character != '\t') + if (FontCascade::treatAsSpace(character) && character != '\t') character = ' '; - else if (Font::treatAsZeroWidthSpace(character)) + else if (FontCascade::treatAsZeroWidthSpace(character)) character = zeroWidthSpace; else if (normalizeMode == HarfBuzzShaper::NormalizeMirrorChars) character = u_charMirror(character); @@ -257,7 +258,7 @@ void HarfBuzzShaper::setNormalizedBuffer(NormalizeMode normalizeMode) } 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, @@ -329,18 +330,9 @@ void HarfBuzzShaper::setPadding(int padding) m_padPerWordBreak = 0; } - -void HarfBuzzShaper::setDrawRange(int from, int to) -{ - ASSERT_WITH_SECURITY_IMPLICATION(from >= 0); - ASSERT_WITH_SECURITY_IMPLICATION(to <= m_run.length()); - m_fromIndex = from; - m_toIndex = to; -} - void HarfBuzzShaper::setFontFeatures() { - const FontDescription& description = m_font->fontDescription(); + const auto& description = m_font->fontDescription(); if (description.orientation() == Vertical) { static hb_feature_t vert = { HarfBuzzFace::vertTag, 1, 0, static_cast<unsigned>(-1) }; static hb_feature_t vrt2 = { HarfBuzzFace::vrt2Tag, 1, 0, static_cast<unsigned>(-1) }; @@ -350,30 +342,28 @@ void HarfBuzzShaper::setFontFeatures() hb_feature_t kerning = { HarfBuzzFace::kernTag, 0, 0, static_cast<unsigned>(-1) }; switch (description.kerning()) { - case FontDescription::NormalKerning: + case Kerning::Normal: kerning.value = 1; m_features.append(kerning); break; - case FontDescription::NoneKerning: + case Kerning::NoShift: kerning.value = 0; m_features.append(kerning); break; - case FontDescription::AutoKerning: + case Kerning::Auto: break; default: ASSERT_NOT_REACHED(); } - FontFeatureSettings* settings = description.featureSettings(); - if (!settings) - return; + const FontFeatureSettings& settings = description.featureSettings(); - unsigned numFeatures = settings->size(); + unsigned numFeatures = settings.size(); for (unsigned i = 0; i < numFeatures; ++i) { hb_feature_t feature; - const UChar* tag = settings->at(i).tag().characters(); + auto& tag = settings[i].tag(); feature.tag = HB_TAG(tag[0], tag[1], tag[2], tag[3]); - feature.value = settings->at(i).value(); + feature.value = settings[i].value(); feature.start = 0; feature.end = static_cast<unsigned>(-1); m_features.append(feature); @@ -413,7 +403,7 @@ bool HarfBuzzShaper::collectHarfBuzzRuns() if (!iterator.consume(character, clusterLength)) return false; - const SimpleFontData* nextFontData = m_font->glyphDataForCharacter(character, false).fontData; + const Font* nextFontData = m_font->glyphDataForCharacter(character, false).font; UErrorCode errorCode = U_ZERO_ERROR; UScriptCode nextScript = uscript_getScript(character, &errorCode); if (U_FAILURE(errorCode)) @@ -421,19 +411,21 @@ bool HarfBuzzShaper::collectHarfBuzzRuns() do { const UChar* currentCharacterPosition = iterator.characters(); - const SimpleFontData* currentFontData = nextFontData; + const Font* currentFontData = nextFontData; + if (!currentFontData) + currentFontData = &m_font->primaryFont(); UScriptCode currentScript = nextScript; for (iterator.advance(clusterLength); iterator.consume(character, clusterLength); iterator.advance(clusterLength)) { - if (Font::treatAsZeroWidthSpace(character)) + if (FontCascade::treatAsZeroWidthSpace(character)) 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; @@ -445,9 +437,9 @@ bool HarfBuzzShaper::collectHarfBuzzRuns() clusterLength = markLength; continue; } - nextFontData = m_font->glyphDataForCharacter(character, false).fontData; + nextFontData = m_font->glyphDataForCharacter(character, false).font; } else - nextFontData = m_font->glyphDataForCharacter(character, false).fontData; + nextFontData = m_font->glyphDataForCharacter(character, false).font; nextScript = uscript_getScript(character, &errorCode); if (U_FAILURE(errorCode)) @@ -458,11 +450,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(HarfBuzzRun::create(currentFontData, startIndexOfCurrentRun, numCharactersOfCurrentRun, m_run.direction(), script)); + 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(); @@ -477,9 +469,7 @@ bool HarfBuzzShaper::shapeHarfBuzzRuns(bool shouldSetDirection) for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) { unsigned runIndex = m_run.rtl() ? m_harfBuzzRuns.size() - i - 1 : i; HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get(); - const SimpleFontData* currentFontData = currentRun->fontData(); - if (currentFontData->isSVGFont()) - return false; + const Font* currentFontData = currentRun->fontData(); hb_buffer_set_script(harfBuzzBuffer.get(), currentRun->script()); if (shouldSetDirection) @@ -494,9 +484,10 @@ bool HarfBuzzShaper::shapeHarfBuzzRuns(bool shouldSetDirection) hb_buffer_add_utf16(harfBuzzBuffer.get(), &preContext, 1, 1, 0); if (m_font->isSmallCaps() && u_islower(m_normalizedBuffer[currentRun->startIndex()])) { - String upperText = String(m_normalizedBuffer.get() + currentRun->startIndex(), currentRun->numCharacters()).upper(); - currentFontData = m_font->glyphDataForCharacter(upperText[0], false, SmallCapsVariant).fontData; - hb_buffer_add_utf16(harfBuzzBuffer.get(), reinterpret_cast<const uint16_t*>(upperText.characters()), currentRun->numCharacters(), 0, currentRun->numCharacters()); + String upperText = String(m_normalizedBuffer.get() + currentRun->startIndex(), currentRun->numCharacters()).convertToUppercaseWithoutLocale(); + currentFontData = m_font->glyphDataForCharacter(upperText[0], false, SmallCapsVariant).font; + const UChar* characters = StringView(upperText).upconvertedCharacters(); + hb_buffer_add_utf16(harfBuzzBuffer.get(), reinterpret_cast<const uint16_t*>(characters), currentRun->numCharacters(), 0, currentRun->numCharacters()); } else hb_buffer_add_utf16(harfBuzzBuffer.get(), reinterpret_cast<const uint16_t*>(m_normalizedBuffer.get() + currentRun->startIndex()), currentRun->numCharacters(), 0, currentRun->numCharacters()); @@ -523,7 +514,7 @@ bool HarfBuzzShaper::shapeHarfBuzzRuns(bool shouldSetDirection) void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb_buffer_t* harfBuzzBuffer) { - const SimpleFontData* currentFontData = currentRun->fontData(); + const Font* currentFontData = currentRun->fontData(); hb_glyph_info_t* glyphInfos = hb_buffer_get_glyph_infos(harfBuzzBuffer, 0); hb_glyph_position_t* glyphPositions = hb_buffer_get_glyph_positions(harfBuzzBuffer, 0); @@ -545,7 +536,7 @@ void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb glyphToCharacterIndexes[i] = glyphInfos[i].cluster; - if (isClusterEnd && !Font::treatAsZeroWidthSpace(m_normalizedBuffer[currentCharacterIndex])) + if (isClusterEnd && !FontCascade::treatAsZeroWidthSpace(m_normalizedBuffer[currentCharacterIndex])) spacing += m_letterSpacing; if (isClusterEnd && isWordEnd(currentCharacterIndex)) @@ -587,15 +578,13 @@ void HarfBuzzShaper::fillGlyphBufferFromHarfBuzzRun(GlyphBuffer* glyphBuffer, Ha float glyphAdvanceX = advances[i] + nextOffset.x() - currentOffset.x(); float glyphAdvanceY = nextOffset.y() - currentOffset.y(); if (m_run.rtl()) { - if (currentCharacterIndex > m_toIndex) + if (currentCharacterIndex > m_run.length()) m_startOffset.move(glyphAdvanceX, glyphAdvanceY); - else if (currentCharacterIndex >= m_fromIndex) - glyphBuffer->add(glyphs[i], currentRun->fontData(), createGlyphBufferAdvance(glyphAdvanceX, glyphAdvanceY)); + else + glyphBuffer->add(glyphs[i], currentRun->fontData(), createGlyphBufferAdvance(glyphAdvanceX, glyphAdvanceY), currentCharacterIndex); } else { - if (currentCharacterIndex < m_fromIndex) - m_startOffset.move(glyphAdvanceX, glyphAdvanceY); - else if (currentCharacterIndex < m_toIndex) - glyphBuffer->add(glyphs[i], currentRun->fontData(), createGlyphBufferAdvance(glyphAdvanceX, glyphAdvanceY)); + if (currentCharacterIndex < m_run.length()) + glyphBuffer->add(glyphs[i], currentRun->fontData(), createGlyphBufferAdvance(glyphAdvanceX, glyphAdvanceY), currentCharacterIndex); } } } @@ -655,7 +644,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; @@ -663,23 +652,34 @@ FloatRect HarfBuzzShaper::selectionRect(const FloatPoint& point, int height, int bool foundFromX = false; bool foundToX = false; + std::optional<unsigned> fromIndex = from; + std::optional<unsigned> toIndex = to; + if (m_run.rtl()) currentX = m_totalWidth; 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) { - fromX = m_harfBuzzRuns[i]->xPositionForOffset(from) + currentX; + unsigned numCharacters = m_harfBuzzRuns[i]->numCharacters(); + if (!foundFromX && fromIndex.value() < numCharacters) { + fromX = m_harfBuzzRuns[i]->xPositionForOffset(fromIndex.value()) + currentX; foundFromX = true; - } else - from -= numCharacters; + } else { + if (fromIndex && fromIndex.value() >= numCharacters) + fromIndex.value() -= numCharacters; + else + fromIndex = std::nullopt; + } - if (!foundToX && to >= 0 && to < numCharacters) { - toX = m_harfBuzzRuns[i]->xPositionForOffset(to) + currentX; + if (!foundToX && toIndex.value() < numCharacters) { + toX = m_harfBuzzRuns[i]->xPositionForOffset(toIndex.value()) + currentX; foundToX = true; - } else - to -= numCharacters; + } else { + if (toIndex && toIndex.value() >= numCharacters) + toIndex.value() -= numCharacters; + else + toIndex = std::nullopt; + } if (foundFromX && foundToX) break; |