WordWrap ActionScript ломает слова - PullRequest
2 голосов
/ 29 июня 2011

У меня есть текстовое поле с заданной высотой и шириной, которое позволяет переносить слова. Когда я добавляю в него текст, я динамически изменяю размер шрифта до тех пор, пока высота текста не станет меньше высоты поля, что позволит ему правильно вписаться. Проблема, с которой я сталкиваюсь, заключается в том, что поле достаточно тонкое по необходимости, и некоторые более длинные слова (например, «Австралия») разбиваются во время переноса слов. Так что, возможно, «Australi» появится в первой строке, а «a» - во второй. Однако, поскольку они удовлетворяют требованию высоты, они больше не уменьшаются. Мне нужен способ обнаружить это и продолжать сокращать эти случаи, чтобы они соответствовали без перерыва. Вот код для динамического сжатия текста, чтобы соответствовать высоте:

text.wordWrap = true;
text.autoSize = TextFieldAutoSize.CENTER;

while(text.height > textBoxVal) {
    myFormat.size = Number(myFormat.size) - 2;
    text.defaultTextFormat = myFormat;
    text.setTextFormat(myFormat);
}

Это отлично работает. Проблема с моим подходом к следующему шагу (сокращение, если горизонтальные ограничения не выполняются из-за разделения слова) состоит в том, что если оставить значение text.wordWrap равным true, более длинные слова будут по-прежнему разрываться и никогда не будут изменены, но при установке этого значения false означает, что другие поля, которые раньше были хорошими из-за включения переноса слов (например, «Соединенные Штаты»), теперь слишком длинные в одной строке и сокращаются, когда этого не должно быть. Для чего это стоит, вот мой код, чтобы сжать горизонтально (сразу следует за кодом выше):

text.wordWrap = false;
text.autoSize = TextFieldAutoSize.LEFT;
while(text.width > textBoxVal) {
    myFormat.size = Number(myFormat.size) - 2;
    text.defaultTextFormat = myFormat;
    text.setTextFormat(myFormat);
}

Есть ли лучший способ сделать это? Возможно, какой-нибудь способ заставить ActionScript не прерывать слова и т. Д.

Редактировать: Чтобы привести пример, посмотрите на скриншот ниже:

enter image description here

При этом используется только первый кодовый блок, который обеспечивает соответствие текста вертикальным ограничениям блока. Вы можете видеть, что некоторые блоки (например, первые для США) хороши, тогда как некоторые из более мелких (например, последние несколько) разделены. Использование моего второго блока кода для изменения размера горизонтальных ограничений не вносит изменений, если перенос по словам истинен, и сделает все поля (включая те, которые хороши, как в США) меньше, чем необходимо, если перенос по словам установлен в ложь.

Ответы [ 2 ]

4 голосов
/ 29 июня 2011

Если ваш текст переносится на другую строку, вы можете проверить maxScrollV.

Мои предположения ниже:

while((text.height > textBoxVal || text.maxScrollV > 1) && myFormat.size > 1) {
    myFormat.size = Math.max(1, Number(myFormat.size) - 2);
    text.defaultTextFormat = myFormat;
    text.setTextFormat(myFormat);
}

РЕДАКТИРОВАТЬ

Я предлагаю

  1. добавить текст в поле слово за словом
  2. , если maxScrollV изменится, вы получите автоматическую перенос слов
  3. вставить неявный разрыв строки
  4. изменить размер текста, чтобы соответствовать желаемой высоте
  5. повторять до тех пор, пока не найдутся все слова

Вот некоторый код для иллюстрации этого:

private function fitText (text:String, rect:Rectangle, tf:TextField, format:TextFormat) : void
{
    // split text by whitespace
    var heap:Array = text.split(/\s+/);

    var size:uint = format.size;
    var maxScroll:uint = 1;
    var text:String;
    var word:String;

    // make sure tf is set up correctly
    tf.defaultTextFormat = format;
    tf.setTextFormat(format);
    tf.multiline = true;
    tf.wordWrap = true;
    tf.autoSize = TextFieldAutoSize.LEFT;
    tf.width = rect.width;

    for (var i:uint = 0; i<heap.length;i+=1) {    
        // insert text word by word
        word = heap[i];
        text = tf.text;
        if (i) {
            tf.text = text + " " + word;
        } else {
            tf.text = word;
        }
        if (tf.maxScrollV > maxScroll) {        
            // the last word you inserted increased number of lines 
            // and possibly got broken

            // increase scroll by 1
            // if scroll actually increased by more than 1,
            // we got word broken multiple times
            maxScroll += 1;

            // insert implicit line break, if not the first word
            if (i) {
                tf.text = text + "\n" + word;
            }
        }

        // do the resizing routine, if needed
        while (tf.height > rect.height || tf.maxScrollV > maxScroll) {
            // we also check tf.maxScrollV,
            // as it can be no more than maxScroll.
            // otherwise we'll get words crippled    

            /*resizing code here*/
        }
    }

    // restore original size
    format.size = size;
}
1 голос
/ 30 июня 2011

Скользите по этому , это может помочь вам обнаружить ситуации.

Обратите особое внимание на то, что ему нужно подождать 1 кадр, чтобы иметь возможность обнаружить нежелательный разрыв строки.

Как только вы его обнаружите, вы сможете уменьшить размер и снова обнаружитьсомнительный разрыв строки.

http://troyworks.com/blog/2011/06/09/flash-as3-detect-undesired-line-break-in-textfield-wordwrap-is-true/

...