| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |