| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/render_text_harfbuzz.h" | 5 #include "ui/gfx/render_text_harfbuzz.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/i18n/bidi_line_iterator.h" | 10 #include "base/i18n/bidi_line_iterator.h" |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 } | 198 } |
| 199 | 199 |
| 200 // A port of hb_icu_script_to_script because harfbuzz on CrOS is built without | 200 // A port of hb_icu_script_to_script because harfbuzz on CrOS is built without |
| 201 // hb-icu. See http://crbug.com/356929 | 201 // hb-icu. See http://crbug.com/356929 |
| 202 inline hb_script_t ICUScriptToHBScript(UScriptCode script) { | 202 inline hb_script_t ICUScriptToHBScript(UScriptCode script) { |
| 203 if (script == USCRIPT_INVALID_CODE) | 203 if (script == USCRIPT_INVALID_CODE) |
| 204 return HB_SCRIPT_INVALID; | 204 return HB_SCRIPT_INVALID; |
| 205 return hb_script_from_string(uscript_getShortName(script), -1); | 205 return hb_script_from_string(uscript_getShortName(script), -1); |
| 206 } | 206 } |
| 207 | 207 |
| 208 // Whether |segment| corresponds to the newline character. |
| 209 bool IsNewlineSegment(const base::string16& text, |
| 210 const internal::LineSegment& segment) { |
| 211 return text[segment.char_range.start()] == '\n'; |
| 212 } |
| 213 |
| 208 // Helper template function for |TextRunHarfBuzz::GetClusterAt()|. |Iterator| | 214 // Helper template function for |TextRunHarfBuzz::GetClusterAt()|. |Iterator| |
| 209 // can be a forward or reverse iterator type depending on the text direction. | 215 // can be a forward or reverse iterator type depending on the text direction. |
| 210 template <class Iterator> | 216 template <class Iterator> |
| 211 void GetClusterAtImpl(size_t pos, | 217 void GetClusterAtImpl(size_t pos, |
| 212 Range range, | 218 Range range, |
| 213 Iterator elements_begin, | 219 Iterator elements_begin, |
| 214 Iterator elements_end, | 220 Iterator elements_end, |
| 215 bool reversed, | 221 bool reversed, |
| 216 Range* chars, | 222 Range* chars, |
| 217 Range* glyphs) { | 223 Range* glyphs) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 for (auto iter = words_->breaks().begin(); iter != words_->breaks().end(); | 288 for (auto iter = words_->breaks().begin(); iter != words_->breaks().end(); |
| 283 iter++) { | 289 iter++) { |
| 284 const Range word_range = words_->GetRange(iter); | 290 const Range word_range = words_->GetRange(iter); |
| 285 std::vector<internal::LineSegment> word_segments; | 291 std::vector<internal::LineSegment> word_segments; |
| 286 SkScalar word_width = GetWordWidth(word_range, &word_segments); | 292 SkScalar word_width = GetWordWidth(word_range, &word_segments); |
| 287 | 293 |
| 288 // If the last word is '\n', we should advance a new line after adding | 294 // If the last word is '\n', we should advance a new line after adding |
| 289 // the word to the current line. | 295 // the word to the current line. |
| 290 bool new_line = false; | 296 bool new_line = false; |
| 291 if (!word_segments.empty() && | 297 if (!word_segments.empty() && |
| 292 text_[word_segments.back().char_range.start()] == '\n') { | 298 IsNewlineSegment(text_, word_segments.back())) { |
| 293 new_line = true; | 299 new_line = true; |
| 294 | 300 |
| 295 // Since the line should at least contain some information regarding the | 301 // Since the line should at least contain some information regarding the |
| 296 // text range it corresponds to, don't pop the newline segment, if it's | 302 // text range it corresponds to, don't pop the newline segment, if it's |
| 297 // the only segment in the line. This ensures that every line has a non- | 303 // the only segment in the line. This ensures that every line has a non- |
| 298 // empty segments vector (except the last in some cases). | 304 // empty segments vector (except the last in some cases). This segment |
| 305 // won't be drawn though. |
| 299 if (word_segments.size() != 1u || available_width_ != max_width_) { | 306 if (word_segments.size() != 1u || available_width_ != max_width_) { |
| 300 word_width -= word_segments.back().width(); | 307 word_width -= word_segments.back().width(); |
| 301 word_segments.pop_back(); | 308 word_segments.pop_back(); |
| 302 } | 309 } |
| 303 } | 310 } |
| 304 | 311 |
| 305 // If the word is not the first word in the line and it can't fit into | 312 // If the word is not the first word in the line and it can't fit into |
| 306 // the current line, advance a new line. | 313 // the current line, advance a new line. |
| 307 if (word_width > available_width_ && available_width_ != max_width_) | 314 if (word_width > available_width_ && available_width_ != max_width_) |
| 308 AdvanceLine(); | 315 AdvanceLine(); |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 ApplyFadeEffects(renderer); | 1216 ApplyFadeEffects(renderer); |
| 1210 ApplyTextShadows(renderer); | 1217 ApplyTextShadows(renderer); |
| 1211 ApplyCompositionAndSelectionStyles(); | 1218 ApplyCompositionAndSelectionStyles(); |
| 1212 | 1219 |
| 1213 internal::TextRunList* run_list = GetRunList(); | 1220 internal::TextRunList* run_list = GetRunList(); |
| 1214 for (size_t i = 0; i < lines().size(); ++i) { | 1221 for (size_t i = 0; i < lines().size(); ++i) { |
| 1215 const internal::Line& line = lines()[i]; | 1222 const internal::Line& line = lines()[i]; |
| 1216 const Vector2d origin = GetLineOffset(i) + Vector2d(0, line.baseline); | 1223 const Vector2d origin = GetLineOffset(i) + Vector2d(0, line.baseline); |
| 1217 SkScalar preceding_segment_widths = 0; | 1224 SkScalar preceding_segment_widths = 0; |
| 1218 for (const internal::LineSegment& segment : line.segments) { | 1225 for (const internal::LineSegment& segment : line.segments) { |
| 1226 // Don't draw the newline glyph (crbug.com/680430). |
| 1227 if (IsNewlineSegment(GetDisplayText(), segment)) |
| 1228 continue; |
| 1229 |
| 1219 const internal::TextRunHarfBuzz& run = *run_list->runs()[segment.run]; | 1230 const internal::TextRunHarfBuzz& run = *run_list->runs()[segment.run]; |
| 1220 renderer->SetTypeface(run.skia_face); | 1231 renderer->SetTypeface(run.skia_face); |
| 1221 renderer->SetTextSize(SkIntToScalar(run.font_size)); | 1232 renderer->SetTextSize(SkIntToScalar(run.font_size)); |
| 1222 renderer->SetFontRenderParams(run.render_params, | 1233 renderer->SetFontRenderParams(run.render_params, |
| 1223 subpixel_rendering_suppressed()); | 1234 subpixel_rendering_suppressed()); |
| 1224 Range glyphs_range = run.CharRangeToGlyphRange(segment.char_range); | 1235 Range glyphs_range = run.CharRangeToGlyphRange(segment.char_range); |
| 1225 std::unique_ptr<SkPoint[]> positions(new SkPoint[glyphs_range.length()]); | 1236 std::unique_ptr<SkPoint[]> positions(new SkPoint[glyphs_range.length()]); |
| 1226 SkScalar offset_x = preceding_segment_widths - | 1237 SkScalar offset_x = preceding_segment_widths - |
| 1227 ((glyphs_range.GetMin() != 0) | 1238 ((glyphs_range.GetMin() != 0) |
| 1228 ? run.positions[glyphs_range.GetMin()].x() | 1239 ? run.positions[glyphs_range.GetMin()].x() |
| (...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1702 | 1713 |
| 1703 attribute.strike = run.strike; | 1714 attribute.strike = run.strike; |
| 1704 attribute.diagonal_strike = run.diagonal_strike; | 1715 attribute.diagonal_strike = run.diagonal_strike; |
| 1705 decorated_text->attributes.push_back(attribute); | 1716 decorated_text->attributes.push_back(attribute); |
| 1706 } | 1717 } |
| 1707 } | 1718 } |
| 1708 return true; | 1719 return true; |
| 1709 } | 1720 } |
| 1710 | 1721 |
| 1711 } // namespace gfx | 1722 } // namespace gfx |
| OLD | NEW |