javascript - 阿拉伯字体在 p5.js 中无法正确显示

标签 javascript fonts p5.js

我想做一些阿拉伯风格的设计,但我对文本的显示方式、从左到右书写和断开连接的方式有疑问。

let bg;
let str = "السلام عليكم";
var Diwani;

function preload() {
  Diwani = loadFont('DiwaniFont.ttf');
}

function setup() {
  bg = loadImage('pattern.png');
  createCanvas(400, 400);
}

function draw() {
  background(bg);
  textSize(40);
  textAlign(CENTER);
  stroke(255, 255, 255);
  strokeWeight(5);
  textFont(Diwani);
  text(str, 200, 200);
}

output

这绝对不是我使用的字体的问题。我尝试了其他方法,但仍然得到相同的结果。

有解决办法吗?

最佳答案

显然,p5.js 在正确渲染从右到左的文本方向时存在问题。

值得注意:使用系统默认字体时,文本方向似乎是正确的。

解决方法 1:在 HTML/CSS 中预加载字体

以下示例加载 google 字体 "Noto Naskh Arabic"通过CSS @font-face以及 HTML 的使用。
将字体 URL 替换为本地可用的“DiwaniFont.ttf”以测试所需的结果。

let bg;
let str = "السلام عليكم";

function setup() {
  //bg = loadImage('pattern.png');
  createCanvas(400, 400);
}

function draw() {
  //background(bg);
  textFont('Diwani');
  textSize(40);
  textAlign(CENTER);
  stroke(255, 255, 255);
  strokeWeight(5);
  text(str, 200, 200);
}
@font-face {
  font-family: 'Diwani';
  font-weight: 400;
  font-stretch: normal;
  src: url('https://fonts.gstatic.com/s/notonaskharabic/v17/RrQ5bpV-9Dd1b1OAGA6M9PkyDuVBePeKNaxcsss0Y7bwvc5Urqc3.ttf') format('truetype');
  font-style: normal;
}

body {
  font-family: 'Diwani';
  font-size: 40px;
}

canvas {
  width: 50%;
  border: 1px solid red;
}

.hidden {
  visibility: hidden;
  position: absolute;
  overflow: hidden;
  width: 0;
  height: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
<p>السلام عليكم</p>
<p class="hidden" aria-hidden="true">السلام عليكم</p>

所以我们实际上是通过 @font-face 注册/加载字体的规则

@font-face {
  font-family: 'Diwani';
  font-weight: 400;
  font-stretch: normal;
  src: url('https://fonts.gstatic.com/s/notonaskharabic/v17/RrQ5bpV-9Dd1b1OAGA6M9PkyDuVBePeKNaxcsss0Y7bwvc5Urqc3.ttf') format('truetype');
  font-style: normal;
}

现在我们不需要使用 loadFont() 预加载字体方法。
相反,我们可以通过名称设置字体系列 textFont('Diwani') .

我们需要确保字体已加载:
添加隐形<p>使用字体系列 (Diwani) 的元素将强制浏览器加载字体文件。

示例 2:仅渲染 Canvas

let bg;
let str = "السلام عليكم";

function setup() {
  //bg = loadImage('pattern.png');
  createCanvas(400, 400);
}

function draw() {
  //background(bg);
  textFont('Diwani');
  textSize(40);
  textAlign(CENTER);
  stroke(255, 255, 255);
  strokeWeight(5);
  text(str, 200, 200);
}
@font-face {
  font-family: 'Diwani';
  font-weight: 400;
  font-stretch: normal;
  src: url('https://fonts.gstatic.com/s/notonaskharabic/v17/RrQ5bpV-9Dd1b1OAGA6M9PkyDuVBePeKNaxcsss0Y7bwvc5Urqc3.ttf') format('truetype');
  font-style: normal;
}

body {
  font-family: 'Diwani';
  font-size: 40px;
}


.hidden {
  visibility: hidden;
  position: absolute;
  overflow: hidden;
  width: 0;
  height: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>
<p class="hidden" aria-hidden="true">السلام عليكم</p>

解决方法 2:通过 javaScript 预加载字体 FontFace() 构造函数

let str = "السلام عليكم";
    let fontUrl =
      "https://fonts.gstatic.com/s/notonaskharabic/v17/RrQ5bpV-9Dd1b1OAGA6M9PkyDuVBePeKNaxcsss0Y7bwvc5Urqc3.ttf";
    let fontFamily = "Diwani";
    let fontOptions = {
      weight: 400,
      style: "normal"
    };


    let fontsReady = new Promise(function(){
      loadFonts(fontFamily, fontUrl, fontOptions);
    });

    async function loadFonts(fontFamily, fontUrl, fontOptions) {
      const font = new FontFace(fontFamily, `url(${fontUrl})`);
      font.weight = fontOptions.weight ? fontOptions.weight : 400;
      font.style = fontOptions.style ? fontOptions.style : "normal";
      // wait for font to be loaded
      await font.load();
      fontsLoaded = true;
      document.fonts.add(font);
      // apply font styles to body
      document.body.setAttribute(
        "style",
        `font-family:${fontFamily}; font-weight:${fontOptions.weight}; font-style:${fontOptions.style}`
      );
    }

    async function setup() {
      createCanvas(400, 400);
      //draw text if fonts are ready
      await fontsReady;
    }

    function draw() {
        textFont('Diwani');
        textSize(40);
        textAlign(CENTER);
        stroke(255, 255, 255);
        strokeWeight(5);
        text(str, 200, 200);
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.min.js"></script>

与前面提到的 html/css 方法相同的概念。
但我们正在通过async function loadFonts(fontFamily, fontUrl, fontOptions)加载字体文件。 .
优点:我们不需要添加任何 css 规则或隐藏的 html 元素。

希望有帮助!
但是你应该report this issue on github.

关于javascript - 阿拉伯字体在 p5.js 中无法正确显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72644831/

相关文章:

javascript - p5.j​​s:为什么我的椭圆闪烁?

javascript - 否定RegEx Javascript中的一对字符

javascript - tip calc equation 在第一个输出上工作,但在第二个输出上使用 number() 返回 NaN

javascript - 我有一个用于学校翻译元素的按钮组,但我无法让我的按钮工作?

javascript - 将字符串表示法转换为递归对象指针

python-3.x - 无法在 tkinter 中更改按钮字体大小

css - 即使在 ?#iefix 到位后,IE @font-face 也无法正常工作

flash - 嵌入字体并在 Flash 中正确显示的问题

javascript - 是否可以让 <h1> 标签自动聚焦?

JavaScript 对象未实例化