static inline SVGInlineTextBoxQueryWalker executeTextQuery(const SVGTextContentElement* element, SVGInlineTextBoxQueryWalker::QueryMode mode, long startPosition = 0, long length = 0, FloatPoint referencePoint = FloatPoint()) { SVGRootInlineBox* rootBox = rootInlineBoxForTextContentElement(element); if (!rootBox) return SVGInlineTextBoxQueryWalker(0, mode); // Find all inline text box associated with our renderer Vector<SVGInlineTextBox*> textBoxes = findInlineTextBoxInTextChunks(element, rootBox->svgTextChunks()); // Walk text chunks to find chunks associated with our inline text box SVGInlineTextBoxQueryWalker walkerCallback(element, mode); walkerCallback.setQueryInputParameters(startPosition, length, referencePoint); SVGTextChunkWalker<SVGInlineTextBoxQueryWalker> walker(&walkerCallback, &SVGInlineTextBoxQueryWalker::chunkPortionCallback); Vector<SVGInlineTextBox*>::iterator it = textBoxes.begin(); Vector<SVGInlineTextBox*>::iterator end = textBoxes.end(); for (; it != end; ++it) { rootBox->walkTextChunks(&walker, *it); if (walkerCallback.stopProcessing()) break; } return walkerCallback; }
static void writeRenderSVGTextBox(TextStream& ts, const RenderBlock& text) { SVGRootInlineBox* box = static_cast<SVGRootInlineBox*>(text.firstRootBox()); if (!box) return; Vector<SVGTextChunk>& chunks = const_cast<Vector<SVGTextChunk>& >(box->svgTextChunks()); ts << " at (" << text.x() << "," << text.y() << ") size " << box->width() << "x" << box->height() << " contains " << chunks.size() << " chunk(s)"; if (text.parent() && (text.parent()->style()->color() != text.style()->color())) writeNameValuePair(ts, "color", text.style()->color().name()); }
static TextStream& operator<<(TextStream& ts, const RenderSVGText& text) { SVGRootInlineBox* box = static_cast<SVGRootInlineBox*>(text.firstRootBox()); if (!box) return ts; Vector<SVGTextChunk>& chunks = const_cast<Vector<SVGTextChunk>& >(box->svgTextChunks()); ts << " at (" << text.xPos() << "," << text.yPos() << ") size " << box->width() << "x" << box->height() << " contains " << chunks.size() << " chunk(s)"; if (text.parent() && (text.parent()->style()->color() != text.style()->color())) ts << " [color=" << text.style()->color().name() << "]"; return ts; }
static inline void writeSVGInlineTextBox(TextStream& ts, SVGInlineTextBox* textBox, int indent) { SVGRootInlineBox* rootBox = textBox->svgRootInlineBox(); if (!rootBox) return; Vector<SVGTextChunk>& chunks = const_cast<Vector<SVGTextChunk>& >(rootBox->svgTextChunks()); Vector<SVGTextChunk>::iterator it = chunks.begin(); Vector<SVGTextChunk>::iterator end = chunks.end(); // Write text chunks unsigned int i = 1; for (; it != end; ++it) { SVGTextChunk& cur = *it; // Write inline box character ranges Vector<SVGInlineBoxCharacterRange>::iterator boxIt = cur.boxes.begin(); Vector<SVGInlineBoxCharacterRange>::iterator boxEnd = cur.boxes.end(); if (!containsInlineTextBox(cur, textBox)) { i++; continue; } writeIndent(ts, indent + 1); unsigned int j = 1; ts << "chunk " << i << " "; if (cur.anchor == TA_MIDDLE) { ts << "(middle anchor"; if (cur.isVerticalText) ts << ", vertical"; ts << ") "; } else if (cur.anchor == TA_END) { ts << "(end anchor"; if (cur.isVerticalText) ts << ", vertical"; ts << ") "; } else if (cur.isVerticalText) ts << "(vertical) "; unsigned int totalOffset = 0; for (; boxIt != boxEnd; ++boxIt) { SVGInlineBoxCharacterRange& range = *boxIt; unsigned int offset = range.endOffset - range.startOffset; ASSERT(cur.start + totalOffset <= cur.end); totalOffset += offset; if (textBox != static_cast<SVGInlineTextBox*>(range.box)) { j++; continue; } FloatPoint topLeft = topLeftPositionOfCharacterRange(cur.start + totalOffset - offset, cur.start + totalOffset); ts << "text run " << j << " at (" << topLeft.x() << "," << topLeft.y() << ") "; ts << "startOffset " << range.startOffset << " endOffset " << range.endOffset; if (cur.isVerticalText) ts << " height " << cummulatedHeightOfInlineBoxCharacterRange(range); else ts << " width " << cummulatedWidthOfInlineBoxCharacterRange(range); if (textBox->direction() == RTL || textBox->m_dirOverride) { ts << (textBox->direction() == RTL ? " RTL" : " LTR"); if (textBox->m_dirOverride) ts << " override"; } ts << ": " << quoteAndEscapeNonPrintables(String(textBox->textRenderer()->text()).substring(textBox->start() + range.startOffset, offset)) << "\n"; j++; } i++; } }