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

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

Issue 2751163002: Report UseCounter metric when observing NotDef glyphs (Closed)
Patch Set: Relax num_glyphs assertion, not feasible on Mac Created 3 years, 7 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
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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 hb_buffer_set_direction(buffer, direction); 143 hb_buffer_set_direction(buffer, direction);
144 144
145 hb_font_t* hb_font = face->GetScaledFont(std::move(current_font_range_set)); 145 hb_font_t* hb_font = face->GetScaledFont(std::move(current_font_range_set));
146 hb_shape(hb_font, buffer, font_features, font_features_size); 146 hb_shape(hb_font, buffer, font_features, font_features_size);
147 147
148 return true; 148 return true;
149 } 149 }
150 150
151 } // namespace 151 } // namespace
152 152
153 bool HarfBuzzShaper::ExtractShapeResults( 153 void HarfBuzzShaper::ExtractShapeResults(
154 RangeData* range_data, 154 RangeData* range_data,
155 bool& font_cycle_queued, 155 bool& font_cycle_queued,
156 const HolesQueueItem& current_queue_item, 156 const HolesQueueItem& current_queue_item,
157 const SimpleFontData* current_font, 157 const SimpleFontData* current_font,
158 UScriptCode current_run_script, 158 UScriptCode current_run_script,
159 bool is_last_resort, 159 bool is_last_resort,
160 ShapeResult* shape_result) const { 160 ShapeResult* shape_result) const {
161 enum ClusterResult { kShaped, kNotDef, kUnknown }; 161 enum ClusterResult { kShaped, kNotDef, kUnknown };
162 ClusterResult current_cluster_result = kUnknown; 162 ClusterResult current_cluster_result = kUnknown;
163 ClusterResult previous_cluster_result = kUnknown; 163 ClusterResult previous_cluster_result = kUnknown;
164 unsigned previous_cluster = 0; 164 unsigned previous_cluster = 0;
165 unsigned current_cluster = 0; 165 unsigned current_cluster = 0;
166 166
167 // Find first notdef glyph in buffer. 167 // Find first notdef glyph in buffer.
168 unsigned num_glyphs = hb_buffer_get_length(range_data->buffer); 168 unsigned num_glyphs = hb_buffer_get_length(range_data->buffer);
169 hb_glyph_info_t* glyph_info = 169 hb_glyph_info_t* glyph_info =
170 hb_buffer_get_glyph_infos(range_data->buffer, 0); 170 hb_buffer_get_glyph_infos(range_data->buffer, 0);
171 171
172 unsigned last_change_position = 0; 172 unsigned last_change_position = 0;
173 173
174 if (!num_glyphs) { 174 if (!num_glyphs)
175 DLOG(ERROR) << "HarfBuzz returned empty glyph buffer after shaping."; 175 return;
176 return false;
177 }
178 176
179 for (unsigned glyph_index = 0; glyph_index <= num_glyphs; ++glyph_index) { 177 for (unsigned glyph_index = 0; glyph_index <= num_glyphs; ++glyph_index) {
180 // Iterating by clusters, check for when the state switches from shaped 178 // Iterating by clusters, check for when the state switches from shaped
181 // to non-shaped and vice versa. Taking into account the edge cases of 179 // to non-shaped and vice versa. Taking into account the edge cases of
182 // beginning of the run and end of the run. 180 // beginning of the run and end of the run.
183 previous_cluster = current_cluster; 181 previous_cluster = current_cluster;
184 current_cluster = glyph_info[glyph_index].cluster; 182 current_cluster = glyph_info[glyph_index].cluster;
185 183
186 if (glyph_index < num_glyphs) { 184 if (glyph_index < num_glyphs) {
187 // Still the same cluster, merge shaping status. 185 // Still the same cluster, merge shaping status.
188 if (previous_cluster == current_cluster && glyph_index != 0) { 186 if (previous_cluster == current_cluster && glyph_index != 0) {
189 if (glyph_info[glyph_index].codepoint == 0) { 187 if (glyph_info[glyph_index].codepoint == 0) {
190 current_cluster_result = kNotDef; 188 current_cluster_result = kNotDef;
191 } else { 189 } else {
192 // We can only call the current cluster fully shapped, if 190 // We can only call the current cluster fully shapped, if
193 // all characters that are part of it are shaped, so update 191 // all characters that are part of it are shaped, so update
194 // currentClusterResult to Shaped only if the previous 192 // currentClusterResult to kShaped only if the previous
195 // characters have been shaped, too. 193 // characters have been shaped, too.
196 current_cluster_result = 194 current_cluster_result =
197 current_cluster_result == kShaped ? kShaped : kNotDef; 195 current_cluster_result == kShaped ? kShaped : kNotDef;
198 } 196 }
199 continue; 197 continue;
200 } 198 }
201 // We've moved to a new cluster. 199 // We've moved to a new cluster.
202 previous_cluster_result = current_cluster_result; 200 previous_cluster_result = current_cluster_result;
203 current_cluster_result = 201 current_cluster_result =
204 glyph_info[glyph_index].codepoint == 0 ? kNotDef : kShaped; 202 glyph_info[glyph_index].codepoint == 0 ? kNotDef : kShaped;
205 } else { 203 } else {
206 // The code below operates on the "flanks"/changes between NotDef 204 // The code below operates on the "flanks"/changes between kNotDef
207 // and Shaped. In order to keep the code below from explictly 205 // and kShaped. In order to keep the code below from explictly
208 // dealing with character indices and run end, we explicitly 206 // dealing with character indices and run end, we explicitly
209 // terminate the cluster/run here by setting the result value to the 207 // terminate the cluster/run here by setting the result value to the
210 // opposite of what it was, leading to atChange turning true. 208 // opposite of what it was, leading to atChange turning true.
211 previous_cluster_result = current_cluster_result; 209 previous_cluster_result = current_cluster_result;
212 current_cluster_result = 210 current_cluster_result =
213 current_cluster_result == kNotDef ? kShaped : kNotDef; 211 current_cluster_result == kNotDef ? kShaped : kNotDef;
214 } 212 }
215 213
216 bool at_change = (previous_cluster_result != current_cluster_result) && 214 bool at_change = (previous_cluster_result != current_cluster_result) &&
217 previous_cluster_result != kUnknown; 215 previous_cluster_result != kUnknown;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 // choice than adding boxes to the ShapeResult. 277 // choice than adding boxes to the ShapeResult.
280 if ((current_cluster_result == kNotDef && num_characters) || 278 if ((current_cluster_result == kNotDef && num_characters) ||
281 is_last_resort) { 279 is_last_resort) {
282 hb_direction_t direction = range_data->HarfBuzzDirection(current_font); 280 hb_direction_t direction = range_data->HarfBuzzDirection(current_font);
283 // Here we need to specify glyph positions. 281 // Here we need to specify glyph positions.
284 ShapeResult::RunInfo* run = new ShapeResult::RunInfo( 282 ShapeResult::RunInfo* run = new ShapeResult::RunInfo(
285 current_font, direction, ICUScriptToHBScript(current_run_script), 283 current_font, direction, ICUScriptToHBScript(current_run_script),
286 start_index, num_glyphs_to_insert, num_characters); 284 start_index, num_glyphs_to_insert, num_characters);
287 shape_result->InsertRun(WTF::WrapUnique(run), last_change_position, 285 shape_result->InsertRun(WTF::WrapUnique(run), last_change_position,
288 num_glyphs_to_insert, range_data->buffer); 286 num_glyphs_to_insert, range_data->buffer);
287 range_data->font->ReportNotDefGlyph();
289 } 288 }
290 last_change_position = glyph_index; 289 last_change_position = glyph_index;
291 } 290 }
292 return true;
293 } 291 }
294 292
295 static inline const SimpleFontData* FontDataAdjustedForOrientation( 293 static inline const SimpleFontData* FontDataAdjustedForOrientation(
296 const SimpleFontData* original_font, 294 const SimpleFontData* original_font,
297 FontOrientation run_orientation, 295 FontOrientation run_orientation,
298 OrientationIterator::RenderOrientation render_orientation) { 296 OrientationIterator::RenderOrientation render_orientation) {
299 if (!IsVerticalBaseline(run_orientation)) 297 if (!IsVerticalBaseline(run_orientation))
300 return original_font; 298 return original_font;
301 299
302 if (run_orientation == FontOrientation::kVerticalRotated || 300 if (run_orientation == FontOrientation::kVerticalRotated ||
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 if (!ShapeRange(range_data->buffer, 667 if (!ShapeRange(range_data->buffer,
670 range_data->font_features.IsEmpty() 668 range_data->font_features.IsEmpty()
671 ? 0 669 ? 0
672 : range_data->font_features.data(), 670 : range_data->font_features.data(),
673 range_data->font_features.size(), 671 range_data->font_features.size(),
674 direction_and_small_caps_adjusted_font, 672 direction_and_small_caps_adjusted_font,
675 current_font_data_for_range_set->Ranges(), segment.script, 673 current_font_data_for_range_set->Ranges(), segment.script,
676 direction, language)) 674 direction, language))
677 DLOG(ERROR) << "Shaping range failed."; 675 DLOG(ERROR) << "Shaping range failed.";
678 676
679 if (!ExtractShapeResults(range_data, font_cycle_queued, current_queue_item, 677 ExtractShapeResults(range_data, font_cycle_queued, current_queue_item,
680 direction_and_small_caps_adjusted_font, 678 direction_and_small_caps_adjusted_font, segment.script,
681 segment.script, !fallback_iterator->HasNext(), 679 !fallback_iterator->HasNext(), result);
682 result))
683 DLOG(ERROR) << "Shape result extraction failed.";
684 680
685 hb_buffer_reset(range_data->buffer); 681 hb_buffer_reset(range_data->buffer);
686 } 682 }
687 } 683 }
688 684
689 PassRefPtr<ShapeResult> HarfBuzzShaper::Shape(const Font* font, 685 PassRefPtr<ShapeResult> HarfBuzzShaper::Shape(const Font* font,
690 TextDirection direction, 686 TextDirection direction,
691 unsigned start, 687 unsigned start,
692 unsigned end) const { 688 unsigned end) const {
693 DCHECK(end >= start); 689 DCHECK(end >= start);
(...skipping 25 matching lines...) Expand all
719 } 715 }
720 return result.Release(); 716 return result.Release();
721 } 717 }
722 718
723 PassRefPtr<ShapeResult> HarfBuzzShaper::Shape(const Font* font, 719 PassRefPtr<ShapeResult> HarfBuzzShaper::Shape(const Font* font,
724 TextDirection direction) const { 720 TextDirection direction) const {
725 return Shape(font, direction, 0, text_length_); 721 return Shape(font, direction, 0, text_length_);
726 } 722 }
727 723
728 } // namespace blink 724 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698