Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt Общие вопросы _ Высота шрифта ?

Автор: flankerr 17.1.2008, 17:42

есть вывод текста

painter->drawText(x,y,"TEST_TXT");

Вопрос как вокруг текста нарисовать прямоугольник ?
(Или как узнать QRect в которм находиться текст)
QFontMetrics выдаёт весьма противоречивый результат....

Автор: flankerr 17.1.2008, 18:09

ширину определить легкоЮ а вот высоту как оказалось...

QFontMetrics fm(painter->font());
fm.height() - слишком большое значение выдаёт..

QRect rect = fm.boundingRect("TEST_TXT");
да, таким образом мы узнаём ширину, однако высота....

rect.height() - выдаёт значение больше чем высота текста

-(rect.top() + rect.bottom())
вот это уже близко но всё равно не то...

QSize sz = fm.size(Qt::TextSingleLine,QString("TEST_LINE_1"));
тоже мимо.

И так. А существует ли в Qt сопособ узнать реальную высоту ???

Автор: ViGOur 17.1.2008, 18:22

Так вроде нормально:

    QPainter painter( this);

    const QFont &font = painter.font();

    int x = 100, y = 50;
    painter.drawText( x, y, "TEST_TXT");

    QFontMetrics fm( font);
    QRect rect = fm.boundingRect( "TEST_TXT");

    rect.setLeft( rect.left() + x);
    rect.setTop( rect.top() + y);
    rect.setRight( x + rect.right());
    rect.setBottom( y + rect.bottom());

    painter.drawRect( rect);

Автор: flankerr 17.1.2008, 18:36

Увы....
С таким же успехом я могу прямоугольник на весь экран нарисовать....
Мне надо чтобы было ТОЧНО пиксель в пиксель по периметру текста...

Автор: ViGOur 17.1.2008, 18:42

А в данном случае как?
У меня отклонение где-то на 1 пиксель неболее, но это ведь просто арифметически можно поправить.

Автор: flankerr 17.1.2008, 18:45

Цитата(ViGOur @ 17.1.2008, 18:42) *
А в данном случае как?
У меня отклонение где-то на 1 пиксель неболее, но это ведь просто арифметически можно поправить.


ты размер шрифта поставь в 100пунктов очень наглядно получиться ;)
а подгонять "арифметически" нет возмоджнсть учитывая что размер шрифта задаёться динамически, нао чтоб само считало

Автор: flankerr 17.1.2008, 19:01

вот с помощью такой феньки

rect = fm.boundingRect
rect.top() + rect.bottom() + fm.lineWidth()

можно получить высоту шрифта без нижнего участка.


Но вот как получить прямоугольник в пикселах сколкьо занимает текст не понятно. Хотя в документации и сказно что это должна делать
boundingRect однако на практике увы....

Автор: ViGOur 17.1.2008, 19:12

Я уже вижу, что пошаманить немного прийдется... :)

Автор: ViGOur 17.1.2008, 19:14

А если попробовать посчитать посимвольно?
С помощью: http://crossplatform.ru/documentation/qtdoc4.3/qfontmetrics.php#boundingRect.

Автор: Litkevich Yuriy 18.1.2008, 9:54

Я тут не вникая глянул в книжку Макса Шлее, там текст нарисован и названия размеров.
текст например такой:

Йорик

описание размеров:
ascent()-от верха буквй "Й" до базовой линии,
descent()-от базовой линии вниз, НО ниже ножки буквы "р", где кончается непонятно,
height()=ascent()+descent()+1,

т.е. имеется какая то не понятка насчет низа, и возможно при рисовании текста, у вас несростухи рамки с низу шрифта?

Автор: ViGOur 18.1.2008, 11:19

Цитата(flankerr @ 17.1.2008, 19:01) *
Но вот как получить прямоугольник в пикселах сколкьо занимает текст не понятно. Хотя в документации и сказно что это должна делать
boundingRect однако на практике увы....
Тебе как я понимаю нужна точность до пикселя?

Автор: flankerr 18.1.2008, 11:22

