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

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

Issue 1806653002: Shape unicode-range: font faces in only one iteration (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update UnicodeRangeSetTests to RefPtrtr, rm copy constructor and test Created 4 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 Google Inc. All rights reserved. 2 * Copyright (c) 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2013 BlackBerry Limited. All rights reserved. 3 * Copyright (C) 2013 BlackBerry Limited. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 } else { 268 } else {
269 hb_buffer_add_utf16(buffer, toUint16(normalizedBuffer), 269 hb_buffer_add_utf16(buffer, toUint16(normalizedBuffer),
270 normalizedBufferLength, startIndex, numCharacters); 270 normalizedBufferLength, startIndex, numCharacters);
271 } 271 }
272 } 272 }
273 273
274 inline bool HarfBuzzShaper::shapeRange(hb_buffer_t* harfBuzzBuffer, 274 inline bool HarfBuzzShaper::shapeRange(hb_buffer_t* harfBuzzBuffer,
275 unsigned startIndex, 275 unsigned startIndex,
276 unsigned numCharacters, 276 unsigned numCharacters,
277 const SimpleFontData* currentFont, 277 const SimpleFontData* currentFont,
278 unsigned currentFontRangeFrom, 278 PassRefPtr<UnicodeRangeSet> currentFontRangeSet,
279 unsigned currentFontRangeTo,
280 UScriptCode currentRunScript, 279 UScriptCode currentRunScript,
281 hb_language_t language) 280 hb_language_t language)
282 { 281 {
283 const FontPlatformData* platformData = &(currentFont->platformData()); 282 const FontPlatformData* platformData = &(currentFont->platformData());
284 HarfBuzzFace* face = platformData->harfBuzzFace(); 283 HarfBuzzFace* face = platformData->harfBuzzFace();
285 if (!face) { 284 if (!face) {
286 WTF_LOG_ERROR("Could not create HarfBuzzFace from FontPlatformData."); 285 WTF_LOG_ERROR("Could not create HarfBuzzFace from FontPlatformData.");
287 return false; 286 return false;
288 } 287 }
289 288
290 hb_buffer_set_language(harfBuzzBuffer, language); 289 hb_buffer_set_language(harfBuzzBuffer, language);
291 hb_buffer_set_script(harfBuzzBuffer, ICUScriptToHBScript(currentRunScript)); 290 hb_buffer_set_script(harfBuzzBuffer, ICUScriptToHBScript(currentRunScript));
292 hb_buffer_set_direction(harfBuzzBuffer, TextDirectionToHBDirection(m_textRun .direction(), 291 hb_buffer_set_direction(harfBuzzBuffer, TextDirectionToHBDirection(m_textRun .direction(),
293 m_font->getFontDescription().orientation(), currentFont)); 292 m_font->getFontDescription().orientation(), currentFont));
294 293
295 addToHarfBuzzBufferInternal(harfBuzzBuffer, 294 addToHarfBuzzBufferInternal(harfBuzzBuffer,
296 m_font->getFontDescription(), m_normalizedBuffer.get(), m_normalizedBuff erLength, 295 m_font->getFontDescription(), m_normalizedBuffer.get(), m_normalizedBuff erLength,
297 startIndex, numCharacters); 296 startIndex, numCharacters);
298 297
299 HarfBuzzScopedPtr<hb_font_t> harfBuzzFont(face->createFont(currentFontRangeF rom, currentFontRangeTo), hb_font_destroy); 298 HarfBuzzScopedPtr<hb_font_t> harfBuzzFont(face->createFont(currentFontRangeS et), hb_font_destroy);
300 hb_shape(harfBuzzFont.get(), harfBuzzBuffer, m_features.isEmpty() ? 0 : m_fe atures.data(), m_features.size()); 299 hb_shape(harfBuzzFont.get(), harfBuzzBuffer, m_features.isEmpty() ? 0 : m_fe atures.data(), m_features.size());
301 300
302 return true; 301 return true;
303 } 302 }
304 303
305 bool HarfBuzzShaper::extractShapeResults(hb_buffer_t* harfBuzzBuffer, 304 bool HarfBuzzShaper::extractShapeResults(hb_buffer_t* harfBuzzBuffer,
306 ShapeResult* shapeResult, 305 ShapeResult* shapeResult,
307 bool& fontCycleQueued, const HolesQueueItem& currentQueueItem, 306 bool& fontCycleQueued, const HolesQueueItem& currentQueueItem,
308 const SimpleFontData* currentFont, 307 const SimpleFontData* currentFont,
309 UScriptCode currentRunScript, 308 UScriptCode currentRunScript,
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 // segmentation plays a role here, does the new scriptRuniterator handle tha t correctly? 504 // segmentation plays a role here, does the new scriptRuniterator handle tha t correctly?
506 while (runSegmenter.consume(&segmentRange)) { 505 while (runSegmenter.consume(&segmentRange)) {
507 RefPtr<FontFallbackIterator> fallbackIterator = 506 RefPtr<FontFallbackIterator> fallbackIterator =
508 m_font->createFontFallbackIterator( 507 m_font->createFontFallbackIterator(
509 segmentRange.fontFallbackPriority); 508 segmentRange.fontFallbackPriority);
510 509
511 appendToHolesQueue(HolesQueueNextFont, 0, 0); 510 appendToHolesQueue(HolesQueueNextFont, 0, 0);
512 appendToHolesQueue(HolesQueueRange, segmentRange.start, segmentRange.end - segmentRange.start); 511 appendToHolesQueue(HolesQueueRange, segmentRange.start, segmentRange.end - segmentRange.start);
513 512
514 const SimpleFontData* currentFont = nullptr; 513 const SimpleFontData* currentFont = nullptr;
515 unsigned currentFontRangeFrom = 0; 514 RefPtr<UnicodeRangeSet> currentFontRangeSet;
516 unsigned currentFontRangeTo = 0;
517 515
518 bool fontCycleQueued = false; 516 bool fontCycleQueued = false;
519 while (m_holesQueue.size()) { 517 while (m_holesQueue.size()) {
520 HolesQueueItem currentQueueItem = m_holesQueue.takeFirst(); 518 HolesQueueItem currentQueueItem = m_holesQueue.takeFirst();
521 519
522 if (currentQueueItem.m_action == HolesQueueNextFont) { 520 if (currentQueueItem.m_action == HolesQueueNextFont) {
523 // For now, we're building a character list with which we probe 521 // For now, we're building a character list with which we probe
524 // for needed fonts depending on the declared unicode-range of a 522 // for needed fonts depending on the declared unicode-range of a
525 // segmented CSS font. Alternatively, we can build a fake font 523 // segmented CSS font. Alternatively, we can build a fake font
526 // for the shaper and check whether any glyphs were found, or 524 // for the shaper and check whether any glyphs were found, or
527 // define a new API on the shaper which will give us coverage 525 // define a new API on the shaper which will give us coverage
528 // information? 526 // information?
529 if (!collectFallbackHintChars(fallbackCharsHint, fallbackIterato r->needsHintList())) { 527 if (!collectFallbackHintChars(fallbackCharsHint, fallbackIterato r->needsHintList())) {
530 // Give up shaping since we cannot retrieve a font fallback 528 // Give up shaping since we cannot retrieve a font fallback
531 // font without a hintlist. 529 // font without a hintlist.
532 m_holesQueue.clear(); 530 m_holesQueue.clear();
533 break; 531 break;
534 } 532 }
535 533
536 FontDataRange nextFontDataRange = fallbackIterator->next(fallbac kCharsHint); 534 FontDataForRangeSet nextFontDataForRangeSet = fallbackIterator-> next(fallbackCharsHint);
537 currentFont = nextFontDataRange.fontData().get(); 535 currentFont = nextFontDataForRangeSet.fontData().get();
538 currentFontRangeFrom = nextFontDataRange.from(); 536 currentFontRangeSet = nextFontDataForRangeSet.ranges();
539 currentFontRangeTo = nextFontDataRange.to(); 537
540 if (!currentFont) { 538 if (!currentFont) {
541 ASSERT(!m_holesQueue.size()); 539 ASSERT(!m_holesQueue.size());
542 break; 540 break;
543 } 541 }
544 fontCycleQueued = false; 542 fontCycleQueued = false;
545 continue; 543 continue;
546 } 544 }
547 545
548 // TODO crbug.com/522964: Only use smallCapsFontData when the font d oes not support true smcp. The spec 546 // TODO crbug.com/522964: Only use smallCapsFontData when the font d oes not support true smcp. The spec
549 // says: "To match the surrounding text, a font may provide alternat e glyphs for caseless characters when 547 // says: "To match the surrounding text, a font may provide alternat e glyphs for caseless characters when
550 // these features are enabled but when a user agent simulates small capitals, it must not attempt to 548 // these features are enabled but when a user agent simulates small capitals, it must not attempt to
551 // simulate alternates for codepoints which are considered caseless. " 549 // simulate alternates for codepoints which are considered caseless. "
552 const SimpleFontData* smallcapsAdjustedFont = segmentRange.smallCaps Behavior == SmallCapsIterator::SmallCapsUppercaseNeeded 550 const SimpleFontData* smallcapsAdjustedFont = segmentRange.smallCaps Behavior == SmallCapsIterator::SmallCapsUppercaseNeeded
553 ? currentFont->smallCapsFontData(fontDescription).get() 551 ? currentFont->smallCapsFontData(fontDescription).get()
554 : currentFont; 552 : currentFont;
555 553
556 // Compatibility with SimpleFontData approach of keeping a flag for overriding drawing direction. 554 // Compatibility with SimpleFontData approach of keeping a flag for overriding drawing direction.
557 // TODO: crbug.com/506224 This should go away in favor of storing th at information elsewhere, for example in 555 // TODO: crbug.com/506224 This should go away in favor of storing th at information elsewhere, for example in
558 // ShapeResult. 556 // ShapeResult.
559 const SimpleFontData* directionAndSmallCapsAdjustedFont = fontDataAd justedForOrientation(smallcapsAdjustedFont, 557 const SimpleFontData* directionAndSmallCapsAdjustedFont = fontDataAd justedForOrientation(smallcapsAdjustedFont,
560 m_font->getFontDescription().orientation(), 558 m_font->getFontDescription().orientation(),
561 segmentRange.renderOrientation); 559 segmentRange.renderOrientation);
562 560
563 if (!shapeRange(harfBuzzBuffer.get(), 561 if (!shapeRange(harfBuzzBuffer.get(),
564 currentQueueItem.m_startIndex, 562 currentQueueItem.m_startIndex,
565 currentQueueItem.m_numCharacters, 563 currentQueueItem.m_numCharacters,
566 directionAndSmallCapsAdjustedFont, 564 directionAndSmallCapsAdjustedFont,
567 currentFontRangeFrom, 565 currentFontRangeSet,
568 currentFontRangeTo,
569 segmentRange.script, 566 segmentRange.script,
570 language)) 567 language))
571 WTF_LOG_ERROR("Shaping range failed."); 568 WTF_LOG_ERROR("Shaping range failed.");
572 569
573 if (!extractShapeResults(harfBuzzBuffer.get(), 570 if (!extractShapeResults(harfBuzzBuffer.get(),
574 result.get(), 571 result.get(),
575 fontCycleQueued, 572 fontCycleQueued,
576 currentQueueItem, 573 currentQueueItem,
577 directionAndSmallCapsAdjustedFont, 574 directionAndSmallCapsAdjustedFont,
578 segmentRange.script, 575 segmentRange.script,
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 result->m_width = run->m_width; 679 result->m_width = run->m_width;
683 result->m_numGlyphs = count; 680 result->m_numGlyphs = count;
684 ASSERT(result->m_numGlyphs == count); // no overflow 681 ASSERT(result->m_numGlyphs == count); // no overflow
685 result->m_hasVerticalOffsets = fontData->platformData().isVerticalAnyUpright (); 682 result->m_hasVerticalOffsets = fontData->platformData().isVerticalAnyUpright ();
686 result->m_runs.append(run.release()); 683 result->m_runs.append(run.release());
687 return result.release(); 684 return result.release();
688 } 685 }
689 686
690 687
691 } // namespace blink 688 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698