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

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

Issue 130433006: Implement CSS Emphasis Marks for complex text (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: WiP Created 6 years, 11 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 | « Source/platform/fonts/harfbuzz/HarfBuzzShaper.h ('k') | no next file » | 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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 // Don't normalize tabs as they are not treated as spaces for word-end. 341 // Don't normalize tabs as they are not treated as spaces for word-end.
342 if (Font::treatAsSpace(character) && character != '\t') 342 if (Font::treatAsSpace(character) && character != '\t')
343 character = ' '; 343 character = ' ';
344 else if (Font::treatAsZeroWidthSpaceInComplexScript(character)) 344 else if (Font::treatAsZeroWidthSpaceInComplexScript(character))
345 character = zeroWidthSpace; 345 character = zeroWidthSpace;
346 U16_APPEND(destination, *destinationLength, length, character, error); 346 U16_APPEND(destination, *destinationLength, length, character, error);
347 ASSERT_UNUSED(error, !error); 347 ASSERT_UNUSED(error, !error);
348 } 348 }
349 } 349 }
350 350
351 HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run) 351 HarfBuzzShaper::HarfBuzzShaper(const Font* font, const TextRun& run, bool forTex tEmphasis)
352 : m_font(font) 352 : m_font(font)
353 , m_normalizedBufferLength(0) 353 , m_normalizedBufferLength(0)
354 , m_run(run) 354 , m_run(run)
355 , m_wordSpacingAdjustment(font->wordSpacing()) 355 , m_wordSpacingAdjustment(font->wordSpacing())
356 , m_padding(0) 356 , m_padding(0)
357 , m_padPerWordBreak(0) 357 , m_padPerWordBreak(0)
358 , m_padError(0) 358 , m_padError(0)
359 , m_letterSpacing(font->letterSpacing()) 359 , m_letterSpacing(font->letterSpacing())
360 , m_fromIndex(0) 360 , m_fromIndex(0)
361 , m_toIndex(m_run.length()) 361 , m_toIndex(m_run.length())
362 , m_forTextEmphasis(forTextEmphasis)
362 { 363 {
363 m_normalizedBuffer = adoptArrayPtr(new UChar[m_run.length() + 1]); 364 m_normalizedBuffer = adoptArrayPtr(new UChar[m_run.length() + 1]);
364 normalizeCharacters(m_run, m_run.length(), m_normalizedBuffer.get(), &m_norm alizedBufferLength); 365 normalizeCharacters(m_run, m_run.length(), m_normalizedBuffer.get(), &m_norm alizedBufferLength);
365 setPadding(m_run.expansion()); 366 setPadding(m_run.expansion());
366 setFontFeatures(); 367 setFontFeatures();
367 } 368 }
368 369
369 static void normalizeSpacesAndMirrorChars(const UChar* source, unsigned length, UChar* destination, unsigned* destinationLength, HarfBuzzShaper::NormalizeMode n ormalizeMode) 370 static void normalizeSpacesAndMirrorChars(const UChar* source, unsigned length, UChar* destination, unsigned* destinationLength, HarfBuzzShaper::NormalizeMode n ormalizeMode)
370 { 371 {
371 unsigned position = 0; 372 unsigned position = 0;
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 668
668 hb_buffer_set_script(harfBuzzBuffer.get(), currentRun->script()); 669 hb_buffer_set_script(harfBuzzBuffer.get(), currentRun->script());
669 hb_buffer_set_direction(harfBuzzBuffer.get(), currentRun->rtl() ? HB_DIR ECTION_RTL : HB_DIRECTION_LTR); 670 hb_buffer_set_direction(harfBuzzBuffer.get(), currentRun->rtl() ? HB_DIR ECTION_RTL : HB_DIRECTION_LTR);
670 671
671 hb_segment_properties_t props; 672 hb_segment_properties_t props;
672 hb_buffer_get_segment_properties(harfBuzzBuffer.get(), &props); 673 hb_buffer_get_segment_properties(harfBuzzBuffer.get(), &props);
673 674
674 const UChar* src = m_normalizedBuffer.get() + currentRun->startIndex(); 675 const UChar* src = m_normalizedBuffer.get() + currentRun->startIndex();
675 std::wstring key(src, src + currentRun->numCharacters()); 676 std::wstring key(src, src + currentRun->numCharacters());
676 677
677 CachedShapingResults* cachedResults = runCache.find(key); 678 CachedShapingResults* cachedResults = m_forTextEmphasis ? 0 : runCache.f ind(key);
678 if (cachedResults) { 679 if (cachedResults) {
679 if (cachedResults->dir == props.direction && cachedResults->font == *m_font) { 680 if (cachedResults->dir == props.direction && cachedResults->font == *m_font) {
680 currentRun->applyShapeResult(cachedResults->buffer); 681 currentRun->applyShapeResult(cachedResults->buffer);
681 setGlyphPositionsForHarfBuzzRun(currentRun, cachedResults->buffe r); 682 setGlyphPositionsForHarfBuzzRun(currentRun, cachedResults->buffe r);
682 683
683 hb_buffer_reset(harfBuzzBuffer.get()); 684 hb_buffer_reset(harfBuzzBuffer.get());
684 685
685 runCache.moveToBack(cachedResults); 686 runCache.moveToBack(cachedResults);
686 687
687 continue; 688 continue;
(...skipping 18 matching lines...) Expand all
706 707
707 if (m_font->fontDescription().orientation() == Vertical) 708 if (m_font->fontDescription().orientation() == Vertical)
708 face->setScriptForVerticalGlyphSubstitution(harfBuzzBuffer.get()); 709 face->setScriptForVerticalGlyphSubstitution(harfBuzzBuffer.get());
709 710
710 HarfBuzzScopedPtr<hb_font_t> harfBuzzFont(face->createFont(), hb_font_de stroy); 711 HarfBuzzScopedPtr<hb_font_t> harfBuzzFont(face->createFont(), hb_font_de stroy);
711 712
712 hb_shape(harfBuzzFont.get(), harfBuzzBuffer.get(), m_features.isEmpty() ? 0 : m_features.data(), m_features.size()); 713 hb_shape(harfBuzzFont.get(), harfBuzzBuffer.get(), m_features.isEmpty() ? 0 : m_features.data(), m_features.size());
713 currentRun->applyShapeResult(harfBuzzBuffer.get()); 714 currentRun->applyShapeResult(harfBuzzBuffer.get());
714 setGlyphPositionsForHarfBuzzRun(currentRun, harfBuzzBuffer.get()); 715 setGlyphPositionsForHarfBuzzRun(currentRun, harfBuzzBuffer.get());
715 716
716 runCache.insert(key, new CachedShapingResults(harfBuzzBuffer.get(), m_fo nt, props.direction)); 717 if (!m_forTextEmphasis)
718 runCache.insert(key, new CachedShapingResults(harfBuzzBuffer.get(), m_font, props.direction));
717 719
718 harfBuzzBuffer.set(hb_buffer_create()); 720 harfBuzzBuffer.set(hb_buffer_create());
719 hb_buffer_set_unicode_funcs(harfBuzzBuffer.get(), hb_icu_get_unicode_fun cs()); 721 hb_buffer_set_unicode_funcs(harfBuzzBuffer.get(), hb_icu_get_unicode_fun cs());
720 } 722 }
721 723
722 return true; 724 return true;
723 } 725 }
724 726
725 void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb _buffer_t* harfBuzzBuffer) 727 void HarfBuzzShaper::setGlyphPositionsForHarfBuzzRun(HarfBuzzRun* currentRun, hb _buffer_t* harfBuzzBuffer)
726 { 728 {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 float* advances = currentRun->advances(); 782 float* advances = currentRun->advances();
781 unsigned numGlyphs = currentRun->numGlyphs(); 783 unsigned numGlyphs = currentRun->numGlyphs();
782 uint16_t* glyphToCharacterIndexes = currentRun->glyphToCharacterIndexes(); 784 uint16_t* glyphToCharacterIndexes = currentRun->glyphToCharacterIndexes();
783 785
784 for (unsigned i = 0; i < numGlyphs; ++i) { 786 for (unsigned i = 0; i < numGlyphs; ++i) {
785 uint16_t currentCharacterIndex = currentRun->startIndex() + glyphToChara cterIndexes[i]; 787 uint16_t currentCharacterIndex = currentRun->startIndex() + glyphToChara cterIndexes[i];
786 FloatPoint& currentOffset = offsets[i]; 788 FloatPoint& currentOffset = offsets[i];
787 FloatPoint& nextOffset = (i == numGlyphs - 1) ? firstOffsetOfNextRun : o ffsets[i + 1]; 789 FloatPoint& nextOffset = (i == numGlyphs - 1) ? firstOffsetOfNextRun : o ffsets[i + 1];
788 float glyphAdvanceX = advances[i] + nextOffset.x() - currentOffset.x(); 790 float glyphAdvanceX = advances[i] + nextOffset.x() - currentOffset.x();
789 float glyphAdvanceY = nextOffset.y() - currentOffset.y(); 791 float glyphAdvanceY = nextOffset.y() - currentOffset.y();
792
793 Glyph glyphToAdd = glyphs[i];
794 UChar ch = m_run[currentCharacterIndex];
795 if (m_forTextEmphasis)
796 printf("Glyph: 0x%x, Character: 0x%x\n", glyphToAdd, ch);
Dominik Röttsches 2014/01/16 16:37:32 When running this against: http://roettsch.es/emph
797
798 // FIXME: Combining marks should receive a text emphasis mark if they ar e combine with a space.
799 if (m_forTextEmphasis && (!Font::canReceiveTextEmphasis(ch) || (U_GET_GC _MASK(ch) & U_GC_M_MASK)))
800 glyphToAdd = 0;
801
790 if (m_run.rtl()) { 802 if (m_run.rtl()) {
791 if (currentCharacterIndex >= m_toIndex) 803 if (currentCharacterIndex >= m_toIndex)
792 m_startOffset.move(glyphAdvanceX, glyphAdvanceY); 804 m_startOffset.move(glyphAdvanceX, glyphAdvanceY);
793 else if (currentCharacterIndex >= m_fromIndex) 805 else if (currentCharacterIndex >= m_fromIndex)
794 glyphBuffer->add(glyphs[i], currentRun->fontData(), createGlyphB ufferAdvance(glyphAdvanceX, glyphAdvanceY)); 806 glyphBuffer->add(glyphToAdd, currentRun->fontData(), createGlyph BufferAdvance(glyphAdvanceX, glyphAdvanceY));
795 } else { 807 } else {
796 if (currentCharacterIndex < m_fromIndex) 808 if (currentCharacterIndex < m_fromIndex)
797 m_startOffset.move(glyphAdvanceX, glyphAdvanceY); 809 m_startOffset.move(glyphAdvanceX, glyphAdvanceY);
798 else if (currentCharacterIndex < m_toIndex) 810 else if (currentCharacterIndex < m_toIndex)
799 glyphBuffer->add(glyphs[i], currentRun->fontData(), createGlyphB ufferAdvance(glyphAdvanceX, glyphAdvanceY)); 811 glyphBuffer->add(glyphToAdd, currentRun->fontData(), createGlyph BufferAdvance(glyphAdvanceX, glyphAdvanceY));
800 } 812 }
801 } 813 }
802 } 814 }
803 815
804 bool HarfBuzzShaper::fillGlyphBuffer(GlyphBuffer* glyphBuffer) 816 bool HarfBuzzShaper::fillGlyphBuffer(GlyphBuffer* glyphBuffer)
805 { 817 {
806 unsigned numRuns = m_harfBuzzRuns.size(); 818 unsigned numRuns = m_harfBuzzRuns.size();
807 if (m_run.rtl()) { 819 if (m_run.rtl()) {
808 m_startOffset = m_harfBuzzRuns.last()->offsets()[0]; 820 m_startOffset = m_harfBuzzRuns.last()->offsets()[0];
809 for (int runIndex = numRuns - 1; runIndex >= 0; --runIndex) { 821 for (int runIndex = numRuns - 1; runIndex >= 0; --runIndex) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 if (!foundToX) 906 if (!foundToX)
895 toX = m_run.rtl() ? 0 : m_totalWidth; 907 toX = m_run.rtl() ? 0 : m_totalWidth;
896 908
897 // Using floorf() and roundf() as the same as mac port. 909 // Using floorf() and roundf() as the same as mac port.
898 if (fromX < toX) 910 if (fromX < toX)
899 return FloatRect(floorf(point.x() + fromX), point.y(), roundf(toX - from X), height); 911 return FloatRect(floorf(point.x() + fromX), point.y(), roundf(toX - from X), height);
900 return FloatRect(floorf(point.x() + toX), point.y(), roundf(fromX - toX), he ight); 912 return FloatRect(floorf(point.x() + toX), point.y(), roundf(fromX - toX), he ight);
901 } 913 }
902 914
903 } // namespace WebCore 915 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/platform/fonts/harfbuzz/HarfBuzzShaper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698