| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 Google Inc. All rights reserved. | 2 * Copyright (c) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 private: | 65 private: |
| 66 T* m_ptr; | 66 T* m_ptr; |
| 67 DestroyFunction m_destroy; | 67 DestroyFunction m_destroy; |
| 68 }; | 68 }; |
| 69 | 69 |
| 70 static inline float harfbuzzPositionToFloat(hb_position_t value) | 70 static inline float harfbuzzPositionToFloat(hb_position_t value) |
| 71 { | 71 { |
| 72 return static_cast<float>(value) / (1 << 16); | 72 return static_cast<float>(value) / (1 << 16); |
| 73 } | 73 } |
| 74 | 74 |
| 75 HarfBuzzShaper::HarfBuzzRun::HarfBuzzRun(const SimpleFontData* fontData, unsigne
d startIndex, unsigned numCharacters, TextDirection direction) | 75 HarfBuzzShaper::HarfBuzzRun::HarfBuzzRun(const SimpleFontData* fontData, unsigne
d startIndex, unsigned numCharacters, TextDirection direction, hb_script_t scrip
t) |
| 76 : m_fontData(fontData) | 76 : m_fontData(fontData) |
| 77 , m_startIndex(startIndex) | 77 , m_startIndex(startIndex) |
| 78 , m_numCharacters(numCharacters) | 78 , m_numCharacters(numCharacters) |
| 79 , m_direction(direction) | 79 , m_direction(direction) |
| 80 , m_script(script) |
| 80 { | 81 { |
| 81 } | 82 } |
| 82 | 83 |
| 83 void HarfBuzzShaper::HarfBuzzRun::applyShapeResult(hb_buffer_t* harfbuzzBuffer) | 84 void HarfBuzzShaper::HarfBuzzRun::applyShapeResult(hb_buffer_t* harfbuzzBuffer) |
| 84 { | 85 { |
| 85 m_numGlyphs = hb_buffer_get_length(harfbuzzBuffer); | 86 m_numGlyphs = hb_buffer_get_length(harfbuzzBuffer); |
| 86 m_glyphs.resize(m_numGlyphs); | 87 m_glyphs.resize(m_numGlyphs); |
| 87 m_advances.resize(m_numGlyphs); | 88 m_advances.resize(m_numGlyphs); |
| 88 m_glyphToCharacterIndexes.resize(m_numGlyphs); | 89 m_glyphToCharacterIndexes.resize(m_numGlyphs); |
| 89 m_offsets.resize(m_numGlyphs); | 90 m_offsets.resize(m_numGlyphs); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 m_features.append(feature); | 224 m_features.append(feature); |
| 224 } | 225 } |
| 225 } | 226 } |
| 226 | 227 |
| 227 bool HarfBuzzShaper::shape(GlyphBuffer* glyphBuffer) | 228 bool HarfBuzzShaper::shape(GlyphBuffer* glyphBuffer) |
| 228 { | 229 { |
| 229 if (!collectHarfBuzzRuns()) | 230 if (!collectHarfBuzzRuns()) |
| 230 return false; | 231 return false; |
| 231 | 232 |
| 232 m_totalWidth = 0; | 233 m_totalWidth = 0; |
| 233 if (!shapeHarfBuzzRuns()) | 234 // WebKit doesn't set direction when calulating widths. Leave the direction
setting to |
| 235 // HarfBuzz when we are calculating widths (except when directionalOverride(
) is set). |
| 236 if (!shapeHarfBuzzRuns(glyphBuffer || m_run.directionalOverride())) |
| 234 return false; | 237 return false; |
| 235 m_totalWidth = roundf(m_totalWidth); | 238 m_totalWidth = roundf(m_totalWidth); |
| 236 | 239 |
| 237 if (glyphBuffer && !fillGlyphBuffer(glyphBuffer)) | 240 if (glyphBuffer && !fillGlyphBuffer(glyphBuffer)) |
| 238 return false; | 241 return false; |
| 239 | 242 |
| 240 return true; | 243 return true; |
| 241 } | 244 } |
| 242 | 245 |
| 243 FloatPoint HarfBuzzShaper::adjustStartPoint(const FloatPoint& point) | 246 FloatPoint HarfBuzzShaper::adjustStartPoint(const FloatPoint& point) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 nextScript = uscript_getScript(character, &errorCode); | 297 nextScript = uscript_getScript(character, &errorCode); |
| 295 if (U_FAILURE(errorCode)) | 298 if (U_FAILURE(errorCode)) |
| 296 return false; | 299 return false; |
| 297 if ((nextFontData != currentFontData) || ((currentScript != nextScri
pt) && (nextScript != USCRIPT_INHERITED))) | 300 if ((nextFontData != currentFontData) || ((currentScript != nextScri
pt) && (nextScript != USCRIPT_INHERITED))) |
| 298 break; | 301 break; |
| 299 if (nextScript == USCRIPT_INHERITED) | 302 if (nextScript == USCRIPT_INHERITED) |
| 300 nextScript = currentScript; | 303 nextScript = currentScript; |
| 301 currentCharacterPosition = iterator.characters(); | 304 currentCharacterPosition = iterator.characters(); |
| 302 } | 305 } |
| 303 unsigned numCharactersOfCurrentRun = iterator.currentCharacter() - start
IndexOfCurrentRun; | 306 unsigned numCharactersOfCurrentRun = iterator.currentCharacter() - start
IndexOfCurrentRun; |
| 304 m_harfbuzzRuns.append(HarfBuzzRun::create(currentFontData, startIndexOfC
urrentRun, numCharactersOfCurrentRun, m_run.direction())); | 307 hb_script_t script = hb_icu_script_to_script(currentScript); |
| 308 m_harfbuzzRuns.append(HarfBuzzRun::create(currentFontData, startIndexOfC
urrentRun, numCharactersOfCurrentRun, m_run.direction(), script)); |
| 305 currentFontData = nextFontData; | 309 currentFontData = nextFontData; |
| 306 startIndexOfCurrentRun = iterator.currentCharacter(); | 310 startIndexOfCurrentRun = iterator.currentCharacter(); |
| 307 } while (iterator.consume(character, clusterLength)); | 311 } while (iterator.consume(character, clusterLength)); |
| 308 | 312 |
| 309 return !m_harfbuzzRuns.isEmpty(); | 313 return !m_harfbuzzRuns.isEmpty(); |
| 310 } | 314 } |
| 311 | 315 |
| 312 bool HarfBuzzShaper::shapeHarfBuzzRuns() | 316 bool HarfBuzzShaper::shapeHarfBuzzRuns(bool shouldSetDirection) |
| 313 { | 317 { |
| 314 HarfBuzzScopedPtr<hb_buffer_t> harfbuzzBuffer(hb_buffer_create(), hb_buffer_
destroy); | 318 HarfBuzzScopedPtr<hb_buffer_t> harfbuzzBuffer(hb_buffer_create(), hb_buffer_
destroy); |
| 315 | 319 |
| 316 hb_buffer_set_unicode_funcs(harfbuzzBuffer.get(), hb_icu_get_unicode_funcs()
); | 320 hb_buffer_set_unicode_funcs(harfbuzzBuffer.get(), hb_icu_get_unicode_funcs()
); |
| 317 if (m_run.rtl() || m_run.directionalOverride()) | |
| 318 hb_buffer_set_direction(harfbuzzBuffer.get(), m_run.rtl() ? HB_DIRECTION
_RTL : HB_DIRECTION_LTR); | |
| 319 | 321 |
| 320 for (unsigned i = 0; i < m_harfbuzzRuns.size(); ++i) { | 322 for (unsigned i = 0; i < m_harfbuzzRuns.size(); ++i) { |
| 321 unsigned runIndex = m_run.rtl() ? m_harfbuzzRuns.size() - i - 1 : i; | 323 unsigned runIndex = m_run.rtl() ? m_harfbuzzRuns.size() - i - 1 : i; |
| 322 HarfBuzzRun* currentRun = m_harfbuzzRuns[runIndex].get(); | 324 HarfBuzzRun* currentRun = m_harfbuzzRuns[runIndex].get(); |
| 323 const SimpleFontData* currentFontData = currentRun->fontData(); | 325 const SimpleFontData* currentFontData = currentRun->fontData(); |
| 324 | 326 |
| 327 hb_buffer_set_script(harfbuzzBuffer.get(), currentRun->script()); |
| 328 if (shouldSetDirection) |
| 329 hb_buffer_set_direction(harfbuzzBuffer.get(), currentRun->rtl() ? HB
_DIRECTION_RTL : HB_DIRECTION_LTR); |
| 330 |
| 325 // Add a space as pre-context to the buffer. This prevents showing dotte
d-circle | 331 // Add a space as pre-context to the buffer. This prevents showing dotte
d-circle |
| 326 // for combining marks at the beginning of runs. | 332 // for combining marks at the beginning of runs. |
| 327 static const uint16_t preContext = ' '; | 333 static const uint16_t preContext = ' '; |
| 328 hb_buffer_add_utf16(harfbuzzBuffer.get(), &preContext, 1, 1, 0); | 334 hb_buffer_add_utf16(harfbuzzBuffer.get(), &preContext, 1, 1, 0); |
| 329 | 335 |
| 330 if (m_font->isSmallCaps() && u_islower(m_normalizedBuffer[currentRun->st
artIndex()])) { | 336 if (m_font->isSmallCaps() && u_islower(m_normalizedBuffer[currentRun->st
artIndex()])) { |
| 331 String upperText = String(m_normalizedBuffer.get() + currentRun->sta
rtIndex(), currentRun->numCharacters()); | 337 String upperText = String(m_normalizedBuffer.get() + currentRun->sta
rtIndex(), currentRun->numCharacters()); |
| 332 upperText.makeUpper(); | 338 upperText.makeUpper(); |
| 333 currentFontData = m_font->glyphDataForCharacter(upperText[0], false,
SmallCapsVariant).fontData; | 339 currentFontData = m_font->glyphDataForCharacter(upperText[0], false,
SmallCapsVariant).fontData; |
| 334 hb_buffer_add_utf16(harfbuzzBuffer.get(), upperText.characters(), cu
rrentRun->numCharacters(), 0, currentRun->numCharacters()); | 340 hb_buffer_add_utf16(harfbuzzBuffer.get(), upperText.characters(), cu
rrentRun->numCharacters(), 0, currentRun->numCharacters()); |
| 335 } else | 341 } else |
| 336 hb_buffer_add_utf16(harfbuzzBuffer.get(), m_normalizedBuffer.get() +
currentRun->startIndex(), currentRun->numCharacters(), 0, currentRun->numCharac
ters()); | 342 hb_buffer_add_utf16(harfbuzzBuffer.get(), m_normalizedBuffer.get() +
currentRun->startIndex(), currentRun->numCharacters(), 0, currentRun->numCharac
ters()); |
| 337 | 343 |
| 338 FontPlatformData* platformData = const_cast<FontPlatformData*>(¤tF
ontData->platformData()); | 344 FontPlatformData* platformData = const_cast<FontPlatformData*>(¤tF
ontData->platformData()); |
| 339 HarfBuzzNGFace* face = platformData->harfbuzzFace(); | 345 HarfBuzzNGFace* face = platformData->harfbuzzFace(); |
| 340 if (!face) | 346 if (!face) |
| 341 return false; | 347 return false; |
| 342 | 348 |
| 343 if (m_font->fontDescription().orientation() == Vertical) | 349 if (m_font->fontDescription().orientation() == Vertical) |
| 344 face->setScriptForVerticalGlyphSubstitution(harfbuzzBuffer.get()); | 350 face->setScriptForVerticalGlyphSubstitution(harfbuzzBuffer.get()); |
| 345 | 351 |
| 346 HarfBuzzScopedPtr<hb_font_t> harfbuzzFont(face->createFont(), hb_font_de
stroy); | 352 HarfBuzzScopedPtr<hb_font_t> harfbuzzFont(face->createFont(), hb_font_de
stroy); |
| 347 | 353 |
| 348 hb_shape(harfbuzzFont.get(), harfbuzzBuffer.get(), m_features.isEmpty()
? 0 : m_features.data(), m_features.size()); | 354 hb_shape(harfbuzzFont.get(), harfbuzzBuffer.get(), m_features.isEmpty()
? 0 : m_features.data(), m_features.size()); |
| 349 | 355 |
| 350 currentRun->applyShapeResult(harfbuzzBuffer.get()); | 356 currentRun->applyShapeResult(harfbuzzBuffer.get()); |
| 351 setGlyphPositionsForHarfBuzzRun(currentRun, harfbuzzBuffer.get()); | 357 setGlyphPositionsForHarfBuzzRun(currentRun, harfbuzzBuffer.get()); |
| 352 | 358 |
| 353 hb_buffer_reset(harfbuzzBuffer.get()); | 359 hb_buffer_reset(harfbuzzBuffer.get()); |
| 354 if (m_run.rtl() || m_run.directionalOverride()) | |
| 355 hb_buffer_set_direction(harfbuzzBuffer.get(), m_run.rtl() ? HB_DIREC
TION_RTL : HB_DIRECTION_LTR); | |
| 356 } | 360 } |
| 357 | 361 |
| 358 return true; | 362 return true; |
| 359 } | 363 } |
| 360 | 364 |
| 361 void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb
_buffer_t* harfbuzzBuffer) | 365 void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb
_buffer_t* harfbuzzBuffer) |
| 362 { | 366 { |
| 363 const SimpleFontData* currentFontData = currentRun->fontData(); | 367 const SimpleFontData* currentFontData = currentRun->fontData(); |
| 364 hb_glyph_info_t* glyphInfos = hb_buffer_get_glyph_infos(harfbuzzBuffer, 0); | 368 hb_glyph_info_t* glyphInfos = hb_buffer_get_glyph_infos(harfbuzzBuffer, 0); |
| 365 hb_glyph_position_t* glyphPositions = hb_buffer_get_glyph_positions(harfbuzz
Buffer, 0); | 369 hb_glyph_position_t* glyphPositions = hb_buffer_get_glyph_positions(harfbuzz
Buffer, 0); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 if (!foundToX) | 534 if (!foundToX) |
| 531 toX = m_run.rtl() ? 0 : m_totalWidth; | 535 toX = m_run.rtl() ? 0 : m_totalWidth; |
| 532 | 536 |
| 533 // Using floorf() and roundf() as the same as mac port. | 537 // Using floorf() and roundf() as the same as mac port. |
| 534 if (fromX < toX) | 538 if (fromX < toX) |
| 535 return FloatRect(floorf(point.x() + fromX), point.y(), roundf(toX - from
X), height); | 539 return FloatRect(floorf(point.x() + fromX), point.y(), roundf(toX - from
X), height); |
| 536 return FloatRect(floorf(point.x() + toX), point.y(), roundf(fromX - toX), he
ight); | 540 return FloatRect(floorf(point.x() + toX), point.y(), roundf(fromX - toX), he
ight); |
| 537 } | 541 } |
| 538 | 542 |
| 539 } // namespace WebCore | 543 } // namespace WebCore |
| OLD | NEW |