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

Side by Side Diff: third_party/WebKit/Source/platform/fonts/Font.cpp

Issue 2707083002: Remove the text blob cache (Closed)
Patch Set: Created 3 years, 10 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2000 Dirk Mueller (mueller@kde.org) 4 * (C) 2000 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved. 5 * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved.
6 * Copyright (c) 2007, 2008, 2010 Google Inc. All rights reserved. 6 * Copyright (c) 2007, 2008, 2010 Google Inc. All rights reserved.
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 bool Font::drawText(PaintCanvas* canvas, 124 bool Font::drawText(PaintCanvas* canvas,
125 const TextRunPaintInfo& runInfo, 125 const TextRunPaintInfo& runInfo,
126 const FloatPoint& point, 126 const FloatPoint& point,
127 float deviceScaleFactor, 127 float deviceScaleFactor,
128 const PaintFlags& flags) const { 128 const PaintFlags& flags) const {
129 // Don't draw anything while we are using custom fonts that are in the process 129 // Don't draw anything while we are using custom fonts that are in the process
130 // of loading. 130 // of loading.
131 if (shouldSkipDrawing()) 131 if (shouldSkipDrawing())
132 return false; 132 return false;
133 133
134 if (runInfo.cachedTextBlob && runInfo.cachedTextBlob->get()) {
135 // we have a pre-cached blob -- happy joy!
136 canvas->drawTextBlob(runInfo.cachedTextBlob->get(), point.x(), point.y(),
137 flags);
138 return true;
139 }
140
141 GlyphBuffer glyphBuffer; 134 GlyphBuffer glyphBuffer;
142 buildGlyphBuffer(runInfo, glyphBuffer); 135 buildGlyphBuffer(runInfo, glyphBuffer);
143 136
144 drawGlyphBuffer(canvas, flags, runInfo, glyphBuffer, point, 137 drawGlyphBuffer(canvas, flags, glyphBuffer, point, deviceScaleFactor);
145 deviceScaleFactor);
146 return true; 138 return true;
147 } 139 }
148 140
149 bool Font::drawBidiText(PaintCanvas* canvas, 141 bool Font::drawBidiText(PaintCanvas* canvas,
150 const TextRunPaintInfo& runInfo, 142 const TextRunPaintInfo& runInfo,
151 const FloatPoint& point, 143 const FloatPoint& point,
152 CustomFontNotReadyAction customFontNotReadyAction, 144 CustomFontNotReadyAction customFontNotReadyAction,
153 float deviceScaleFactor, 145 float deviceScaleFactor,
154 const PaintFlags& flags) const { 146 const PaintFlags& flags) const {
155 // Don't draw anything while we are using custom fonts that are in the process 147 // Don't draw anything while we are using custom fonts that are in the process
(...skipping 27 matching lines...) Expand all
183 subrun.setDirection(isRTL ? TextDirection::kRtl : TextDirection::kLtr); 175 subrun.setDirection(isRTL ? TextDirection::kRtl : TextDirection::kLtr);
184 subrun.setDirectionalOverride(bidiRun->dirOverride(false)); 176 subrun.setDirectionalOverride(bidiRun->dirOverride(false));
185 177
186 TextRunPaintInfo subrunInfo(subrun); 178 TextRunPaintInfo subrunInfo(subrun);
187 subrunInfo.bounds = runInfo.bounds; 179 subrunInfo.bounds = runInfo.bounds;
188 180
189 // TODO: investigate blob consolidation/caching (technically, 181 // TODO: investigate blob consolidation/caching (technically,
190 // all subruns could be part of the same blob). 182 // all subruns could be part of the same blob).
191 GlyphBuffer glyphBuffer; 183 GlyphBuffer glyphBuffer;
192 float runWidth = buildGlyphBuffer(subrunInfo, glyphBuffer); 184 float runWidth = buildGlyphBuffer(subrunInfo, glyphBuffer);
193 drawGlyphBuffer(canvas, flags, subrunInfo, glyphBuffer, currPoint, 185 drawGlyphBuffer(canvas, flags, glyphBuffer, currPoint, deviceScaleFactor);
194 deviceScaleFactor);
195 186
196 bidiRun = bidiRun->next(); 187 bidiRun = bidiRun->next();
197 currPoint.move(runWidth, 0); 188 currPoint.move(runWidth, 0);
198 } 189 }
199 190
200 bidiRuns.deleteRuns(); 191 bidiRuns.deleteRuns();
201 return true; 192 return true;
202 } 193 }
203 194
204 void Font::drawEmphasisMarks(PaintCanvas* canvas, 195 void Font::drawEmphasisMarks(PaintCanvas* canvas,
(...skipping 14 matching lines...) Expand all
219 ASSERT(emphasisGlyphData.fontData); 210 ASSERT(emphasisGlyphData.fontData);
220 if (!emphasisGlyphData.fontData) 211 if (!emphasisGlyphData.fontData)
221 return; 212 return;
222 213
223 GlyphBuffer glyphBuffer; 214 GlyphBuffer glyphBuffer;
224 buildGlyphBuffer(runInfo, glyphBuffer, &emphasisGlyphData); 215 buildGlyphBuffer(runInfo, glyphBuffer, &emphasisGlyphData);
225 216
226 if (glyphBuffer.isEmpty()) 217 if (glyphBuffer.isEmpty())
227 return; 218 return;
228 219
229 drawGlyphBuffer(canvas, flags, runInfo, glyphBuffer, point, 220 drawGlyphBuffer(canvas, flags, glyphBuffer, point, deviceScaleFactor);
230 deviceScaleFactor);
231 } 221 }
232 222
233 float Font::width(const TextRun& run, 223 float Font::width(const TextRun& run,
234 HashSet<const SimpleFontData*>* fallbackFonts, 224 HashSet<const SimpleFontData*>* fallbackFonts,
235 FloatRect* glyphBounds) const { 225 FloatRect* glyphBounds) const {
236 FontCachePurgePreventer purgePreventer; 226 FontCachePurgePreventer purgePreventer;
237 CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription)); 227 CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription));
238 float width = shaper.width(this, run, fallbackFonts, glyphBounds); 228 float width = shaper.width(this, run, fallbackFonts, glyphBounds);
239 return width; 229 return width;
240 } 230 }
(...skipping 10 matching lines...) Expand all
251 public: 241 public:
252 GlyphBufferBloberizer(const GlyphBuffer& buffer, 242 GlyphBufferBloberizer(const GlyphBuffer& buffer,
253 const Font* font, 243 const Font* font,
254 float deviceScaleFactor) 244 float deviceScaleFactor)
255 : m_buffer(buffer), 245 : m_buffer(buffer),
256 m_font(font), 246 m_font(font),
257 m_deviceScaleFactor(deviceScaleFactor), 247 m_deviceScaleFactor(deviceScaleFactor),
258 m_hasVerticalOffsets(buffer.hasVerticalOffsets()), 248 m_hasVerticalOffsets(buffer.hasVerticalOffsets()),
259 m_index(0), 249 m_index(0),
260 m_endIndex(m_buffer.size()), 250 m_endIndex(m_buffer.size()),
261 m_blobCount(0),
262 m_rotation(buffer.isEmpty() ? NoRotation : computeBlobRotation( 251 m_rotation(buffer.isEmpty() ? NoRotation : computeBlobRotation(
263 buffer.fontDataAt(0))) {} 252 buffer.fontDataAt(0))) {}
264 253
265 bool done() const { return m_index >= m_endIndex; } 254 bool done() const { return m_index >= m_endIndex; }
266 unsigned blobCount() const { return m_blobCount; }
267 255
268 std::pair<sk_sp<SkTextBlob>, BlobRotation> next() { 256 std::pair<sk_sp<SkTextBlob>, BlobRotation> next() {
269 ASSERT(!done()); 257 ASSERT(!done());
270 const BlobRotation currentRotation = m_rotation; 258 const BlobRotation currentRotation = m_rotation;
271 259
272 while (m_index < m_endIndex) { 260 while (m_index < m_endIndex) {
273 const SimpleFontData* fontData = m_buffer.fontDataAt(m_index); 261 const SimpleFontData* fontData = m_buffer.fontDataAt(m_index);
274 ASSERT(fontData); 262 ASSERT(fontData);
275 263
276 const BlobRotation newRotation = computeBlobRotation(fontData); 264 const BlobRotation newRotation = computeBlobRotation(fontData);
277 if (newRotation != m_rotation) { 265 if (newRotation != m_rotation) {
278 // We're switching to an orientation which requires a different rotation 266 // We're switching to an orientation which requires a different rotation
279 // => emit the pending blob (and start a new one with the new 267 // => emit the pending blob (and start a new one with the new
280 // rotation). 268 // rotation).
281 m_rotation = newRotation; 269 m_rotation = newRotation;
282 break; 270 break;
283 } 271 }
284 272
285 const unsigned start = m_index++; 273 const unsigned start = m_index++;
286 while (m_index < m_endIndex && m_buffer.fontDataAt(m_index) == fontData) 274 while (m_index < m_endIndex && m_buffer.fontDataAt(m_index) == fontData)
287 m_index++; 275 m_index++;
288 276
289 appendRun(start, m_index - start, fontData); 277 appendRun(start, m_index - start, fontData);
290 } 278 }
291 279
292 m_blobCount++;
293 return std::make_pair(m_builder.make(), currentRotation); 280 return std::make_pair(m_builder.make(), currentRotation);
294 } 281 }
295 282
296 private: 283 private:
297 static BlobRotation computeBlobRotation(const SimpleFontData* font) { 284 static BlobRotation computeBlobRotation(const SimpleFontData* font) {
298 // For vertical upright text we need to compensate the inherited 90deg CW 285 // For vertical upright text we need to compensate the inherited 90deg CW
299 // rotation (using a 90deg CCW rotation). 286 // rotation (using a 90deg CCW rotation).
300 return (font->platformData().isVerticalAnyUpright() && font->verticalData()) 287 return (font->platformData().isVerticalAnyUpright() && font->verticalData())
301 ? CCWRotation 288 ? CCWRotation
302 : NoRotation; 289 : NoRotation;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 } 324 }
338 325
339 const GlyphBuffer& m_buffer; 326 const GlyphBuffer& m_buffer;
340 const Font* m_font; 327 const Font* m_font;
341 const float m_deviceScaleFactor; 328 const float m_deviceScaleFactor;
342 const bool m_hasVerticalOffsets; 329 const bool m_hasVerticalOffsets;
343 330
344 SkTextBlobBuilder m_builder; 331 SkTextBlobBuilder m_builder;
345 unsigned m_index; 332 unsigned m_index;
346 unsigned m_endIndex; 333 unsigned m_endIndex;
347 unsigned m_blobCount;
348 BlobRotation m_rotation; 334 BlobRotation m_rotation;
349 }; 335 };
350 336
351 } // anonymous namespace 337 } // anonymous namespace
352 338
353 void Font::drawGlyphBuffer(PaintCanvas* canvas, 339 void Font::drawGlyphBuffer(PaintCanvas* canvas,
354 const PaintFlags& flags, 340 const PaintFlags& flags,
355 const TextRunPaintInfo& runInfo,
356 const GlyphBuffer& glyphBuffer, 341 const GlyphBuffer& glyphBuffer,
357 const FloatPoint& point, 342 const FloatPoint& point,
358 float deviceScaleFactor) const { 343 float deviceScaleFactor) const {
359 GlyphBufferBloberizer bloberizer(glyphBuffer, this, deviceScaleFactor); 344 GlyphBufferBloberizer bloberizer(glyphBuffer, this, deviceScaleFactor);
360 std::pair<sk_sp<SkTextBlob>, BlobRotation> blob;
361 345
362 while (!bloberizer.done()) { 346 while (!bloberizer.done()) {
363 blob = bloberizer.next(); 347 auto blob = bloberizer.next();
364 ASSERT(blob.first); 348 ASSERT(blob.first);
365 349
366 PaintCanvasAutoRestore autoRestore(canvas, false); 350 PaintCanvasAutoRestore autoRestore(canvas, false);
367 if (blob.second == CCWRotation) { 351 if (blob.second == CCWRotation) {
368 canvas->save(); 352 canvas->save();
369 353
370 SkMatrix m; 354 SkMatrix m;
371 m.setSinCos(-1, 0, point.x(), point.y()); 355 m.setSinCos(-1, 0, point.x(), point.y());
372 canvas->concat(m); 356 canvas->concat(m);
373 } 357 }
374 358
375 canvas->drawTextBlob(blob.first, point.x(), point.y(), flags); 359 canvas->drawTextBlob(blob.first, point.x(), point.y(), flags);
376 } 360 }
377
378 // Cache results when
379 // 1) requested by clients, and
380 // 2) the glyph buffer is encoded as a single blob, and
381 // 3) the blob is not upright/rotated
382 if (runInfo.cachedTextBlob && bloberizer.blobCount() == 1 &&
383 blob.second == NoRotation) {
384 ASSERT(!*runInfo.cachedTextBlob);
385 *runInfo.cachedTextBlob = std::move(blob.first);
386 ASSERT(*runInfo.cachedTextBlob);
387 }
388 } 361 }
389 362
390 static int getInterceptsFromBloberizer(const GlyphBuffer& glyphBuffer, 363 static int getInterceptsFromBloberizer(const GlyphBuffer& glyphBuffer,
391 const Font* font, 364 const Font* font,
392 const PaintFlags& flags, 365 const PaintFlags& flags,
393 float deviceScaleFactor, 366 float deviceScaleFactor,
394 const std::tuple<float, float>& bounds, 367 const std::tuple<float, float>& bounds,
395 SkScalar* interceptsBuffer) { 368 SkScalar* interceptsBuffer) {
396 SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)}; 369 SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)};
397 GlyphBufferBloberizer bloberizer(glyphBuffer, font, deviceScaleFactor); 370 GlyphBufferBloberizer bloberizer(glyphBuffer, font, deviceScaleFactor);
398 std::pair<sk_sp<SkTextBlob>, BlobRotation> blob;
399 371
400 int numIntervals = 0; 372 int numIntervals = 0;
401 while (!bloberizer.done()) { 373 while (!bloberizer.done()) {
402 blob = bloberizer.next(); 374 auto blob = bloberizer.next();
403 DCHECK(blob.first); 375 DCHECK(blob.first);
404 376
405 // GlyphBufferBloberizer splits for a new blob rotation, but does not split 377 // GlyphBufferBloberizer splits for a new blob rotation, but does not split
406 // for a change in font. A TextBlob can contain runs with differing fonts 378 // for a change in font. A TextBlob can contain runs with differing fonts
407 // and the getTextBlobIntercepts method handles multiple fonts for us. For 379 // and the getTextBlobIntercepts method handles multiple fonts for us. For
408 // upright in vertical blobs we currently have to bail, see crbug.com/655154 380 // upright in vertical blobs we currently have to bail, see crbug.com/655154
409 if (blob.second == BlobRotation::CCWRotation) 381 if (blob.second == BlobRotation::CCWRotation)
410 continue; 382 continue;
411 383
412 SkScalar* offsetInterceptsBuffer = nullptr; 384 SkScalar* offsetInterceptsBuffer = nullptr;
413 if (interceptsBuffer) 385 if (interceptsBuffer)
414 offsetInterceptsBuffer = &interceptsBuffer[numIntervals]; 386 offsetInterceptsBuffer = &interceptsBuffer[numIntervals];
415 numIntervals += flags.getTextBlobIntercepts(blob.first.get(), boundsArray, 387 numIntervals += flags.getTextBlobIntercepts(blob.first.get(), boundsArray,
416 offsetInterceptsBuffer); 388 offsetInterceptsBuffer);
417 } 389 }
418 return numIntervals; 390 return numIntervals;
419 } 391 }
420 392
421 void Font::getTextIntercepts(const TextRunPaintInfo& runInfo, 393 void Font::getTextIntercepts(const TextRunPaintInfo& runInfo,
422 float deviceScaleFactor, 394 float deviceScaleFactor,
423 const PaintFlags& flags, 395 const PaintFlags& flags,
424 const std::tuple<float, float>& bounds, 396 const std::tuple<float, float>& bounds,
425 Vector<TextIntercept>& intercepts) const { 397 Vector<TextIntercept>& intercepts) const {
426 if (shouldSkipDrawing()) 398 if (shouldSkipDrawing())
427 return; 399 return;
428 400
429 DCHECK(!runInfo.cachedTextBlob);
430
431 GlyphBuffer glyphBuffer(GlyphBuffer::Type::TextIntercepts); 401 GlyphBuffer glyphBuffer(GlyphBuffer::Type::TextIntercepts);
432 buildGlyphBuffer(runInfo, glyphBuffer); 402 buildGlyphBuffer(runInfo, glyphBuffer);
433 403
434 // Get the number of intervals, without copying the actual values by 404 // Get the number of intervals, without copying the actual values by
435 // specifying nullptr for the buffer, following the Skia allocation model for 405 // specifying nullptr for the buffer, following the Skia allocation model for
436 // retrieving text intercepts. 406 // retrieving text intercepts.
437 int numIntervals = getInterceptsFromBloberizer( 407 int numIntervals = getInterceptsFromBloberizer(
438 glyphBuffer, this, flags, deviceScaleFactor, bounds, nullptr); 408 glyphBuffer, this, flags, deviceScaleFactor, bounds, nullptr);
439 if (!numIntervals) 409 if (!numIntervals)
440 return; 410 return;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 580
611 bool Font::loadingCustomFonts() const { 581 bool Font::loadingCustomFonts() const {
612 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); 582 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts();
613 } 583 }
614 584
615 bool Font::isFallbackValid() const { 585 bool Font::isFallbackValid() const {
616 return !m_fontFallbackList || m_fontFallbackList->isValid(); 586 return !m_fontFallbackList || m_fontFallbackList->isValid();
617 } 587 }
618 588
619 } // namespace blink 589 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/fonts/Font.h ('k') | third_party/WebKit/Source/platform/fonts/TextBlob.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698