HTML5 Canvas fillText со строкой справа налево - PullRequest
8 голосов
/ 22 января 2012

Я пытаюсь использовать метод fillText () в 2D-контексте HTML5 Canvas для рисования строки, написанной на арабском языке. Это работает отлично, пока я не поставлю знак препинания в конце строки. Затем знак препинания появляется на неправильной стороне строки (в начале, а не в конце, как если бы это была строка ltr, а не rtl). Я поиграл со свойством Context.textAlign, но, похоже, это касается только способа отрисовки строки относительно указанной позиции, а не фактического направления текста. Кто-нибудь знает решение этой проблемы?

Спасибо.

Обновление: Ответ, который я нашел, заключается в добавлении атрибута "dir" к элементу canvas на странице. Например,

<canvas dir="rtl">

Однако я все еще не знаю, как изменить атрибут dir для отдельных строк, отправляемых в fillText. Есть идеи?

Ответы [ 4 ]

9 голосов
/ 12 апреля 2013

Вам не нужно устанавливать направление для каждой отдельной строки. Смотрите следующий пример, который также показывает правильное использование неявных контрольных отметок двунаправленного текста для правильного порядка отображения:

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>

  <body>
    <canvas id="myCanvas" width="700" dir="rtl" height="250" style="border:1px solid #d3d3d3;">
      Your browser does not support the HTML5 canvas tag.
    </canvas>

    <script type="text/javascript" charset="utf-8">
      var c = document.getElementById("myCanvas");
      var cArabic = c.getContext("2d");
      cArabic.font="25px Arial";

      // Simple Sentence with punctuation.
      var str1 = "این یک آزمایش است.";
      // Few sentences with punctuation and numerals. 
      var str2 = "۱ آزمایش. 2 آزمایش، سه آزمایش & Foo آزمایش!";
      // Needs implicit bidi marks to display correctly.
      var str3 = "آزمایش برای Foo Ltd. و Bar Inc. باشد که آزموده شود.";
      // Implicit bidi marks added; "Foo Ltd.&lrm; و Bar Inc.&lrm;"
      var str4 = "آزمایش برای Foo Ltd.‎ و Bar Inc.‎ باشد که آزموده شود.";

      cArabic.fillText(str1, 600, 60);
      cArabic.fillText(str2, 600, 100);
      cArabic.fillText(str3, 600, 140);
      cArabic.fillText(str4, 600, 180);
    </script>

  </body>
</html>

А вот и вывод: image26.0.1410.64 m on MS Windows XP SP3">

2 голосов
/ 06 мая 2012

Настройка параметра dir для всего холста - для отдельных строк, которые ведут себя плохо, вы можете вручную добавить маркер RTL (U + 200F) после кавычки.

0 голосов
/ 14 апреля 2018

Проблема в том, что '.'символ является «нейтрально-направленным символом», это означает, что он получает направление от следующего сильного направленного символа, если после этого символа нет, он получает его из контейнера.В вашем случае это последний.Одним из решений, как уже было найдено, является создание контейнера справа налево.Но есть еще два других решения:

1 - Поставьте еще один невидимый сильный направленный символ справа налево после «.».К счастью, у юникода есть один специальный символ для того, что является «меткой справа налево» (U + 200F)

2- Поставьте «символ переопределения справа налево» (U + 202E) передтекст, поэтому после этой отметки любой нейтральный символ получает направление справа налево.Вы можете завершить переопределение, добавив символ «всплывающее направленное форматирование» (U + 202C).

Я изменил пример кода @ shervin, чтобы продемонстрировать его.

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>

  <body>
    <canvas id="myCanvas" width="700" height="250" style="border:1px solid #d3d3d3;">
      Your browser does not support the HTML5 canvas tag.
    </canvas>

    <script type="text/javascript" charset="utf-8">
      var c = document.getElementById("myCanvas");
      var cArabic = c.getContext("2d");
      cArabic.font="20px Arial";

      //option 1 : adding right-to-left mark at the end to put the '.' between two strong right to left charachters, so it will treated as right to left.
      var str1 = "این یک آزمایش است." + "\u200F";

      //option 2 : adding right-to-left override at the begining of the text so every neutral charachter afterward becomes righ to left.
      var str2;
      str2 = "\u202E";
      str2+= "این یک آزمایش است.";
      //           you might want to finish the override by 'pop directional formatting' charachter
      str2 += "\u202C";

      cArabic.fillText(str1, 200, 30);
      cArabic.fillText(str2, 200, 70);
    </script>

  </body>
</html>

Результирующее изображение

Существуют и другие решения.Вы можете найти их в спецификации Unicode на этой странице .Это «изоляция направления» (U + 2067), которая имеет проблемы с рендерингом в Chrome.И «внедрение направления» с U + 202B, что аналогично переопределению направления.

0 голосов
/ 28 января 2018

Вы можете сделать это с помощью:
ctx.textAlign = "end";
или
ctx.textAlign = "вправо"

И сделать его снова слева направо:
ctx.textAlign = "start";

...