Чтобы добавлять сообщения и комментарии, .

@develar:
develar

Ага. Стало понятно теперь, почему в TLF от Adobe такая убогая непредсказуемая отрисовка underline, в то время как в TinyTLF всегда красивая и черточка не прилеплена к тексту. Вся штука в том, что FTE это хорошая тема, и в руки нам дается прекрасный API. API этот, в частности, позволяет спросить у element format FontMetrics, а вот FontMetrics как и содержит "suggested vertical offset from the Roman baseline for an underline.".

Видимо, авторы TLF, как всегда, забыли, что Flash Player при отрисовке чего-то, заданного float (а underlineOffset может быть равен 0.451171875) subpixel rendering не осуществляет.

@werdn:
werdn

Убить всех авторов этого чуда, за то что они сделали LinkElement как final class!!111
есть какой-нить другой способ прикрепить кастомное поле к ссылке?

@develar:
develar

Кто-нибудь еще сомневается, что можно иметь что-то общее с этими отмороженными дебилами (медицинский термин, ага) #1179963 ?

Технически инженер из Adobe прав ( forums.adobe.com ). Прав на 100%.
Есть только два нюансы — мы, черт возьми, люди.

Два вопроса:
1) Какого черта оно после прокрутки до упора вниз (key down) и прокрутки взад до упора вверх (key up) не восстанавливает позицию (текст будет прилеплен)?
2) АУ! На дворе чертов 2011 год, романтика программирования ушла и канула в лету, откройте тот же Interface Builder да накидайте вы TextView и посмотрите как оно себя ведет. Что, тоже торкает как оно аккуратно рассчитывает середину текста и плавно откручивает при достижении viewHeight ровнехонько на -viewHeight/2 с сохранением позиции курсора (вопрос номер три – какого черта оно при достижении конца переносит мой курсор в конец строки (все правильно) и потом забывает вернуть взад?).

Между прочим, TinyTLF скоро будет поддерживать редактирование, а уже сейчас дает с в разы меньшими вложениями в разы более нормальное (читай как в твоей ОСи, а не как в мозгу обкуренных не той травой "инженеров" Adobe) поведение (+как плюшка производительность, но в нашей то ситуации дай бог сделать нормально и в срок).

@yzh44yzh:
yzh44yzh

Замучался сражаться с TLF. Уперся в пару мелких проблем, которые сложно решить, но которые сводят на нет всю юзабельность продукта.

Ну что ж, давно хотел пощупать TinyTLF github.com видимо пришло время.

@Constantiner:
Constantiner

