void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const { #if PLATFORM(CHROMIUM) if (preferHarfBuzz(this)) { GlyphBuffer glyphBuffer; HarfBuzzShaper shaper(this, run); shaper.setDrawRange(from, to); if (shaper.shape(&glyphBuffer)) { drawGlyphBuffer(context, run, glyphBuffer, point); return; } } #endif // This glyph buffer holds our glyphs + advances + font data for each glyph. GlyphBuffer glyphBuffer; float startX = point.x() + getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer); // We couldn't generate any glyphs for the run. Give up. if (glyphBuffer.isEmpty()) return; // Draw the glyph buffer now at the starting point returned in startX. FloatPoint startPoint(startX, point.y()); drawGlyphBuffer(context, run, glyphBuffer, startPoint); }
void Font::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const { GlyphBuffer glyphBuffer; float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis); if (glyphBuffer.isEmpty()) return; drawEmphasisMarks(context, run, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y())); }
DashArray FontCascade::dashesForIntersectionsWithRect(const TextRun& run, const FloatPoint& textOrigin, const FloatRect& lineExtents) const { if (isLoadingCustomFonts()) return DashArray(); GlyphBuffer glyphBuffer; glyphBuffer.saveOffsetsInString(); float deltaX; if (codePath(run) != FontCascade::Complex) deltaX = getGlyphsAndAdvancesForSimpleText(run, 0, run.length(), glyphBuffer); else deltaX = getGlyphsAndAdvancesForComplexText(run, 0, run.length(), glyphBuffer); if (!glyphBuffer.size()) return DashArray(); // FIXME: Handle SVG + non-SVG interleaved runs. https://bugs.webkit.org/show_bug.cgi?id=133778 FloatPoint origin = FloatPoint(textOrigin.x() + deltaX, textOrigin.y()); std::unique_ptr<GlyphToPathTranslator> translator = std::make_unique<CairoGlyphToPathTranslator>(run, glyphBuffer, origin); DashArray result; for (int index = 0; translator->containsMorePaths(); ++index, translator->advance()) { float centerOfLine = lineExtents.y() + (lineExtents.height() / 2); GlyphIterationState info = GlyphIterationState(FloatPoint(), FloatPoint(), centerOfLine, lineExtents.x() + lineExtents.width(), lineExtents.x()); const Font* localFontData = glyphBuffer.fontAt(index); if (!localFontData) { // The advances will get all messed up if we do anything other than bail here. result.clear(); break; } switch (translator->underlineType()) { case GlyphToPathTranslator::GlyphUnderlineType::SkipDescenders: { Path path = translator->path(); path.apply([&info](const PathElement& pathElement) { findPathIntersections(info, pathElement); }); if (info.minX < info.maxX) { result.append(info.minX - lineExtents.x()); result.append(info.maxX - lineExtents.x()); } break; } case GlyphToPathTranslator::GlyphUnderlineType::SkipGlyph: { std::pair<float, float> extents = translator->extents(); result.append(extents.first - lineExtents.x()); result.append(extents.second - lineExtents.x()); break; } case GlyphToPathTranslator::GlyphUnderlineType::DrawOverGlyph: // Nothing to do break; } } return result; }
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const { // This glyph buffer holds our glyphs + advances + font data for each glyph. GlyphBuffer glyphBuffer; float startX = point.x() + getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer); // We couldn't generate any glyphs for the run. Give up. if (glyphBuffer.isEmpty()) return; // Draw the glyph buffer now at the starting point returned in startX. FloatPoint startPoint(startX, point.y()); drawGlyphBuffer(context, glyphBuffer, startPoint); }