Просмотр полной версии : Реальные размеры объекта TextField
Friday13
03.07.2007, 20:06
Как вычислить реальные размеры текстового поля, чтобы они соответствовали Break Apart этого тектового поля.
Не могу прикрепить пример, говорит загрузка прошла неудачна.
вот код
for (var z in this) {
if (this[z] instanceof TextField) {
var my_fmt:TextFormat = this[z].getTextFormat()
var metrics:Object = my_fmt.getTextExtent(this[z].text);
this[z].autoSize = "left";
var wdth = metrics.width;
var hght = metrics.height;
var x = this[z]._x;
var y = this[z]._y;
this.lineStyle(0.25, 0x00ee00)
this.moveTo(x, y);
this.lineTo(x + wdth, y);
this.lineTo(x + wdth, y + hght);
this.lineTo(x, y + hght);
this.lineTo(x, y);
var wdth = this[z]._width;
var hght = this[z]._height;
var x = this[z]._x;
var y = this[z]._y;
this.lineStyle(0.25, 0xff0000)
this.moveTo(x, y);
this.lineTo(x + wdth, y);
this.lineTo(x + wdth, y + hght);
this.lineTo(x, y + hght);
this.lineTo(x, y);
var wdth = this[z].textWidth;
var hght = this[z].textHeight;
var x = this[z]._x;
var y = this[z]._y;
this.lineStyle(0.25, 0x0000ff)
this.moveTo(x, y);
this.lineTo(x + wdth, y);
this.lineTo(x + wdth, y + hght);
this.lineTo(x, y + hght);
this.lineTo(x, y);
}
}
Чтобы заработал, создайте в Stage несколько тектовых полей с заембеденными символами, тип поля dynamic.
Можно попробовать с помощью BitmapData…
Friday13
04.07.2007, 14:35
Можно. Я пробовал, есть одна проблема. Мне эти данные нужно на сервер передать чтобы сервер отрисовал у себя такую же надпись. А если я передам "..." (текст в ковычках) , то верхней левой точкой будут не корректные координаты.
А что мешает отправить сам текст в BitmapData?
chingachgoog
04.07.2007, 14:41
Вопрос был про размеры а-ля Break Apart.
"..." - определиться точно по размерам, не так ли?
Координаты - другой вопрос.
Насколько я понимаю, они всегда будут +2 пиксела от координат текстового поля.
Friday13
04.07.2007, 15:31
давайте мыло, я вышлю пример, залить не получается. пишет ошибка
А что мешает отправить сам текст в BitmapData?
мешает следующее, есть фонты начертания которых вылазит за границы их размеров. допустим ChinaCyr, Dollar, Monotype Corsiva.
Повторяю еще раз, я пробовал через битмапдату. вычислял левую верхнюю точку и правую нижнюю, вариант не подходит.
Нет, ты меня не понял — я говорю о том, что отправить весь BitmapData на сервер, прям вместе с текстом.
Зачем отправлять какие-то там координаты и т.п., когда можно готовую картинку отправить?
Friday13
04.07.2007, 15:37
"..." - определиться точно по размерам, не так ли?
у сервера другое мнение какие размеры у надписи аля троеточие :) он почему то считает что они на N пикселей выше от левой верхней точки:)
Нет, ты меня не понял — я говорю о том, что отправить весь BitmapData на сервер, прям вместе с текстом.
Зачем отправлять какие-то там координаты и т.п., когда можно готовую картинку отправить?
опа.. поподробнее пожалуйста? если через BitmapData.getPixel() то получается 4 картинки 280*280 надо отправлять. Или может есть другой способ?
Ну да, getPixel, все дела. Отправляем в каком-нибудь удобоваримом виде в php, а он уже соберет картинку и сохранит, например, в JPEG.
Friday13
04.07.2007, 15:49
а есть алгоритмы сжатия данных во флеше? а то 280*280*6=470400 байт :(
я конечно понимаю ты можешь подколоть анлимом, но это рассчитанно на пользователей модемов;)
Ну, для начала можно бинарно слать, через amfphp, это уже 200 КБ получается. Потом, ты можешь использовать LZW сжатие (соответствующие классы есть). Килобайт 80 будет в итоге…
chingachgoog
04.07.2007, 15:52
а есть алгоритмы сжатия данных во флеше? а то 280*280*6=470400 байт :(
Тут где-то была ссылка на исходник с таким кодом, надо поиском пройтись.
Friday13
04.07.2007, 16:00
не подходит.
спасибо за информацию.
Если кто нибудь может, скажите мне что мне попались глючные фонты, и я успокоюсь:) Только аргументируйте:)))
Фонты не глючные. У каждого символа есть определенные рамки и не всегда они совпадают с визуальными размерами символа (точнее, никогда не совпадают).
Friday13
04.07.2007, 16:53
А как эти рамки вытащить из символа???
Friday13
04.07.2007, 17:00
Я уже ручками пытаюсь найти логику в отношении координат и размеров надписи и ее Break Apart , но пока не нахожу ее.
«Логика» зашита в самом файле шрифта.
Friday13
04.07.2007, 17:29
Еще бы найти описание как вытащить эту логику из файла шрифта...
Никак, в swf есть тег шрифта, самого файла там нет, а все параметры заданы жестко и не доступны для прочтения.
Friday13
04.07.2007, 19:10
Да хотябы те что жестко вручную в коде забить константами.
Для каждого символа значения отступов и проч. — свои.
Мне не понятно, почему нельзя передать сам текст, его размер, и данные: италик, болд? Серверу должно быть пофиг размеры текстового поля, он лишь построит по этим данным надпись и обрежет лишнее.
Friday13
04.07.2007, 20:03
В том то и дело что я так и передаю. но!! на выходе получается не совсем то что нужно. Сервер рисует надпись под обрез, флеш же передает координаты и размеры с учетом отступов TextField . И как вычислить эти отступы я сейчас пытаюсь уяснить.
Причем тут координаты и размеры текстового поля? Я говорю про размер шрифта.
Гм, чем BitmapData не угодил? Можно по горизонтали определить строки, в которых только прозрачные пиксели, потом по вертикали…
Изврат, конечно, но как вариант.
Гм, чем BitmapData не угодил? Можно по горизонтали определить строки, в которых только прозрачные пиксели, потом по вертикали…
Изврат, конечно, но как вариант.
Это не изврат, а второй варинт, который я хотел только что предложить :) если на стороне сервера нельзя определить необходимые размеры для картинки исходя из размеров шрифта.
Friday13
04.07.2007, 20:33
Ребята, не подходят эти варианты, я тестил...
Пока выход - сервер будет рисовать с кривыми координатами
Второй вариант не подходит? Чем и почему?
Molecula
04.07.2007, 20:59
"Мне эти данные (т.е. текст текстового поля) нужно на сервер передать чтобы сервер отрисовал (что значит отрисовал? данные из флешового текстового поля перенес в форму на странице?) у себя такую же надпись."
Я тоже не пойму, чем этот пример http://www.sephiroth.it/tutorials/flashPHP/print_screen/
не устраивает?
Это не изврат, а второй варинт, который я хотел только что предложить :) если на стороне сервера нельзя определить необходимые размеры для картинки исходя из размеров шрифта.
То, что ты его хотел предложить, не отменяет извратности :D
То, что ты его хотел предложить, не отменяет извратности :DА в чем тут изврат?
В общей методике ковыряния в пикселях.
В общей методике ковыряния в пикселях.Это почему?
Ну я не знаю, на мой взгляд, инструменты для определения размеров шейпа должны быть проще и не заморачиваться на неточных вычислениях количества пикселей с прозрачностью больше нуля и прочим хламом. Сама среда такие инструменты не представила, а подобные решения я считаю реальным извратом (т.е. применить можно, но не в массовом порядке). ИМХО.
Нам много чего не предоставили, и много приходиться писать самим, но это не считается извратом. Флеш не виноват в том, что некоторые шрифты кривые.
Гм, где шрифты кривые? textHeight и textWidth возвращают размеры, включая символьные рамки.
textHeight и textWidth возвращают размеры, включая символьные рамки.Без рамок. Выдели все символы, возращается размер области, который инвертирован. То есть учитываются метрики шрифта, которых нет, когда делаем Break Apart. Отсюда невозможность определить размеры другим способом. И если задать символу в метрика ширину или высоту меньшую размерам вектора, то флеш в результате выдаст textWidth меньший, чем будет ширина после Break Apart.
Friday13
05.07.2007, 09:49
Метод с битмапдата не подходит, потому что пакет отправляемый на сервер не должен превышать 2-5кб за весь сеанс работы флешки.
Я понимаю что при помощи битмапдата я мог бы многое решить, но не подходит:) Именно из-за большого размера пакета.
Тогда предложенный выше способ в руки.
Friday13
05.07.2007, 10:12
Какой именно??
http://www.friday13.pisem.net/
у всех прямоугольников верхняя левая точка это TextField[_x, _y]
Зеленый прямоугольник - TextField.getTextFormat().getTextExtent(TextField.text)[width, height]
Красный прямоугольник TextField[_width, _height]
Синий прямоугольник TextField[textWidth, textHeight]
Какой именно??
вот этот http://www.flasher.ru/forum/showpost.php?p=657666&postcount=26
битмапа используется не для того, чтобы передать саму картинку, а чтобы определить истинные размеры
Friday13
05.07.2007, 10:37
ага... вроде получилось, как выложить пример для будущих поколений???
Код киньте :) Аттачи временно не работают.
Friday13
05.07.2007, 10:41
Блин.. на ChinaCyr код работает, для Dollar глючит:(((
в Stage нужно создать текстовое поле, обозвать z, внедрить нужные фонты, написать что нибудь в нем, конвертнуть в символ MovieClip и обозвать тоже z
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Matrix;
import flash.geom.ColorTransform;
trace(getTimer());
z.z.autoSize = "left";
var myBitmapData:BitmapData = new BitmapData(z._width * 1.3, z._height * 1.3, false, 0x00000000);
var mc_1:MovieClip = this.createEmptyMovieClip("mc", this.getNextHighestDepth());
mc_1.attachBitmap(myBitmapData, this.getNextHighestDepth());
mc_1._x = 10;
mc_1._y = 10;
z.autoSize = "left";
var myMatrix:Matrix = new Matrix();
myMatrix.ty = z._width * 0.15;
myMatrix.ty = z._height * 0.15;
myMatrix.scale(z._xscale / 100, z._yscale / 100);
mc.onMouseDown = function() {
var alpha:String = (myBitmapData.getPixel32(this._xmouse, this._ymouse) >> 24 & 0xFF).toString(16);
trace(">> alpha: " + alpha);
// ff
var red:String = (myBitmapData.getPixel32(this._xmouse, this._ymouse) >> 16 & 0xFF).toString(16);
trace(">> red: " + red);
// aa
var green:String = (myBitmapData.getPixel32(this._xmouse, this._ymouse) >> 8 & 0xFF).toString(16);
trace(">> green: " + green);
// cc
var blue:String = (myBitmapData.getPixel32(this._xmouse, this._ymouse) & 0xFF).toString(16);
trace(">> blue: " + blue);
// ee
trace("0x" + alpha + red + green + blue);
// 0xffaaccee
};
var myColorTransform:ColorTransform = new ColorTransform(0, 0, 1, 1, 0, 0, 255, 0);
var blendMode:String = "normal";
var myRectangle:Rectangle = new Rectangle(0, 0, z._width * 1.3, z._height * 1.3);
var smooth:Boolean = false;
myBitmapData.draw(z, myMatrix, myColorTransform, blendMode, myRectangle, smooth);
var colorBoundsRect:Rectangle = myBitmapData.getColorBoundsRect(0xff0000FF, 0xFF000000, false);
trace(colorBoundsRect);
var my = this.createEmptyMovieClip("my", this.getNextHighestDepth());
my._x = colorBoundsRect.x + 10;
my._y = colorBoundsRect.y + 10;
my.lineStyle(0.25, 0xffffff);
my.lineTo(colorBoundsRect.width, 0);
my.lineTo(colorBoundsRect.width, colorBoundsRect.height);
my.lineTo(0, colorBoundsRect.height);
my.lineTo(0, 0);
trace(getTimer());
ПАЛУЧИЛАСЬ!
Всем спасибо:)
Не надо создавать несколько сообщений подряд, надо исправить последнее в теме.
Что-то код слишком громоздкий. Мой вариант:
function getSize (txt:TextField):Object {
var bmp:BitmapData = new BitmapData (Math.ceil (txt._width), Math.ceil (txt._height), true, 0x00);
var bmpW:BitmapData = new BitmapData (1, bmp.height, true, 0x00);
var bmpH:BitmapData = new BitmapData (bmp.width, 1, true, 0x00);
bmp.draw (txt);
var offsetW:Number = 0;
var offsetH:Number = 0;
var i:Number = bmp.width;
while (i > 0 && !bmp.hitTest (new Point (0, 0), 1, bmpW, new Point (i, 0), 0)) {
i--;
}
offsetW = i;
i = 0;
while (i < bmp.width && !bmp.hitTest (new Point (0, 0), 1, bmpW, new Point (i, 0), 0)) {
i++;
}
offsetW -= i - 2;
////
i = bmp.height;
while (i > 0 && !bmp.hitTest (new Point (0, 0), 1, bmpH, new Point (0, i), 0)) {
i--;
}
offsetH = i;
i = 0;
while (i < bmp.height && !bmp.hitTest (new Point (0, 0), 1, bmpH, new Point (0, i), 0)) {
i++;
}
offsetH -= i - 2;
return {w:offsetW, h:offsetH};
}
var o:Object = getSize (txt);
trace (o.w + " " + o.h);
Friday13
05.07.2007, 12:04
А координаты текстового поля? верхнего левого пикселя?
У меня в коде много мусора:) Вспомогательного, я не почистил, на радостях бросил все что было в фрейме.
можно еще так попробовать
function getSize (txt:TextField):Object {
var bmp:BitmapData = new BitmapData (Math.ceil (txt._width), Math.ceil (txt._height), true, 0);
bmp.draw (txt);
var rec:Rectangle=bmp.getColorBoundsRect(0xFF000000, 0x00000000,false);
return {w:rec.width, h:rec.height};
}
если надо с координатами TL угла
function getSize (txt:TextField):Rectangle {
var bmp:BitmapData = new BitmapData (Math.ceil (txt._width), Math.ceil (txt._height), true, 0);
bmp.draw (txt);
return bmp.getColorBoundsRect(0xFF000000, 0x00000000,false);
}
Еще лучше :) Но у меня получилось, что к ширине и высоте надо по пикселю добавлять.
Friday13
05.07.2007, 12:22
bmp.draw (txt);
гы... чего то отказался метод draw рисовать объект TextField
У меня тоже не работает draw на текст.
Не знаю почему, но draw может работать с эмбед шрифтом, только, если стоит Anti-alias for animation или BitmapText, иначе надо помещать текстовое поле в мувиклип.
странно, что сейчас у меня все рисует..
но в одном проекте был такой затык, решился через blendMode метода draw:
bmp.draw(txt,new Matrix(),null,"layer",null,true);
не все вполне ясно с этими текстфилдами..
blendMode по барабану, антиалисинг какой стоит?
дада, blendMode не решает: для ембеденного шрифта и anti-alias for readability не рисует..
Я за точность :D
import flash.geom.*;
import flash.display.BitmapData;
getTextBounds = function(txt) {
var x = txt._x;
var y = txt._y;
var w = txt._width;
var h = txt._height;
var xs = txt._xscale;
var ys = txt._yscale;
var scale = 20;
txt._xscale = xs*scale;
txt._yscale = ys*scale;
var bmp = new BitmapData(txt._width,txt._height,true,0);
var mtx = new Matrix();
mtx.scale(scale,scale);
bmp.draw(txt, mtx);
bmp.colorTransform(bmp.rectangle,new ColorTransform(1,1,1,1,0,0,0,255));
var rect = bmp.getColorBoundsRect(0xFF000000,0x00000000, false);
bmp.fillRect(rect,0x80FFFF00);
rect.x /= scale;
rect.y /= scale;
rect.width /= scale;
rect.height /= scale;
txt._xscale = xs;
txt._yscale = ys;
bmp.dispose();
return rect;
}
rect = getTextBounds(txt);
beginFill(0xFF0000, 30);
trace(rect);
moveTo(txt._x+rect.x+2,txt._y+rect.y+2);
lineTo(txt._x+rect.x+rect.width+2,txt._y+rect.y+2);
lineTo(txt._x+rect.x+rect.width+2,txt._y+rect.y+rect.height+2);
lineTo(txt._x+rect.x+2,txt._y+rect.y+rect.height+2);
endFill();
Friday13
05.07.2007, 19:19
Я за точность :D
неплохо с фонтами разобрались товарищи:)
У меня пишется undefined и ничего не рисуется.
У меня рисует раз через пять, причем непонятно от чего зависит. Ставил input, dynamic, разные параметры сглаживания и разный размер шрифта. Не стоит отрисовывать битмапой тектовое поле, нет в это веры.
Стало быть...
import flash.geom.*;
import flash.display.BitmapData;
function getSize (mc:MovieClip):Rectangle {
var bmp:BitmapData = new BitmapData (Math.ceil(mc._width), Math.ceil(mc._height), true, 0);
bmp.draw (mc);
var rect:Rectangle = bmp.getColorBoundsRect(0xFF000000, 0x00000000,false);
bmp.dispose();
drawBounds(mc, rect);
return rect;
}
getTextBounds = function(txt) {
var x = txt._x;
var y = txt._y;
var w = txt._width;
var h = txt._height;
var temp_mc:MovieClip = createEmptyMovieClip('temp_mc', getNextHighestDepth());
var temp_txt:TextField = temp_mc.createTextField('txt',1,0,0,w+5,h+5);
temp_txt.embedFonts = txt.embedFonts;
temp_txt.text = txt.text;
temp_txt.setTextFormat(txt.getTextFormat());
var rect:Rectangle = getSize(temp_mc);
// temp_mc.removeMovieClip();
rect.offset(x,y);
return rect;
}
function drawBounds( mc:MovieClip, rect:Rectangle ){
mc.clear();
mc.beginFill(0xFF0000, 30);
mc.moveTo(rect.left, rect.top);
mc.lineTo(rect.left, rect.bottom);
mc.lineTo(rect.right, rect.bottom);
mc.lineTo(rect.right, rect.top);
mc.lineTo(rect.left, rect.top);
mc.endFill();
}
rect = getTextBounds(txt);
drawBounds(this, rect);
trace(rect);
Все равно косячит, но программный клон нормально обводит.
import flash.geom.*;
import flash.display.BitmapData;
getTextBounds = function(txt) {
var mc = txt._parent.createEmptyMovieClip('__textBounds_mc',-3288);
var t = mc.createTextField('txt',0,0,0,100,100);
t.setNewTextFormat(txt.getTextFormat());
t.embedFonts = txt.embedFonts;
t.html = txt.html;
t.htmlText = txt.htmlText;
t._width = txt._width;
t._height = txt._height;
txt = t;
var xs = txt._xscale;
var ys = txt._yscale;
var scale = 20;
var maxXScale = 2800/txt._width;
var maxYScale = 2800/txt._height;
if (maxXScale < scale) {
scale = maxXScale;
}
if (maxYScale < scale) {
scale = maxYScale;
}
txt._xscale = xs*scale;
txt._yscale = ys*scale;
var bmp = new BitmapData(mc._width,mc._height,true,0);
bmp.draw(mc);
bmp.colorTransform(bmp.rectangle,new ColorTransform(1,1,1,1,0,0,0,255));
var rect = bmp.getColorBoundsRect(0xFF000000,0x00000000, false);
bmp.fillRect(rect,0x80FFFF00);
rect.x /= scale;
rect.y /= scale;
rect.width /= scale;
rect.height /= scale;
txt._xscale = xs;
txt._yscale = ys;
bmp.dispose();
mc.swapDepths(6550);
mc.removeMovieClip();
return rect;
}
rect = getTextBounds(txt);
beginFill(0xFF0000, 30);
moveTo(txt._x+rect.x,txt._y+rect.y);
lineTo(txt._x+rect.x+rect.width,txt._y+rect.y);
lineTo(txt._x+rect.x+rect.width,txt._y+rect.y+rect.height);
lineTo(txt._x+rect.x,txt._y+rect.y+rect.height);
endFill();
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.