Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(813)

Unified Diff: third_party/WebKit/Source/platform/fonts/Font.cpp

Issue 2714413003: Remove GlyphBuffer (Closed)
Patch Set: format Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/fonts/Font.cpp
diff --git a/third_party/WebKit/Source/platform/fonts/Font.cpp b/third_party/WebKit/Source/platform/fonts/Font.cpp
index e858b6757e3a01b97499351bdf83ecc42631529b..131e11cdbfb94c15be4f44401d50df74666462cc 100644
--- a/third_party/WebKit/Source/platform/fonts/Font.cpp
+++ b/third_party/WebKit/Source/platform/fonts/Font.cpp
@@ -31,9 +31,9 @@
#include "platform/fonts/FontCache.h"
#include "platform/fonts/FontFallbackIterator.h"
#include "platform/fonts/FontFallbackList.h"
-#include "platform/fonts/GlyphBuffer.h"
#include "platform/fonts/SimpleFontData.h"
#include "platform/fonts/shaping/CachingWordShaper.h"
+#include "platform/fonts/shaping/ShapeResultBloberizer.h"
#include "platform/geometry/FloatRect.h"
#include "platform/graphics/paint/PaintCanvas.h"
#include "platform/graphics/paint/PaintFlags.h"
@@ -105,22 +105,29 @@ void Font::update(FontSelector* fontSelector) const {
m_fontFallbackList->invalidate(fontSelector);
}
-float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo,
- GlyphBuffer& glyphBuffer,
- const GlyphData* emphasisData) const {
- float width;
- CachingWordShaper shaper(*this);
- if (emphasisData) {
- width = shaper.fillGlyphBufferForTextEmphasis(runInfo.run,
- emphasisData, &glyphBuffer,
- runInfo.from, runInfo.to);
- } else {
- width = shaper.fillGlyphBuffer(runInfo.run, &glyphBuffer,
- runInfo.from, runInfo.to);
+namespace {
+
+void drawBlobs(PaintCanvas* canvas,
+ const PaintFlags& flags,
+ const ShapeResultBloberizer::BlobBuffer& blobs,
+ const FloatPoint& point) {
+ for (const auto& blobInfo : blobs) {
+ DCHECK(blobInfo.blob);
+ PaintCanvasAutoRestore autoRestore(canvas, false);
+ if (blobInfo.rotation == ShapeResultBloberizer::BlobRotation::CCWRotation) {
+ canvas->save();
+
+ SkMatrix m;
+ m.setSinCos(-1, 0, point.x(), point.y());
+ canvas->concat(m);
+ }
+
+ canvas->drawTextBlob(blobInfo.blob, point.x(), point.y(), flags);
}
- return width;
}
+} // anonymous ns
+
bool Font::drawText(PaintCanvas* canvas,
const TextRunPaintInfo& runInfo,
const FloatPoint& point,
@@ -131,10 +138,9 @@ bool Font::drawText(PaintCanvas* canvas,
if (shouldSkipDrawing())
return false;
- GlyphBuffer glyphBuffer;
- buildGlyphBuffer(runInfo, glyphBuffer);
-
- drawGlyphBuffer(canvas, flags, glyphBuffer, point, deviceScaleFactor);
+ ShapeResultBloberizer bloberizer(*this, deviceScaleFactor);
+ CachingWordShaper(*this).fillGlyphs(runInfo, bloberizer);
+ drawBlobs(canvas, flags, bloberizer.blobs(), point);
return true;
}
@@ -178,11 +184,10 @@ bool Font::drawBidiText(PaintCanvas* canvas,
TextRunPaintInfo subrunInfo(subrun);
subrunInfo.bounds = runInfo.bounds;
- // TODO: investigate blob consolidation/caching (technically,
- // all subruns could be part of the same blob).
- GlyphBuffer glyphBuffer;
- float runWidth = buildGlyphBuffer(subrunInfo, glyphBuffer);
- drawGlyphBuffer(canvas, flags, glyphBuffer, currPoint, deviceScaleFactor);
+ ShapeResultBloberizer bloberizer(*this, deviceScaleFactor);
+ float runWidth =
+ CachingWordShaper(*this).fillGlyphs(subrunInfo, bloberizer);
+ drawBlobs(canvas, flags, bloberizer.blobs(), currPoint);
bidiRun = bidiRun->next();
currPoint.move(runWidth, 0);
@@ -207,13 +212,10 @@ void Font::drawEmphasisMarks(PaintCanvas* canvas,
if (!emphasisGlyphData.fontData)
return;
- GlyphBuffer glyphBuffer;
- buildGlyphBuffer(runInfo, glyphBuffer, &emphasisGlyphData);
-
- if (glyphBuffer.isEmpty())
- return;
-
- drawGlyphBuffer(canvas, flags, glyphBuffer, point, deviceScaleFactor);
+ ShapeResultBloberizer bloberizer(*this, deviceScaleFactor);
+ CachingWordShaper(*this).fillTextEmphasisGlyphs(runInfo, emphasisGlyphData,
+ bloberizer);
+ drawBlobs(canvas, flags, bloberizer.blobs(), point);
}
float Font::width(const TextRun& run,
@@ -224,163 +226,29 @@ float Font::width(const TextRun& run,
return shaper.width(run, fallbackFonts, glyphBounds);
}
-namespace {
-
-enum BlobRotation {
- NoRotation,
- CCWRotation,
-};
-
-class GlyphBufferBloberizer {
- STACK_ALLOCATED()
- public:
- GlyphBufferBloberizer(const GlyphBuffer& buffer,
- const Font* font,
- float deviceScaleFactor)
- : m_buffer(buffer),
- m_font(font),
- m_deviceScaleFactor(deviceScaleFactor),
- m_hasVerticalOffsets(buffer.hasVerticalOffsets()),
- m_index(0),
- m_endIndex(m_buffer.size()),
- m_rotation(buffer.isEmpty() ? NoRotation : computeBlobRotation(
- buffer.fontDataAt(0))) {}
-
- bool done() const { return m_index >= m_endIndex; }
-
- std::pair<sk_sp<SkTextBlob>, BlobRotation> next() {
- ASSERT(!done());
- const BlobRotation currentRotation = m_rotation;
-
- while (m_index < m_endIndex) {
- const SimpleFontData* fontData = m_buffer.fontDataAt(m_index);
- ASSERT(fontData);
-
- const BlobRotation newRotation = computeBlobRotation(fontData);
- if (newRotation != m_rotation) {
- // We're switching to an orientation which requires a different rotation
- // => emit the pending blob (and start a new one with the new
- // rotation).
- m_rotation = newRotation;
- break;
- }
-
- const unsigned start = m_index++;
- while (m_index < m_endIndex && m_buffer.fontDataAt(m_index) == fontData)
- m_index++;
-
- appendRun(start, m_index - start, fontData);
- }
-
- return std::make_pair(m_builder.make(), currentRotation);
- }
-
- private:
- static BlobRotation computeBlobRotation(const SimpleFontData* font) {
- // For vertical upright text we need to compensate the inherited 90deg CW
- // rotation (using a 90deg CCW rotation).
- return (font->platformData().isVerticalAnyUpright() && font->verticalData())
- ? CCWRotation
- : NoRotation;
- }
-
- void appendRun(unsigned start,
- unsigned count,
- const SimpleFontData* fontData) {
- SkPaint paint;
- fontData->platformData().setupPaint(&paint, m_deviceScaleFactor, m_font);
- paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-
- const SkTextBlobBuilder::RunBuffer& buffer =
- m_hasVerticalOffsets ? m_builder.allocRunPos(paint, count)
- : m_builder.allocRunPosH(paint, count, 0);
-
- const uint16_t* glyphs = m_buffer.glyphs(start);
- const float* offsets = m_buffer.offsets(start);
- std::copy(glyphs, glyphs + count, buffer.glyphs);
-
- if (m_rotation == NoRotation) {
- std::copy(offsets, offsets + (m_hasVerticalOffsets ? 2 * count : count),
- buffer.pos);
- } else {
- ASSERT(m_hasVerticalOffsets);
-
- const float verticalBaselineXOffset =
- fontData->getFontMetrics().floatAscent() -
- fontData->getFontMetrics().floatAscent(IdeographicBaseline);
-
- // TODO(fmalita): why don't we apply this adjustment when building the
- // glyph buffer?
- for (unsigned i = 0; i < 2 * count; i += 2) {
- buffer.pos[i] = SkFloatToScalar(offsets[i] + verticalBaselineXOffset);
- buffer.pos[i + 1] = SkFloatToScalar(offsets[i + 1]);
- }
- }
- }
-
- const GlyphBuffer& m_buffer;
- const Font* m_font;
- const float m_deviceScaleFactor;
- const bool m_hasVerticalOffsets;
-
- SkTextBlobBuilder m_builder;
- unsigned m_index;
- unsigned m_endIndex;
- BlobRotation m_rotation;
-};
-
-} // anonymous namespace
-
-void Font::drawGlyphBuffer(PaintCanvas* canvas,
- const PaintFlags& flags,
- const GlyphBuffer& glyphBuffer,
- const FloatPoint& point,
- float deviceScaleFactor) const {
- GlyphBufferBloberizer bloberizer(glyphBuffer, this, deviceScaleFactor);
-
- while (!bloberizer.done()) {
- auto blob = bloberizer.next();
- ASSERT(blob.first);
-
- PaintCanvasAutoRestore autoRestore(canvas, false);
- if (blob.second == CCWRotation) {
- canvas->save();
-
- SkMatrix m;
- m.setSinCos(-1, 0, point.x(), point.y());
- canvas->concat(m);
- }
-
- canvas->drawTextBlob(blob.first, point.x(), point.y(), flags);
- }
-}
-
-static int getInterceptsFromBloberizer(const GlyphBuffer& glyphBuffer,
- const Font* font,
- const SkPaint& paint,
- float deviceScaleFactor,
- const std::tuple<float, float>& bounds,
- SkScalar* interceptsBuffer) {
+static int getInterceptsFromBlobs(
+ const ShapeResultBloberizer::BlobBuffer& blobs,
+ const SkPaint& paint,
+ const std::tuple<float, float>& bounds,
+ SkScalar* interceptsBuffer) {
SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)};
- GlyphBufferBloberizer bloberizer(glyphBuffer, font, deviceScaleFactor);
int numIntervals = 0;
- while (!bloberizer.done()) {
- auto blob = bloberizer.next();
- DCHECK(blob.first);
+ for (const auto& blobInfo : blobs) {
+ DCHECK(blobInfo.blob);
- // GlyphBufferBloberizer splits for a new blob rotation, but does not split
+ // ShapeResultBloberizer splits for a new blob rotation, but does not split
// for a change in font. A TextBlob can contain runs with differing fonts
// and the getTextBlobIntercepts method handles multiple fonts for us. For
// upright in vertical blobs we currently have to bail, see crbug.com/655154
- if (blob.second == BlobRotation::CCWRotation)
+ if (blobInfo.rotation == ShapeResultBloberizer::BlobRotation::CCWRotation)
continue;
SkScalar* offsetInterceptsBuffer = nullptr;
if (interceptsBuffer)
offsetInterceptsBuffer = &interceptsBuffer[numIntervals];
- numIntervals += paint.getTextBlobIntercepts(blob.first.get(), boundsArray,
- offsetInterceptsBuffer);
+ numIntervals += paint.getTextBlobIntercepts(
+ blobInfo.blob.get(), boundsArray, offsetInterceptsBuffer);
}
return numIntervals;
}
@@ -393,23 +261,23 @@ void Font::getTextIntercepts(const TextRunPaintInfo& runInfo,
if (shouldSkipDrawing())
return;
- GlyphBuffer glyphBuffer(GlyphBuffer::Type::TextIntercepts);
- buildGlyphBuffer(runInfo, glyphBuffer);
+ ShapeResultBloberizer bloberizer(*this, deviceScaleFactor,
+ ShapeResultBloberizer::Type::TextIntercepts);
+ CachingWordShaper(*this).fillGlyphs(runInfo, bloberizer);
+ const auto& blobs = bloberizer.blobs();
// Get the number of intervals, without copying the actual values by
// specifying nullptr for the buffer, following the Skia allocation model for
// retrieving text intercepts.
SkPaint paint(ToSkPaint(flags));
- int numIntervals = getInterceptsFromBloberizer(
- glyphBuffer, this, paint, deviceScaleFactor, bounds, nullptr);
+ int numIntervals = getInterceptsFromBlobs(blobs, paint, bounds, nullptr);
if (!numIntervals)
return;
DCHECK_EQ(numIntervals % 2, 0);
intercepts.resize(numIntervals / 2);
- getInterceptsFromBloberizer(glyphBuffer, this, paint, deviceScaleFactor,
- bounds,
- reinterpret_cast<SkScalar*>(intercepts.data()));
+ getInterceptsFromBlobs(blobs, paint, bounds,
+ reinterpret_cast<SkScalar*>(intercepts.data()));
}
static inline FloatRect pixelSnappedSelectionRect(FloatRect rect) {

Powered by Google App Engine
This is Rietveld 408576698