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); }
int Font::offsetForPositionForComplexText(const TextRun& run, float x, bool includePartialGlyphs) const { if (preferHarfBuzz(this)) { HarfBuzzShaper shaper(this, run); if (shaper.shape()) return shaper.offsetForPosition(x); } ComplexTextController controller(this, run); return controller.offsetForPosition(x, includePartialGlyphs); }
float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const { if (preferHarfBuzz(this)) { HarfBuzzShaper shaper(this, run); if (shaper.shape()) return shaper.totalWidth(); } ComplexTextController controller(this, run, true, fallbackFonts); if (glyphOverflow) { glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().ascent())); glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().descent())); glyphOverflow->left = max<int>(0, ceilf(-controller.minGlyphBoundingBoxX())); glyphOverflow->right = max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.totalWidth())); } return controller.totalWidth(); }
FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& point, int h, int from, int to) const { if (preferHarfBuzz(this)) { HarfBuzzShaper shaper(this, run); if (shaper.shape()) return shaper.selectionRect(point, h, from, to); } ComplexTextController controller(this, run); controller.advance(from); float beforeWidth = controller.runWidthSoFar(); controller.advance(to); float afterWidth = controller.runWidthSoFar(); // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning if (run.rtl()) { float totalWidth = controller.totalWidth(); return FloatRect(floorf(point.x() + totalWidth - afterWidth), point.y(), roundf(point.x() + totalWidth - beforeWidth) - floorf(point.x() + totalWidth - afterWidth), h); } return FloatRect(floorf(point.x() + beforeWidth), point.y(), roundf(point.x() + afterWidth) - floorf(point.x() + beforeWidth), h); }