!13491 font descriptor code 3

Merge pull request !13491 from changleipeng/font_descriptor_3
This commit is contained in:
openharmony_ci 2024-09-10 13:18:40 +00:00 committed by Gitee
commit 5909942f02
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
19 changed files with 857 additions and 83 deletions

View File

@ -0,0 +1,143 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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.
*/
#ifndef C_INCLUDE_DRAWING_TEXT_FONT_DESCRIPTOR_H
#define C_INCLUDE_DRAWING_TEXT_FONT_DESCRIPTOR_H
/**
* @addtogroup Drawing
* @{
*
* @brief Provides the font descriptor capability.
*
* @syscap SystemCapability.Graphic.Graphic2D.NativeDrawing
*
* @since 8
* @version 1.0
*/
/**
* @file drawing_text_font_descriptor.h
*
* @brief Provide the ability to provide <b>OH_Drawing_FontDescriptor</b>.
*
* @kit ArkGraphics2D
* @library libnative_drawing.so
* @syscap SystemCapability.Graphic.Graphic2D.NativeDrawing
* @since 8
* @version 1.0
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Type style flag.
*
* @since 14
* @version 1.0
*/
typedef enum {
/** Italic font */
ITALIC = 1 << 0,
/** Bold font */
BOLD = 1 << 1,
} OH_Drawing_FontTypeStyle;
/**
* @brief Describes the font information.
*
* @since 12
* @version 1.0
*/
typedef struct OH_Drawing_FontDescriptor {
/** The file path of System font */
char* path = NULL;
/** A name that uniquely identifies the font */
char* postScriptName = NULL;
/** The name of System font */
char* fullName = NULL;
/** The family of System font */
char* fontFamily = NULL;
/** The subfont family of the system font */
char* fontSubfamily = NULL;
/** The weight of System font */
int weight = 0;
/** The width of System font */
int width = 0;
/** Whether the system font is tilted */
int italic = 0;
/** Whether the system font is compact */
bool monoSpace = false;
/** whether symbolic fonts are supported */
bool symbolic = false;
/** Font size */
size_t size = 0;
/** Font style flag, from OH_Drawing_FontTypeStyle */
int typeStyle = 0;
} OH_Drawing_FontDescriptor;
/**
* @brief Creates an <b>OH_Drawing_FontDescriptor</b> object.
*
* @syscap SystemCapability.Graphic.Graphic2D.NativeDrawing
* @return Returns the pointer to the font descriptor object <b>OH_Drawing_FontDescriptor</b> created.
* @since 12
* @version 1.0
*/
OH_Drawing_FontDescriptor* OH_Drawing_CreateFontDescriptor(void);
/**
* @brief Releases the memory occupied by an <b>OH_Drawing_FontDescriptor</b> object.
*
* @syscap SystemCapability.Graphic.Graphic2D.NativeDrawing
* @param OH_Drawing_FontDescriptor the pointer to the font descriptor object <b>OH_Drawing_FontDescriptor</b>.
* @since 12
* @version 1.0
*/
void OH_Drawing_DestroyFontDescriptor(OH_Drawing_FontDescriptor*);
/**
* @brief Obtain all system font descriptive symbols that match the specified font descriptor. Where the 'path' and
* 'size' fields are not considered as valid matching values, It takes effect when the remaining fields are not
* default values, If all the fields of the parameters <b>OH_Drawing_FontDescriptor</b> are default, obtain all system
* font descriptors. If the match fails, return nullptr.
*
* @syscap SystemCapability.Graphic.Graphic2D.NativeDrawing
* @param OH_Drawing_FontDescriptor The pointer to the <b>OH_Drawing_FontDescriptor</b> object.
* @param size_t Indicates the count of obtained <b>OH_Drawing_FontDescriptor</b>.
* @return Returns an array of <b>OH_Drawing_FontDescriptor</b>.
* @since 14
* @version 1.0
*/
OH_Drawing_FontDescriptor* OH_Drawing_MatchFontDescriptors(OH_Drawing_FontDescriptor*, size_t*);
/**
* @brief Releases the <b>OH_Drawing_FontDescriptor</b> array.
*
* @syscap SystemCapability.Graphic.Graphic2D.NativeDrawing
* @param OH_Drawing_FontDescriptor Pointer to <b>OH_Drawing_FontDescriptor</b> array.
* @param size_t Represents the number of members of the OH_Drawing_FontDescriptor array.
* @since 14
* @version 1.0
*/
void OH_Drawing_DestroyFontDescriptors(OH_Drawing_FontDescriptor*, size_t);
#ifdef __cplusplus
}
#endif
/** @} */
#endif

View File

