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

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

Issue 2598393002: Do not skip ink for ideographic scripts (Closed)
Patch Set: drott review Created 3 years, 11 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 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 STACK_ALLOCATED() 250 STACK_ALLOCATED()
251 public: 251 public:
252 GlyphBufferBloberizer(const GlyphBuffer& buffer, 252 GlyphBufferBloberizer(const GlyphBuffer& buffer,
253 const Font* font, 253 const Font* font,
254 float deviceScaleFactor) 254 float deviceScaleFactor)
255 : m_buffer(buffer), 255 : m_buffer(buffer),
256 m_font(font), 256 m_font(font),
257 m_deviceScaleFactor(deviceScaleFactor), 257 m_deviceScaleFactor(deviceScaleFactor),
258 m_hasVerticalOffsets(buffer.hasVerticalOffsets()), 258 m_hasVerticalOffsets(buffer.hasVerticalOffsets()),
259 m_index(0), 259 m_index(0),
260 m_endIndex(m_buffer.size()),
260 m_blobCount(0), 261 m_blobCount(0),
261 m_rotation(buffer.isEmpty() ? NoRotation : computeBlobRotation( 262 m_rotation(buffer.isEmpty() ? NoRotation : computeBlobRotation(
262 buffer.fontDataAt(0))) {} 263 buffer.fontDataAt(0))),
264 m_skipGlyphs(nullptr) {}
263 265
264 bool done() const { return m_index >= m_buffer.size(); } 266 bool done() const { return m_index >= m_endIndex; }
265 unsigned blobCount() const { return m_blobCount; } 267 unsigned blobCount() const { return m_blobCount; }
266 268
267 std::pair<sk_sp<SkTextBlob>, BlobRotation> next() { 269 std::pair<sk_sp<SkTextBlob>, BlobRotation> next() {
268 ASSERT(!done()); 270 ASSERT(!done());
269 const BlobRotation currentRotation = m_rotation; 271 const BlobRotation currentRotation = m_rotation;
270 272
271 while (m_index < m_buffer.size()) { 273 while (m_index < m_endIndex) {
274 if (m_skipGlyphs) {
275 while (m_index < m_endIndex && (*m_skipGlyphs)[m_index])
276 m_index++;
277 }
278
272 const SimpleFontData* fontData = m_buffer.fontDataAt(m_index); 279 const SimpleFontData* fontData = m_buffer.fontDataAt(m_index);
273 ASSERT(fontData); 280 ASSERT(fontData);
274 281
275 const BlobRotation newRotation = computeBlobRotation(fontData); 282 const BlobRotation newRotation = computeBlobRotation(fontData);
276 if (newRotation != m_rotation) { 283 if (newRotation != m_rotation) {
277 // We're switching to an orientation which requires a different rotation 284 // We're switching to an orientation which requires a different rotation
278 // => emit the pending blob (and start a new one with the new 285 // => emit the pending blob (and start a new one with the new
279 // rotation). 286 // rotation).
280 m_rotation = newRotation; 287 m_rotation = newRotation;
281 break; 288 break;
282 } 289 }
283 290
284 const unsigned start = m_index++; 291 const unsigned start = m_index++;
285 while (m_index < m_buffer.size() && 292 while (m_index < m_endIndex && m_buffer.fontDataAt(m_index) == fontData &&
286 m_buffer.fontDataAt(m_index) == fontData) 293 !(m_skipGlyphs && (*m_skipGlyphs)[m_index]))
287 m_index++; 294 m_index++;
288 295
289 appendRun(start, m_index - start, fontData); 296 appendRun(start, m_index - start, fontData);
290 } 297 }
291 298
292 m_blobCount++; 299 m_blobCount++;
293 return std::make_pair(m_builder.make(), currentRotation); 300 return std::make_pair(m_builder.make(), currentRotation);
294 } 301 }
295 302
303 void setSkipGlyphs(const Vector<bool>* skipGlyphs) {
drott 2017/01/02 15:07:46 As mentioned below, I'd prefer if we use the glyph
304 m_skipGlyphs = skipGlyphs;
305 m_endIndex = m_buffer.size();
306 if (m_skipGlyphs) {
307 while (m_endIndex > 0 && (*m_skipGlyphs)[m_endIndex - 1])
308 m_endIndex--;
309 }
310 }
311
296 private: 312 private:
297 static BlobRotation computeBlobRotation(const SimpleFontData* font) { 313 static BlobRotation computeBlobRotation(const SimpleFontData* font) {
298 // For vertical upright text we need to compensate the inherited 90deg CW 314 // For vertical upright text we need to compensate the inherited 90deg CW
299 // rotation (using a 90deg CCW rotation). 315 // rotation (using a 90deg CCW rotation).
300 return (font->platformData().isVerticalAnyUpright() && font->verticalData()) 316 return (font->platformData().isVerticalAnyUpright() && font->verticalData())
301 ? CCWRotation 317 ? CCWRotation
302 : NoRotation; 318 : NoRotation;
303 } 319 }
304 320
305 void appendRun(unsigned start, 321 void appendRun(unsigned start,
(...skipping 30 matching lines...) Expand all
336 } 352 }
337 } 353 }
338 354
339 const GlyphBuffer& m_buffer; 355 const GlyphBuffer& m_buffer;
340 const Font* m_font; 356 const Font* m_font;
341 const float m_deviceScaleFactor; 357 const float m_deviceScaleFactor;
342 const bool m_hasVerticalOffsets; 358 const bool m_hasVerticalOffsets;
343 359
344 SkTextBlobBuilder m_builder; 360 SkTextBlobBuilder m_builder;
345 unsigned m_index; 361 unsigned m_index;
362 unsigned m_endIndex;
346 unsigned m_blobCount; 363 unsigned m_blobCount;
347 BlobRotation m_rotation; 364 BlobRotation m_rotation;
365 const Vector<bool>* m_skipGlyphs;
drott 2017/01/02 15:07:46 I believe we can use this from m_buffer directly?
348 }; 366 };
349 367
350 } // anonymous namespace 368 } // anonymous namespace
351 369
352 void Font::drawGlyphBuffer(SkCanvas* canvas, 370 void Font::drawGlyphBuffer(SkCanvas* canvas,
353 const SkPaint& paint, 371 const SkPaint& paint,
354 const TextRunPaintInfo& runInfo, 372 const TextRunPaintInfo& runInfo,
355 const GlyphBuffer& glyphBuffer, 373 const GlyphBuffer& glyphBuffer,
356 const FloatPoint& point, 374 const FloatPoint& point,
357 float deviceScaleFactor) const { 375 float deviceScaleFactor) const {
(...skipping 26 matching lines...) Expand all
384 *runInfo.cachedTextBlob = std::move(blob.first); 402 *runInfo.cachedTextBlob = std::move(blob.first);
385 ASSERT(*runInfo.cachedTextBlob); 403 ASSERT(*runInfo.cachedTextBlob);
386 } 404 }
387 } 405 }
388 406
389 static int getInterceptsFromBloberizer(const GlyphBuffer& glyphBuffer, 407 static int getInterceptsFromBloberizer(const GlyphBuffer& glyphBuffer,
390 const Font* font, 408 const Font* font,
391 const SkPaint& paint, 409 const SkPaint& paint,
392 float deviceScaleFactor, 410 float deviceScaleFactor,
393 const std::tuple<float, float>& bounds, 411 const std::tuple<float, float>& bounds,
412 const Vector<bool>* skipGlyphs,
drott 2017/01/02 15:07:46 See below, I think we can remove this argument...
394 SkScalar* interceptsBuffer) { 413 SkScalar* interceptsBuffer) {
395 SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)}; 414 SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)};
396 GlyphBufferBloberizer bloberizer(glyphBuffer, font, deviceScaleFactor); 415 GlyphBufferBloberizer bloberizer(glyphBuffer, font, deviceScaleFactor);
416 bloberizer.setSkipGlyphs(skipGlyphs);
drott 2017/01/02 15:07:46 and this explicit transfer of the skipExceptions v
397 std::pair<sk_sp<SkTextBlob>, BlobRotation> blob; 417 std::pair<sk_sp<SkTextBlob>, BlobRotation> blob;
398 418
399 int numIntervals = 0; 419 int numIntervals = 0;
400 while (!bloberizer.done()) { 420 while (!bloberizer.done()) {
401 blob = bloberizer.next(); 421 blob = bloberizer.next();
402 DCHECK(blob.first); 422 DCHECK(blob.first);
403 423
404 // GlyphBufferBloberizer splits for a new blob rotation, but does not split 424 // GlyphBufferBloberizer splits for a new blob rotation, but does not split
405 // for a change in font. A TextBlob can contain runs with differing fonts 425 // for a change in font. A TextBlob can contain runs with differing fonts
406 // and the getTextBlobIntercepts method handles multiple fonts for us. For 426 // and the getTextBlobIntercepts method handles multiple fonts for us. For
(...skipping 25 matching lines...) Expand all
432 if (!numIntervals) 452 if (!numIntervals)
433 return; 453 return;
434 DCHECK_EQ(numIntervals % 2, 0); 454 DCHECK_EQ(numIntervals % 2, 0);
435 intercepts.resize(numIntervals / 2); 455 intercepts.resize(numIntervals / 2);
436 paint.getTextBlobIntercepts(runInfo.cachedTextBlob->get(), boundsArray, 456 paint.getTextBlobIntercepts(runInfo.cachedTextBlob->get(), boundsArray,
437 reinterpret_cast<SkScalar*>(intercepts.data())); 457 reinterpret_cast<SkScalar*>(intercepts.data()));
438 return; 458 return;
439 } 459 }
440 460
441 GlyphBuffer glyphBuffer; 461 GlyphBuffer glyphBuffer;
442 buildGlyphBuffer(runInfo, glyphBuffer); 462 const Vector<bool>* skipGlyphs = nullptr;
463 if (runInfo.run.is8Bit()) {
464 // All characters in Latin-1 should skip inks, so no skipInkExceptions.
465 buildGlyphBuffer(runInfo, glyphBuffer);
466 } else {
467 glyphBuffer.saveSkipInkExceptions();
468 buildGlyphBuffer(runInfo, glyphBuffer);
469 skipGlyphs = &glyphBuffer.skipInkExceptions();
drott 2017/01/02 15:07:46 Using state in the GlyphBuffer for shouldSaveSkipI
470 }
443 471
444 // Get the number of intervals, without copying the actual values by 472 // Get the number of intervals, without copying the actual values by
445 // specifying nullptr for the buffer, following the Skia allocation model for 473 // specifying nullptr for the buffer, following the Skia allocation model for
446 // retrieving text intercepts. 474 // retrieving text intercepts.
447 int numIntervals = getInterceptsFromBloberizer( 475 int numIntervals = getInterceptsFromBloberizer(
448 glyphBuffer, this, paint, deviceScaleFactor, bounds, nullptr); 476 glyphBuffer, this, paint, deviceScaleFactor, bounds, skipGlyphs, nullptr);
449 if (!numIntervals) 477 if (!numIntervals)
450 return; 478 return;
451 DCHECK_EQ(numIntervals % 2, 0); 479 DCHECK_EQ(numIntervals % 2, 0);
452 intercepts.resize(numIntervals / 2); 480 intercepts.resize(numIntervals / 2);
453 481
454 getInterceptsFromBloberizer(glyphBuffer, this, paint, deviceScaleFactor, 482 getInterceptsFromBloberizer(glyphBuffer, this, paint, deviceScaleFactor,
455 bounds, 483 bounds, skipGlyphs,
456 reinterpret_cast<SkScalar*>(intercepts.data())); 484 reinterpret_cast<SkScalar*>(intercepts.data()));
457 } 485 }
458 486
459 static inline FloatRect pixelSnappedSelectionRect(FloatRect rect) { 487 static inline FloatRect pixelSnappedSelectionRect(FloatRect rect) {
460 // Using roundf() rather than ceilf() for the right edge as a compromise to 488 // Using roundf() rather than ceilf() for the right edge as a compromise to
461 // ensure correct caret positioning. 489 // ensure correct caret positioning.
462 float roundedX = roundf(rect.x()); 490 float roundedX = roundf(rect.x());
463 return FloatRect(roundedX, rect.y(), roundf(rect.maxX() - roundedX), 491 return FloatRect(roundedX, rect.y(), roundf(rect.maxX() - roundedX),
464 rect.height()); 492 rect.height());
465 } 493 }
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 648
621 bool Font::loadingCustomFonts() const { 649 bool Font::loadingCustomFonts() const {
622 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); 650 return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts();
623 } 651 }
624 652
625 bool Font::isFallbackValid() const { 653 bool Font::isFallbackValid() const {
626 return !m_fontFallbackList || m_fontFallbackList->isValid(); 654 return !m_fontFallbackList || m_fontFallbackList->isValid();
627 } 655 }
628 656
629 } // namespace blink 657 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698