我的一个项目全文用C++编写,但在最后阶段需要得到一个字符串在某一字体下某一字号的实际显示高度和长度。
比如说,使用如下代码,
<html>
<head>
<meta charset="utf-8">
<title>TEST</title>
<style>
p {font-size:25px;}
p.sansserif{font-family:"Microsoft YaHei";}
</style>
</head>
<body>
<p class="sansserif">
<span>A</span>
<span>I</span>
<span>可</span>
<span>香</span>
</p>
</body>
</html>
,在浏览器中F12
中元素
,选中span那一行可以显示当前字体的实际高度和长度(以px为单位)。
现在需要在这个C++程序中,运用某些方法得到特定字符串的显示高度和长度。
已经测试过如下代码:
EM_ASM_INT(
{
function computeFontSize(str, size, family)
{
let spanDom = document.createElement("span");
spanDom.style.fontSize = size;
spanDom.style.opacity = "0";
// spanDom.style.fontFamily = family;
spanDom.innerHTML = str;
document.body.append(spanDom);
let sizeD = {};
sizeD.width = spanDom.offsetWidth;
sizeD.height = spanDom.offsetHeight;
spanDom.remove();
return sizeD;
}
let str = currentDanmaku->Text;
let st = computeFontSize(str, "16px", "Microsoft YaHei");
return st;
}
);
编译器VS2022在EM_ASM_下划下划线,提示
#define EM_ASM_(code, ...) emscripten_asm_const_int(CODE_EXPR(#code)_EM_ASM_PREP_ARGS(_VA_ARGS_)
Old forms for compatibility, no need to use these.
Replace EM_ASM, EM_ASM_ARGS and EM_ASM_INT_V with EM_ASM_INT, and EM_ASM_DOUBLE_V with EM_ASM_DOUBLE.
扩展到: emscripten_asm_const_int((_extension_({_attribute_((section("em_asm"), aligned(1))) static const char x[] = "{function computeFontSize(str, size, family) { let spanDom = document.createElement("span"); spanDom.style.fontSize = size; spanDom.style.opacity ="0"; spanDom.innerHTML = str; document.body.append(spanDom); let sizeD = {}; sizeD.width = spanDom.offsetWidth; sizeD.height = spanDom.offsetHeight; spanDom.remove(); return sizeD; } }"; x; })),__em_asm_sig_builder<__typeof__(__em_asm_make_type_tuple())>::buffer)
按照提示修改为EM_ASM_INT
,错误信息变为:
#define EM_ASM_INT(code, ...) emscripten_asm_const_int(CODE_EXPR(#code)_EM_ASM_PREP_ARGS(_VA_ARGS_)
Runs the given JavaScript code on the calling thread (synchronously), and returns an i32 back.
扩展到: emscripten_asm_const_int((_extension_({_attribute_((section("em_asm"), aligned(1))) static const char x[] = "{function computeFontSize(str, size, family) { let spanDom = document.createElement("span"); spanDom.style.fontSize = size; spanDom.style.opacity ="0"; spanDom.innerHTML = str; document.body.append(spanDom); let sizeD = {}; sizeD.width = spanDom.offsetWidth; sizeD.height = spanDom.offsetHeight; spanDom.remove(); return sizeD; } }"; x; })),__em_asm_sig_builder<__typeof__(__em_asm_make_type_tuple())>::buffer)
自始至终这行都报错
不允许强制转换到类型 "_attribute_"
附可能用到的源码:
Main.cpp
#include <fstream>
#include <iostream>
#include <map>
#include <math.h>
#include <string>
#include "D:\emsdk\upstream\emscripten\system\include\emscripten\emscripten.h"
#include "Character Comparator.h"
#include "Class of Danmaku.h"
#include "Data Type Converter.h"
#include "QuickSort.h"
//#include "Get String Length.js"
using namespace std;
int main()
{
class Danmaku
{
public:
int type; // 类型
__int64 row_id; // row_id我发现的都有56位,于是用64位整型
string Text; // 要获取长度的字符串
string Fontname; // 字体名称
};
...
map<int, Danmaku*> AllDanmaku;
...
currentDanmaku = AllDanmaku[serial];
...
for (serial = 0;; serial++)
{
...
EM_ASM_INT(
{
function computeFontSize(str, size, family)
{
let spanDom = document.createElement("span");
spanDom.style.fontSize = size;
spanDom.style.opacity = "0";
// spanDom.style.fontFamily = family;
spanDom.innerHTML = str;
document.body.append(spanDom);
let sizeD = {};
sizeD.width = spanDom.offsetWidth;
sizeD.height = spanDom.offsetHeight;
spanDom.remove();
return sizeD;
}
let str = currentDanmaku->Text; // 需要传入的参数分别是这里的Text和下一行的FontName
let st = computeFontSize(str, "25px", currentDanmaku->FontName);
return st; // 然后要把这个st传回C++代码,后续要对其进行运算。
}
);
...
}
Get String Length.js (复制自https://blog.csdn.net/u014771745/article/details/102828237)
function computeFontSize(str, size, family) {
let spanDom = document.createElement("span");
spanDom.style.fontSize = size;
spanDom.style.opacity = "0";
// spanDom.style.fontFamily = family;
spanDom.innerHTML = str;
document.body.append(spanDom);
let sizeD = {};
sizeD.width = spanDom.offsetWidth;
sizeD.height = spanDom.offsetHeight;
spanDom.remove();
return sizeD;
}
let str = currentDanmaku->Text;
let st = computeFontSize(str, "25px", currentDanmaku->FontName);
return st;