Когда пытаешься в интернете найти инфу об устройстве bidirectional text в Adobe TLF, то попадаешь исключительно на рекламу, как классно он в TLF поддерживается. Очевидно, что конкретика в коде. Так не хочется :(

@Constantiner:
Constantiner

К предыдущему #1114763 и #1114706. Только три вида операций могут сливаться. Эту инфу можно найти в коде метода merge класса flashx.textLayout.operations.CompositeOperation. Операции эти суть InsertTextOperation, SplitParagraphOperation и DeleteTextOperation. Может, кому пригодится.

@Constantiner:
Constantiner

В классе flashx.textLayout.operations.FlowOperation есть метод tlf_internal function merge(operation:FlowOperation):FlowOperation коммент к которому гласит:

Combine this operation with another operation if the result can
be represented as a single operation. In general, operations cannot be
merged. But sequential inserts or deletes may be mergeable.

Ну не суки ли написать такой важный коммент там, где можно прочитать лишь если залезть в код? :(

@Constantiner:
Constantiner

Опять сграный TLF. Ну вот хрена он кэширует операции изменения в текстовом поле? Если вставлять в текст одну и ту же букву, то он будет каждый раз присылать событие, в котором InsertTextOperation будет один и тот же объект, а вот вставляемый текст разный. Ну вот нафига?

@Constantiner:
Constantiner

В продолжение #1106352 о пиздатости дизайна TLF и Flex.

Ну вот я решил отнаследовать RichEditableTextContainerManager и, конечно, отнаследовать RichEditableText, в котором этот отнаследованный менеджер будет использоваться. Все, вроде, здорово. Мне даже не надо отнаследоваться от TextArea так как у нас есть механизм скинов, в котором мы можем легко и просто подменить наш RichEditableText на RichEditableTextExt. Конечно, тут тоже не все пучком. Ибо скин приходится полностью копировать, но это уже баян и не смешно.

Но метод создания RichEditableTextContainerManager в RichEditableText, который мне надо переопределить, состоит из одной строчки:

return new RichEditableTextContainerManager(this, staticConfiguration)
При этом staticConfiguration — это приватное статическое поле. Понятно, что код его создания придется копировать тоже. Ну вот ничего у Адобов нельзя сделать быстро просто и красиво. А ведь когда-то так не было. Как-то проще все было…

@Constantiner:
Constantiner

Ненавижу Адобов за кривизну и непродуманность года :( У них в TextArea, а если точнее, то в RichEditableText, есть поле textContainerManager типа TextContainerManager. Он якобы является фасадом для ContainerController, решая якобы задачи производительности. Вариант убогий, но приемлемый. Убогость варианта в том, что к этому полю доступ идет через контейнер (в данном случае RichEditableText), который обычно не отнаследован в других контролах, а идет композитом. Соответственно, красиво и универсально передавать некому классу TextFlow уже не получится. Надо передавать контейнер и иметь все замечательные проверки его типа и кастинги.

Тем не менее, этот TextContainerManager решает вопросы перехвата событий мыши в виде событий, когда ContainerController предполагает наследование и переопределение соответствующих обработчиков. Решение кривоватое (обращение только через контейнер), но решение. А теперь такой момент, что контекстное меню они решили из этого класса исключить. Ничего страшного. Сделаем свой ContainerController, в котором переопределим menuSelectHandler. Но в итоге оказывается, что старый ContainerController в TextFlow уже не заменить столь безболезненно, особенно ничего не зная о нашем контейнере и оперируя лишь TextFlow (как нам этого бы и хотелось).

Дело в том: что этот TextContainerManager имеет внутренний класс, отнаследованный от ContainerController, на который жестко, а не по родителям или интерфейсу завязан. То есть распутать их нельзя. NPE обеспечено. Они ссылаются друг на друга и ввиду того, что TMContainerController — класс внутренний, он не наследуется и не подменяется.

В итоге сейчас пойду наследовать TextContainerManager, что все равно предполагает, что придется общаться с контейнером.

Ух, Адобы, кривые вы уроды! И все это на фоне чрезмерной усложненности TLF, который почему-то должен быть MVC. Хотя никто не может в точности сказать, где там M, где V, а где C. Ибо роли нечетки размазаны тонким слоем по хлебу :(

Я высказался :)

@zEvg:
zEvg

Это жопа — 96 % CPU при отображении 22800 символов в TLF :(( . Где из тегов только <p> и <b>

@develar:
develar

Еще одним несомненным плюсом tinytlf является отсутствие такого маразма как TextFlow. Моделью выступают непосредственно классы Flash Player — ContentElement (see guyinthechair.com Model Agnosticism). При этом вы не обязаны предоставить движку (да, да, движку, что невозможно сказать в отношении TLF, то в случае tinytlf именно text engine) сразу всю модель — можно как поток, посредством реализации ITextBlockFactory — спросили у вас nextBlock — отдали. Это абсолютно не имеет смысла, если вам нужно просто отобразить некий статический текст, но ведь, черт возьми, это ведь text engine — оно должно давать удобный API в том случае, если текст у вас строится динамически.

@develar:
develar

В отличие от идиотов в Adobe, автор tinytlf нормальный, в tinytlf нет никакого asdoc в классах реализации — только в интерфейсах.
Понятный и удобный API (если мне нужно установить только ширину, я explicitWidth = newW, а не setCompositionSize(newW, NaN)).

Минусы только по оформлению кода — явно видно, что автор пользуется блокнотом/Flash Builder, а не IntelliJ IDEA.

Черт возьми, впервые за 5 лет испытал удовольствие от работы со сторонней библиотекой на ActionScript (mate не в счет). По привычке порывался при использовании писать свое, но чудо — интерфейсы тут не только для галочки. И даже абстрактные классы можно использовать как базовые (с Flex SDK и TLF это невозможно — интерфейсы не используются, типы параметров/свойств конкретные, а в случае с tlf добавляется еще и tlf_internal). Да — если в неком коде используются пространства имен — разработчика кастрировать, а также всех сопричастных (в моей библиотеке Cocoa используется пространство имен ui для ui component skin parts, но это лишь от бедности — все время не найду написать compiler extension для ast генерации в compile time — то бишь в runtime этот namespace никак не является частью API/рабочего кода). Использование пространств имен это отличный индикатор убожества архитектуры. Потому что с ними все эти высокотеоретические выкладки об ООП смываются и размываются — это даже не прострелить себе ногу. И отсутствие поддержки пространств имен для интерфейсов это показатель, да.

Помимо пула для textLine (reuse на уровне плеера, добавление/удаление из пула на уровне as), также есть пул для textBlock (только на уровне as, при написании своей реализации ITextBlockFactory, нужно знать об этом пуле и использовать его) — вот этого в tlf нет.

Есть хитрый момент с инвалидацией. TextEngine принимает необязательный параметр stage. Stage ему нужен как раз для валидации — как во флексе, отрисовка происходит не на каждое изменение данных, а в определенный момент времени. И tinytlf вешается на ENTER_FRAME и RENDER (какой раньше придет — пришел — отписались от обоих и render). Если мы используем tinytlf во флекс-приложении, где уже есть свой LayoutManager, делающий ту же работу, то нужно ли нам передавать tinytlf stage? Если текст не интерактивный — можно всю валидацию осуществлять в host component — он на updateDisplayList вызывает у textEngine render и все (тема встраивания text engine во flex component lifecycle (типа measure) обширна и в этот топик не входит, могу лишь сказать, что тут tlf sucks, а tinytlf берет пирожок). А вот если интерактивный — то ничего работать не будет (то бишь никакой отрисовки в ответ на действия пользователя) — ведь он будет ждать, пока его отвалидируют. Интересно, что в реализации RichTextField данный момент никак не решен (тупо передается stage — то есть возможен сценарий гонки — когда оно отрисуется до updateDisplayList). Решается написанием своего (патч автору еще не отправил).

А gestures — это песня. Вам не нужен ParagraphSelectionBehavior? Ну так не мапьте его — оставьте только CharacterSelectionBehavior и WordSelectionBehavior. Впрочем — управление курсором вкупе со ссылками из разных блоков — получается порнография. Потому что стека курсора нет, получается гонка и как результат вы на второй ссылке получите auto вместо button/ibeam. Вряд ли автор tinytlf поправит это (невоспроизводимо на обычных текстах), пока что на это забил.

Нерваное выделение текста, как и должно быть в Mac OS X — juick.com

Черт возьми, оно умеет отрисовывать подчеркивания не как путь всегда обкуренных сотрудников Adobe домой — то прилеплено к глифам, то нет, а нормально — всегда с отступом.

И, да, кайфую от того, что когда-то исправил компилятор таким образом, что вектор созданный в виде литерала, является фиксированным ( juick.com ).

@develar:
develar

Еще не работал, но уже чувствую, что Adobe должна уволить весь TLF team и нанять guyinthechair.com <guyinthechair.com> You can grab mavenized project github.com (just open in IntelliJ IDEA and get configured ide project).

@develar:
develar

Профилировал juick.com FB профайлер тормозной (IDEA берет те же данные гораздо быстрее, вот только показывает она их не так удобно — видимо, тут ошибка Adobe в том, что они перенесли/реализовали часть вычисления на сторону flash player, а по сути правильно отправить лишние несколько метров на сторону java и пусть она сама считает) — при наведении на ссылку он подвисает, а потом можно видеть в таблице результатов — TLF честно полностью композирует весь TextFlow (flowComposer.updateAllControllers()). В моем случае оно честно вызывает 198 раз createTextLine. Правильно, а вдруг в новом формате ссылки новый fontSize? Только, сцуко, не в их наркотическом бреду, а в реальной жизни у нас меняется только и только цвет у ссылки (а то и вовсе — подчеркивание, то есть даже и одного вызова recreateTextLine не будет — тупо удостовериться, что sprite для отрисовки уже добавлен в существующий textLine, и отрисоваться в нем) — и нет никаких проблем проверить эти два условия (и только в худшем случае recompose all)).

@develar:
develar

Есть у меня 30 штук spans со ссылками. И вот при перемещении мышкой по этим ссылках оно явно тормозит (курсор и подчеркивание с задержкой) на i7 процессоре. Кто работал с TLF — это нормально? Придется опять профилировщиком смотреть и фиксить.

@develar:
develar

Сборки TLF для мавена, как уже писалось, можно брать тут — repository.flyti.org

Опубликовал немного дополненную 2.0.189-de1 (192 билд). У FlowGroupElement

public function set children(chidlren:Vector.<FlowElement>):void

и

public function set child(child:FlowElement):void

Для чего? Если вам надо добавить в параграф 100 span, то использование addChild (100 раз) повлечет за собой вызов replaceChildren. А там мама роди меня обратно. Логичнее иметь некий инициализирующий сеттер для childArray.

И у textFlow свойство skipNormalization. Если у вас руки не дрожат и вы сами инициализируете textFlow и оно не editable, то даром не нужно нормализовывать. Тем более, что оно там есть интересные моменты — если вы установите interactionManager до добавления контента, то оно... отнормализует его — добавит span в пустой параграф (а вы будете мучиться паранойей, откуда в новом параграфе дети и почему numChildren не равен 0 изначально).

@develar:
develar

А можете ли подтвердить криворукость разработчиков TLF касательно "FTE performance will degrade on a large paragraph"? Это цитата из RichEditableText. Опуская неграмотность того, кто написал этот комментарий (FTE оперирует только строками, то есть тут имелся ввиду именно TLF, а не FTE), был ли у вас печальный опыт (tlf это один большой печальный опыт, но имеется ввиду именно падение производительности при куче span в одном параграфе)?

@develar:
develar

TLF вообще тестировался в Adobe? Есть текст, используется device font. И он подчеркнут. Так эта самая линия подчеркивания то имеет отступ от текста, то прилипает к буквам. Понятно, почему так происходит, но разработчики TLF могли бы, раз уж так получилось, тоже пойти к флешерам и спросить.

И не надо потом спрашивать, а почему вы не используете флекс напрямую, а только как базу для собственых компонент — juick.com .

@develar:
develar

Убогий TLF. Есть span, текст которого содержит возврат каретки — "\n". Все работает — перенос строки есть. Но если установить у параграфа или самого span BreakOpportunity.ANY, то переноса строки нет — все в одну строчку toFit. Какого черта? Какое отношение BreakOpportunity имеет к символу \n?

@Constantiner:
Constantiner

Я сцуко победитель TLF! Все косяки разрулил, все сделал очень няшно. Практически полностью доволен. Проявил нед/женную выдержку, героизм, смекалку и поисковые навыки :)

@Constantiner:
Constantiner

Что-то я не смог понять, куда в адобовской JIRA постить баги по TLF. Может, у кого есть готовая инфа?

@Constantiner:
Constantiner

Вот строчка из кода TLF (клас FlowLeafElement):
tlf_internal override function getEventMirror():EventDispatcher
Вроде, ничего страшного. А теперь ASDoc к этому методу:
Gets the EventDispatcher associated with this FlowElement. Use the functions
of EventDispatcher such as setEventHandler() and removeEventHandler()
to capture events that happen over this FlowLeafElement object. The
event handler that you specify will be called after this FlowElement object does
the processing it needs to do.


Ну вы поняли? Человек, писавший этот код, считает, что у EventDispatcher есть методы setEventHandler и removeEventHandler. И эти люди запрещают мне ковыряться в носу!

@Constantiner:
Constantiner

InlineGraphicElement is final. TLF — реальное говно. Реальное. У него столько лишних возможностей, но чтобы его расширить для довольно очевидных случаев (типа адекватного поведения курсора и интерактива для встроенной в текст графики) надо тупо дублировать код и упираться в private, final-классы и прочее говноедство. Уйду я от тебя, Adobe. Все грожусь, но рано или поздно уйду. Еще несколько лет назад можно было нормально разрабатывать. Но теперь произведено столько ужасного нового говнокода, что я не закрываю Google :( А я хочу просто воплощать идеи и требования. А не говноедствовать.

@Constantiner:
Constantiner

Пять тысяч строк копипасты из-за того, что эти говнари сделали поле приватным. Adobe, гори в аду! За такой код убивают сразу и надолго :(

@ilja-panin:
ilja-panin

Никто не сталкивался с тем что TLF обрезает в некоторых случах часть крайнего правого столбца?
Выяснить закономерность у меня не получатеся %(, но обычно это происходит при инициализации компонента.

@Constantiner:
Constantiner

Сцуко вы не поверите я заембедил фонты флекс 3 прейложенье и фонты там cff прешлось компилить во флекс читыри и загружать ебацца нахуй блять

@Constantiner:
Constantiner

В общем, как я понял, при использовании Flex 3 совместно с TLF шансов использовать embedded fonts нет. Ибо TLF поддерживает только шрифты, заембеденные как CFF, а Flex 3 такой embed не поддерживает. Прав ли я? Это уже не говоря о том, что Flex 3 несовместим с TLF в области embedded fonts еще и по части SWFContext. Честно, у меня уже злости нет. Просто опускаются руки :(

@Constantiner:
Constantiner

И все же инженеры из Adobe мудаки :( Все по поводу этого вот #1010011 Даже те хаки, что предлагаются, расчитаны на Flex 4, в то время как TLF типа не привязана к Flex. Вот и получается, что ни встраиваемых шрифтов искаропки, ни решений/хаков, которые подошли бы просто в любой ситуации :( Мудаки, хуле. Правая рука не знает, на что дрочит левая.

@Constantiner:
Constantiner

В итоге зашаманил отображение HTML+CSS из подружаемых файлов. Осталась проблема только с img. Ну не хочет оно отображаться как отдельная картинка (то есть идет текст, потом картинка, потом опять текст). При этом если ставить ей align="left" или right — идет нормальное обтекание, а вот чтобы ьезо всякого обтекания картинка в тексте — не идет :( Злобно все. Тыкаюсь дальше :)

@Constantiner:
Constantiner

Продолжаю мучаться с TLF. А я реально мучаюсь, не доставляет он мне и капли радости. Каждый шажок — огромный стопор, куча доки итд. Ну вот как просто тупо вывести содержимое TextFlow в строку для дебага? Ну почему эти контрацептивы не реализовали toString() и вообще пренебрегают реализацией toString()?

@develar:
develar

За три дня от разных производителей ненужного информационного шума (и по направлению) куча постов WTF о шрифтах (как вершина айсберга, лакмусовая бумажка) и убогости текстовой подсистемы флеша (+tlf, как бы идиотам в Adobe не хотелось отгородить его). Да. Adobe умеют доставить. Но я уже проникся философией @Constantiner ;) Поэтому будем радоваться просто, что мы все олени. Все-таки зима скоро.

@Constantiner:
Constantiner

Срач в комментах forums.adobe.com и куски говна в сторону Adobe какбе подтверждают мои непонятки #1012377

@Constantiner:
Constantiner

А, может, кто знает какой-нибудь фрэймворк или либу над TLF, решающую простые задачи простыми вызовами? Или описания как проще и без гемора отобразить HTML+CSS? Это к #1012377

@Constantiner:
Constantiner

Я правда не понимаю, зачем Адобы в TLF понаписали столько сложного кода, который при этом не умеет искаропки в две строчки отобразить HTML+CSS. Или я что-то упустил? Или правда всем так нравится городить 50 строк конфигурации и читать тонну доки ради самых распространенных задач?

@Constantiner:
Constantiner

Так и не понял я, как в TLF сделать чтобы заэмбеденный шрифт отображался в точности так же, как остальные в приложении. И мне одному кажется, что все же TLF немного переусложнено для повседневного использования?

@develar:
develar

В тему juick.com — трава — "The factory and the composer produce slightly different results which can confuse the scroller." — если для RichEditableText есть скроллер, то он в любом случае будет конвертировать текст в textFlow. По логике, надо было разбираться почему slightly different results.

@develar:
develar

В тему juick.com . Предположим, вы решили не патчить TLF для решения этого идиотизма, а грустно вспомнили что вы проститутка и решили просто таскать с собой textFlow. Вы думаете, все проблемы решены? Трава. Если вы установили textFlow для RichEditableText, то не надо думать, что вам позволят сохранить ссылку на него — вы обязаны всегда теперь таскаться с instance RichEditableText, потому что в textContainerManager_damageHandler он может тупо _textFlow = textContainerManager.getTextFlow(); — то есть если вы у вашего textFlow смените fontFamily, то ничего не произойдет, так как TLF оперирует уже другим. Adobe, когда ты сменишь поставщика травы?

@develar:
develar

Трава. Как уже писалось, идиоты в Adobe спроектировали TFL так, что textFlow не может быть расшарен. Есть еще один нюанс — если вы скармливаете textFlow некий textFormat, то он:

if (_format is TextLayoutFormat || _format is TextLayoutFormat)
useFormat = _format;
else
useFormat = new TextLayoutFormat(_format);
_computedPrototypeFormat = FlowElement.createTextLayoutFormatPrototype(useFormat,null);

То есть вы никак не можете динамически стилизовать textFlow. Чтобы установить новый font family, у вас есть два пути — 1) непосредственно у textFlow установить свойство fontFamily 2) клонировать свой формат (тот же instance не покатит) и присвоить ему новое значение (на perfomance мы уже давно положили болт и о нем даже речи нет). Казалось бы, — установи ты свойство напрямую у textFlow и не выпендривайся. Это покатит в простом приложении. В сложном возникает ряд нюансов — этот формат нужен не только TLF, но и высокоуровневому ui-control textArea для расчета char metrics (посчитать тот же height in lines). Если вы делаете Font Panel (то есть даете пользователю некий тул типа как в MS Office для кастомизации шрифта, цвета и прочего), то для Font Panel в разы удобнее работать именно с некой моделью простой, а не с textFlow (тем более, что она не должна быть зависима от TLF — может мне хватит формата и я отрисую текст посредством flash text engine напрямую). Черт возьми, ну как можно так проектировать? Какие к черту митинги и обсуждения, если это не rocket science?

@develar:
develar

Вышла новая сборка TLF. Ох, явно не ту траву они курят — "API Change: ISelectionManager functions getCommonCharacterFormat, getCommonParagraphFormat and getCommonContainerFormat now return a

TextLayoutFormat instead of an ITextLayoutFormat. This change is backwards compatible with current code because TextLayoutFormat

implements ITextLayoutFormat." Правильно, интерфейсы эта такая штука, она для красоты.