1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/fonts/symbols_iterator.h"
#include <unicode/uchar.h>
#include <unicode/uniset.h>
#include <memory>
#include "third_party/blink/renderer/platform/fonts/utf16_ragel_iterator.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/text/character.h"
namespace blink {
namespace {
using emoji_text_iter_t = UTF16RagelIterator;
// Scanner code generated by Ragel and imported from third_party.
#include "third_party/emoji-segmenter/src/emoji_presentation_scanner.c"
} // namespace
SymbolsIterator::SymbolsIterator(base::span<const UChar> buffer) {
if (!buffer.empty()) {
buffer_iterator_ = UTF16RagelIterator(buffer);
next_token_end_ = cursor_ + (scan_emoji_presentation(
buffer_iterator_, buffer_iterator_.end(),
&next_token_emoji_, &next_token_has_vs_) -
buffer_iterator_);
}
}
bool SymbolsIterator::Consume(unsigned* symbols_limit,
FontFallbackPriority* font_fallback_priority) {
if (cursor_ >= buffer_iterator_.size()) {
return false;
}
bool current_token_emoji = false;
bool curr_has_vs = false;
do {
cursor_ = next_token_end_;
current_token_emoji = next_token_emoji_;
curr_has_vs = next_token_has_vs_;
if (cursor_ >= buffer_iterator_.end().Cursor())
break;
if (!current_token_emoji &&
!Character::MaybeEmojiPresentation(buffer_iterator_.PeekCodepoint())) {
++buffer_iterator_;
next_token_end_ = buffer_iterator_.Cursor();
next_token_has_vs_ = false;
continue;
}
buffer_iterator_.SetCursor(cursor_);
next_token_end_ = cursor_ + (scan_emoji_presentation(
buffer_iterator_, buffer_iterator_.end(),
&next_token_emoji_, &next_token_has_vs_) -
buffer_iterator_);
} while (current_token_emoji == next_token_emoji_ &&
(curr_has_vs == next_token_has_vs_));
if (curr_has_vs) {
*font_fallback_priority = current_token_emoji
? FontFallbackPriority::kEmojiEmojiWithVS
: FontFallbackPriority::kEmojiTextWithVS;
} else {
*font_fallback_priority = current_token_emoji
? FontFallbackPriority::kEmojiEmoji
: FontFallbackPriority::kText;
}
*symbols_limit = cursor_;
return true;
}
} // namespace blink
|