解决中文显示乱码问题

This commit is contained in:
JackLee 2026-03-27 21:50:33 +08:00
parent 51dd9c79b6
commit 050403d971
84 changed files with 221 additions and 62 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
entry/libs/x86_64/libbz2.so Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -4,6 +4,7 @@ project(opencax)
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
add_definitions(-DOHOS_PLATFORM)
add_definitions (-DHAVE_FREETYPE)
set(CMAKE_CXX_STANDARD 17)
# NAPI
@ -23,7 +24,10 @@ set(OCCT_CORE_LIBS
TKDESTEP TKShHealing TKHLR TKVCAF TKBO TKPrim TKBool TKDE TKXSBase
)
set(OCCT_3RD_LIBS libfreetype.so.6)
set(OCCT_3RD_LIBS
libfreetype.so.6 libharfbuzz.so libbz2.so libbrotlienc.so.1
libbrotlidec.so.1 libbrotlicommon.so.1 libpng16.so.16
)
foreach(LIB_NAME ${OCCT_CORE_LIBS})
list(APPEND OCCT_IMPORTED_LIBS ${OCCT_LIB_DIR}/lib${LIB_NAME}.so.${OCCT_VERSION})

View File

@ -15,9 +15,7 @@ NativeRender::NativeRender(int w, int h)
ogd(new OpenGlGraphicDriver), ts(new TextStyle), vw(new View), vr(new Viewer), win(new Window) {
width = w;
height = h;
ftMgr=Font_FontMgr::GetInstance();
ftMgr->SetPrintErrors(true);
ftMgr->SetTraceAliases(true);
}
NativeRender::~NativeRender() { shapes_.clear(); }
@ -231,18 +229,32 @@ void NativeRender::fontDev() {
//
// }
//OCCT字体管理信息获取
// auto mgr=Font_FontMgr::GetInstance();
// auto mgr=Font_FontMgr::GetInstance();
// Handle(Font_SystemFont) sysFont=new Font_SystemFont("HarmonyOS_Sans_Regular");
// sysFont->SetFontPath(Font_FontAspect_Regular, "/data/storage/el1/bundle/entry/resources/rawfile/fonts/HarmonyOS_Sans_Regular.ttf");
// TCollection_ExtendedString aFontName("HarmonyOS_Sans_Regular"); // 为你自定义的字体起一个名称,后续绘制时会用到
//
// // 注册字体。第二个参数如果是 Standard_True表示强制注册即使同名也覆盖。
// bool isRegistered = mgr->RegisterFont(sysFont, Standard_True);
//
// if (!isRegistered) {
// OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","Error: Cannot register font: %{public}s",sysFont->FontName().ToCString());
// return; // 或者进行错误处理
// } else {
// OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","Successfully registered font: %{public}s",sysFont->FontName().ToCString());
// }
// mgr->InitFontDataBase();
// mgr->AddFontAlias("HarmonyOS-Sans", "HarmonyOS-Sans");
// Font_FontAspect aspect = Font_FA_Regular;
// // 查找sans别名优先匹配HarmonyOS Sans
// Handle(Font_SystemFont) font = mgr->FindFont("HarmonyOS-Sans", aspect);
// Handle(Font_SystemFont) font = mgr->FindFont("HarmonyOS_Sans_Regular", aspect);
// if (!font.IsNull()) {
// // 打印实际匹配到的字体名若为HarmonyOS Sans则生效
// OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","SO库匹配到的字体名:%{public}s",font->FontName().ToCString());
// }
// mgr->InitFontDataBase();
// Handle(Font_SystemFont) sysFont=new Font_SystemFont("HarmonyOS-Sans");
// sysFont->SetFontPath(Font_FontAspect_Regular, "/system/fonts/");
// bool err=mgr->RegisterFont(sysFont,false);
// sysFont->SetFontPath(Font_FontAspect_Regular, "/data/storage/el1/bundle/entry/resources/rawfile/fonts");
// bool err=mgr->RegisterFont(sysFont,true);
// if(err){
// OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT RegisterFont Done");
// }
@ -251,9 +263,10 @@ void NativeRender::fontDev() {
// for(auto ft:theAliases){
// OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Aliases: %{public}s", ft->ToCString());
// }
// Handle(Font_SystemFont)sFont = mgr->GetFont("HarmonyOS-Sans");
// OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT sysFont: %{public}s", sFont->FontName().ToCString());
// //查找指定的字体
//Handle(Font_SystemFont)sFont = mgr->GetFont("HarmonyOS-Sans");
//OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT sysFont: %{public}s", sFont->FontName().ToCString());
//查找指定的字体
// const TCollection_AsciiString theFontName='HarmonyOS-Sans';
// Font_FontAspect theFontAspect;
// mgr->FindFont(theFontName, theFontAspect);
@ -261,14 +274,16 @@ void NativeRender::fontDev() {
//字体示例
Handle(AIS_TextLabel) aTextLabel = new AIS_TextLabel();
aTextLabel->SetText(TCollection_ExtendedString(u8"共产主义接班人"));
Handle(Prs3d_TextAspect) textAspect = aTextLabel->Attributes()->TextAspect();
textAspect->SetFont("HarmonyOS Sans");
textAspect->SetHeight(10000.0);
textAspect->SetColor(Quantity_Color(Quantity_NOC_YELLOW));
//TCollection_ExtendedString tostr;
//const char* str = "\xC4\xE3\xBA\xC3";
//Resource_Unicode::ConvertGBToUnicode(str, tostr);
const char16_t chinese_array[] = u"新时代社会主义新中国接班人";
aTextLabel->SetText(chinese_array);
aTextLabel->Attributes()->SetTextAspect(ts->text);
gp_Pnt position(0.0, 0.0, 0.0); // 例如,在原点
aTextLabel->SetPosition(position);
ctx->context->Display(aTextLabel, Standard_True);
vw->ResetView();
HILOG_ERROR(NATIVE_TAG, "aTextLabel字体名字:%{public}s", aTextLabel->FontName().ToCString());
HILOG_ERROR(NATIVE_TAG, "aTextLabel字体名字:%{public}s", aTextLabel->Attributes()->TextAspect()->Aspect()->Font().ToCString());
}
} // namespace NativeOpenCAX

View File

@ -73,7 +73,6 @@ private:
View* vw;
Viewer* vr;
Window* win;
Handle(Font_FontMgr) ftMgr ;
std::vector<Handle(AIS_Shape)> shapes_;
};
} // namespace NativeRender

