Add command line option to supply --font-directory=<dir>

Change-Id: If3036a32a82249c9c95d2c5722bdb5ab097c20a1
This commit is contained in:
Gary Qian
2017-06-05 12:08:21 -07:00
parent 79f20a8886
commit 63bc51106c
12 changed files with 133 additions and 26 deletions

View File

@@ -21,6 +21,7 @@
#include "lib/ftl/logging.h"
#include "lib/txt/src/font_skia.h"
#include "third_party/skia/include/ports/SkFontMgr.h"
#include "third_party/skia/include/ports/SkFontMgr_directory.h"
namespace txt {
@@ -36,17 +37,21 @@ FontCollection::FontCollection() = default;
FontCollection::~FontCollection() = default;
std::shared_ptr<minikin::FontCollection>
FontCollection::GetMinikinFontCollectionForFamily(const std::string& family) {
FontCollection::GetMinikinFontCollectionForFamily(const std::string& family,
const std::string& dir) {
// Get the Skia font manager.
auto skia_font_manager = SkFontMgr::RefDefault();
auto skia_font_manager = dir.length() != 0
? SkFontMgr_New_Custom_Directory(dir.c_str())
: SkFontMgr::RefDefault();
FTL_DCHECK(skia_font_manager != nullptr);
// Ask Skia to resolve a font style set for a font family name.
// FIXME(chinmaygarde): The name "Hevetica" is hardcoded because CoreText
// FIXME(chinmaygarde): The name "Sample Font" is hardcoded because CoreText
// crashes when passed a null string. This seems to be a bug in Skia as
// SkFontMgr explicitly says passing in nullptr gives the default font.
auto font_style_set = skia_font_manager->matchFamily(
family.length() == 0 ? "Helvetica" : family.c_str());
family.length() == 0 ? "Sample Font" : family.c_str());
FTL_DCHECK(font_style_set != nullptr);
std::vector<minikin::Font> minikin_fonts;
@@ -56,7 +61,6 @@ FontCollection::GetMinikinFontCollectionForFamily(const std::string& family) {
// Create the skia typeface
auto skia_typeface =
sk_ref_sp<SkTypeface>(font_style_set->createTypeface(i));
if (skia_typeface == nullptr) {
continue;
}

View File

@@ -36,7 +36,8 @@ class FontCollection {
~FontCollection();
std::shared_ptr<minikin::FontCollection> GetMinikinFontCollectionForFamily(
const std::string& family);
const std::string& family,
const std::string& dir = "");
private:
// TODO(chinmaygarde): Caches go here.

View File

@@ -113,9 +113,9 @@ void Paragraph::SetText(std::vector<uint16_t> text, StyledRuns runs) {
breaker_.setText();
}
void Paragraph::AddRunsToLineBreaker() {
void Paragraph::AddRunsToLineBreaker(const std::string& rootdir) {
auto collection = FontCollection::GetDefaultFontCollection()
.GetMinikinFontCollectionForFamily("");
.GetMinikinFontCollectionForFamily("", rootdir);
minikin::FontStyle font;
minikin::MinikinPaint paint;
for (size_t i = 0; i < runs_.size(); ++i) {
@@ -125,9 +125,10 @@ void Paragraph::AddRunsToLineBreaker() {
}
}
void Paragraph::Layout(const ParagraphConstraints& constraints) {
void Paragraph::Layout(const ParagraphConstraints& constraints,
const std::string& rootdir) {
breaker_.setLineWidths(0.0f, 0, constraints.width());
AddRunsToLineBreaker();
AddRunsToLineBreaker(rootdir);
size_t breaks_count = breaker_.computeBreaks();
const int* breaks = breaker_.getBreaks();
@@ -140,7 +141,7 @@ void Paragraph::Layout(const ParagraphConstraints& constraints) {
SkTextBlobBuilder builder;
auto collection = FontCollection::GetDefaultFontCollection()
.GetMinikinFontCollectionForFamily("");
.GetMinikinFontCollectionForFamily("", rootdir);
minikin::Layout layout;
SkScalar x = 0.0f;
SkScalar y = 0.0f;

View File

@@ -36,7 +36,8 @@ class Paragraph {
~Paragraph();
void Layout(const ParagraphConstraints& constraints);
void Layout(const ParagraphConstraints& constraints,
const std::string& rootdir = "");
void Paint(SkCanvas* canvas, double x, double y);
@@ -50,7 +51,7 @@ class Paragraph {
void SetText(std::vector<uint16_t> text, StyledRuns runs);
void AddRunsToLineBreaker();
void AddRunsToLineBreaker(const std::string& rootdir = "");
FTL_DISALLOW_COPY_AND_ASSIGN(Paragraph);
};

View File

@@ -25,7 +25,10 @@ executable("txt") {
"font_collection_unittests.cc",
"paragraph_unittests.cc",
"render_test.cc",
"render_test.h",
"txt_run_all_unittests.cc",
"utils.cc",
"utils.h",
]
deps = [

View File

@@ -16,10 +16,14 @@
#include "font_collection.h"
#include "gtest/gtest.h"
#include "lib/ftl/command_line.h"
#include "lib/ftl/logging.h"
#include "lib/txt/tests/txt/utils.h"
TEST(FontCollection, HasDefaultRegistrations) {
auto collection = txt::FontCollection::GetDefaultFontCollection()
.GetMinikinFontCollectionForFamily("");
auto collection =
txt::FontCollection::GetDefaultFontCollection()
.GetMinikinFontCollectionForFamily("", txt::GetFontDir());
ASSERT_NE(collection.get(), nullptr);
}

View File

@@ -14,6 +14,8 @@
* limitations under the License.
*/
#include "lib/ftl/logging.h"
#include "lib/txt/tests/txt/utils.h"
#include "paragraph.h"
#include "paragraph_builder.h"
#include "render_test.h"
@@ -38,8 +40,8 @@ TEST_F(RenderTest, SimpleParagraph) {
builder.Pop();
auto paragraph = builder.Build();
paragraph->Layout(txt::ParagraphConstraints{GetTestCanvasWidth()});
paragraph->Layout(txt::ParagraphConstraints{GetTestCanvasWidth()},
txt::GetFontDir());
paragraph->Paint(GetCanvas(), 10.0, 10.0);

View File

@@ -16,9 +16,26 @@
#include "flutter/fml/icu_util.h"
#include "gtest/gtest.h"
#include "lib/ftl/command_line.h"
#include "lib/ftl/logging.h"
#include "lib/txt/tests/txt/utils.h"
#include "third_party/skia/include/core/SkGraphics.h"
#include <cassert>
int main(int argc, char** argv) {
ftl::CommandLine cmd = ftl::CommandLineFromArgcArgv(argc, argv);
txt::SetCommandLine(cmd);
std::string dir = txt::GetCommandLineForProcess().GetOptionValueWithDefault(
"font-directory", "");
txt::SetFontDir(dir);
if (txt::GetFontDir().length() <= 0) {
FTL_LOG(ERROR) << "Font directory must be specified with "
"--font-directoy=\"<directoy>\" to run this test.";
return EXIT_FAILURE;
}
FTL_DCHECK(txt::GetFontDir().length() > 0);
fml::icu::InitializeICU();
SkGraphics::Init();
testing::InitGoogleTest(&argc, argv);

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2017 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string>
#include "lib/ftl/command_line.h"
#include "lib/txt/tests/txt/utils.h"
namespace txt {
static std::string gFontdir;
static ftl::CommandLine gCommandLine;
const std::string GetFontDir() {
return gFontdir;
}
void SetFontDir(std::string& dir) {
gFontdir = dir;
}
const ftl::CommandLine& GetCommandLineForProcess() {
return gCommandLine;
}
void SetCommandLine(ftl::CommandLine cmd) {
gCommandLine = std::move(cmd);
}
} // namespace txt

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2017 Google, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string>
#include "lib/ftl/command_line.h"
namespace txt {
const std::string GetFontDir();
void SetFontDir(std::string& dir);
const ftl::CommandLine& GetCommandLineForProcess();
void SetCommandLine(ftl::CommandLine cmd);
} // namespace txt

View File

@@ -23,13 +23,14 @@
#include <vector>
std::vector<uint8_t> readWholeFile(const std::string& filePath) {
FILE* fp = fopen(filePath.c_str(), "r");
LOG_ALWAYS_FATAL_IF(fp == nullptr);
struct stat st;
LOG_ALWAYS_FATAL_IF(fstat(fileno(fp), &st) != 0);
FILE* fp = fopen(filePath.c_str(), "r");
LOG_ALWAYS_FATAL_IF(fp == nullptr);
struct stat st;
LOG_ALWAYS_FATAL_IF(fstat(fileno(fp), &st) != 0);
std::vector<uint8_t> result(st.st_size);
LOG_ALWAYS_FATAL_IF(fread(result.data(), 1, st.st_size, fp) != static_cast<size_t>(st.st_size));
fclose(fp);
return result;
std::vector<uint8_t> result(st.st_size);
LOG_ALWAYS_FATAL_IF(fread(result.data(), 1, st.st_size, fp) !=
static_cast<size_t>(st.st_size));
fclose(fp);
return result;
}

View File

@@ -15,4 +15,3 @@
*/
std::vector<uint8_t> readWholeFile(const std::string& filePath);