@ -42,6 +42,7 @@
#include "drawing_color.h"
#include "drawing_font.h"
#include "drawing_text_declaration.h"
#include "drawing_text_font_descriptor.h" // External interface, do not delete.
#include "drawing_types.h"
#include "stdint.h"
@ -191,35 +192,6 @@ typedef struct {
double baselineOffset;
} OH_Drawing_PlaceholderSpan;
/**
* @brief Describes the font information.
*
* @since 12
* @version 1.0
*/
typedef struct OH_Drawing_FontDescriptor {
/** The file path of System font */
char* path;
/** A name that uniquely identifies the font */
char* postScriptName;
/** The name of System font */
char* fullName;
/** The family of System font */
char* fontFamily;
/** The subfont family of the system font */
char* fontSubfamily;
/** The weight of System font */
int weight;
/** The width of System font */
int width;
/** Whether the system font is tilted */
int italic;
/** Whether the system font is compact */
bool monoSpace;
/** whether symbolic fonts are supported */
bool symbolic;
} OH_Drawing_FontDescriptor;
/**
* @brief The metrics of line.
*
@ -1449,26 +1421,6 @@ OH_Drawing_Range* OH_Drawing_TypographyGetLineTextRange(OH_Drawing_Typography*,
*/
bool OH_Drawing_TypographyGetLineInfo(OH_Drawing_Typography*, int, bool, bool, OH_Drawing_LineMetrics*);
/**
* @brief Creates an <b>OH_Drawing_FontDescriptor</b> object.
*
* @syscap SystemCapability.Graphic.Graphic2D.NativeDrawing
* @return Returns the pointer to the font descriptor object <b>OH_Drawing_FontDescriptor</b> created.
* @since 12
* @version 1.0
*/
OH_Drawing_FontDescriptor* OH_Drawing_CreateFontDescriptor(void);
/**
* @brief Releases the memory occupied by an <b>OH_Drawing_FontDescriptor</b> object.
*
* @syscap SystemCapability.Graphic.Graphic2D.NativeDrawing
* @param OH_Drawing_FontDescriptor the pointer to the font descriptor object <b>OH_Drawing_FontDescriptor</b>.
* @since 12
* @version 1.0
*/
void OH_Drawing_DestroyFontDescriptor(OH_Drawing_FontDescriptor*);
/**
* @brief Creates an <b>OH_Drawing_FontParser</b> object.
*

View File

@ -24,6 +24,7 @@
#include <vector>
#include "font_config.h"
#include "font_descriptor_mgr.h"
#include "font_parser.h"
#include "rosen_text/font_collection.h"
#include "rosen_text/typography.h"
@ -1125,19 +1126,77 @@ void OH_Drawing_TextStyleGetBackgroundPen(OH_Drawing_TextStyle* style, OH_Drawin
OH_Drawing_FontDescriptor* OH_Drawing_CreateFontDescriptor(void)
{
auto fontDescriptor = new (std::nothrow) TextEngine::FontParser::FontDescriptor;
if (fontDescriptor == nullptr) {
return nullptr;
}
return (OH_Drawing_FontDescriptor*)fontDescriptor;
return new (std::nothrow) OH_Drawing_FontDescriptor;
}
void OH_Drawing_DestroyFontDescriptor(OH_Drawing_FontDescriptor* descriptor)
{
if (descriptor) {
delete ConvertToOriginalText<TextEngine::FontParser::FontDescriptor>(descriptor);
descriptor = nullptr;
delete descriptor;
}
OH_Drawing_FontDescriptor* OH_Drawing_MatchFontDescriptors(OH_Drawing_FontDescriptor* desc, size_t* num)
{
if (desc == nullptr || num == nullptr) {
return nullptr;
}
using namespace OHOS::Rosen::TextEngine;
std::shared_ptr<FontParser::FontDescriptor> condition = std::make_shared<FontParser::FontDescriptor>();
condition->postScriptName = (desc->postScriptName == nullptr) ? "" : desc->postScriptName;
condition->fullName = (desc->fullName == nullptr) ? "" : desc->fullName;
condition->fontFamily = (desc->fontFamily == nullptr) ? "" : desc->fontFamily;
condition->fontSubfamily = (desc->fontSubfamily == nullptr) ? "" : desc->fontSubfamily;
condition->weight = desc->weight;
condition->width = desc->width;
condition->italic = desc->italic;
condition->monoSpace = desc->monoSpace;
condition->symbolic = desc->symbolic;
condition->typeStyle = desc->typeStyle;
std::set<std::shared_ptr<FontParser::FontDescriptor>> result;
FontDescriptorMgrInstance.MatchFontDescriptors(condition, result);
if (result.empty()) {
*num = 0;
return nullptr;
}
*num = result.size();
OH_Drawing_FontDescriptor* descriptors = new (std::nothrow) OH_Drawing_FontDescriptor[*num];
if (descriptors == nullptr) {
*num = 0;
return nullptr;
}
int i = 0;
for (const auto& item : result) {
descriptors[i].path = strdup(item->path.c_str());
descriptors[i].postScriptName = strdup(item->postScriptName.c_str());
descriptors[i].fullName = strdup(item->fullName.c_str());
descriptors[i].fontFamily = strdup(item->fontFamily.c_str());
descriptors[i].fontSubfamily = strdup(item->fontSubfamily.c_str());
descriptors[i].weight = item->weight;
descriptors[i].width = item->width;
descriptors[i].italic = item->italic;
descriptors[i].monoSpace = item->monoSpace;
descriptors[i].symbolic = item->symbolic;
descriptors[i].size = item->size;
descriptors[i].typeStyle = item->typeStyle;
++i;
}
return descriptors;
}
void OH_Drawing_DestroyFontDescriptors(OH_Drawing_FontDescriptor* descriptors, size_t num)
{
if (descriptors == nullptr || num == 0) {
return;
}
for (size_t i = 0; i < num; ++i) {
free(descriptors[i].path);
free(descriptors[i].postScriptName);
free(descriptors[i].fullName);
free(descriptors[i].fontFamily);
free(descriptors[i].fontSubfamily);
}
delete[] descriptors;
}
OH_Drawing_FontParser* OH_Drawing_CreateFontParser(void)
@ -1248,17 +1307,29 @@ OH_Drawing_FontDescriptor* OH_Drawing_FontParserGetFontByName(OH_Drawing_FontPar
}
std::vector<TextEngine::FontParser::FontDescriptor> systemFontList =
ConvertToOriginalText<TextEngine::FontParser>(fontParser)->GetVisibilityFonts();
TextEngine::FontParser::FontDescriptor* descriptor = new (std::nothrow) TextEngine::FontParser::FontDescriptor;
if (descriptor == nullptr) {
return nullptr;
}
for (size_t i = 0; i < systemFontList.size(); ++i) {
if (strcmp(name, systemFontList[i].fullName.c_str()) == 0) {
*descriptor = systemFontList[i];
return (OH_Drawing_FontDescriptor*)descriptor;
if (strcmp(name, systemFontList[i].fullName.c_str()) != 0) {
continue;
}
OH_Drawing_FontDescriptor* descriptor = new (std::nothrow) OH_Drawing_FontDescriptor();
if (descriptor == nullptr) {
return nullptr;
}
descriptor->path = strdup(systemFontList[i].path.c_str());
descriptor->postScriptName = strdup(systemFontList[i].postScriptName.c_str());
descriptor->fullName = strdup(systemFontList[i].fullName.c_str());
descriptor->fontFamily = strdup(systemFontList[i].fontFamily.c_str());
descriptor->fontSubfamily = strdup(systemFontList[i].fontSubfamily.c_str());
descriptor->weight = systemFontList[i].weight;
descriptor->width = systemFontList[i].width;
descriptor->italic = systemFontList[i].italic;
descriptor->monoSpace = systemFontList[i].monoSpace;
descriptor->symbolic = systemFontList[i].symbolic;
descriptor->size = systemFontList[i].size;
descriptor->typeStyle = systemFontList[i].typeStyle;
return descriptor;
}
delete descriptor;
return nullptr;
}

View File

@ -42,6 +42,7 @@ public:
static void UnRegisterCallBackFunc(std::function<bool(std::shared_ptr<Typeface>)> func);
static std::function<bool(std::shared_ptr<Typeface>)>& GetTypefaceRegisterCallBack();
static std::function<bool(std::shared_ptr<Typeface>)>& GetTypefaceUnRegisterCallBack();
static std::vector<std::shared_ptr<Typeface>> GetSystemFonts();
/**
* @brief Get the familyName for this typeface.
@ -49,6 +50,8 @@ public:
*/
std::string GetFamilyName() const;
std::string GetFontPath() const;
/**
* @brief Get the fontStyle for this typeface.
* @return FontStyle.

View File

@ -32,6 +32,7 @@ class TypefaceImpl : public BaseImpl {
public:
~TypefaceImpl() override = default;
virtual std::string GetFamilyName() const = 0;
virtual std::string GetFontPath() const = 0;
virtual FontStyle GetFontStyle() const = 0;
virtual size_t GetTableSize(uint32_t tag) const = 0;
virtual size_t GetTableData(uint32_t tag, size_t offset, size_t length, void* data) const = 0;

View File

@ -57,6 +57,11 @@ std::shared_ptr<Typeface> SkiaStaticFactory::MakeFromFile(const char path[], int
return SkiaTypeface::MakeFromFile(path, index);
}
std::vector<std::shared_ptr<Typeface>> SkiaStaticFactory::GetSystemFonts()
{
return SkiaTypeface::GetSystemFonts();
}
std::shared_ptr<Typeface> SkiaStaticFactory::MakeFromStream(std::unique_ptr<MemoryStream> memoryStream, int32_t index)
{
return SkiaTypeface::MakeFromStream(std::move(memoryStream), index);

View File

@ -44,6 +44,8 @@ public:
const RSXform xform[], const Font& font, TextEncoding encoding);
static std::shared_ptr<Typeface> MakeDefault();
static std::shared_ptr<Typeface> MakeFromFile(const char path[], int index);
static std::vector<std::shared_ptr<Typeface>> GetSystemFonts();
static std::shared_ptr<Typeface> MakeFromStream(std::unique_ptr<MemoryStream> memoryStream, int32_t index);
static std::shared_ptr<Typeface> MakeFromName(const char familyName[], FontStyle fontStyle);
#ifdef ACE_ENABLE_GPU

View File

@ -48,6 +48,19 @@ std::string SkiaTypeface::GetFamilyName() const
return name;
}
std::string SkiaTypeface::GetFontPath() const
{
std::string path;
if (!skTypeface_) {
LOGE("skTypeface nullptr");
return path;
}
SkString skName;
skTypeface_->getFontPath(&skName);
SkiaConvertUtils::SkStringCastToStdString(skName, path);
return path;
}
FontStyle SkiaTypeface::GetFontStyle() const
{
FontStyle fontStyle;
@ -180,6 +193,22 @@ std::shared_ptr<Typeface> SkiaTypeface::MakeFromFile(const char path[], int inde
return std::make_shared<Typeface>(typefaceImpl);
}
std::vector<std::shared_ptr<Typeface>> SkiaTypeface::GetSystemFonts()
{
std::vector<sk_sp<SkTypeface>> skTypefaces = SkTypeface::GetSystemFonts();
if (skTypefaces.empty()) {
return {};
}
std::vector<std::shared_ptr<Typeface>> typefaces;
typefaces.reserve(skTypefaces.size());
for (auto& item : skTypefaces) {
item->setIsCustomTypeface(false);
std::shared_ptr<TypefaceImpl> typefaceImpl = std::make_shared<SkiaTypeface>(item);
typefaces.emplace_back(std::make_shared<Typeface>(typefaceImpl));
}
return typefaces;
}
std::shared_ptr<Typeface> SkiaTypeface::MakeFromStream(std::unique_ptr<MemoryStream> memoryStream, int32_t index)
{
if (!memoryStream) {

View File

@ -41,6 +41,7 @@ public:
sk_sp<SkTypeface> GetTypeface() const;
std::string GetFamilyName() const override;
std::string GetFontPath() const override;
FontStyle GetFontStyle() const override;
size_t GetTableSize(uint32_t tag) const override;
size_t GetTableData(uint32_t tag, size_t offset, size_t length, void* data) const override;
@ -53,6 +54,7 @@ public:
static std::shared_ptr<Typeface> MakeDefault();
static std::shared_ptr<Typeface> MakeFromFile(const char path[], int index);
static std::vector<std::shared_ptr<Typeface>> GetSystemFonts();
static std::shared_ptr<Typeface> MakeFromStream(std::unique_ptr<MemoryStream> memoryStream, int32_t index);
static std::shared_ptr<Typeface> MakeFromName(const char familyName[], FontStyle fontStyle);

View File

@ -79,6 +79,16 @@ std::shared_ptr<Typeface> StaticFactory::MakeFromFile(const char path[], int ind
return EngineStaticFactory::MakeFromFile(path, index);
}
std::vector<std::shared_ptr<Typeface>> StaticFactory::GetSystemFonts()
{
#ifdef ENABLE_DDGR_OPTIMIZE
if (SystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
return DDGRStaticFactory::GetSystemFonts();
}
#endif
return EngineStaticFactory::GetSystemFonts();
}
std::shared_ptr<Typeface> StaticFactory::MakeFromStream(std::unique_ptr<MemoryStream> memoryStream, int32_t index)
{
#ifdef ENABLE_DDGR_OPTIMIZE

View File

@ -44,6 +44,7 @@ public:
const RSXform xform[], const Font& font, TextEncoding encoding);
static std::shared_ptr<Typeface> MakeDefault();
static std::shared_ptr<Typeface> MakeFromFile(const char path[], int index);
static std::vector<std::shared_ptr<Typeface>> GetSystemFonts();
static std::shared_ptr<Typeface> MakeFromStream(std::unique_ptr<MemoryStream> memoryStream, int32_t index);
static std::shared_ptr<Typeface> MakeFromName(const char familyName[], FontStyle fontStyle);
#ifdef ACE_ENABLE_GPU

View File

@ -33,6 +33,11 @@ std::shared_ptr<Typeface> Typeface::MakeFromFile(const char path[], int index)
return StaticFactory::MakeFromFile(path, index);
}
std::vector<std::shared_ptr<Typeface>> Typeface::GetSystemFonts()
{
return StaticFactory::GetSystemFonts();
}
std::shared_ptr<Typeface> Typeface::MakeFromStream(std::unique_ptr<MemoryStream> memoryStream, int32_t index)
{
return StaticFactory::MakeFromStream(std::move(memoryStream), index);
@ -51,6 +56,11 @@ std::string Typeface::GetFamilyName() const
return std::string();
}
std::string Typeface::GetFontPath() const
{
return (typefaceImpl_ == nullptr) ? "" : typefaceImpl_->GetFontPath();
}
FontStyle Typeface::GetFontStyle() const
{
if (typefaceImpl_) {

View File

@ -64,6 +64,8 @@ ohos_source_set("libtexgine_source") {
if (is_ok) {
sources = [
"src/font_config.cpp",
"src/font_descriptor_cache.cpp",
"src/font_descriptor_mgr.cpp",
"src/font_parser.cpp",
"src/opentype_parser/cmap_table_parser.cpp",
"src/opentype_parser/name_table_parser.cpp",

View File

@ -0,0 +1,344 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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 "font_descriptor_cache.h"
#include <algorithm>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include "font_config.h"
#include "utils/text_log.h"
namespace OHOS::Rosen {
namespace {
constexpr uint32_t WEIGHT_400 = 400;
}
FontDescriptorCache::FontDescriptorCache() {}
FontDescriptorCache::~FontDescriptorCache() {}
void FontDescriptorCache::ClearFontFileCache()
{
allFontDescriptor_.clear();
fontFamilyMap_.clear();
fullNameMap_.clear();
postScriptNameMap_.clear();
fontSubfamilyNameMap_.clear();
boldCache_.clear();
italicCache_.clear();
monoSpaceCache_.clear();
symbolicCache_.clear();
}
void FontDescriptorCache::ParserSystemFonts()
{
for (auto& item : parser_.GetSystemFonts()) {
FontDescriptorScatter(item);
}
Dump();
}
void FontDescriptorCache::FontDescriptorScatter(FontDescSharedPtr desc)
{
auto ret = allFontDescriptor_.emplace(desc);
if (!ret.second) {
return;
}
auto handleMapScatter = [&](auto& map, const auto& key) {
map[key].emplace(desc);
};
handleMapScatter(fontFamilyMap_, desc->fontFamily);
handleMapScatter(fullNameMap_, desc->fullName);
handleMapScatter(postScriptNameMap_, desc->postScriptName);
handleMapScatter(fontSubfamilyNameMap_, desc->fontSubfamily);
if (desc->weight > WEIGHT_400) {
desc->typeStyle |= TextEngine::FontParser::FontTypeStyle::BOLD;
boldCache_.emplace(desc);
}
if (desc->italic != 0) {
desc->typeStyle |= TextEngine::FontParser::FontTypeStyle::ITALIC;
italicCache_.emplace(desc);
}
if (desc->monoSpace) {
monoSpaceCache_.emplace(desc);
}
if (desc->symbolic) {
symbolicCache_.emplace(desc);
}
}
bool FontDescriptorCache::HandleMapIntersection(std::set<FontDescSharedPtr>& finishRet, const std::string& name,
std::unordered_map<std::string, std::set<FontDescSharedPtr>>& map)
{
if (name.empty()) {
return true;
}
auto iter = map.find(name);
if (iter == map.end()) {
return false;
}
if (finishRet.empty()) {
finishRet = iter->second;
} else {
std::set<FontDescSharedPtr> temp;
std::set_intersection(iter->second.begin(), iter->second.end(), finishRet.begin(), finishRet.end(),
std::insert_iterator<std::set<FontDescSharedPtr>>(temp, temp.begin()));
if (temp.empty()) {
return false;
}
finishRet = std::move(temp);
}
return true;
}
bool FontDescriptorCache::FilterBoldCache(int weight, std::set<FontDescSharedPtr>& finishRet)
{
if (weight < 0) {
return false;
}
if (weight == 0) {
return true;
}
std::set<FontDescSharedPtr> temp;
std::set<FontDescSharedPtr>::iterator begin;
std::set<FontDescSharedPtr>::iterator end;
if (!finishRet.empty()) {
begin = finishRet.begin();
end = finishRet.end();
} else if (weight > WEIGHT_400) {
begin = boldCache_.begin();
end = boldCache_.end();
} else {
begin = allFontDescriptor_.begin();
end = allFontDescriptor_.end();
}
std::for_each(begin, end, [&](FontDescSharedPtr item) {
if (item->weight == weight) {
temp.emplace(item);
}
});
if (temp.empty()) {
TEXT_LOGD("Failed to match weight");
return false;
}
finishRet = std::move(temp);
return true;
}
bool FontDescriptorCache::FilterWidthCache(int width, std::set<FontDescSharedPtr>& finishRet)
{
if (width < 0) {
return false;
}
if (width == 0) {
return true;
}
std::set<FontDescSharedPtr> temp;
std::set<FontDescSharedPtr>::iterator begin;
std::set<FontDescSharedPtr>::iterator end;
if (!finishRet.empty()) {
begin = finishRet.begin();
end = finishRet.end();
} else {
begin = allFontDescriptor_.begin();
end = allFontDescriptor_.end();
}
std::for_each(begin, end, [&](FontDescSharedPtr item) {
if (item->width == width) {
temp.emplace(item);
}
});
if (temp.empty()) {
TEXT_LOGD("Failed to match width");
return false;
}
finishRet = std::move(temp);
return true;
}
bool FontDescriptorCache::FilterItalicCache(int italic, std::set<FontDescSharedPtr>& finishRet)
{
if (italic == 0) {
return true;
}
std::set<FontDescSharedPtr> temp;
if (!finishRet.empty()) {
std::for_each(finishRet.begin(), finishRet.end(), [&](FontDescSharedPtr item) {
if (item->italic != 0) {
temp.emplace(item);
}
});
} else {
temp = italicCache_;
}
if (temp.empty()) {
TEXT_LOGD("Failed to match italic");
return false;
}
finishRet = std::move(temp);
return true;
}
bool FontDescriptorCache::FilterMonoSpaceCache(bool monoSpace, std::set<FontDescSharedPtr>& finishRet)
{
if (!monoSpace) {
return true;
}
std::set<FontDescSharedPtr> temp;
if (!finishRet.empty()) {
std::for_each(finishRet.begin(), finishRet.end(), [&](FontDescSharedPtr item) {
if (item->monoSpace) {
temp.emplace(item);
}
});
} else {
temp = monoSpaceCache_;
}
if (temp.empty()) {
TEXT_LOGD("Failed to match monoSpace");
return false;
}
finishRet = std::move(temp);
return true;
}
bool FontDescriptorCache::FilterSymbolicCache(bool symbolic, std::set<FontDescSharedPtr>& finishRet)
{
if (!symbolic) {
return true;
}
std::set<FontDescSharedPtr> temp;
if (!finishRet.empty()) {
std::for_each(finishRet.begin(), finishRet.end(), [&](FontDescSharedPtr item) {
if (item->symbolic) {
temp.emplace(item);
}
});
} else {
temp = symbolicCache_;
}
if (temp.empty()) {
TEXT_LOGD("Failed to match symbolic");
return false;
}
finishRet = std::move(temp);
return true;
}
bool FontDescriptorCache::FilterTypeStyle(int typeStyle, std::set<FontDescSharedPtr>& finishRet)
{
if (typeStyle < 0) {
return false;
}
if (typeStyle == 0) {
return true;
}
bool italicFlag = typeStyle & TextEngine::FontParser::FontTypeStyle::ITALIC;
bool boldFlag = typeStyle & TextEngine::FontParser::FontTypeStyle::BOLD;
auto handleCache = [&](const std::set<FontDescSharedPtr>& cache, const char* cacheName) {
if (cache.empty()) {
TEXT_LOGD("%{public}s is empty", cacheName);
return false;
}
if (finishRet.empty()) {
finishRet = cache;
} else {
std::set<FontDescSharedPtr> temp;
std::set_intersection(finishRet.begin(), finishRet.end(), cache.begin(), cache.end(),
std::inserter(temp, temp.begin()));
if (temp.empty()) {
TEXT_LOGD("Failed to match typeStyle %{public}s", cacheName);
return false;
}
finishRet = std::move(temp);
}
return true;
};
if (italicFlag && !handleCache(italicCache_, "italic")) {
return false;
}
if (boldFlag && !handleCache(boldCache_, "bold")) {
return false;
}
return true;
}
bool FontDescriptorCache::IsDefault(FontDescSharedPtr desc)
{
if (desc->fontFamily.empty() && desc->fullName.empty() && desc->postScriptName.empty()
&& desc->fontSubfamily.empty() && desc->weight == 0 && desc->width == 0 && desc->italic == 0
&& !desc->monoSpace && !desc->symbolic && desc->typeStyle == 0) {
return true;
}
return false;
}
void FontDescriptorCache::MatchFromFontDescriptor(FontDescSharedPtr desc, std::set<FontDescSharedPtr>& result)
{
if (desc == nullptr) {
TEXT_LOGE("desc is nullptr");
return;
}
if (IsDefault(desc)) {
result = std::set<FontDescSharedPtr>(allFontDescriptor_.begin(), allFontDescriptor_.end());
return;
}
std::set<FontDescSharedPtr> finishRet;
TEXT_INFO_CHECK(HandleMapIntersection(finishRet, desc->fontFamily, fontFamilyMap_), return,
"Failed to match fontFamily");
TEXT_INFO_CHECK(HandleMapIntersection(finishRet, desc->fullName, fullNameMap_), return, "Failed to match fullName");
TEXT_INFO_CHECK(HandleMapIntersection(finishRet, desc->postScriptName, postScriptNameMap_), return,
"Failed to match postScriptName");
TEXT_INFO_CHECK(HandleMapIntersection(finishRet, desc->fontSubfamily, fontSubfamilyNameMap_), return,
"Failed to match fontSubfamily");
TEXT_CHECK(FilterBoldCache(desc->weight, finishRet), return);
TEXT_CHECK(FilterWidthCache(desc->width, finishRet), return);
TEXT_CHECK(FilterItalicCache(desc->italic, finishRet), return);
TEXT_CHECK(FilterMonoSpaceCache(desc->monoSpace, finishRet), return);
TEXT_CHECK(FilterSymbolicCache(desc->symbolic, finishRet), return);
TEXT_CHECK(FilterTypeStyle(desc->typeStyle, finishRet), return);
result = std::move(finishRet);
}
void FontDescriptorCache::Dump()
{
TEXT_LOGD("allFontDescriptor size: %{public}zu, fontFamilyMap size: %{public}zu, fullNameMap size: %{public}zu \
postScriptNameMap size: %{public}zu, fontSubfamilyNameMap size: %{public}zu, boldCache size: %{public}zu \
italicCache size: %{public}zu, monoSpaceCache size: %{public}zu, symbolicCache size: %{public}zu",
allFontDescriptor_.size(), fontFamilyMap_.size(), fullNameMap_.size(), postScriptNameMap_.size(),
fontSubfamilyNameMap_.size(), boldCache_.size(), italicCache_.size(), monoSpaceCache_.size(),
symbolicCache_.size());
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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.
*/
#ifndef OHOS_ROSEN_FONT_DESCRIPTOR_CACHE_H
#define OHOS_ROSEN_FONT_DESCRIPTOR_CACHE_H
#include <memory>
#include <set>
#include <unordered_map>
#include <vector>
#include "font_parser.h"
namespace OHOS::Rosen {
using FontDescSharedPtr = std::shared_ptr<TextEngine::FontParser::FontDescriptor>;
class FontDescriptorCache {
public:
FontDescriptorCache();
~FontDescriptorCache();
void ParserSystemFonts();
void MatchFromFontDescriptor(FontDescSharedPtr desc, std::set<FontDescSharedPtr>& result);
void ClearFontFileCache();
void Dump();
private:
void FontDescriptorScatter(FontDescSharedPtr desc);
bool HandleMapIntersection(std::set<FontDescSharedPtr>& finishRet, const std::string& name,
std::unordered_map<std::string, std::set<FontDescSharedPtr>>& map);
bool FilterBoldCache(int weight, std::set<FontDescSharedPtr>& finishRet);
bool FilterWidthCache(int width, std::set<FontDescSharedPtr>& finishRet);
bool FilterItalicCache(int italic, std::set<FontDescSharedPtr>& finishRet);
bool FilterMonoSpaceCache(bool monoSpace, std::set<FontDescSharedPtr>& finishRet);
bool FilterSymbolicCache(bool symbolic, std::set<FontDescSharedPtr>& finishRet);
bool FilterTypeStyle(int typeStyle, std::set<FontDescSharedPtr>& finishRet);
bool IsDefault(FontDescSharedPtr desc);
private:
TextEngine::FontParser parser_;
struct FontDescriptorEqual {
bool operator()(const FontDescSharedPtr& lhs, const FontDescSharedPtr& rhs) const
{
if (lhs->fontFamily == rhs->fontFamily) {
return lhs->fullName < rhs->fullName;
}
return lhs->fontFamily < rhs->fontFamily;
}
};
std::set<FontDescSharedPtr, FontDescriptorEqual> allFontDescriptor_;
std::unordered_map<std::string, std::set<FontDescSharedPtr>> fontFamilyMap_;
std::unordered_map<std::string, std::set<FontDescSharedPtr>> fullNameMap_;
std::unordered_map<std::string, std::set<FontDescSharedPtr>> postScriptNameMap_;
std::unordered_map<std::string, std::set<FontDescSharedPtr>> fontSubfamilyNameMap_;
std::set<FontDescSharedPtr> boldCache_;
std::set<FontDescSharedPtr> italicCache_;
std::set<FontDescSharedPtr> monoSpaceCache_;
std::set<FontDescSharedPtr> symbolicCache_;
};
} // namespace OHOS::Rosen
#endif // OHOS_ROSEN_FONT_DESCRIPTOR_CACHE_H

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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 "font_descriptor_mgr.h"
namespace OHOS::Rosen {
FontDescriptorMgr& FontDescriptorMgr::GetInstance()
{
static FontDescriptorMgr instance;
return instance;
}
FontDescriptorMgr::FontDescriptorMgr()
{
ParseAllFontSource();
}
FontDescriptorMgr::~FontDescriptorMgr() {}
void FontDescriptorMgr::ParseAllFontSource()
{
std::unique_lock<std::mutex> guard(parserMtx_);
descCache_.ParserSystemFonts();
}
void FontDescriptorMgr::ClearFontFileCache()
{
std::unique_lock<std::mutex> guard(parserMtx_);
descCache_.ClearFontFileCache();
}
void FontDescriptorMgr::MatchFontDescriptors(FontDescSharedPtr desc, std::set<FontDescSharedPtr>& descs)
{
std::unique_lock<std::mutex> guard(parserMtx_);
descCache_.MatchFromFontDescriptor(desc, descs);
}
} // namespace OHOS::Rosen

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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.
*/
#ifndef OHOS_ROSEN_FONT_DESCRIPTOR_MGR_H
#define OHOS_ROSEN_FONT_DESCRIPTOR_MGR_H
#ifdef BUILD_NON_SDK_VER
#include <nocopyable.h>
#endif
#include <mutex>
#include "font_descriptor_cache.h"
#include "font_parser.h"
namespace OHOS::Rosen {
using FontDescSharedPtr = std::shared_ptr<TextEngine::FontParser::FontDescriptor>;
class FontDescriptorMgr {
public:
static FontDescriptorMgr& GetInstance();
virtual ~FontDescriptorMgr();
#ifdef BUILD_NON_SDK_VER
DISALLOW_COPY_AND_MOVE(FontDescriptorMgr);
#endif
void ParseAllFontSource();
void MatchFontDescriptors(FontDescSharedPtr desc, std::set<FontDescSharedPtr>& descs);
void ClearFontFileCache();
private:
FontDescriptorMgr();
FontDescriptorCache descCache_;
std::mutex parserMtx_;
};
} // namespace OHOS::Rosen
#define FontDescriptorMgrInstance OHOS::Rosen::FontDescriptorMgr::GetInstance()
#endif // OHOS_ROSEN_FONT_DESCRIPTOR_MGR_H

