| 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 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 reversed ? elements_end - element : element - elements_begin); | 226 reversed ? elements_end - element : element - elements_begin); |
| 227 if (reversed) | 227 if (reversed) |
| 228 *glyphs = Range(glyphs->end(), glyphs->start()); | 228 *glyphs = Range(glyphs->end(), glyphs->start()); |
| 229 | 229 |
| 230 DCHECK(!chars->is_reversed()); | 230 DCHECK(!chars->is_reversed()); |
| 231 DCHECK(!chars->is_empty()); | 231 DCHECK(!chars->is_empty()); |
| 232 DCHECK(!glyphs->is_reversed()); | 232 DCHECK(!glyphs->is_reversed()); |
| 233 DCHECK(!glyphs->is_empty()); | 233 DCHECK(!glyphs->is_empty()); |
| 234 } | 234 } |
| 235 | 235 |
| 236 // Returns the line segment index for the |line|, |text_x| pair. |text_x| is |
| 237 // relative to text in the given line. Returns -1 if |text_x| is to the left |
| 238 // of text in the line and |line|.segments.size() if it's to the right. |
| 239 // |offset_relative_segment| will contain the offset of |text_x| relative to |
| 240 // the start of the segment it is contained in. |
| 241 int GetLineSegmentContainingXCoord(const internal::Line& line, |
| 242 float line_x, |
| 243 float* offset_relative_segment) { |
| 244 DCHECK(offset_relative_segment); |
| 245 |
| 246 *offset_relative_segment = 0; |
| 247 if (line_x < 0) |
| 248 return -1; |
| 249 for (size_t i = 0; i < line.segments.size(); i++) { |
| 250 const internal::LineSegment& segment = line.segments[i]; |
| 251 |
| 252 // segment.x_range is not used because it is in text space. |
| 253 if (line_x < segment.width()) { |
| 254 *offset_relative_segment = line_x; |
| 255 return i; |
| 256 } |
| 257 line_x -= segment.width(); |
| 258 } |
| 259 return line.segments.size(); |
| 260 } |
| 261 |
| 236 // Internal class to generate Line structures. If |multiline| is true, the text | 262 // Internal class to generate Line structures. If |multiline| is true, the text |
| 237 // is broken into lines at |words| boundaries such that each line is no longer | 263 // is broken into lines at |words| boundaries such that each line is no longer |
| 238 // than |max_width|. If |multiline| is false, only outputs a single Line from | 264 // than |max_width|. If |multiline| is false, only outputs a single Line from |
| 239 // the given runs. |min_baseline| and |min_height| are the minimum baseline and | 265 // the given runs. |min_baseline| and |min_height| are the minimum baseline and |
| 240 // height for each line. | 266 // height for each line. |
| 241 // TODO(ckocagil): Expose the interface of this class in the header and test | 267 // TODO(ckocagil): Expose the interface of this class in the header and test |
| 242 // this class directly. | 268 // this class directly. |
| 243 class HarfBuzzLineBreaker { | 269 class HarfBuzzLineBreaker { |
| 244 public: | 270 public: |
| 245 HarfBuzzLineBreaker(size_t max_width, | 271 HarfBuzzLineBreaker(size_t max_width, |
| (...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 LogicalCursorDirection affinity = caret.caret_affinity(); | 1306 LogicalCursorDirection affinity = caret.caret_affinity(); |
| 1281 internal::TextRunList* run_list = GetRunList(); | 1307 internal::TextRunList* run_list = GetRunList(); |
| 1282 for (size_t i = 0; i < run_list->size(); ++i) { | 1308 for (size_t i = 0; i < run_list->size(); ++i) { |
| 1283 internal::TextRunHarfBuzz* run = run_list->runs()[i]; | 1309 internal::TextRunHarfBuzz* run = run_list->runs()[i]; |
| 1284 if (RangeContainsCaret(run->range, layout_position, affinity)) | 1310 if (RangeContainsCaret(run->range, layout_position, affinity)) |
| 1285 return i; | 1311 return i; |
| 1286 } | 1312 } |
| 1287 return run_list->size(); | 1313 return run_list->size(); |
| 1288 } | 1314 } |
| 1289 | 1315 |
| 1290 int RenderTextHarfBuzz::GetLineContainingYCoord(float text_y) { | |
| 1291 if (text_y < 0) | |
| 1292 return -1; | |
| 1293 | |
| 1294 for (size_t i = 0; i < lines().size(); i++) { | |
| 1295 const internal::Line& line = lines()[i]; | |
| 1296 | |
| 1297 if (text_y <= line.size.height()) | |
| 1298 return i; | |
| 1299 text_y -= line.size.height(); | |
| 1300 } | |
| 1301 | |
| 1302 return lines().size(); | |
| 1303 } | |
| 1304 | |
| 1305 int RenderTextHarfBuzz::GetLineSegmentContainingXCoord( | |
| 1306 const internal::Line& line, | |
| 1307 float line_x, | |
| 1308 float* offset_relative_segment) { | |
| 1309 DCHECK(offset_relative_segment); | |
| 1310 | |
| 1311 *offset_relative_segment = 0; | |
| 1312 if (line_x < 0) | |
| 1313 return -1; | |
| 1314 for (size_t i = 0; i < line.segments.size(); i++) { | |
| 1315 const internal::LineSegment& segment = line.segments[i]; | |
| 1316 | |
| 1317 // segment.x_range is not used because it is in text space. | |
| 1318 if (line_x < segment.width()) { | |
| 1319 *offset_relative_segment = line_x; | |
| 1320 return i; | |
| 1321 } | |
| 1322 line_x -= segment.width(); | |
| 1323 } | |
| 1324 return line.segments.size(); | |
| 1325 } | |
| 1326 | |
| 1327 SelectionModel RenderTextHarfBuzz::FirstSelectionModelInsideRun( | 1316 SelectionModel RenderTextHarfBuzz::FirstSelectionModelInsideRun( |
| 1328 const internal::TextRunHarfBuzz* run) { | 1317 const internal::TextRunHarfBuzz* run) { |
| 1329 size_t position = DisplayIndexToTextIndex(run->range.start()); | 1318 size_t position = DisplayIndexToTextIndex(run->range.start()); |
| 1330 position = IndexOfAdjacentGrapheme(position, CURSOR_FORWARD); | 1319 position = IndexOfAdjacentGrapheme(position, CURSOR_FORWARD); |
| 1331 return SelectionModel(position, CURSOR_BACKWARD); | 1320 return SelectionModel(position, CURSOR_BACKWARD); |
| 1332 } | 1321 } |
| 1333 | 1322 |
| 1334 SelectionModel RenderTextHarfBuzz::LastSelectionModelInsideRun( | 1323 SelectionModel RenderTextHarfBuzz::LastSelectionModelInsideRun( |
| 1335 const internal::TextRunHarfBuzz* run) { | 1324 const internal::TextRunHarfBuzz* run) { |
| 1336 size_t position = DisplayIndexToTextIndex(run->range.end()); | 1325 size_t position = DisplayIndexToTextIndex(run->range.end()); |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1702 | 1691 |
| 1703 attribute.strike = run.strike; | 1692 attribute.strike = run.strike; |
| 1704 attribute.diagonal_strike = run.diagonal_strike; | 1693 attribute.diagonal_strike = run.diagonal_strike; |
| 1705 decorated_text->attributes.push_back(attribute); | 1694 decorated_text->attributes.push_back(attribute); |
| 1706 } | 1695 } |
| 1707 } | 1696 } |
| 1708 return true; | 1697 return true; |
| 1709 } | 1698 } |
| 1710 | 1699 |
| 1711 } // namespace gfx | 1700 } // namespace gfx |
| OLD | NEW |