int ComplexTextController::offsetForPosition(int targetX) { unsigned basePosition = 0; int x = offsetX(); while (nextScriptRun()) { int nextX = offsetX(); if (std::min(x, nextX) <= targetX && targetX <= std::max(x, nextX)) { // The x value in question is within this script run. const int glyphIndex = glyphIndexForXPositionInScriptRun(targetX); // Now that we have a glyph index, we have to turn that into a // code-point index. Because of ligatures, several code-points may // have gone into a single glyph. We iterate over the clusters log // and find the first code-point which contributed to the glyph. // Some shapers (i.e. Khmer) will produce cluster logs which report // that /no/ code points contributed to certain glyphs. Because of // this, we take any code point which contributed to the glyph in // question, or any subsequent glyph. If we run off the end, then // we take the last code point. for (unsigned j = 0; j < numCodePoints(); ++j) { if (m_item.log_clusters[j] >= glyphIndex) return basePosition + j; } return basePosition + numCodePoints() - 1; } basePosition += numCodePoints(); } return basePosition; }
float ComplexTextController::widthOfFullRun() { float widthSum = 0; while (nextScriptRun()) widthSum += width(); return widthSum; }
float widthOfFullRun() { float widthSum = 0; while (nextScriptRun()) widthSum += width(); return widthSum; }
FloatRect ComplexTextController::selectionRect(const FloatPoint& point, int height, int from, int to) { int fromX = -1, toX = -1; // Iterate through the script runs in logical order, searching for the run covering the positions of interest. while (nextScriptRun() && (fromX == -1 || toX == -1)) { if (fromX == -1 && from >= 0 && static_cast<unsigned>(from) < numCodePoints()) { // |from| is within this script run. So we index the clusters log to // find which glyph this code-point contributed to and find its x // position. int glyph = m_item.log_clusters[from]; fromX = positions()[glyph].x(); if (rtl()) fromX += truncateFixedPointToInteger(m_item.advances[glyph]); } else from -= numCodePoints(); if (toX == -1 && to >= 0 && static_cast<unsigned>(to) < numCodePoints()) { int glyph = m_item.log_clusters[to]; toX = positions()[glyph].x(); if (rtl()) toX += truncateFixedPointToInteger(m_item.advances[glyph]); } else to -= numCodePoints(); } // The position in question might be just after the text. if (fromX == -1) fromX = offsetX(); if (toX == -1) toX = offsetX(); ASSERT(fromX != -1 && toX != -1); if (fromX < toX) return FloatRect(point.x() + fromX, point.y(), toX - fromX, height); return FloatRect(point.x() + toX, point.y(), fromX - toX, height); }