View File

@ -43,13 +43,6 @@ namespace TextEngine {
#define HALF(a) ((a) / 2)
// "weight" and "italic" will assigned value 0 and 1, -1 used to exclude unassigned
FontParser::FontDescriptor::FontDescriptor(): path(""), postScriptName(""), fullName(""),
fontFamily(""), fontSubfamily(""), postScriptNameLid(0), fullNameLid(0), fontFamilyLid(0),
fontSubfamilyLid(0), requestedLid(0), weight(-1), width(0), italic(-1), monoSpace(0), symbolic(0)
{
}
FontParser::FontParser()
{
data_ = nullptr;
@ -396,6 +389,30 @@ private:
std::shared_ptr<std::vector<std::string>> systemFontSet_;
};
std::vector<std::shared_ptr<FontParser::FontDescriptor>> FontParser::GetSystemFonts(const std::string locale)
{
std::vector<std::shared_ptr<Drawing::Typeface>> typefaces = Drawing::Typeface::GetSystemFonts();
if (typefaces.empty()) {
return {};
}
std::vector<std::shared_ptr<FontDescriptor>> descriptors;
descriptors.reserve(typefaces.size());
for (auto& item : typefaces) {
FontDescriptor desc;
desc.requestedLid = GetLanguageId(locale);
desc.path = item->GetFontPath();
auto fontStyle = item->GetFontStyle();
desc.weight = fontStyle.GetWeight();
desc.width = fontStyle.GetWidth();
if (ParseTable(item, desc) != SUCCESSED) {
continue;
}
descriptors.emplace_back(std::make_shared<FontDescriptor>(desc));
}
return descriptors;
}
std::unique_ptr<FontParser::FontDescriptor> FontParser::ParseFontDescriptor(const std::string& fontName,
const unsigned int languageId)
{

View File

@ -68,30 +68,38 @@ public:
TRADEMARK = 7,
};
enum FontTypeStyle {
ITALIC = 1 << 0,
BOLD = 1 << 1,
};
struct FontDescriptor {
FontDescriptor();
std::string path;
std::string postScriptName;
std::string fullName;
std::string fontFamily;
std::string fontSubfamily;
std::string requestedFullname;
unsigned int postScriptNameLid;
unsigned int fullNameLid;
unsigned int fontFamilyLid;
unsigned int fontSubfamilyLid;
unsigned int requestedLid;
int weight;
int width;
int italic;
bool monoSpace;
bool symbolic;
unsigned int postScriptNameLid = 0;
unsigned int fullNameLid = 0;
unsigned int fontFamilyLid = 0;
unsigned int fontSubfamilyLid = 0;
unsigned int requestedLid = 0;
int weight = 0;
int width = 0;
int italic = 0;
bool monoSpace = false;
bool symbolic = false;
double size = 0;
int typeStyle = 0;
};
FontParser();
std::vector<FontDescriptor> GetVisibilityFonts(const std::string &locale = SIMPLIFIED_CHINESE);
std::unique_ptr<FontDescriptor> GetVisibilityFontByName(const std::string& fontName,
const std::string locale = SIMPLIFIED_CHINESE);
std::vector<std::shared_ptr<FontDescriptor>> GetSystemFonts(const std::string locale = SIMPLIFIED_CHINESE);
private:
static void GetStringFromNameId(NameId nameId, unsigned int languageId, const std::string& nameString,