View File

@ -1,4 +1,5 @@
#include "NativeRenderThread.h"
#include "Font_FontAspect.hxx"
#include "NativeEGLOCCT/common.h"
#include <cstdio>
#include <unistd.h>
@ -56,6 +57,39 @@ void NativeRenderThread::renderLoop() {
if (!eglCore_->init(nativeWindow_)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "EGLCoreInit","Failed to initialize EGL");
}
ftMgr=Font_FontMgr::GetInstance();
ftMgr->InitFontDataBase();
ftMgr->SetPrintErrors(true);
ftMgr->SetTraceAliases(true);
Handle(Font_SystemFont) sysFont=new Font_SystemFont("HarmonyOS_Sans_Medium");
sysFont->SetFontPath(Font_FontAspect_Regular, "/data/storage/el2/base/haps/entry/files/fonts/");
// 注册字体。第二个参数如果是 Standard_True表示强制注册即使同名也覆盖。
bool isRegistered = ftMgr->RegisterFont(sysFont, Standard_True);
if (!isRegistered) {
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","Error: Cannot register font: %{public}s",sysFont->FontName().ToCString());
return; // 或者进行错误处理
} else {
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","Successfully registered font: %{public}s",sysFont->FontName().ToCString());
}
Handle(Font_SystemFont) fsf;
fsf=ftMgr->GetFont("HarmonyOS_Sans_Medium");
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Path: %{public}s", fsf->FontPath(Font_FontAspect_Regular).ToCString());
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT GetFont: %{public}s", fsf->FontName().ToCString());
//输出所有字体
NCollection_Sequence<occ::handle<TCollection_HAsciiString>> theAliases;
ftMgr->GetAllAliases(theAliases);
for(auto ft:theAliases){
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Aliases: %{public}s", ft->ToCString());
}
//checkfont
NCollection_List<occ::handle<Font_SystemFont>> fsfs;
fsfs=ftMgr->GetAvailableFonts();
for(auto fta:fsfs){
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Font: %{public}s", fta->FontName().ToCString());
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Font Path: %{public}s", fta->FontPath(Font_FontAspect_Regular).ToCString());
}
// 初始化OCCT渲染器
if (!renderer_->init(*eglCore_)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit","Failed to initialize OCCT renderer");

View File

@ -10,6 +10,10 @@
#include "EGLCore.h"
#include "NativeRender.h"
#include <Font_FontMgr.hxx>
#include <AIS_TextLabel.hxx>
#include <Resource_Unicode.hxx>
namespace NativeOpenCAX {
class NativeRenderThread {
@ -68,7 +72,7 @@ private:
std::mutex callbackMutex_;
Callback renderCompleteCallback_;
Handle(Font_FontMgr) ftMgr ;
int windowWidth_;
int windowHeight_;
};

View File

@ -10,6 +10,7 @@
#define NATIVE_TAG "TEXTSTYLE"
#endif
//该类型主要用于全局字体,样式设置.包含字体.大小.颜色.渲染方式
namespace NativeOpenCAX {
@ -20,7 +21,7 @@ bool TextStyle::InitTextStyle() {
try {
text = new Prs3d_TextAspect();
text->SetFont("HarmonyOS Sans");
text->SetHeight(12);
text->SetHeight(5000);
text->Aspect()->SetColor(Quantity_NOC_GRAY95);
text->Aspect()->SetColorSubTitle(Quantity_NOC_BLACK);
text->Aspect()->SetDisplayType(Aspect_TODT_SHADOW);

View File

@ -7,10 +7,16 @@
#ifndef OPENCAX_TEXTSTYLE_H
#define OPENCAX_TEXTSTYLE_H
#include <map>
#include "NativeEGLOCCT/common.h"
#include "Font_NameOfFont.hxx"
#include <Prs3d_TextAspect.hxx>
//字体样式类型.主要用于区别该样式用于何处
enum FONT_STYLE_TYPE{
STYLE_AXIS,
STYLE_FACE,
};
namespace NativeOpenCAX{
class TextStyle{
public:
@ -19,6 +25,8 @@ public:
bool InitTextStyle();
public:
Handle(Prs3d_TextAspect) text;
//一个字体管理样式对象管理.主要负责对字体样式的归一化集中管理
std::map<FONT_STYLE_TYPE, Handle(Prs3d_TextAspect)> fontStyle;
};
}

View File

@ -31,6 +31,45 @@
class TCollection_HAsciiString;
class NCollection_Buffer;
// list of supported extensions
static const char* Font_FontMgr_Extensions[] = {"ttf",
"otf",
"ttc",
"pfa",
"pfb",
#ifdef __APPLE__
// Datafork TrueType (OS X), obsolete
//"dfont",
#endif
nullptr};
#if defined(HAVE_FREETYPE_OHOS) && !defined(__ANDROID__) && !defined(__APPLE__) \
&& !defined(__EMSCRIPTEN__)
// X11 configuration file in plain text format (obsolete - doesn't exists in modern distributives)
static const char* myFontServiceConf[] = {"/etc/X11/fs/config",
"/usr/X11R6/lib/X11/fs/config",
"/usr/X11/lib/X11/fs/config",
nullptr};
// Although fontconfig library can be built for various platforms,
// practically it is useful only on desktop Linux distributions, where it is always packaged.
//Harmony OS not
#include <fontconfig/fontconfig.h>
#endif
#ifdef __APPLE__
// default fonts paths in Mac OS X
static const char* myDefaultFontsDirs[] = {"/System/Library/Fonts", "/Library/Fonts", nullptr};
#else
// default fonts paths in most Unix systems (Linux and others)
// static const char* myDefaultFontsDirs[] = {"/system/fonts", // Android
// "/usr/share/fonts",
// "/usr/local/share/fonts",
// nullptr};
static const char* myDefaultFontsDirs[] = {"/data/storage/el2/base/haps/entry/files/fonts", // Harmony OS
nullptr};
#endif
//! Collects and provides information about available fonts in system.
class Font_FontMgr : public Standard_Transient
{

View File

@ -1,4 +1,4 @@
// Created on: 2026-03-25
// Created on: 2026-03-27
// Copyright (c) 2002-2025 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.

View File

@ -6,8 +6,6 @@ import { ModelViewTab } from './modelViewTab'
import { TitleColumnSub } from './TitleLayout/TitleColumnSub'
import { mwInfo } from './AppStorageV2Class'
import fs from '@ohos.file.fs';
import resourceManager from '@ohos.resourceManager';
import fileIO from '@ohos.fileio';
const DOMAIN = 0x0000;
@ -29,50 +27,80 @@ struct Index {
@Provider('panelWidth') panelWidth:number=mwInfo.mainWindowWidth * 0.15;
//列出资源管理器指定目录下的所有问题件
async HilogToDirFile(dir: string){
const context = getContext(this);
HilogToDirFile(){
const context = this.getUIContext().getHostContext();
// 获取资源管理器
const rm = context.resourceManager;
// 列出 rawfile/fonts/
const fontFiles: string[] = await rm.getRawFileList(dir);
console.info(dir+'目录下文件:', JSON.stringify(fontFiles));
if (fontFiles.length === 0) {
console.warn(dir +':目录为空');
return;
}
const rm = context?.filesDir+'/fonts/';
fs.listFile(rm).then((filenames: Array<string>) => {
console.info('沙箱文件信息'); // 打印成功日志
console.info('目录路径:'+rm); // 打印成功日志
console.log('指定目录文件数: ' + filenames.length) // 打印文件数量
// 遍历打印所有文件名到控制台
for (let i = 0; i < filenames.length; i++) {
console.log('文件名:', filenames[i]);
}
}).catch((err: BusinessError) => {
// 捕获并打印文件列表获取失败的错误信息
console.error('list file failed with error message: ' + err.message + ', error code: ' + err.code);
});
}
//复制字体到沙盒指定目录
//SandBoxFontDir:"/data/storage/el2/base/haps/entry/files/fonts"
async CopyFontToSandbox(fontFiles: Array<string>) {
try {
const context = getContext(this);
let srcPath = context.resourceDir+'/fonts/';
let destPath = context.filesDir + '/fonts/';
// 判断文件夹是否存在
if (!fs.accessSync(destPath)) {
fs.mkdirSync(destPath);
console.info('创建沙箱目录成功:', destPath);
}
console.info('srcPath', srcPath);
console.info('destPath', destPath);
fs.copyDirSync(srcPath, destPath, 0)
} catch (err) {
let msg = 'Unknown error';
if (err instanceof Error) {
msg = err.message;
} else if (typeof err === 'string') {
msg = err;
}
console.error(`Copy failed: ${msg}`);
throw new Error(`Failed to copy ${fontFiles} to sandbox: ${msg}`);
CopyFontToSandbox() {
try {
const context = this.getUIContext().getHostContext();
let srcPath = context?.resourceDir+ '/fonts/';
let destPath = context?.filesDir + '/fonts/';
if (!srcPath || !destPath) {
throw new Error('Resource or files directory is not available.');
}
console.info('srcPath', srcPath);
console.info('destPath', destPath);
// 1. 检查源目录是否存在
try {
fs.access(srcPath);
} catch (error) {
console.error('Source directory does not exist:', srcPath);
return; // 或者抛出错误
}
// 2. 创建目标目录
// 使用 mkdir 同步或异步版本,并处理已存在的异常
try {
fs.mkdir(destPath);
console.info('Created sandbox directory successfully:', destPath);
} catch (mkdirErr) {
// 如果目录已存在mkdir 会失败,这通常是无害的
console.info('Sandbox directory already exists:', destPath);
}
// 3. 复制目录
// 关键修改点:移除第三个参数 '1',该参数是无效的。
// 可以选择性地添加一个空的 flags 对象 {}
fs.copyDir(srcPath, destPath);
console.info('Fonts copied to sandbox successfully.');
} catch (err) {
let msg = 'Unknown error';
if (err instanceof Error) {
msg = err.message;
} else if (typeof err === 'string') {
msg = err;
}
console.error(`Copy failed: ${msg}`);
// 注意:模板字符串需要反引号 ``,您原代码中的单引号 '' 会直接输出变量名
throw new Error(`Failed to copy to sandbox: ${msg}`);
}
}
//Copy Font File to Sandbox
aboutToAppear() {
this.HilogToDirFile('fonts/');
this.CopyFontToSandbox(Fonts);
this.CopyFontToSandbox();
//输出沙盘下得文件名
this.HilogToDirFile();
}
build() {

View File

@ -8,6 +8,7 @@ import { LayoutSwitch } from "../LayoutInterface/Layout/LayoutSwitch";
import { FileMenuData } from "../LayoutInterface/Layout/FileMenuData";
import { mwInfo } from "../AppStorageV2Class";
import { SubColumnMenu} from "../CustomStyle/Button";
import { fileIo } from "@kit.CoreFileKit";
@ComponentV2

View File

@ -24,9 +24,35 @@ export struct ModelView {
private nodeContent: NodeContent = new NodeContent();
aboutToAppear() {
const context = getContext(this);
modelPath = `${context.filesDir}/${this.modelName}`
NativeOpenCAX.createNativeNode(this.nodeContent);
this.copyRawFileToSandbox();
}
async copyRawFileToSandbox() {
try {
const context = getContext(this);
modelPath = `${context.filesDir}/${this.modelName}`;
const arrayBuffer:Uint8Array = await context.resourceManager.getRawFileContent(this.modelName);
const buffer = arrayBuffer.buffer;
console.log('Raw file size:', arrayBuffer.byteLength);
if (fs.accessSync(modelPath)) {
fs.unlinkSync(modelPath);
}
const fd = fileIO.openSync(modelPath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE,0o666);
const bytesWritten = fileIO.writeSync(fd, buffer);
console.log('Bytes written:', bytesWritten);
fileIO.closeSync(fd);
console.log('SanBox File:', arrayBuffer.byteLength);
console.log('WriteModelPath:', modelPath);
} catch (err) {
let msg = 'Unknown error';
if (err instanceof Error) {
msg = err.message;
} else if (typeof err === 'string') {
msg = err;
}
console.error(`Copy failed: ${msg}`);
throw new Error(`Failed to copy ${this.modelName} to sandbox: ${msg}`);
}
}
build() {

Binary file not shown.