Цитата(ViGOur @ 17.1.2008, 19:14) *
А если попробовать посчитать посимвольно?
С помощью: http://crossplatform.ru/documentation/qtdoc4.3/qfontmetrics.php#boundingRect.


boundingRect('A') == boundingRect('a') == boundingRect ('_')
и это равенство противоречит описанию результата для данной функции...(или я что-то не понимаю...)

Rect описывающий заглавную букву можно найти таким вот образом (как уже писал выше)
rect = fm.boundingRect('A')
-(rect.top() + rect.bottom() + fm.lineWidth())

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

Автор: flankerr 18.1.2008, 11:25

Цитата(ViGOur @ 18.1.2008, 11:19) *
Цитата(flankerr @ 17.1.2008, 19:01) *
Но вот как получить прямоугольник в пикселах сколкьо занимает текст не понятно. Хотя в документации и сказно что это должна делать
boundingRect однако на практике увы....
Тебе как я понимаю нужна точность до пикселя?


погрешность в один пиксель на маленьклм разрешении и маленьком размере шрифта выливается в более чем ощутимую погрешность елси тоже самое применить на большем разрешении...

Автор: flankerr 18.1.2008, 11:50

кстати нашёл ещё интересную вещь

QFontMetrics::underlinePos ()
Возвращает расстояние от базовой линии до места, в котором должна рисаваться подчеркивающая линия.

int QFontMetrics::strikeOutPos () const
Возвращает расстояние от базовой линии до места, в котором должна рисоваться перечеркивающая линия.

int QFontMetrics::underlinePos () const
Возвращает расстояние от базовой линии до места, в котором должна рисаваться подчеркивающая линия.

Автор: ViGOur 18.1.2008, 11:54

Вот я тут попробовал русские буквы, можешь посмотреть результат, скорее всего это и заложено, отступы, вроде самого высокого симовла, для самого низкого и прочее.

    QPainter painter( this);

    QFont font=QFont( "Arial", 36);
    painter.setFont( font);

    int x = 50, y = 150;
    painter.drawText( x, y, "_АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩьЫЪЭЮЯ");

    QFontMetrics fm( font);
    QRect rect = fm.boundingRect( "_АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩьЫЪЭЮЯ");

    rect.setLeft( rect.left() + x);
    rect.setTop( rect.top() + y);
    rect.setRight( x + rect.right());
    rect.setBottom( y + rect.bottom());

    painter.drawRect( rect);
По все видимости нужно попробовать посчитать самый высокий и самый низкий из текущего набора...

Автор: flankerr 18.1.2008, 12:17

boundingRect
выдаёт правильно ширину для заданного текста или символа а вот высоту он выдаёт для самого большого символа в шрифте отсюда и идут все проблемы.
просчитать высоту заданного символа практически не реально. Т.е. можно, НО с предварительно анализом символа и то без гарантий. Т.е. проверять с начала проверять большая буква или маленькая подразумевается что у нее есть верхний апостроф или нет, есть у нё завитки ниже базовой или нет и т.п.
и исходя из этого уже делать прогноз (даже тут точность нет будет лищь прогноз) высоты основываясь на имеющихся возможностях фонтметрикс.
Поэтому казалось бы на первый взгляд тривиальная задача узнать высоту буквы на практике оказывается разрешимой лишь частично

Автор: ViGOur 18.1.2008, 12:35

Цитата(flankerr @ 18.1.2008, 12:17) *
выдаёт правильно ширину для заданного текста или символа а вот высоту он выдаёт для самого большого символа в шрифте отсюда и идут все проблемы.
Вот и я об этом же.

А какая задача стоит, может можно еще как решить ее?

Автор: Tonal 19.1.2008, 11:44

На WinApi таки можно узнать "реальную" высоту строки до пикселя.
Для этого надо перегнать строку в кривые спомощью Path-а. Его можно перегнать в регион, а уже у того запросить охватывающий прямоугольник.

Я сильно с рисовкой под Qt не разбирался, но вполне возможно, есть подобный метод. :)

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)