Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Сбиваются индексы из-за иконок Emoji (http://www.flasher.ru/forum/showthread.php?t=215064)

djken 08.02.2018 20:39

Сбиваются индексы из-за иконок Emoji
 
Всем привет!

Вывожу текст в TextField с хэштегами и иконками. Иконки emoji конечно же не выводятся - они мне не нужны.
Задача: все хэштеги в тексте подсветить определенным цветом.

Код AS3:

var txt:TextField = new TextField();
txt.autoSize = TextFieldAutoSize.LEFT;
txt.text = "Любой текст с #хэштегами для #теста. Any text with #hashtags for the #test";
addChild(txt);
 
var fmt:TextFormat = new TextFormat();
fmt.color = 0x0033CC;
 
var arr:Array = getPosHashtags(txt.text);
for (var i in arr)
        txt.setTextFormat(fmt, arr[i][0], arr[i][1]);
 
function getPosHashtags(str:String):Array
{
        var arr:Array = [];
        var pattern:RegExp = /#[\S]*/g;
        var result:Object = pattern.exec(str);
 
        while (result != null)
        {
                arr.push([result.index, result.index + result[0].length]);
                result = pattern.exec(str);
        }
 
        return arr;
}

Проблема: если в тексте есть иконки emoji, то подсветка хэштегов съезжает...

Код AS3:

txt.text = "Любой текст с #хэштегами и котиками 🐈🐈 для #теста. Any text with #hashtags 😟 for the #test";

Как я догадываюсь, setTextFormat не учитывает скрытые символы в текстовом поле - из-за этого и происходит такой сдвиг...

В общем, решил я перед всем этим делом очищать текст от всех иконок...
Вот, например, хочу удалить из текста иконки с котом, которому соответствует unicode код u+1F408, но что-то никак не выходит...

Код AS3:

var str:String = "Тут иконки с котиками 🐈🐈 Попробуй-ка их удалить...";
trace("\t", s1); // с котами
 
var re:RegExp = new RegExp("([" + gen(0x1F408) + "])", "gi");
str = str.replace(re, "");
trace("\t", str); // ожидаю текст без котов, но увы..
 
function gen (obj:Object):String
{
        return String.fromCharCode(obj);
}

Плз, помогите советом

in4core 08.02.2018 21:11

djken - понимаю не лучший вариант, но я бы сплитом удалил нафиг, хз как это скажется на оптимихации, но думаю не сильно убьет ваш чат.

Код AS3:

for(var i:int = 0; i < arrayCats.length; i++)  text.split(arrayCats[i]).join("");


djken 08.02.2018 21:41

Вложений: 1
На PHP, например, для нахождения иконкок emoji справляется регулярка:

PHP код:

/[\x{1F000}-\x{1F6FF}]/gu 

Как подобное написать на actionscript? Пытался по-всякому, но так и не получилось..

Добавлено через 24 минуты
Интересно, почему, во Flash IDE в swf файле выводятся emoji ?
Код AS3:

var txt:TextField = new TextField();
txt.autoSize = TextFieldAutoSize.LEFT;
txt.text = "\u041e\u0442\u043c\u0435\u0442\u044c \u0442\u0430\u043a\u043e\u0433\u043e \u0434\u0440\u0443\u0433\u0430\ud83d\udc47\ud83d\ude02\n#hashtag";
addChild(txt);

Вложение 33202

А во FlashBuilder только текст...

djken 09.02.2018 03:09

Вложений: 1
Ура! Проблему решил!
Причина была вот в чем: многие иконки emoji состоят из суррогатных пар - например, \ud83d\ude0d. Это 2 символа. Но регулярка почему-то засчитывает эту комбинацию как один символ. В итоге все найденные индексы сдвинуты. Но если воспользоваться методом length у класса String, то длина текста выводится верно.
Код AS3:

trace(String("\ud83d\ude0d").length); // выведет 2

Отсюда пришел к выводу, что надо попробовать искать индексы хэштегов не через RegExp, а через методы String.
В итоге все хэштеги нахожу через RegExp и запоминаю в массив, а потом прохожусь по этому массиву и ищу эти найденные хэштеги в тексте с помощью indexOf, записывая индексы начала и конца хэштега.

Код AS3:

var txt:TextField = new TextField();
txt.x = txt.y = 15;
txt.autoSize = TextFieldAutoSize.LEFT;
addChild(txt);
 
txt.text = "#Dog \ud83d\ude0d #Test \ud83d\ude0e #Night Всякий текст с \n#хэштегами и смайликами";
var arr:Array = searchHashtag(txt.text);
 
var baseFormat:TextFormat = new TextFormat(new PartnerCondensedBold().fontName, 30, 0xFFFFFF);
txt.setTextFormat(baseFormat);
 
var tagColorize:TextFormat = new TextFormat(null, null, 0x66FE03);
for (var i:uint in arr)
        txt.setTextFormat(tagColorize, arr[i][0], arr[i][1]);
 
function searchHashtag(str:String):Array
{
        var arr:Array = new Array();
        var pattern:RegExp = /#[\S]+/g;
        arr = str.match(pattern);
 
        var res:Array = new Array();
        var index:uint = 0;
        var s1:uint;
        var s2:uint;
 
        for (var i:uint in arr)
        {
                s1 = str.indexOf(arr[i], index);
                s2 = s1 + arr[i].length;
                res.push([s1,s2]);
 
                index = s2;
        }
 
        return res;
}

И кстати, emoji тоже получилось отображать прямо в тексте - просто создал текстовое поле программно и они отобразились :confused:

Вложение 33203

undefined 09.02.2018 03:21

Прикольно, не знал, что штатный текстфилд без танцев с бубном умеет смайлы рисовать. А откуда растр берется? Ось предоставляет? Так только с системными шрифтами можно?

djken 09.02.2018 03:53

undefined, если ты про растр, который на фоне - тоже в скрипте прописан, просто не вывел в примере.

А смайлы и не надеялся выводить, т.к. знал что это трудоемко - но случайно заметил что программным текстфилдом отрисовались. При чем нормально позиционируются, выделяются вместе с текстом. Шрифт не системный - PartnerCondensed. С другими шрифтами тоже работает.

djken 09.02.2018 04:25

Вложений: 1
ссори.. проверил сейчас - с заранее созданными текстовыми полями на сцене тоже все работает )

Вложение 33204

Теперь понял почему до этого не выводились смайлы. Смайл можно записать в виде суррогатной пары \uxxxx\uxxxx , либо в общем виде \uxxxxx.
Например, иконку "fire / огонь" можно записать так \u1F525 либо суррогатами \udd25\ud83d. Вторым способом выведет, первым - нет. В этом не особо разбираюсь, но думаю связано с размером кодировки - не умеет работать с этим диапазоном наверно..

Кому интересно, тут находил формулы преобразования в суррогатные пары:
http://as3coder.blogspot.ru/2014/08/emoji.html

undefined 09.02.2018 10:40

Цитата:

Сообщение от djken (Сообщение 1204216)
undefined, если ты про растр, который на фоне - тоже в скрипте прописан, просто не вывел в примере.

Нет, я про растр для смайлов. Откуда он берется?

Wolsh 09.02.2018 13:06

Текст в обычном текстфилде, шрифт не внедренный, значит используется системный рендер. Видимо, ОС и подставляет. Не факт, что будет работать на других осях.

djken 09.02.2018 14:04

Да, проверил на другой машине с Виндой - там вместо смайлов пустые квадраты


Часовой пояс GMT +4, время: 20:16.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.