/* * Copyright (c) 2020-2022 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/ui_font.h" #include "common/text.h" #include "font/ui_font_cache.h" #include "font/font_ram_allocator.h" #if defined(ENABLE_VECTOR_FONT) && ENABLE_VECTOR_FONT #include "font/ui_font_vector.h" #endif #if defined(ENABLE_BITMAP_FONT) && ENABLE_BITMAP_FONT #include "font/ui_font_bitmap.h" #endif #include "graphic_config.h" #if defined(ENABLE_MULTI_FONT) && ENABLE_MULTI_FONT #include "font/ui_multi_font_manager.h" #endif namespace OHOS { bool UIFont::setFontAllocFlag_ = false; UIFont::UIFont() : instance_(nullptr), defaultInstance_(nullptr) {} UIFont::~UIFont() {} UIFont* UIFont::GetInstance() { static UIFont instance; #if defined(ENABLE_BITMAP_FONT) && ENABLE_BITMAP_FONT if (instance.instance_ == nullptr) { instance.defaultInstance_ = new UIFontBitmap(); instance.instance_ = instance.defaultInstance_; setFontAllocFlag_ = true; } #endif #if defined(ENABLE_VECTOR_FONT) && ENABLE_VECTOR_FONT if (instance.instance_ == nullptr) { instance.defaultInstance_ = new UIFontVector(); instance.instance_ = instance.defaultInstance_; setFontAllocFlag_ = true; } #endif return &instance; } void UIFont::SetFont(BaseFont* font) { if (font != nullptr) { if (defaultInstance_ != nullptr && setFontAllocFlag_) { delete defaultInstance_; defaultInstance_ = nullptr; setFontAllocFlag_ = false; } defaultInstance_ = font; instance_ = font; } } BaseFont* UIFont::GetFont() { return instance_; } #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1)) void UIFont::SetBitmapFont(BaseFont* font) { if (font == nullptr) { return; } GetBitmapInstance()->SetFont(font); } UIFont* UIFont::GetBitmapInstance() { static UIFont instance; if (instance.instance_ == nullptr) { instance.defaultInstance_ = new UIFontBitmap(); instance.instance_ = instance.defaultInstance_; setFontAllocFlag_ = true; } return &instance; } #endif void UIFont::SetFontFileOffset(uint32_t offset) { #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1)) GetBitmapInstance()->GetFont()->SetFontFileOffset(offset); #else instance_->SetFontFileOffset(offset); #endif } int8_t UIFont::SetCurrentLangId(uint8_t langId) { #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1)) return GetBitmapInstance()->GetFont()->SetCurrentLangId(langId); #else return instance_->SetCurrentLangId(langId); #endif } uint8_t UIFont::GetCurrentLangId() const { #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1)) return GetBitmapInstance()->GetFont()->GetCurrentLangId(); #else return instance_->GetCurrentLangId(); #endif } int8_t UIFont::SetFontPath(const char* path, BaseFont::FontType type) { #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1)) if (type == BaseFont::FontType::VECTOR_FONT) { return instance_->SetFontPath(path, type); } return GetBitmapInstance()->GetFont()->SetFontPath(path, type); #else return instance_->SetFontPath(path, type); #endif } int8_t UIFont::GetTextUtf8(uint16_t textId, uint8_t** utf8Addr, uint16_t& utf8Len) const { #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1)) return GetBitmapInstance()->GetFont()->GetTextUtf8(textId, utf8Addr, utf8Len); #else return instance_->GetTextUtf8(textId, utf8Addr, utf8Len); #endif } int8_t UIFont::GetTextParam(uint16_t textId, UITextLanguageTextParam& param) const { #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1)) return GetBitmapInstance()->GetFont()->GetTextParam(textId, param); #else return instance_->GetTextParam(textId, param); #endif } int8_t UIFont::GetWildCardStaticStr(uint16_t textId, UITextWildcardStaticType type, uint8_t** strAddr, uint16_t& strLen) const { #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1)) return GetBitmapInstance()->GetFont()->GetWildCardStaticStr(textId, type, strAddr, strLen); #else return instance_->GetWildCardStaticStr(textId, type, strAddr, strLen); #endif } int8_t UIFont::GetCodePoints(uint16_t textId, uint32_t** codePoints, uint16_t& codePointsNum) const { #if (defined(ENABLE_MIX_FONT) && (ENABLE_MIX_FONT == 1)) return GetBitmapInstance()->GetFont()->GetCodePoints(textId, codePoints, codePointsNum); #else return instance_->GetCodePoints(textId, codePoints, codePointsNum); #endif } uint8_t* UIFont::GetBitmap(uint32_t unicode, GlyphNode& glyphNode, uint16_t fontId, uint8_t fontSize, uint8_t shapingFont) { uint8_t* bitmap = nullptr; #if ENABLE_MULTI_FONT // shaping font is in search list, search shaping font first if (shapingFont > 1) { bitmap = instance_->GetBitmap(unicode, glyphNode, shapingFont, fontSize); if (bitmap != nullptr) { return bitmap; } } #endif bitmap = instance_->GetBitmap(unicode, glyphNode, fontId, fontSize); if (bitmap != nullptr) { return bitmap; } #if ENABLE_MULTI_FONT uint16_t* searchLists = nullptr; int32_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists); int32_t currentIndex = 0; if ((searchLists == nullptr) || (listSize == 0)) { return nullptr; } do { bitmap = instance_->GetBitmap(unicode, glyphNode, searchLists[currentIndex], fontSize); if (bitmap != nullptr) { return bitmap; } // switch to next search List currentIndex++; } while ((currentIndex < listSize) && (searchLists != nullptr)); #endif return nullptr; } int8_t UIFont::GetGlyphNode(uint32_t unicode, GlyphNode& glyphNode, uint16_t fontId, uint8_t fontSize) { int8_t result = instance_->GetGlyphNode(unicode, glyphNode, fontId, fontSize); if (result == RET_VALUE_OK) { return result; } #if defined(ENABLE_MULTI_FONT) && ENABLE_MULTI_FONT uint16_t* searchLists = nullptr; int32_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists); if ((searchLists == nullptr) || (listSize == 0)) { return INVALID_RET_VALUE; } int32_t currentIndex = 0; do { result = instance_->GetGlyphNode(unicode, glyphNode, searchLists[currentIndex], fontSize); if (result == RET_VALUE_OK) { return result; } currentIndex++; } while ((currentIndex < listSize) && (searchLists != nullptr)); #endif return INVALID_RET_VALUE; } uint16_t UIFont::GetWidth(uint32_t unicode, uint16_t fontId, uint8_t fontSize, uint8_t shapingId) { int16_t result; #if ENABLE_MULTI_FONT if (shapingId > 1) { result = instance_->GetWidth(unicode, shapingId, fontSize); if (result >= 0) { return result; } } #endif result = instance_->GetWidth(unicode, fontId, fontSize); if (result >= 0) { return result; } #if ENABLE_MULTI_FONT uint16_t* searchLists = nullptr; int32_t listSize = UIMultiFontManager::GetInstance()->GetSearchFontList(fontId, &searchLists); if ((searchLists == nullptr) || (listSize == 0)) { return 0; } int32_t currentIndex = 0; do { result = instance_->GetWidth(unicode, searchLists[currentIndex], fontSize); if (result >= 0) { return result; } currentIndex++; } while ((currentIndex < listSize) && (searchLists != nullptr)); #endif return 0; } uint16_t UIFont::GetLineMaxHeight(const char* text, uint16_t lineLength, uint16_t fontId, uint8_t fontSize, uint16_t letterIndex, SpannableString* spannableString) { return instance_->GetLineMaxHeight(text, lineLength, fontId, fontSize, letterIndex, spannableString); } } // namespace OHOS