blob: 25f52a7316868338e70c05f4da069bb26ae2a2d0 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
class NotoFont {
const NotoFont(this.name, this.url, this._rangeStarts, this._rangeEnds);
factory NotoFont.fromFlatRanges(String name, String url, List<int> flatRanges) {
final List<int> starts = <int>[];
final List<int> ends = <int>[];
for (int i = 0; i < flatRanges.length; i += 2) {
starts.add(flatRanges[i]);
ends.add(flatRanges[i+1]);
}
return NotoFont(name, url, starts, ends);
}
final String name;
final String url;
// A sorted list of Unicode range start points.
final List<int> _rangeStarts;
// A sorted list of Unicode range end points.
final List<int> _rangeEnds;
List<CodeunitRange> computeUnicodeRanges() {
final List<CodeunitRange> result = <CodeunitRange>[];
for (int i = 0; i < _rangeStarts.length; i++) {
result.add(CodeunitRange(_rangeStarts[i], _rangeEnds[i]));
}
return result;
}
// Returns `true` if this font has a glyph for the given [codeunit].
bool contains(int codeUnit) {
// Binary search through the starts and ends to see if there
// is a range that contains the codeunit.
int min = 0;
int max = _rangeStarts.length - 1;
while (min <= max) {
final int mid = (min + max) ~/ 2;
if (_rangeStarts[mid] > codeUnit) {
max = mid - 1;
} else {
// _rangeStarts[mid] <= codeUnit
if (_rangeEnds[mid] >= codeUnit) {
return true;
}
min = mid + 1;
}
}
return false;
}
}
class CodeunitRange {
const CodeunitRange(this.start, this.end);
final int start;
final int end;
bool contains(int codeUnit) {
return start <= codeUnit && codeUnit <= end;
}
@override
bool operator ==(Object other) {
if (other is! CodeunitRange) {
return false;
}
final CodeunitRange range = other;
return range.start == start && range.end == end;
}
@override
int get hashCode => Object.hash(start, end);
@override
String toString() => '[$start, $end]';
}