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