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 |