void InlineTextBox::showBox(int printedCharacters) const { String value = text(); value.replaceWithLiteral('\\', "\\\\"); value.replaceWithLiteral('\n', "\\n"); printedCharacters += fprintf(stderr, "%s %p", boxName(), this); for (; printedCharacters < showTreeCharacterOffset; printedCharacters++) fputc(' ', stderr); const LineLayoutText obj = lineLayoutItem(); printedCharacters = fprintf(stderr, "\t%s %p", obj.name(), obj.debugPointer()); const int layoutObjectCharacterOffset = 75; for (; printedCharacters < layoutObjectCharacterOffset; printedCharacters++) fputc(' ', stderr); fprintf(stderr, "(%d,%d) \"%s\"\n", start(), start() + len(), value.utf8().data()); }
int InlineTextBox::offsetForPosition(LayoutUnit lineOffset, bool includePartialGlyphs) const { if (isLineBreak()) return 0; if (lineOffset - logicalLeft() > logicalWidth()) return isLeftToRightDirection() ? len() : 0; if (lineOffset - logicalLeft() < 0) return isLeftToRightDirection() ? 0 : len(); LineLayoutText text = lineLayoutItem(); const ComputedStyle& style = text.styleRef(isFirstLineStyle()); const Font& font = style.font(); return font.offsetForPosition(constructTextRun(style, font), (lineOffset - logicalLeft()).toFloat(), includePartialGlyphs); }
LayoutUnit InlineTextBox::positionForOffset(int offset) const { ASSERT(offset >= m_start); ASSERT(offset <= m_start + m_len); if (isLineBreak()) return logicalLeft(); LineLayoutText text = lineLayoutItem(); const ComputedStyle& styleToUse = text.styleRef(isFirstLineStyle()); const Font& font = styleToUse.font(); int from = !isLeftToRightDirection() ? offset - m_start : 0; int to = !isLeftToRightDirection() ? m_len : offset - m_start; // FIXME: Do we need to add rightBearing here? return font.selectionRectForText(constructTextRun(styleToUse, font), IntPoint(logicalLeft(), 0), 0, from, to).maxX(); }
TextRun constructTextRun(const Font& font, const LineLayoutText text, unsigned offset, unsigned length, const ComputedStyle& style) { ASSERT(offset + length <= text.textLength()); if (text.hasEmptyText()) return constructTextRunInternal(font, static_cast<const LChar*>(nullptr), 0, style, LTR); if (text.is8Bit()) return constructTextRunInternal(font, text.characters8() + offset, length, style, LTR); TextRun run = constructTextRunInternal(font, text.characters16() + offset, length, style, LTR); run.setDirection(directionForRun(run)); return run; }
TextRun SVGInlineTextBox::constructTextRun(const ComputedStyle& style, const SVGTextFragment& fragment) const { LineLayoutText text = lineLayoutItem(); // FIXME(crbug.com/264211): This should not be necessary but can occur if we // layout during layout. Remove this when 264211 is fixed. RELEASE_ASSERT(!text.needsLayout()); TextRun run(static_cast<const LChar*>(nullptr) // characters, will be set below if non-zero. , 0 // length, will be set below if non-zero. , 0 // xPos, only relevant with allowTabs=true , 0 // padding, only relevant for justified text, not relevant for SVG , TextRun::AllowTrailingExpansion , direction() , dirOverride() || style.rtlOrdering() == VisualOrder /* directionalOverride */); if (fragment.length) { if (text.is8Bit()) run.setText(text.characters8() + fragment.characterOffset, fragment.length); else run.setText(text.characters16() + fragment.characterOffset, fragment.length); } // We handle letter & word spacing ourselves. run.disableSpacing(); // Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring. run.setCharactersLength(text.textLength() - fragment.characterOffset); ASSERT(run.charactersLength() >= run.length()); return run; }
TextRun SVGInlineTextBox::constructTextRun( const ComputedStyle& style, const SVGTextFragment& fragment) const { LineLayoutText text = getLineLayoutItem(); CHECK(!text.needsLayout()); TextRun run( // characters, will be set below if non-zero. static_cast<const LChar*>(nullptr), 0, // length, will be set below if non-zero. 0, // xPos, only relevant with allowTabs=true 0, // padding, only relevant for justified text, not relevant for SVG TextRun::AllowTrailingExpansion, direction(), dirOverride() || style.rtlOrdering() == VisualOrder /* directionalOverride */); if (fragment.length) { if (text.is8Bit()) run.setText(text.characters8() + fragment.characterOffset, fragment.length); else run.setText(text.characters16() + fragment.characterOffset, fragment.length); } // We handle letter & word spacing ourselves. run.disableSpacing(); // Propagate the maximum length of the characters buffer to the TextRun, even // when we're only processing a substring. run.setCharactersLength(text.textLength() - fragment.characterOffset); ASSERT(run.charactersLength() >= run.length()); return run; }