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

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

Issue 1173533004: Rename m_run to m_textRun in Shaper (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 6 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
« no previous file with comments | « no previous file | Source/platform/fonts/shaping/Shaper.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 } 371 }
372 372
373 HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run, const Glyph Data* emphasisData, 373 HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run, const Glyph Data* emphasisData,
374 HashSet<const SimpleFontData*>* fallbackFonts, FloatRect* bounds) 374 HashSet<const SimpleFontData*>* fallbackFonts, FloatRect* bounds)
375 : Shaper(font, run, emphasisData, fallbackFonts, bounds) 375 : Shaper(font, run, emphasisData, fallbackFonts, bounds)
376 , m_normalizedBufferLength(0) 376 , m_normalizedBufferLength(0)
377 , m_wordSpacingAdjustment(font->fontDescription().wordSpacing()) 377 , m_wordSpacingAdjustment(font->fontDescription().wordSpacing())
378 , m_letterSpacing(font->fontDescription().letterSpacing()) 378 , m_letterSpacing(font->fontDescription().letterSpacing())
379 , m_expansionOpportunityCount(0) 379 , m_expansionOpportunityCount(0)
380 , m_fromIndex(0) 380 , m_fromIndex(0)
381 , m_toIndex(m_run.length()) 381 , m_toIndex(m_textRun.length())
382 , m_totalWidth(0) 382 , m_totalWidth(0)
383 { 383 {
384 m_normalizedBuffer = adoptArrayPtr(new UChar[m_run.length() + 1]); 384 m_normalizedBuffer = adoptArrayPtr(new UChar[m_textRun.length() + 1]);
385 normalizeCharacters(m_run, m_run.length(), m_normalizedBuffer.get(), &m_norm alizedBufferLength); 385 normalizeCharacters(m_textRun, m_textRun.length(), m_normalizedBuffer.get(), &m_normalizedBufferLength);
386 setExpansion(m_run.expansion()); 386 setExpansion(m_textRun.expansion());
387 setFontFeatures(); 387 setFontFeatures();
388 } 388 }
389 389
390 float HarfBuzzShaper::nextExpansionPerOpportunity() 390 float HarfBuzzShaper::nextExpansionPerOpportunity()
391 { 391 {
392 if (!m_expansionOpportunityCount) { 392 if (!m_expansionOpportunityCount) {
393 ASSERT_NOT_REACHED(); // failures indicate that the logic in HarfBuzzSha per does not match to the one in expansionOpportunityCount() 393 ASSERT_NOT_REACHED(); // failures indicate that the logic in HarfBuzzSha per does not match to the one in expansionOpportunityCount()
394 return 0; 394 return 0;
395 } 395 }
396 if (!--m_expansionOpportunityCount) { 396 if (!--m_expansionOpportunityCount) {
397 float remaining = m_expansion; 397 float remaining = m_expansion;
398 m_expansion = 0; 398 m_expansion = 0;
399 return remaining; 399 return remaining;
400 } 400 }
401 m_expansion -= m_expansionPerOpportunity; 401 m_expansion -= m_expansionPerOpportunity;
402 return m_expansionPerOpportunity; 402 return m_expansionPerOpportunity;
403 } 403 }
404 404
405 // setPadding sets a number of pixels to be distributed across the TextRun. 405 // setPadding sets a number of pixels to be distributed across the TextRun.
406 // WebKit uses this to justify text. 406 // WebKit uses this to justify text.
407 void HarfBuzzShaper::setExpansion(float padding) 407 void HarfBuzzShaper::setExpansion(float padding)
408 { 408 {
409 m_expansion = padding; 409 m_expansion = padding;
410 if (!m_expansion) 410 if (!m_expansion)
411 return; 411 return;
412 412
413 // If we have padding to distribute, then we try to give an equal 413 // If we have padding to distribute, then we try to give an equal
414 // amount to each expansion opportunity. 414 // amount to each expansion opportunity.
415 bool isAfterExpansion = m_isAfterExpansion; 415 bool isAfterExpansion = m_isAfterExpansion;
416 m_expansionOpportunityCount = Character::expansionOpportunityCount(m_normali zedBuffer.get(), m_normalizedBufferLength, m_run.direction(), isAfterExpansion, m_run.textJustify()); 416 m_expansionOpportunityCount = Character::expansionOpportunityCount(m_normali zedBuffer.get(), m_normalizedBufferLength, m_textRun.direction(), isAfterExpansi on, m_textRun.textJustify());
417 if (isAfterExpansion && !m_run.allowsTrailingExpansion()) { 417 if (isAfterExpansion && !m_textRun.allowsTrailingExpansion()) {
418 ASSERT(m_expansionOpportunityCount > 0); 418 ASSERT(m_expansionOpportunityCount > 0);
419 --m_expansionOpportunityCount; 419 --m_expansionOpportunityCount;
420 } 420 }
421 421
422 if (m_expansionOpportunityCount) 422 if (m_expansionOpportunityCount)
423 m_expansionPerOpportunity = m_expansion / m_expansionOpportunityCount; 423 m_expansionPerOpportunity = m_expansion / m_expansionOpportunityCount;
424 else 424 else
425 m_expansionPerOpportunity = 0; 425 m_expansionPerOpportunity = 0;
426 } 426 }
427 427
428 428
429 void HarfBuzzShaper::setDrawRange(int from, int to) 429 void HarfBuzzShaper::setDrawRange(int from, int to)
430 { 430 {
431 ASSERT_WITH_SECURITY_IMPLICATION(from >= 0); 431 ASSERT_WITH_SECURITY_IMPLICATION(from >= 0);
432 ASSERT_WITH_SECURITY_IMPLICATION(to <= m_run.length()); 432 ASSERT_WITH_SECURITY_IMPLICATION(to <= m_textRun.length());
433 m_fromIndex = from; 433 m_fromIndex = from;
434 m_toIndex = to; 434 m_toIndex = to;
435 } 435 }
436 436
437 void HarfBuzzShaper::setFontFeatures() 437 void HarfBuzzShaper::setFontFeatures()
438 { 438 {
439 const FontDescription& description = m_font->fontDescription(); 439 const FontDescription& description = m_font->fontDescription();
440 440
441 static hb_feature_t noKern = { HB_TAG('k', 'e', 'r', 'n'), 0, 0, static_cast <unsigned>(-1) }; 441 static hb_feature_t noKern = { HB_TAG('k', 'e', 'r', 'n'), 0, 0, static_cast <unsigned>(-1) };
442 static hb_feature_t noVkrn = { HB_TAG('v', 'k', 'r', 'n'), 0, 0, static_cast <unsigned>(-1) }; 442 static hb_feature_t noVkrn = { HB_TAG('v', 'k', 'r', 'n'), 0, 0, static_cast <unsigned>(-1) };
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 } 692 }
693 693
694 // For ideographic (CJK) documents, 90-95% of calls from width() are one charact er length 694 // For ideographic (CJK) documents, 90-95% of calls from width() are one charact er length
695 // because most characters have break opportunities both before and after. 695 // because most characters have break opportunities both before and after.
696 bool HarfBuzzShaper::createHarfBuzzRunsForSingleCharacter() 696 bool HarfBuzzShaper::createHarfBuzzRunsForSingleCharacter()
697 { 697 {
698 ASSERT(m_normalizedBufferLength == 1); 698 ASSERT(m_normalizedBufferLength == 1);
699 UChar32 character = m_normalizedBuffer[0]; 699 UChar32 character = m_normalizedBuffer[0];
700 if (!U16_IS_SINGLE(character)) 700 if (!U16_IS_SINGLE(character))
701 return false; 701 return false;
702 const SimpleFontData* fontData = m_font->glyphDataForCharacter(character, fa lse, m_run.normalizeSpace()).fontData; 702 const SimpleFontData* fontData = m_font->glyphDataForCharacter(character, fa lse, m_textRun.normalizeSpace()).fontData;
703 UErrorCode errorCode = U_ZERO_ERROR; 703 UErrorCode errorCode = U_ZERO_ERROR;
704 UScriptCode script = uscript_getScript(character, &errorCode); 704 UScriptCode script = uscript_getScript(character, &errorCode);
705 if (U_FAILURE(errorCode)) 705 if (U_FAILURE(errorCode))
706 return false; 706 return false;
707 addHarfBuzzRun(0, 1, fontData, script); 707 addHarfBuzzRun(0, 1, fontData, script);
708 return true; 708 return true;
709 } 709 }
710 710
711 bool HarfBuzzShaper::createHarfBuzzRuns() 711 bool HarfBuzzShaper::createHarfBuzzRuns()
712 { 712 {
713 if (m_normalizedBufferLength == 1) 713 if (m_normalizedBufferLength == 1)
714 return createHarfBuzzRunsForSingleCharacter(); 714 return createHarfBuzzRunsForSingleCharacter();
715 715
716 Vector<CandidateRun> candidateRuns; 716 Vector<CandidateRun> candidateRuns;
717 if (!collectCandidateRuns(m_normalizedBuffer.get(), 717 if (!collectCandidateRuns(m_normalizedBuffer.get(),
718 m_normalizedBufferLength, m_font, &candidateRuns, m_run.normalizeSpace() )) 718 m_normalizedBufferLength, m_font, &candidateRuns, m_textRun.normalizeSpa ce()))
719 return false; 719 return false;
720 720
721 if (!resolveCandidateRuns(candidateRuns)) 721 if (!resolveCandidateRuns(candidateRuns))
722 return false; 722 return false;
723 723
724 size_t length = candidateRuns.size(); 724 size_t length = candidateRuns.size();
725 for (size_t i = 0; i < length; ) { 725 for (size_t i = 0; i < length; ) {
726 CandidateRun& run = candidateRuns[i]; 726 CandidateRun& run = candidateRuns[i];
727 CandidateRun lastMatchingRun = run; 727 CandidateRun lastMatchingRun = run;
728 for (i++; i < length; i++) { 728 for (i++; i < length; i++) {
(...skipping 26 matching lines...) Expand all
755 void HarfBuzzShaper::addHarfBuzzRun(unsigned startCharacter, 755 void HarfBuzzShaper::addHarfBuzzRun(unsigned startCharacter,
756 unsigned endCharacter, const SimpleFontData* fontData, 756 unsigned endCharacter, const SimpleFontData* fontData,
757 UScriptCode script) 757 UScriptCode script)
758 { 758 {
759 ASSERT(endCharacter > startCharacter); 759 ASSERT(endCharacter > startCharacter);
760 ASSERT(script != USCRIPT_INVALID_CODE); 760 ASSERT(script != USCRIPT_INVALID_CODE);
761 if (m_fallbackFonts) 761 if (m_fallbackFonts)
762 trackNonPrimaryFallbackFont(fontData); 762 trackNonPrimaryFallbackFont(fontData);
763 return m_harfBuzzRuns.append(HarfBuzzRun::create(fontData, 763 return m_harfBuzzRuns.append(HarfBuzzRun::create(fontData,
764 startCharacter, endCharacter - startCharacter, 764 startCharacter, endCharacter - startCharacter,
765 TextDirectionToHBDirection(m_run.direction(), m_font->fontDescription(). orientation(), fontData), 765 TextDirectionToHBDirection(m_textRun.direction(), m_font->fontDescriptio n().orientation(), fontData),
766 ICUScriptToHBScript(script))); 766 ICUScriptToHBScript(script)));
767 } 767 }
768 768
769 static inline bool isValidCachedResult(const Font* font, hb_direction_t dir, 769 static inline bool isValidCachedResult(const Font* font, hb_direction_t dir,
770 const String& localeString, const CachedShapingResults* cachedResults) 770 const String& localeString, const CachedShapingResults* cachedResults)
771 { 771 {
772 ASSERT(cachedResults); 772 ASSERT(cachedResults);
773 return cachedResults->dir == dir 773 return cachedResults->dir == dir
774 && cachedResults->font == *font 774 && cachedResults->font == *font
775 && !cachedResults->font.loadingCustomFonts() 775 && !cachedResults->font.loadingCustomFonts()
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 { 809 {
810 HarfBuzzScopedPtr<hb_buffer_t> harfBuzzBuffer(hb_buffer_create(), hb_buffer_ destroy); 810 HarfBuzzScopedPtr<hb_buffer_t> harfBuzzBuffer(hb_buffer_create(), hb_buffer_ destroy);
811 811
812 HarfBuzzRunCache& runCache = harfBuzzRunCache(); 812 HarfBuzzRunCache& runCache = harfBuzzRunCache();
813 const FontDescription& fontDescription = m_font->fontDescription(); 813 const FontDescription& fontDescription = m_font->fontDescription();
814 const String& localeString = fontDescription.locale(); 814 const String& localeString = fontDescription.locale();
815 CString locale = localeString.latin1(); 815 CString locale = localeString.latin1();
816 const hb_language_t language = hb_language_from_string(locale.data(), locale .length()); 816 const hb_language_t language = hb_language_from_string(locale.data(), locale .length());
817 817
818 for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) { 818 for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) {
819 unsigned runIndex = m_run.rtl() ? m_harfBuzzRuns.size() - i - 1 : i; 819 unsigned runIndex = m_textRun.rtl() ? m_harfBuzzRuns.size() - i - 1 : i;
820 HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get(); 820 HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get();
821 821
822 const SimpleFontData* currentFontData = currentRun->fontData(); 822 const SimpleFontData* currentFontData = currentRun->fontData();
823 FontPlatformData* platformData = const_cast<FontPlatformData*>(&currentF ontData->platformData()); 823 FontPlatformData* platformData = const_cast<FontPlatformData*>(&currentF ontData->platformData());
824 HarfBuzzFace* face = platformData->harfBuzzFace(); 824 HarfBuzzFace* face = platformData->harfBuzzFace();
825 if (!face) 825 if (!face)
826 return false; 826 return false;
827 827
828 hb_buffer_set_language(harfBuzzBuffer.get(), language); 828 hb_buffer_set_language(harfBuzzBuffer.get(), language);
829 hb_buffer_set_script(harfBuzzBuffer.get(), currentRun->script()); 829 hb_buffer_set_script(harfBuzzBuffer.get(), currentRun->script());
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 914
915 if (isClusterEnd) 915 if (isClusterEnd)
916 spacing += adjustSpacing(currentRun, i, currentCharacterIndex, *dire ctionOffset, totalAdvance); 916 spacing += adjustSpacing(currentRun, i, currentCharacterIndex, *dire ctionOffset, totalAdvance);
917 917
918 if (currentFontData->isZeroWidthSpaceGlyph(glyph)) { 918 if (currentFontData->isZeroWidthSpaceGlyph(glyph)) {
919 currentRun->setGlyphAndPositions(i, glyph, 0, 0, 0); 919 currentRun->setGlyphAndPositions(i, glyph, 0, 0, 0);
920 continue; 920 continue;
921 } 921 }
922 922
923 advance += spacing; 923 advance += spacing;
924 if (m_run.rtl()) { 924 if (m_textRun.rtl()) {
925 // In RTL, spacing should be added to left side of glyphs. 925 // In RTL, spacing should be added to left side of glyphs.
926 *directionOffset += spacing; 926 *directionOffset += spacing;
927 if (!isClusterEnd) 927 if (!isClusterEnd)
928 *directionOffset += m_letterSpacing; 928 *directionOffset += m_letterSpacing;
929 } 929 }
930 930
931 currentRun->setGlyphAndPositions(i, glyph, advance, offsetX, offsetY); 931 currentRun->setGlyphAndPositions(i, glyph, advance, offsetX, offsetY);
932 932
933 if (m_glyphBoundingBox) { 933 if (m_glyphBoundingBox) {
934 FloatRect glyphBounds = currentFontData->boundsForGlyph(glyph); 934 FloatRect glyphBounds = currentFontData->boundsForGlyph(glyph);
935 glyphBounds.move(glyphOrigin.x(), glyphOrigin.y()); 935 glyphBounds.move(glyphOrigin.x(), glyphOrigin.y());
936 m_glyphBoundingBox->unite(glyphBounds); 936 m_glyphBoundingBox->unite(glyphBounds);
937 glyphOrigin += FloatSize(advance + offsetX, offsetY); 937 glyphOrigin += FloatSize(advance + offsetX, offsetY);
938 } 938 }
939 939
940 totalAdvance += advance; 940 totalAdvance += advance;
941 } 941 }
942 currentRun->setWidth(totalAdvance > 0.0 ? totalAdvance : 0.0); 942 currentRun->setWidth(totalAdvance > 0.0 ? totalAdvance : 0.0);
943 m_totalWidth += currentRun->width(); 943 m_totalWidth += currentRun->width();
944 } 944 }
945 945
946 float HarfBuzzShaper::adjustSpacing(HarfBuzzRun* currentRun, size_t glyphIndex, unsigned currentCharacterIndex, float& offset, float& totalAdvance) 946 float HarfBuzzShaper::adjustSpacing(HarfBuzzRun* currentRun, size_t glyphIndex, unsigned currentCharacterIndex, float& offset, float& totalAdvance)
947 { 947 {
948 float spacing = 0; 948 float spacing = 0;
949 UChar32 character = m_normalizedBuffer[currentCharacterIndex]; 949 UChar32 character = m_normalizedBuffer[currentCharacterIndex];
950 if (m_letterSpacing && !Character::treatAsZeroWidthSpace(character)) 950 if (m_letterSpacing && !Character::treatAsZeroWidthSpace(character))
951 spacing += m_letterSpacing; 951 spacing += m_letterSpacing;
952 952
953 bool treatAsSpace = Character::treatAsSpace(character); 953 bool treatAsSpace = Character::treatAsSpace(character);
954 if (treatAsSpace && currentCharacterIndex && (character != '\t' || !m_run.al lowTabs())) 954 if (treatAsSpace && currentCharacterIndex && (character != '\t' || !m_textRu n.allowTabs()))
955 spacing += m_wordSpacingAdjustment; 955 spacing += m_wordSpacingAdjustment;
956 956
957 if (!m_expansionOpportunityCount) 957 if (!m_expansionOpportunityCount)
958 return spacing; 958 return spacing;
959 959
960 if (treatAsSpace) { 960 if (treatAsSpace) {
961 spacing += nextExpansionPerOpportunity(); 961 spacing += nextExpansionPerOpportunity();
962 m_isAfterExpansion = true; 962 m_isAfterExpansion = true;
963 return spacing; 963 return spacing;
964 } 964 }
965 965
966 if (m_run.textJustify() != TextJustify::TextJustifyAuto) { 966 if (m_textRun.textJustify() != TextJustify::TextJustifyAuto) {
967 m_isAfterExpansion = false; 967 m_isAfterExpansion = false;
968 return spacing; 968 return spacing;
969 } 969 }
970 970
971 // isCJKIdeographOrSymbol() has expansion opportunities both before and afte r each character. 971 // isCJKIdeographOrSymbol() has expansion opportunities both before and afte r each character.
972 // http://www.w3.org/TR/jlreq/#line_adjustment 972 // http://www.w3.org/TR/jlreq/#line_adjustment
973 if (U16_IS_LEAD(character) && currentCharacterIndex + 1 < m_normalizedBuffer Length && U16_IS_TRAIL(m_normalizedBuffer[currentCharacterIndex + 1])) 973 if (U16_IS_LEAD(character) && currentCharacterIndex + 1 < m_normalizedBuffer Length && U16_IS_TRAIL(m_normalizedBuffer[currentCharacterIndex + 1]))
974 character = U16_GET_SUPPLEMENTARY(character, m_normalizedBuffer[currentC haracterIndex + 1]); 974 character = U16_GET_SUPPLEMENTARY(character, m_normalizedBuffer[currentC haracterIndex + 1]);
975 if (!Character::isCJKIdeographOrSymbol(character)) { 975 if (!Character::isCJKIdeographOrSymbol(character)) {
976 m_isAfterExpansion = false; 976 m_isAfterExpansion = false;
977 return spacing; 977 return spacing;
978 } 978 }
979 979
980 if (!m_isAfterExpansion) { 980 if (!m_isAfterExpansion) {
981 // Take the expansion opportunity before this ideograph. 981 // Take the expansion opportunity before this ideograph.
982 float expandBefore = nextExpansionPerOpportunity(); 982 float expandBefore = nextExpansionPerOpportunity();
983 if (expandBefore) { 983 if (expandBefore) {
984 if (glyphIndex > 0) { 984 if (glyphIndex > 0) {
985 currentRun->addAdvance(glyphIndex - 1, expandBefore); 985 currentRun->addAdvance(glyphIndex - 1, expandBefore);
986 totalAdvance += expandBefore; 986 totalAdvance += expandBefore;
987 } else { 987 } else {
988 offset += expandBefore; 988 offset += expandBefore;
989 spacing += expandBefore; 989 spacing += expandBefore;
990 } 990 }
991 } 991 }
992 if (!m_expansionOpportunityCount) 992 if (!m_expansionOpportunityCount)
993 return spacing; 993 return spacing;
994 } 994 }
995 995
996 // Don't need to check m_run.allowsTrailingExpansion() since it's covered by !m_expansionOpportunityCount above 996 // Don't need to check m_textRun.allowsTrailingExpansion() since it's covere d by !m_expansionOpportunityCount above
997 spacing += nextExpansionPerOpportunity(); 997 spacing += nextExpansionPerOpportunity();
998 m_isAfterExpansion = true; 998 m_isAfterExpansion = true;
999 return spacing; 999 return spacing;
1000 } 1000 }
1001 1001
1002 float HarfBuzzShaper::fillGlyphBufferFromHarfBuzzRun(GlyphBuffer* glyphBuffer, 1002 float HarfBuzzShaper::fillGlyphBufferFromHarfBuzzRun(GlyphBuffer* glyphBuffer,
1003 HarfBuzzRun* currentRun, float initialAdvance) 1003 HarfBuzzRun* currentRun, float initialAdvance)
1004 { 1004 {
1005 unsigned numGlyphs = currentRun->numGlyphs(); 1005 unsigned numGlyphs = currentRun->numGlyphs();
1006 float advanceSoFar = initialAdvance; 1006 float advanceSoFar = initialAdvance;
1007 if (m_run.rtl()) { 1007 if (m_textRun.rtl()) {
1008 for (unsigned i = 0; i < numGlyphs; ++i) { 1008 for (unsigned i = 0; i < numGlyphs; ++i) {
1009 HarfBuzzRunGlyphData& glyphData = currentRun->glyphData(i); 1009 HarfBuzzRunGlyphData& glyphData = currentRun->glyphData(i);
1010 uint16_t currentCharacterIndex = currentRun->startIndex() + glyphDat a.characterIndex; 1010 uint16_t currentCharacterIndex = currentRun->startIndex() + glyphDat a.characterIndex;
1011 if (currentCharacterIndex >= m_toIndex) { 1011 if (currentCharacterIndex >= m_toIndex) {
1012 advanceSoFar += glyphData.advance; 1012 advanceSoFar += glyphData.advance;
1013 } else if (currentCharacterIndex >= m_fromIndex) { 1013 } else if (currentCharacterIndex >= m_fromIndex) {
1014 FloatPoint runStartOffset = HB_DIRECTION_IS_HORIZONTAL(currentRu n->direction()) ? 1014 FloatPoint runStartOffset = HB_DIRECTION_IS_HORIZONTAL(currentRu n->direction()) ?
1015 FloatPoint(advanceSoFar, 0) : FloatPoint(0, advanceSoFar); 1015 FloatPoint(advanceSoFar, 0) : FloatPoint(0, advanceSoFar);
1016 glyphBuffer->add(glyphData.glyph, currentRun->fontData(), runSta rtOffset + glyphData.offset); 1016 glyphBuffer->add(glyphData.glyph, currentRun->fontData(), runSta rtOffset + glyphData.offset);
1017 advanceSoFar += glyphData.advance; 1017 advanceSoFar += glyphData.advance;
(...skipping 25 matching lines...) Expand all
1043 uint16_t clusterStart; 1043 uint16_t clusterStart;
1044 1044
1045 // A "cluster" in this context means a cluster as it is used by HarfBuzz: 1045 // A "cluster" in this context means a cluster as it is used by HarfBuzz:
1046 // The minimal group of characters and corresponding glyphs, that cannot be broken 1046 // The minimal group of characters and corresponding glyphs, that cannot be broken
1047 // down further from a text shaping point of view. 1047 // down further from a text shaping point of view.
1048 // A cluster can contain multiple glyphs and grapheme clusters, with mutuall y 1048 // A cluster can contain multiple glyphs and grapheme clusters, with mutuall y
1049 // overlapping boundaries. Below we count grapheme clusters per HarfBuzz clu sters, 1049 // overlapping boundaries. Below we count grapheme clusters per HarfBuzz clu sters,
1050 // then linearly split the sum of corresponding glyph advances by the number of 1050 // then linearly split the sum of corresponding glyph advances by the number of
1051 // grapheme clusters in order to find positions for emphasis mark drawing. 1051 // grapheme clusters in order to find positions for emphasis mark drawing.
1052 1052
1053 if (m_run.rtl()) 1053 if (m_textRun.rtl())
1054 clusterStart = currentRun->startIndex() + currentRun->numCharacters(); 1054 clusterStart = currentRun->startIndex() + currentRun->numCharacters();
1055 else 1055 else
1056 clusterStart = currentRun->glyphToCharacterIndex(0); 1056 clusterStart = currentRun->glyphToCharacterIndex(0);
1057 1057
1058 float advanceSoFar = initialAdvance; 1058 float advanceSoFar = initialAdvance;
1059 for (unsigned i = 0; i < numGlyphs; ++i) { 1059 for (unsigned i = 0; i < numGlyphs; ++i) {
1060 HarfBuzzRunGlyphData& glyphData = currentRun->glyphData(i); 1060 HarfBuzzRunGlyphData& glyphData = currentRun->glyphData(i);
1061 uint16_t currentCharacterIndex = currentRun->startIndex() + glyphData.ch aracterIndex; 1061 uint16_t currentCharacterIndex = currentRun->startIndex() + glyphData.ch aracterIndex;
1062 bool isRunEnd = (i + 1 == numGlyphs); 1062 bool isRunEnd = (i + 1 == numGlyphs);
1063 bool isClusterEnd = isRunEnd || (currentRun->glyphToCharacterIndex(i + 1) != currentCharacterIndex); 1063 bool isClusterEnd = isRunEnd || (currentRun->glyphToCharacterIndex(i + 1) != currentCharacterIndex);
1064 1064
1065 if ((m_run.rtl() && currentCharacterIndex >= m_toIndex) || (!m_run.rtl() && currentCharacterIndex < m_fromIndex)) { 1065 if ((m_textRun.rtl() && currentCharacterIndex >= m_toIndex) || (!m_textR un.rtl() && currentCharacterIndex < m_fromIndex)) {
1066 advanceSoFar += glyphData.advance; 1066 advanceSoFar += glyphData.advance;
1067 m_run.rtl() ? --clusterStart : ++clusterStart; 1067 m_textRun.rtl() ? --clusterStart : ++clusterStart;
1068 continue; 1068 continue;
1069 } 1069 }
1070 1070
1071 clusterAdvance += glyphData.advance; 1071 clusterAdvance += glyphData.advance;
1072 1072
1073 if (isClusterEnd) { 1073 if (isClusterEnd) {
1074 uint16_t clusterEnd; 1074 uint16_t clusterEnd;
1075 if (m_run.rtl()) 1075 if (m_textRun.rtl())
1076 clusterEnd = currentCharacterIndex; 1076 clusterEnd = currentCharacterIndex;
1077 else 1077 else
1078 clusterEnd = isRunEnd ? currentRun->startIndex() + currentRun->n umCharacters() : currentRun->glyphToCharacterIndex(i + 1); 1078 clusterEnd = isRunEnd ? currentRun->startIndex() + currentRun->n umCharacters() : currentRun->glyphToCharacterIndex(i + 1);
1079 1079
1080 graphemesInCluster = countGraphemesInCluster(m_normalizedBuffer.get( ), m_normalizedBufferLength, clusterStart, clusterEnd); 1080 graphemesInCluster = countGraphemesInCluster(m_normalizedBuffer.get( ), m_normalizedBufferLength, clusterStart, clusterEnd);
1081 if (!graphemesInCluster || !clusterAdvance) 1081 if (!graphemesInCluster || !clusterAdvance)
1082 continue; 1082 continue;
1083 1083
1084 float glyphAdvanceX = clusterAdvance / graphemesInCluster; 1084 float glyphAdvanceX = clusterAdvance / graphemesInCluster;
1085 for (unsigned j = 0; j < graphemesInCluster; ++j) { 1085 for (unsigned j = 0; j < graphemesInCluster; ++j) {
1086 // Do not put emphasis marks on space, separator, and control ch aracters. 1086 // Do not put emphasis marks on space, separator, and control ch aracters.
1087 if (Character::canReceiveTextEmphasis(m_run[currentCharacterInde x])) 1087 if (Character::canReceiveTextEmphasis(m_textRun[currentCharacter Index]))
1088 addEmphasisMark(glyphBuffer, advanceSoFar + glyphAdvanceX / 2); 1088 addEmphasisMark(glyphBuffer, advanceSoFar + glyphAdvanceX / 2);
1089 1089
1090 advanceSoFar += glyphAdvanceX; 1090 advanceSoFar += glyphAdvanceX;
1091 } 1091 }
1092 clusterStart = clusterEnd; 1092 clusterStart = clusterEnd;
1093 clusterAdvance = 0; 1093 clusterAdvance = 0;
1094 } 1094 }
1095 } 1095 }
1096 1096
1097 return advanceSoFar - initialAdvance; 1097 return advanceSoFar - initialAdvance;
1098 } 1098 }
1099 1099
1100 bool HarfBuzzShaper::fillGlyphBuffer(GlyphBuffer* glyphBuffer) 1100 bool HarfBuzzShaper::fillGlyphBuffer(GlyphBuffer* glyphBuffer)
1101 { 1101 {
1102 ASSERT(glyphBuffer); 1102 ASSERT(glyphBuffer);
1103 1103
1104 unsigned numRuns = m_harfBuzzRuns.size(); 1104 unsigned numRuns = m_harfBuzzRuns.size();
1105 float advanceSoFar = 0; 1105 float advanceSoFar = 0;
1106 for (unsigned runIndex = 0; runIndex < numRuns; ++runIndex) { 1106 for (unsigned runIndex = 0; runIndex < numRuns; ++runIndex) {
1107 HarfBuzzRun* currentRun = m_harfBuzzRuns[m_run.ltr() ? runIndex : numRun s - runIndex - 1].get(); 1107 HarfBuzzRun* currentRun = m_harfBuzzRuns[m_textRun.ltr() ? runIndex : nu mRuns - runIndex - 1].get();
1108 // Skip runs that only contain control characters. 1108 // Skip runs that only contain control characters.
1109 if (!currentRun->numGlyphs()) 1109 if (!currentRun->numGlyphs())
1110 continue; 1110 continue;
1111 advanceSoFar += forTextEmphasis() 1111 advanceSoFar += forTextEmphasis()
1112 ? fillGlyphBufferForTextEmphasis(glyphBuffer, currentRun, advanceSoF ar) 1112 ? fillGlyphBufferForTextEmphasis(glyphBuffer, currentRun, advanceSoF ar)
1113 : fillGlyphBufferFromHarfBuzzRun(glyphBuffer, currentRun, advanceSoF ar); 1113 : fillGlyphBufferFromHarfBuzzRun(glyphBuffer, currentRun, advanceSoF ar);
1114 } 1114 }
1115 return glyphBuffer->size(); 1115 return glyphBuffer->size();
1116 } 1116 }
1117 1117
1118 int HarfBuzzShaper::offsetForPosition(float targetX) 1118 int HarfBuzzShaper::offsetForPosition(float targetX)
1119 { 1119 {
1120 int charactersSoFar = 0; 1120 int charactersSoFar = 0;
1121 float currentX = 0; 1121 float currentX = 0;
1122 1122
1123 if (m_run.rtl()) { 1123 if (m_textRun.rtl()) {
1124 charactersSoFar = m_normalizedBufferLength; 1124 charactersSoFar = m_normalizedBufferLength;
1125 for (int i = m_harfBuzzRuns.size() - 1; i >= 0; --i) { 1125 for (int i = m_harfBuzzRuns.size() - 1; i >= 0; --i) {
1126 charactersSoFar -= m_harfBuzzRuns[i]->numCharacters(); 1126 charactersSoFar -= m_harfBuzzRuns[i]->numCharacters();
1127 float nextX = currentX + m_harfBuzzRuns[i]->width(); 1127 float nextX = currentX + m_harfBuzzRuns[i]->width();
1128 float offsetForRun = targetX - currentX; 1128 float offsetForRun = targetX - currentX;
1129 if (offsetForRun >= 0 && offsetForRun <= m_harfBuzzRuns[i]->width()) { 1129 if (offsetForRun >= 0 && offsetForRun <= m_harfBuzzRuns[i]->width()) {
1130 // The x value in question is within this script run. 1130 // The x value in question is within this script run.
1131 const unsigned index = m_harfBuzzRuns[i]->characterIndexForXPosi tion(offsetForRun); 1131 const unsigned index = m_harfBuzzRuns[i]->characterIndexForXPosi tion(offsetForRun);
1132 return charactersSoFar + index; 1132 return charactersSoFar + index;
1133 } 1133 }
(...skipping 16 matching lines...) Expand all
1150 } 1150 }
1151 1151
1152 FloatRect HarfBuzzShaper::selectionRect(const FloatPoint& point, int height, int from, int to) 1152 FloatRect HarfBuzzShaper::selectionRect(const FloatPoint& point, int height, int from, int to)
1153 { 1153 {
1154 float currentX = 0; 1154 float currentX = 0;
1155 float fromX = 0; 1155 float fromX = 0;
1156 float toX = 0; 1156 float toX = 0;
1157 bool foundFromX = false; 1157 bool foundFromX = false;
1158 bool foundToX = false; 1158 bool foundToX = false;
1159 1159
1160 if (m_run.rtl()) 1160 if (m_textRun.rtl())
1161 currentX = m_totalWidth; 1161 currentX = m_totalWidth;
1162 for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) { 1162 for (unsigned i = 0; i < m_harfBuzzRuns.size(); ++i) {
1163 if (m_run.rtl()) 1163 if (m_textRun.rtl())
1164 currentX -= m_harfBuzzRuns[i]->width(); 1164 currentX -= m_harfBuzzRuns[i]->width();
1165 int numCharacters = m_harfBuzzRuns[i]->numCharacters(); 1165 int numCharacters = m_harfBuzzRuns[i]->numCharacters();
1166 if (!foundFromX && from >= 0 && from < numCharacters) { 1166 if (!foundFromX && from >= 0 && from < numCharacters) {
1167 fromX = m_harfBuzzRuns[i]->xPositionForOffset(from) + currentX; 1167 fromX = m_harfBuzzRuns[i]->xPositionForOffset(from) + currentX;
1168 foundFromX = true; 1168 foundFromX = true;
1169 } else { 1169 } else {
1170 from -= numCharacters; 1170 from -= numCharacters;
1171 } 1171 }
1172 1172
1173 if (!foundToX && to >= 0 && to < numCharacters) { 1173 if (!foundToX && to >= 0 && to < numCharacters) {
1174 toX = m_harfBuzzRuns[i]->xPositionForOffset(to) + currentX; 1174 toX = m_harfBuzzRuns[i]->xPositionForOffset(to) + currentX;
1175 foundToX = true; 1175 foundToX = true;
1176 } else { 1176 } else {
1177 to -= numCharacters; 1177 to -= numCharacters;
1178 } 1178 }
1179 1179
1180 if (foundFromX && foundToX) 1180 if (foundFromX && foundToX)
1181 break; 1181 break;
1182 if (!m_run.rtl()) 1182 if (!m_textRun.rtl())
1183 currentX += m_harfBuzzRuns[i]->width(); 1183 currentX += m_harfBuzzRuns[i]->width();
1184 } 1184 }
1185 1185
1186 // The position in question might be just after the text. 1186 // The position in question might be just after the text.
1187 if (!foundFromX) 1187 if (!foundFromX)
1188 fromX = 0; 1188 fromX = 0;
1189 if (!foundToX) 1189 if (!foundToX)
1190 toX = m_run.rtl() ? 0 : m_totalWidth; 1190 toX = m_textRun.rtl() ? 0 : m_totalWidth;
1191 // None of our HarfBuzzRuns is part of the selection, 1191 // None of our HarfBuzzRuns is part of the selection,
1192 // possibly invalid from, to arguments. 1192 // possibly invalid from, to arguments.
1193 if (!foundToX && !foundFromX) 1193 if (!foundToX && !foundFromX)
1194 fromX = toX = 0; 1194 fromX = toX = 0;
1195 1195
1196 if (fromX < toX) 1196 if (fromX < toX)
1197 return FloatRect(point.x() + fromX, point.y(), toX - fromX, height); 1197 return FloatRect(point.x() + fromX, point.y(), toX - fromX, height);
1198 return FloatRect(point.x() + toX, point.y(), fromX - toX, height); 1198 return FloatRect(point.x() + toX, point.y(), fromX - toX, height);
1199 } 1199 }
1200 1200
1201 } // namespace blink 1201 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | Source/platform/fonts/shaping/Shaper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698