summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/aapt2/cmd/Link.cpp30
-rw-r--r--tools/aapt2/java/JavaClassGenerator.cpp64
-rw-r--r--tools/aapt2/java/JavaClassGenerator.h16
-rw-r--r--tools/aapt2/jni/aapt2_jni.cpp8
-rw-r--r--tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h8
-rw-r--r--tools/aapt2/xml/XmlDom.cpp5
-rw-r--r--tools/aapt2/xml/XmlDom.h7
-rwxr-xr-xtools/fonts/fontchain_lint.py98
-rw-r--r--tools/layoutlib/Android.mk9
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java2
10 files changed, 188 insertions, 59 deletions
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 48eae4d72814..b86188fa8503 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -87,6 +87,7 @@ struct LinkOptions {
Maybe<std::string> generate_java_class_path;
Maybe<std::string> custom_java_package;
std::set<std::string> extra_java_packages;
+ Maybe<std::string> generate_text_symbols_path;
Maybe<std::string> generate_proguard_rules_path;
Maybe<std::string> generate_main_dex_proguard_rules_path;
bool generate_non_final_ids = false;
@@ -376,8 +377,8 @@ bool ResourceFileFlattener::LinkAndVersionXmlFile(ResourceTable* table, FileOper
versioned_file_desc.config.sdkVersion = (uint16_t)sdk_level;
FileOperation new_file_op;
- new_file_op.xml_to_flatten =
- util::make_unique<xml::XmlResource>(versioned_file_desc, doc->root->Clone());
+ new_file_op.xml_to_flatten = util::make_unique<xml::XmlResource>(
+ versioned_file_desc, StringPool{}, doc->root->Clone());
new_file_op.config = versioned_file_desc.config;
new_file_op.entry = file_op->entry;
new_file_op.dst_path =
@@ -837,8 +838,8 @@ class LinkCommand {
}
bool WriteJavaFile(ResourceTable* table, const StringPiece& package_name_to_generate,
- const StringPiece& out_package,
- const JavaClassGeneratorOptions& java_options) {
+ const StringPiece& out_package, const JavaClassGeneratorOptions& java_options,
+ const Maybe<std::string> out_text_symbols_path = {}) {
if (!options_.generate_java_class_path) {
return true;
}
@@ -861,8 +862,20 @@ class LinkCommand {
return false;
}
+ std::unique_ptr<std::ofstream> fout_text;
+ if (out_text_symbols_path) {
+ fout_text =
+ util::make_unique<std::ofstream>(out_text_symbols_path.value(), std::ofstream::binary);
+ if (!*fout_text) {
+ context_->GetDiagnostics()->Error(
+ DiagMessage() << "failed writing to '" << out_text_symbols_path.value()
+ << "': " << android::base::SystemErrorCodeToString(errno));
+ return false;
+ }
+ }
+
JavaClassGenerator generator(context_, table, java_options);
- if (!generator.Generate(package_name_to_generate, out_package, &fout)) {
+ if (!generator.Generate(package_name_to_generate, out_package, &fout, fout_text.get())) {
context_->GetDiagnostics()->Error(DiagMessage(out_path) << generator.getError());
return false;
}
@@ -1683,7 +1696,8 @@ class LinkCommand {
std::move(packages_to_callback);
}
- if (!WriteJavaFile(&final_table_, actual_package, output_package, options)) {
+ if (!WriteJavaFile(&final_table_, actual_package, output_package, options,
+ options_.generate_text_symbols_path)) {
return 1;
}
}
@@ -1841,6 +1855,10 @@ int Link(const std::vector<StringPiece>& args) {
.OptionalFlagList("--add-javadoc-annotation",
"Adds a JavaDoc annotation to all generated Java classes.",
&options.javadoc_annotations)
+ .OptionalFlag("--output-text-symbols",
+ "Generates a text file containing the resource symbols of the R class in\n"
+ "the specified folder.",
+ &options.generate_text_symbols_path)
.OptionalSwitch("--auto-add-overlay",
"Allows the addition of new resources in overlays without\n"
"<add-resource> tags.",
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index 68bdb959ca07..a8226c0a9082 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -22,6 +22,7 @@
#include <sstream>
#include <tuple>
+#include "android-base/errors.h"
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
#include "androidfw/StringPiece.h"
@@ -227,7 +228,8 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
const Styleable& styleable,
const StringPiece& package_name_to_generate,
ClassDefinition* out_class_def,
- MethodDefinition* out_rewrite_method) {
+ MethodDefinition* out_rewrite_method,
+ std::ostream* out_r_txt) {
const std::string array_field_name = TransformToFieldName(name.entry);
std::unique_ptr<ResourceArrayMember> array_def =
util::make_unique<ResourceArrayMember>(array_field_name);
@@ -328,10 +330,25 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
array_def->GetCommentBuilder()->AppendComment(styleable_comment.str());
}
+ if (out_r_txt != nullptr) {
+ *out_r_txt << "int[] styleable " << array_field_name << " {";
+ }
+
// Add the ResourceIds to the array member.
- for (const StyleableAttr& styleable_attr : sorted_attributes) {
- const ResourceId id = styleable_attr.attr_ref->id.value_or_default(ResourceId(0));
+ for (size_t i = 0; i < attr_count; i++) {
+ const ResourceId id = sorted_attributes[i].attr_ref->id.value_or_default(ResourceId(0));
array_def->AddElement(id);
+
+ if (out_r_txt != nullptr) {
+ if (i != 0) {
+ *out_r_txt << ",";
+ }
+ *out_r_txt << " " << id;
+ }
+ }
+
+ if (out_r_txt != nullptr) {
+ *out_r_txt << " }\n";
}
// Add the Styleable array to the Styleable class.
@@ -386,6 +403,11 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
attr_processor->AppendComment(
StringPrintf("@attr name %s:%s", package_name.data(), attr_name.entry.data()));
+ if (out_r_txt != nullptr) {
+ *out_r_txt << StringPrintf("int styleable %s %d\n", sorted_attributes[i].field_name.data(),
+ (int)i);
+ }
+
out_class_def->AddMember(std::move(index_member));
}
@@ -406,7 +428,8 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const ResourceId& id,
const ResourceEntry& entry, ClassDefinition* out_class_def,
- MethodDefinition* out_rewrite_method) {
+ MethodDefinition* out_rewrite_method,
+ std::ostream* out_r_txt) {
const std::string field_name = TransformToFieldName(name.entry);
std::unique_ptr<ResourceMember> resource_member =
util::make_unique<ResourceMember>(field_name, id);
@@ -434,6 +457,10 @@ void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const Reso
out_class_def->AddMember(std::move(resource_member));
+ if (out_r_txt != nullptr) {
+ *out_r_txt << "int " << name.type << " " << field_name << " " << id << "\n";
+ }
+
if (out_rewrite_method != nullptr) {
const StringPiece& type_str = ToString(name.type);
out_rewrite_method->AppendStatement(StringPrintf("%s.%s = (%s.%s & 0x00ffffff) | (p << 24);",
@@ -470,7 +497,8 @@ bool JavaClassGenerator::ProcessType(const StringPiece& package_name_to_generate
const ResourceTablePackage& package,
const ResourceTableType& type,
ClassDefinition* out_type_class_def,
- MethodDefinition* out_rewrite_method_def) {
+ MethodDefinition* out_rewrite_method_def,
+ std::ostream* out_r_txt) {
for (const auto& entry : type.entries) {
const Maybe<std::string> unmangled_name =
UnmangleResource(package.name, package_name_to_generate, *entry);
@@ -505,15 +533,17 @@ bool JavaClassGenerator::ProcessType(const StringPiece& package_name_to_generate
static_cast<const Styleable*>(entry->values.front()->value.get());
ProcessStyleable(resource_name, id, *styleable, package_name_to_generate, out_type_class_def,
- out_rewrite_method_def);
+ out_rewrite_method_def, out_r_txt);
} else {
- ProcessResource(resource_name, id, *entry, out_type_class_def, out_rewrite_method_def);
+ ProcessResource(resource_name, id, *entry, out_type_class_def, out_rewrite_method_def,
+ out_r_txt);
}
}
return true;
}
-bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, std::ostream* out) {
+bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate, std::ostream* out,
+ std::ostream* out_r_txt) {
return Generate(package_name_to_generate, package_name_to_generate, out);
}
@@ -527,8 +557,8 @@ static void AppendJavaDocAnnotations(const std::vector<std::string>& annotations
}
bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
- const StringPiece& out_package_name,
- std::ostream* out) {
+ const StringPiece& out_package_name, std::ostream* out,
+ std::ostream* out_r_txt) {
ClassDefinition r_class("R", ClassQualifier::kNone, true);
std::unique_ptr<MethodDefinition> rewrite_method;
@@ -558,7 +588,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
std::unique_ptr<ClassDefinition> class_def = util::make_unique<ClassDefinition>(
ToString(type->type), ClassQualifier::kStatic, force_creation_if_empty);
if (!ProcessType(package_name_to_generate, *package, *type, class_def.get(),
- rewrite_method.get())) {
+ rewrite_method.get(), out_r_txt)) {
return false;
}
@@ -567,7 +597,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
const ResourceTableType* priv_type = package->FindType(ResourceType::kAttrPrivate);
if (priv_type) {
if (!ProcessType(package_name_to_generate, *package, *priv_type, class_def.get(),
- rewrite_method.get())) {
+ rewrite_method.get(), out_r_txt)) {
return false;
}
}
@@ -597,6 +627,16 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
}
out->flush();
+
+ if (out_r_txt != nullptr) {
+ out_r_txt->flush();
+
+ if (!*out_r_txt) {
+ error_ = android::base::SystemErrorCodeToString(errno);
+ return false;
+ }
+ }
+
return true;
}
diff --git a/tools/aapt2/java/JavaClassGenerator.h b/tools/aapt2/java/JavaClassGenerator.h
index 45104301e7f5..18746ffc5a0a 100644
--- a/tools/aapt2/java/JavaClassGenerator.h
+++ b/tools/aapt2/java/JavaClassGenerator.h
@@ -59,7 +59,7 @@ struct JavaClassGeneratorOptions {
std::vector<std::string> javadoc_annotations;
};
-// Generates the R.java file for a resource table.
+// Generates the R.java file for a resource table and optionally an R.txt file.
class JavaClassGenerator {
public:
JavaClassGenerator(IAaptContext* context, ResourceTable* table,
@@ -69,10 +69,12 @@ class JavaClassGenerator {
// All symbols technically belong to a single package, but linked libraries will
// have their names mangled, denoting that they came from a different package.
// We need to generate these symbols in a separate file. Returns true on success.
- bool Generate(const android::StringPiece& package_name_to_generate, std::ostream* out);
+ bool Generate(const android::StringPiece& package_name_to_generate, std::ostream* out,
+ std::ostream* out_r_txt = nullptr);
bool Generate(const android::StringPiece& package_name_to_generate,
- const android::StringPiece& output_package_name, std::ostream* out);
+ const android::StringPiece& output_package_name, std::ostream* out,
+ std::ostream* out_r_txt = nullptr);
const std::string& getError() const;
@@ -88,13 +90,14 @@ class JavaClassGenerator {
bool ProcessType(const android::StringPiece& package_name_to_generate,
const ResourceTablePackage& package, const ResourceTableType& type,
- ClassDefinition* out_type_class_def, MethodDefinition* out_rewrite_method_def);
+ ClassDefinition* out_type_class_def, MethodDefinition* out_rewrite_method_def,
+ std::ostream* out_r_txt);
// Writes a resource to the R.java file, optionally writing out a rewrite rule for its package
// ID if `out_rewrite_method` is not nullptr.
void ProcessResource(const ResourceNameRef& name, const ResourceId& id,
const ResourceEntry& entry, ClassDefinition* out_class_def,
- MethodDefinition* out_rewrite_method);
+ MethodDefinition* out_rewrite_method, std::ostream* out_r_txt);
// Writes a styleable resource to the R.java file, optionally writing out a rewrite rule for
// its package ID if `out_rewrite_method` is not nullptr.
@@ -102,7 +105,8 @@ class JavaClassGenerator {
void ProcessStyleable(const ResourceNameRef& name, const ResourceId& id,
const Styleable& styleable,
const android::StringPiece& package_name_to_generate,
- ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method);
+ ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method,
+ std::ostream* out_r_txt);
IAaptContext* context_;
ResourceTable* table_;
diff --git a/tools/aapt2/jni/aapt2_jni.cpp b/tools/aapt2/jni/aapt2_jni.cpp
index b029b20bcf15..ce3d282e6f9b 100644
--- a/tools/aapt2/jni/aapt2_jni.cpp
+++ b/tools/aapt2/jni/aapt2_jni.cpp
@@ -77,20 +77,20 @@ static std::vector<StringPiece> extract_pieces(const std::vector<ScopedUtfChars>
return pieces;
}
-JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeCompile(
+JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeCompile(
JNIEnv *env, jclass aapt_obj, jobject arguments_obj) {
std::vector<ScopedUtfChars> compile_args_jni =
list_to_utfchars(env, arguments_obj);
std::vector<StringPiece> compile_args = extract_pieces(compile_args_jni);
- aapt::Compile(compile_args);
+ return aapt::Compile(compile_args);
}
-JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeLink(
+JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeLink(
JNIEnv *env, jclass aapt_obj, jobject arguments_obj) {
std::vector<ScopedUtfChars> link_args_jni =
list_to_utfchars(env, arguments_obj);
std::vector<StringPiece> link_args = extract_pieces(link_args_jni);
- aapt::Link(link_args);
+ return aapt::Link(link_args);
}
JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_ping(
diff --git a/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h b/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h
index 56c3c18e3a1e..90150b4d731e 100644
--- a/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h
+++ b/tools/aapt2/jni/com_android_tools_aapt2_Aapt2Jni.h
@@ -18,17 +18,17 @@ JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_ping
/*
* Class: com_android_tools_aapt2_Aapt2Jni
* Method: nativeCompile
- * Signature: (Ljava/util/List;)V
+ * Signature: (Ljava/util/List;)I
*/
-JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeCompile
+JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeCompile
(JNIEnv *, jclass, jobject);
/*
* Class: com_android_tools_aapt2_Aapt2Jni
* Method: nativeLink
- * Signature: (Ljava/util/List;)V
+ * Signature: (Ljava/util/List;)I
*/
-JNIEXPORT void JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeLink
+JNIEXPORT jint JNICALL Java_com_android_tools_aapt2_Aapt2Jni_nativeLink
(JNIEnv *, jclass, jobject);
#ifdef __cplusplus
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index 4a278f632a4a..60551901fe8d 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -224,7 +224,8 @@ std::unique_ptr<XmlResource> Inflate(std::istream* in, IDiagnostics* diag, const
XML_ParserFree(parser);
if (stack.root) {
- return util::make_unique<XmlResource>(ResourceFile{{}, {}, source}, std::move(stack.root));
+ return util::make_unique<XmlResource>(ResourceFile{{}, {}, source}, StringPool{},
+ std::move(stack.root));
}
return {};
}
@@ -357,7 +358,7 @@ std::unique_ptr<XmlResource> Inflate(const void* data, size_t data_len, IDiagnos
}
}
}
- return util::make_unique<XmlResource>(ResourceFile{}, std::move(root), std::move(string_pool));
+ return util::make_unique<XmlResource>(ResourceFile{}, std::move(string_pool), std::move(root));
}
std::unique_ptr<Node> Namespace::Clone() {
diff --git a/tools/aapt2/xml/XmlDom.h b/tools/aapt2/xml/XmlDom.h
index f1d0953c5494..6950c307abf3 100644
--- a/tools/aapt2/xml/XmlDom.h
+++ b/tools/aapt2/xml/XmlDom.h
@@ -128,8 +128,13 @@ class Text : public BaseNode<Text> {
class XmlResource {
public:
ResourceFile file;
- std::unique_ptr<xml::Node> root;
+
+ // StringPool must come before the xml::Node. Destructors are called in reverse order, and
+ // the xml::Node may have StringPool references that need to be destroyed before the StringPool
+ // is destroyed.
StringPool string_pool;
+
+ std::unique_ptr<xml::Node> root;
};
/**
diff --git a/tools/fonts/fontchain_lint.py b/tools/fonts/fontchain_lint.py
index baee21c315d6..f5b904220f76 100755
--- a/tools/fonts/fontchain_lint.py
+++ b/tools/fonts/fontchain_lint.py
@@ -126,7 +126,10 @@ def get_emoji_map(font):
# Add GSUB rules
ttfont = open_font(font)
for lookup in ttfont['GSUB'].table.LookupList.Lookup:
- assert lookup.LookupType == 4, 'We only understand type 4 lookups'
+ if lookup.LookupType != 4:
+ # Other lookups are used in the emoji font for fallback.
+ # We ignore them for now.
+ continue
for subtable in lookup.SubTable:
ligatures = subtable.ligatures
for first_glyph in ligatures:
@@ -385,7 +388,7 @@ def parse_unicode_datafile(file_path, reverse=False):
return output_dict
-def parse_standardized_variants(file_path):
+def parse_emoji_variants(file_path):
emoji_set = set()
text_set = set()
with open(file_path) as datafile:
@@ -420,8 +423,8 @@ def parse_ucd(ucd_path):
_chars_by_age = parse_unicode_datafile(
path.join(ucd_path, 'DerivedAge.txt'), reverse=True)
- sequences = parse_standardized_variants(
- path.join(ucd_path, 'StandardizedVariants.txt'))
+ sequences = parse_emoji_variants(
+ path.join(ucd_path, 'emoji-variation-sequences.txt'))
_text_variation_sequences, _emoji_variation_sequences = sequences
_emoji_sequences = parse_unicode_datafile(
path.join(ucd_path, 'emoji-sequences.txt'))
@@ -442,8 +445,7 @@ UNSUPPORTED_FLAGS = frozenset({
flag_sequence('GF'), flag_sequence('GP'), flag_sequence('GS'),
flag_sequence('MF'), flag_sequence('MQ'), flag_sequence('NC'),
flag_sequence('PM'), flag_sequence('RE'), flag_sequence('TF'),
- flag_sequence('UN'), flag_sequence('WF'), flag_sequence('XK'),
- flag_sequence('YT'),
+ flag_sequence('WF'), flag_sequence('XK'), flag_sequence('YT'),
})
EQUIVALENT_FLAGS = {
@@ -489,6 +491,55 @@ ZWJ_IDENTICALS = {
(0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F466): 0x1F46A,
}
+ZWJ = 0x200D
+FEMALE_SIGN = 0x2640
+MALE_SIGN = 0x2642
+
+GENDER_DEFAULTS = [
+ (0x26F9, MALE_SIGN), # PERSON WITH BALL
+ (0x1F3C3, MALE_SIGN), # RUNNER
+ (0x1F3C4, MALE_SIGN), # SURFER
+ (0x1F3CA, MALE_SIGN), # SWIMMER
+ (0x1F3CB, MALE_SIGN), # WEIGHT LIFTER
+ (0x1F3CC, MALE_SIGN), # GOLFER
+ (0x1F46E, MALE_SIGN), # POLICE OFFICER
+ (0x1F46F, FEMALE_SIGN), # WOMAN WITH BUNNY EARS
+ (0x1F471, MALE_SIGN), # PERSON WITH BLOND HAIR
+ (0x1F473, MALE_SIGN), # MAN WITH TURBAN
+ (0x1F477, MALE_SIGN), # CONSTRUCTION WORKER
+ (0x1F481, FEMALE_SIGN), # INFORMATION DESK PERSON
+ (0x1F482, MALE_SIGN), # GUARDSMAN
+ (0x1F486, FEMALE_SIGN), # FACE MASSAGE
+ (0x1F487, FEMALE_SIGN), # HAIRCUT
+ (0x1F575, MALE_SIGN), # SLEUTH OR SPY
+ (0x1F645, FEMALE_SIGN), # FACE WITH NO GOOD GESTURE
+ (0x1F646, FEMALE_SIGN), # FACE WITH OK GESTURE
+ (0x1F647, MALE_SIGN), # PERSON BOWING DEEPLY
+ (0x1F64B, FEMALE_SIGN), # HAPPY PERSON RAISING ONE HAND
+ (0x1F64D, FEMALE_SIGN), # PERSON FROWNING
+ (0x1F64E, FEMALE_SIGN), # PERSON WITH POUTING FACE
+ (0x1F6A3, MALE_SIGN), # ROWBOAT
+ (0x1F6B4, MALE_SIGN), # BICYCLIST
+ (0x1F6B5, MALE_SIGN), # MOUNTAIN BICYCLIST
+ (0x1F6B6, MALE_SIGN), # PEDESTRIAN
+ (0x1F926, FEMALE_SIGN), # FACE PALM
+ (0x1F937, FEMALE_SIGN), # SHRUG
+ (0x1F938, MALE_SIGN), # PERSON DOING CARTWHEEL
+ (0x1F939, MALE_SIGN), # JUGGLING
+ (0x1F93C, MALE_SIGN), # WRESTLERS
+ (0x1F93D, MALE_SIGN), # WATER POLO
+ (0x1F93E, MALE_SIGN), # HANDBALL
+ (0x1F9D6, FEMALE_SIGN), # PERSON IN STEAMY ROOM
+ (0x1F9D7, FEMALE_SIGN), # PERSON CLIMBING
+ (0x1F9D8, FEMALE_SIGN), # PERSON IN LOTUS POSITION
+ (0x1F9D9, FEMALE_SIGN), # MAGE
+ (0x1F9DA, FEMALE_SIGN), # FAIRY
+ (0x1F9DB, FEMALE_SIGN), # VAMPIRE
+ (0x1F9DC, FEMALE_SIGN), # MERPERSON
+ (0x1F9DD, FEMALE_SIGN), # ELF
+ (0x1F9DE, FEMALE_SIGN), # GENIE
+ (0x1F9DF, FEMALE_SIGN), # ZOMBIE
+]
def is_fitzpatrick_modifier(cp):
return 0x1F3FB <= cp <= 0x1F3FF
@@ -514,10 +565,20 @@ def compute_expected_emoji():
adjusted_emoji_zwj_sequences = dict(_emoji_zwj_sequences)
adjusted_emoji_zwj_sequences.update(_emoji_zwj_sequences)
+ # Add empty flag tag sequence that is supported as fallback
+ _emoji_sequences[(0x1F3F4, 0xE007F)] = 'Emoji_Tag_Sequence'
+
for sequence in _emoji_sequences.keys():
sequence = tuple(ch for ch in sequence if ch != EMOJI_VS)
all_sequences.add(sequence)
sequence_pieces.update(sequence)
+ if _emoji_sequences.get(sequence, None) == 'Emoji_Tag_Sequence':
+ # Add reverse of all emoji ZWJ sequences, which are added to the fonts
+ # as a workaround to get the sequences work in RTL text.
+ # TODO: test if these are actually needed by Minikin/HarfBuzz.
+ reversed_seq = reverse_emoji(sequence)
+ all_sequences.add(reversed_seq)
+ equivalent_emoji[reversed_seq] = sequence
for sequence in adjusted_emoji_zwj_sequences.keys():
sequence = tuple(ch for ch in sequence if ch != EMOJI_VS)
@@ -529,13 +590,12 @@ def compute_expected_emoji():
all_sequences.add(reversed_seq)
equivalent_emoji[reversed_seq] = sequence
- # Add all two-letter flag sequences, as even the unsupported ones should
- # resolve to a flag tofu.
- all_letters = [chr(code) for code in range(ord('A'), ord('Z')+1)]
- all_two_letter_codes = itertools.product(all_letters, repeat=2)
- all_flags = {flag_sequence(code) for code in all_two_letter_codes}
- all_sequences.update(all_flags)
- tofu_flags = UNSUPPORTED_FLAGS | (all_flags - set(_emoji_sequences.keys()))
+ # Remove unsupported flags
+ all_sequences.difference_update(UNSUPPORTED_FLAGS)
+
+ # Add all tag characters used in flags
+ sequence_pieces.update(range(0xE0030, 0xE0039 + 1))
+ sequence_pieces.update(range(0xE0061, 0xE007A + 1))
all_emoji = (
_emoji_properties['Emoji'] |
@@ -547,13 +607,17 @@ def compute_expected_emoji():
all_sequences |
set(LEGACY_ANDROID_EMOJI.keys()))
- first_tofu_flag = sorted(tofu_flags)[0]
- for flag in tofu_flags:
- if flag != first_tofu_flag:
- equivalent_emoji[flag] = first_tofu_flag
equivalent_emoji.update(EQUIVALENT_FLAGS)
equivalent_emoji.update(LEGACY_ANDROID_EMOJI)
equivalent_emoji.update(ZWJ_IDENTICALS)
+
+ for ch, gender in GENDER_DEFAULTS:
+ equivalent_emoji[(ch, ZWJ, gender)] = ch
+ for skin_tone in range(0x1F3FB, 0x1F3FF+1):
+ skin_toned = (ch, skin_tone, ZWJ, gender)
+ if skin_toned in all_emoji:
+ equivalent_emoji[skin_toned] = (ch, skin_tone)
+
for seq in _emoji_variation_sequences:
equivalent_emoji[seq] = seq[0]
diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk
index f87f6c53c8dc..29c933ac7e75 100644
--- a/tools/layoutlib/Android.mk
+++ b/tools/layoutlib/Android.mk
@@ -36,20 +36,18 @@ built_core_classes := $(call java-lib-files,core-libart)
built_ext_dep := $(call java-lib-deps,ext)
built_ext_classes := $(call java-lib-files,ext)
-built_ext_data := $(call intermediates-dir-for, \
- JAVA_LIBRARIES,ext,,COMMON)/javalib.jar
+
built_icudata_dep := $(call java-lib-deps,icu4j-icudata-host-jarjar,HOST)
built_icutzdata_dep := $(call java-lib-deps,icu4j-icutzdata-host-jarjar,HOST)
-built_layoutlib_create_jar := $(call intermediates-dir-for, \
- JAVA_LIBRARIES,layoutlib_create,HOST)/javalib.jar
+built_layoutlib_create_jar := $(call java-lib-files,layoutlib_create,HOST)
# This is mostly a copy of config/host_java_library.mk
LOCAL_MODULE := temp_layoutlib
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX)
LOCAL_IS_HOST_MODULE := true
-LOCAL_BUILT_MODULE_STEM := javalib.jar
+LOCAL_BUILT_MODULE_STEM := classes.jar
#######################################
include $(BUILD_SYSTEM)/base_rules.mk
@@ -59,7 +57,6 @@ $(LOCAL_BUILT_MODULE): $(built_oj_dep) \
$(built_core_dep) \
$(built_framework_dep) \
$(built_ext_dep) \
- $(built_ext_data) \
$(built_icudata_dep) \
$(built_icutzdata_dep) \
$(built_layoutlib_create_jar)
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index a21fe68e9003..78b6f7187af3 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -45,7 +45,7 @@ import java.util.Map;
import java.util.Scanner;
import java.util.Set;
-import static android.graphics.Typeface.Builder.RESOLVE_BY_FONT_TABLE;
+import static android.graphics.Typeface.RESOLVE_BY_FONT_TABLE;
import static android.graphics.Typeface_Delegate.SYSTEM_FONTS;
/**