| OLD | NEW |
| (Empty) |
| 1 // | |
| 2 // Copyright 2014 Google Inc. All rights reserved. | |
| 3 // | |
| 4 // Use of this source code is governed by a BSD-style | |
| 5 // license that can be found in the LICENSE file or at | |
| 6 // https://developers.google.com/open-source/licenses/bsd | |
| 7 // | |
| 8 | |
| 9 library charted.core.text_metrics.segmentation; | |
| 10 | |
| 11 import "package:charted/core/text_metrics/segmentation_utils.dart"; | |
| 12 import "package:charted/core/text_metrics/segmentation_data.dart"; | |
| 13 | |
| 14 /// Current unicode version. | |
| 15 /// Character database available at http://www.unicode.org/Public/7.0.0/ucd/ | |
| 16 const UNICODE_VERSION = '7.0.0'; | |
| 17 | |
| 18 // Code table based on: | |
| 19 // http://www.unicode.org/Public/7.0.0/ucd/auxiliary/GraphemeBreakTest.html | |
| 20 // GRAPHEME_BREAK_TABLE[prevType * TYPE_COUNT + curType] == 1 means break. | |
| 21 const GRAPHEME_BREAK_TABLE = const[ | |
| 22 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, | |
| 23 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 24 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 25 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 26 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, | |
| 27 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, | |
| 28 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, | |
| 29 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, | |
| 30 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, | |
| 31 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, | |
| 32 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, | |
| 33 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0 | |
| 34 ]; | |
| 35 | |
| 36 /// Get type of a given char code. | |
| 37 int _typeForRune(int rune) { | |
| 38 int count = CODE_POINT_BLOCKS.length ~/ 3; | |
| 39 int min = 0; | |
| 40 int max = count - 1; | |
| 41 while (max >= min) { | |
| 42 int mid = (max + min) ~/ 2; | |
| 43 int idx = mid * 3; | |
| 44 if (CODE_POINT_BLOCKS[idx] <= rune && rune <= CODE_POINT_BLOCKS[idx+1]) { | |
| 45 return CODE_POINT_BLOCKS[idx+2]; // Return the found character type | |
| 46 } | |
| 47 if (CODE_POINT_BLOCKS[idx] > rune) { | |
| 48 max = mid - 1; | |
| 49 } | |
| 50 else if (CODE_POINT_BLOCKS[idx+1] < rune) { | |
| 51 min = max + 1; | |
| 52 } | |
| 53 } | |
| 54 return CODE_CATEGORY_OTHER; // Defaults to OTHER. | |
| 55 } | |
| 56 | |
| 57 Iterable<int> graphemeBreakIndices(String s) { | |
| 58 List<int> indices = []; | |
| 59 int previousType = 0; | |
| 60 for (var iter = s.runes.iterator; iter.moveNext();) { | |
| 61 int currentType = _typeForRune(iter.current); | |
| 62 if (GRAPHEME_BREAK_TABLE[previousType * 12 + currentType] == 1) { | |
| 63 indices.add(iter.rawIndex); | |
| 64 } | |
| 65 previousType = currentType; | |
| 66 } | |
| 67 return indices; | |
| 68 } | |
| OLD | NEW |