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

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

Issue 676523003: Offset-only GlyphBuffer (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: minor cleanup Created 6 years, 1 month 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 | Annotate | Revision Log
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 931 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 glyphBounds.move(glyphOrigin.x(), glyphOrigin.y()); 942 glyphBounds.move(glyphOrigin.x(), glyphOrigin.y());
943 m_glyphBoundingBox.unite(glyphBounds); 943 m_glyphBoundingBox.unite(glyphBounds);
944 glyphOrigin += FloatSize(advance + offsetX, offsetY); 944 glyphOrigin += FloatSize(advance + offsetX, offsetY);
945 945
946 totalAdvance += advance; 946 totalAdvance += advance;
947 } 947 }
948 currentRun->setWidth(totalAdvance > 0.0 ? totalAdvance : 0.0); 948 currentRun->setWidth(totalAdvance > 0.0 ? totalAdvance : 0.0);
949 m_totalWidth += currentRun->width(); 949 m_totalWidth += currentRun->width();
950 } 950 }
951 951
952 void HarfBuzzShaper::fillGlyphBufferFromHarfBuzzRun(GlyphBuffer* glyphBuffer, 952 float HarfBuzzShaper::fillGlyphBufferFromHarfBuzzRun(GlyphBuffer* glyphBuffer,
953 HarfBuzzRun* currentRun, float& carryAdvance) 953 HarfBuzzRun* currentRun, float initialAdvance)
954 { 954 {
955 FloatSize* offsets = currentRun->offsets(); 955 FloatSize* offsets = currentRun->offsets();
956 uint16_t* glyphs = currentRun->glyphs(); 956 uint16_t* glyphs = currentRun->glyphs();
957 float* advances = currentRun->advances(); 957 float* advances = currentRun->advances();
958 unsigned numGlyphs = currentRun->numGlyphs(); 958 unsigned numGlyphs = currentRun->numGlyphs();
959 uint16_t* glyphToCharacterIndexes = currentRun->glyphToCharacterIndexes(); 959 uint16_t* glyphToCharacterIndexes = currentRun->glyphToCharacterIndexes();
960 FloatSize runStartOffset = FloatSize(); 960 float advanceSoFar = initialAdvance;
961 if (m_run.rtl()) { 961 if (m_run.rtl()) {
962 for (unsigned i = 0; i < numGlyphs; ++i) { 962 for (unsigned i = 0; i < numGlyphs; ++i) {
963 uint16_t currentCharacterIndex = currentRun->startIndex() + glyphToC haracterIndexes[i]; 963 uint16_t currentCharacterIndex = currentRun->startIndex() + glyphToC haracterIndexes[i];
964 if (currentCharacterIndex >= m_toIndex) { 964 if (currentCharacterIndex >= m_toIndex) {
965 carryAdvance += advances[i]; 965 advanceSoFar += advances[i];
966 } else if (currentCharacterIndex >= m_fromIndex) { 966 } else if (currentCharacterIndex >= m_fromIndex) {
967 runStartOffset = HB_DIRECTION_IS_HORIZONTAL(currentRun->directio n()) ? FloatSize(carryAdvance, 0) : FloatSize(0, carryAdvance); 967 FloatPoint runStartOffset = HB_DIRECTION_IS_HORIZONTAL(currentRu n->direction()) ?
968 glyphBuffer->add(glyphs[i], currentRun->fontData(), runStartOffs et + offsets[i], carryAdvance + advances[i]); 968 FloatPoint(advanceSoFar, 0) : FloatPoint(0, advanceSoFar);
969 carryAdvance = 0; 969 glyphBuffer->add(glyphs[i], currentRun->fontData(), runStartOffs et + offsets[i]);
970 advanceSoFar += advances[i];
970 } 971 }
971 } 972 }
972 } else { 973 } else {
973 for (unsigned i = 0; i < numGlyphs; ++i) { 974 for (unsigned i = 0; i < numGlyphs; ++i) {
974 uint16_t currentCharacterIndex = currentRun->startIndex() + glyphToC haracterIndexes[i]; 975 uint16_t currentCharacterIndex = currentRun->startIndex() + glyphToC haracterIndexes[i];
975 if (currentCharacterIndex < m_fromIndex) { 976 if (currentCharacterIndex < m_fromIndex) {
976 carryAdvance += advances[i]; 977 advanceSoFar += advances[i];
977 } else if (currentCharacterIndex < m_toIndex) { 978 } else if (currentCharacterIndex < m_toIndex) {
978 runStartOffset = HB_DIRECTION_IS_HORIZONTAL(currentRun->directio n()) ? FloatSize(carryAdvance, 0) : FloatSize(0, carryAdvance); 979 FloatPoint runStartOffset = HB_DIRECTION_IS_HORIZONTAL(currentRu n->direction()) ?
979 glyphBuffer->add(glyphs[i], currentRun->fontData(), runStartOffs et + offsets[i], carryAdvance + advances[i]); 980 FloatPoint(advanceSoFar, 0) : FloatPoint(0, advanceSoFar);
980 carryAdvance = 0; 981 glyphBuffer->add(glyphs[i], currentRun->fontData(), runStartOffs et + offsets[i]);
982 advanceSoFar += advances[i];
981 } 983 }
982 } 984 }
983 } 985 }
986
987 return advanceSoFar - initialAdvance;
984 } 988 }
985 989
986 void HarfBuzzShaper::fillGlyphBufferForTextEmphasis(GlyphBuffer* glyphBuffer, Ha rfBuzzRun* currentRun) 990 float HarfBuzzShaper::fillGlyphBufferForTextEmphasis(GlyphBuffer* glyphBuffer, H arfBuzzRun* currentRun, float initialAdvance)
987 { 991 {
988 // FIXME: Instead of generating a synthetic GlyphBuffer here which is then u sed by the 992 // FIXME: Instead of generating a synthetic GlyphBuffer here which is then u sed by the
989 // drawEmphasisMarks method of FontFastPath, we should roll our own emphasis mark drawing function. 993 // drawEmphasisMarks method of FontFastPath, we should roll our own emphasis mark drawing function.
990 994
991 float* advances = currentRun->advances(); 995 float* advances = currentRun->advances();
992 unsigned numGlyphs = currentRun->numGlyphs(); 996 unsigned numGlyphs = currentRun->numGlyphs();
993 uint16_t* glyphToCharacterIndexes = currentRun->glyphToCharacterIndexes(); 997 uint16_t* glyphToCharacterIndexes = currentRun->glyphToCharacterIndexes();
994 unsigned graphemesInCluster = 1; 998 unsigned graphemesInCluster = 1;
995 float clusterAdvance = 0; 999 float clusterAdvance = 0;
996 uint16_t clusterStart; 1000 uint16_t clusterStart;
997 1001
998 // A "cluster" in this context means a cluster as it is used by HarfBuzz: 1002 // A "cluster" in this context means a cluster as it is used by HarfBuzz:
999 // The minimal group of characters and corresponding glyphs, that cannot be broken 1003 // The minimal group of characters and corresponding glyphs, that cannot be broken
1000 // down further from a text shaping point of view. 1004 // down further from a text shaping point of view.
1001 // A cluster can contain multiple glyphs and grapheme clusters, with mutuall y 1005 // A cluster can contain multiple glyphs and grapheme clusters, with mutuall y
1002 // overlapping boundaries. Below we count grapheme clusters per HarfBuzz clu sters, 1006 // overlapping boundaries. Below we count grapheme clusters per HarfBuzz clu sters,
1003 // then linearly split the sum of corresponding glyph advances by the number of 1007 // then linearly split the sum of corresponding glyph advances by the number of
1004 // grapheme clusters in order to find positions for emphasis mark drawing. 1008 // grapheme clusters in order to find positions for emphasis mark drawing.
1005 1009
1006 if (m_run.rtl()) 1010 if (m_run.rtl())
1007 clusterStart = currentRun->startIndex() + currentRun->numCharacters(); 1011 clusterStart = currentRun->startIndex() + currentRun->numCharacters();
1008 else 1012 else
1009 clusterStart = currentRun->startIndex() + glyphToCharacterIndexes[0]; 1013 clusterStart = currentRun->startIndex() + glyphToCharacterIndexes[0];
1010 1014
1015 float advanceSoFar = initialAdvance;
1011 for (unsigned i = 0; i < numGlyphs; ++i) { 1016 for (unsigned i = 0; i < numGlyphs; ++i) {
1012 uint16_t currentCharacterIndex = currentRun->startIndex() + glyphToChara cterIndexes[i]; 1017 uint16_t currentCharacterIndex = currentRun->startIndex() + glyphToChara cterIndexes[i];
1013 bool isRunEnd = (i + 1 == numGlyphs); 1018 bool isRunEnd = (i + 1 == numGlyphs);
1014 bool isClusterEnd = isRunEnd || (currentRun->startIndex() + glyphToChar acterIndexes[i + 1] != currentCharacterIndex); 1019 bool isClusterEnd = isRunEnd || (currentRun->startIndex() + glyphToChar acterIndexes[i + 1] != currentCharacterIndex);
1015 clusterAdvance += advances[i]; 1020 clusterAdvance += advances[i];
1016 1021
1017 if (isClusterEnd) { 1022 if (isClusterEnd) {
1018 uint16_t clusterEnd; 1023 uint16_t clusterEnd;
1019 if (m_run.rtl()) 1024 if (m_run.rtl())
1020 clusterEnd = currentCharacterIndex; 1025 clusterEnd = currentCharacterIndex;
1021 else 1026 else
1022 clusterEnd = isRunEnd ? currentRun->startIndex() + currentRun->n umCharacters() : currentRun->startIndex() + glyphToCharacterIndexes[i + 1]; 1027 clusterEnd = isRunEnd ? currentRun->startIndex() + currentRun->n umCharacters() : currentRun->startIndex() + glyphToCharacterIndexes[i + 1];
1023 1028
1024 graphemesInCluster = countGraphemesInCluster(m_normalizedBuffer.get( ), m_normalizedBufferLength, clusterStart, clusterEnd); 1029 graphemesInCluster = countGraphemesInCluster(m_normalizedBuffer.get( ), m_normalizedBufferLength, clusterStart, clusterEnd);
1025 if (!graphemesInCluster || !clusterAdvance) 1030 if (!graphemesInCluster || !clusterAdvance)
1026 continue; 1031 continue;
1027 1032
1028 float glyphAdvanceX = clusterAdvance / graphemesInCluster; 1033 float glyphAdvanceX = clusterAdvance / graphemesInCluster;
1029 for (unsigned j = 0; j < graphemesInCluster; ++j) { 1034 for (unsigned j = 0; j < graphemesInCluster; ++j) {
1030 // Do not put emphasis marks on space, separator, and control ch aracters. 1035 // Do not put emphasis marks on space, separator, and control ch aracters.
1031 Glyph glyphToAdd = Character::canReceiveTextEmphasis(m_run[curre ntCharacterIndex]) ? 1 : 0; 1036 Glyph glyphToAdd = Character::canReceiveTextEmphasis(m_run[curre ntCharacterIndex]) ? 1 : 0;
1032 glyphBuffer->add(glyphToAdd, currentRun->fontData(), glyphAdvanc eX); 1037 // The emphasis code expects mid-glyph offsets.
1038 glyphBuffer->add(glyphToAdd, currentRun->fontData(), advanceSoFa r + glyphAdvanceX / 2);
1039 advanceSoFar += glyphAdvanceX;
1033 } 1040 }
1034 clusterStart = clusterEnd; 1041 clusterStart = clusterEnd;
1035 clusterAdvance = 0; 1042 clusterAdvance = 0;
1036 } 1043 }
1037 } 1044 }
1045
1046 return advanceSoFar - initialAdvance;
1038 } 1047 }
1039 1048
1040 bool HarfBuzzShaper::fillGlyphBuffer(GlyphBuffer* glyphBuffer) 1049 bool HarfBuzzShaper::fillGlyphBuffer(GlyphBuffer* glyphBuffer)
1041 { 1050 {
1051 ASSERT(glyphBuffer);
1052
1042 unsigned numRuns = m_harfBuzzRuns.size(); 1053 unsigned numRuns = m_harfBuzzRuns.size();
1043 float carryAdvance = 0; 1054 float advanceSoFar = 0;
1044 if (m_run.rtl()) { 1055 for (unsigned runIndex = 0; runIndex < numRuns; ++runIndex) {
1045 for (int runIndex = numRuns - 1; runIndex >= 0; --runIndex) { 1056 HarfBuzzRun* currentRun = m_harfBuzzRuns[m_run.ltr() ? runIndex : numRun s - runIndex - 1].get();
1046 HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get(); 1057 if (!currentRun->hasGlyphToCharacterIndexes()) {
1047 if (!currentRun->hasGlyphToCharacterIndexes()) { 1058 // FIXME: bug 337886, 359664
1048 // FIXME: bug 337886, 359664 1059 continue;
1049 continue;
1050 }
1051 if (m_forTextEmphasis == ForTextEmphasis) {
1052 fillGlyphBufferForTextEmphasis(glyphBuffer, currentRun);
1053 } else {
1054 fillGlyphBufferFromHarfBuzzRun(glyphBuffer, currentRun, carryAdv ance);
1055 }
1056 } 1060 }
1057 } else { 1061 advanceSoFar += (m_forTextEmphasis == ForTextEmphasis)
1058 for (unsigned runIndex = 0; runIndex < numRuns; ++runIndex) { 1062 ? fillGlyphBufferForTextEmphasis(glyphBuffer, currentRun, advanceSoF ar)
1059 HarfBuzzRun* currentRun = m_harfBuzzRuns[runIndex].get(); 1063 : fillGlyphBufferFromHarfBuzzRun(glyphBuffer, currentRun, advanceSoF ar);
1060 if (!currentRun->hasGlyphToCharacterIndexes()) {
1061 // FIXME: bug 337886, 359664
1062 continue;
1063 }
1064 if (m_forTextEmphasis == ForTextEmphasis) {
1065 fillGlyphBufferForTextEmphasis(glyphBuffer, currentRun);
1066 } else {
1067 fillGlyphBufferFromHarfBuzzRun(glyphBuffer, currentRun, carryAdv ance);
1068 }
1069 }
1070 } 1064 }
1071 return glyphBuffer->size(); 1065 return glyphBuffer->size();
1072 } 1066 }
1073 1067
1074 int HarfBuzzShaper::offsetForPosition(float targetX) 1068 int HarfBuzzShaper::offsetForPosition(float targetX)
1075 { 1069 {
1076 int charactersSoFar = 0; 1070 int charactersSoFar = 0;
1077 float currentX = 0; 1071 float currentX = 0;
1078 1072
1079 if (m_run.rtl()) { 1073 if (m_run.rtl()) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 fromX = 0; 1138 fromX = 0;
1145 if (!foundToX) 1139 if (!foundToX)
1146 toX = m_run.rtl() ? 0 : m_totalWidth; 1140 toX = m_run.rtl() ? 0 : m_totalWidth;
1147 1141
1148 if (fromX < toX) 1142 if (fromX < toX)
1149 return FloatRect(point.x() + fromX, point.y(), toX - fromX, height); 1143 return FloatRect(point.x() + fromX, point.y(), toX - fromX, height);
1150 return FloatRect(point.x() + toX, point.y(), fromX - toX, height); 1144 return FloatRect(point.x() + toX, point.y(), fromX - toX, height);
1151 } 1145 }
1152 1146
1153 } // namespace blink 1147 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698