ADN Club > ObjectARX
subViewportDraw() и плот
Михаил Голубев:
Добрый день
Сделал объект, производный от AcDbText, с целью добиться автоматическтого разворота текста на 180 градусов, если он читается вверх ногами на листе.
Добился результата используяю subViewportDraw(). В нем я сравниваю угол viewport и угол текста. Если текст попадает в опроделенный диапазон, то AcDbText::subViewportDraw(mode) не вызывается, но вырисовывается новый текст с помощью mode->geometry().text(), который переворачивается на 180 градусов при отрисовке. Таки образом текст, к примеру, названий улиц, всегда "лицом" к читателю.
В программе работает как надо, пока... но при распечатке все разворачивается на 90 градусов, а код это не улавливает. Подскажите, как уловить угов viewport при распечатке, или еще как решить эту проблему.
В программе так:
При печате так:
На всякий случай код subViewportDraw():
--- Код - C++ [Выбрать] ---void DRIText::subViewportDraw(AcGiViewportDraw * mode){ assertReadEnabled(); AcGePoint3d orgn; AcGeVector3d xa, ya, za; AcGeMatrix3d transform; mode->viewport().getEyeToWorldTransform(transform); transform.getCoordSystem(orgn, xa, ya, za); double lLimit, uLimit; double rot = rotation(); double vpRot = atan2(xa.y, xa.x); //Counterclockwise rotation if (vpRot < 0) vpRot *= -1; else vpRot = 2.0 * PI - vpRot; lLimit = (PI * 0.5) - vpRot; uLimit = (1.5 * PI) - vpRot; if (lLimit < 0) lLimit += 2.0 * PI; if (uLimit <= 0) uLimit += 2.0 * PI; bool toRotate = false; //General case, quadrant I and IV if ((vpRot < (PI * 0.5)) || (vpRot >= (1.5 * PI))) { if (rot > lLimit && rot < uLimit) toRotate = true; } //General case, quadrant II and III else if ((vpRot >= (PI * 0.5)) && (vpRot < (1.5 * PI))) { if (rot < uLimit || rot > lLimit) toRotate = true; } if (toRotate) { AcGeVector3d dir{ AcGeVector3d(cos(rot),sin(rot),0.0) }; dir.normalize(); AcGeVector3d dirPerp{ AcGeVector3d(cos(rot + PI * 0.5),sin(rot + PI * 0.5),0.0) }; dirPerp.normalize(); AcString text = textString(); AcGiTextStyle style; fromAcDbTextStyle(style, this->textStyle()); style.loadStyleRec(); AcGePoint2d extents = style.extents(textString(), Adesk::kFalse, text.length(), Adesk::kTrue); mode->geometry().text(position() + dir * extents.x + dirPerp * extents.y, AcGeVector3d::kZAxis, dir * -1, height(), 1.0, 0.0, text); } else AcDbText::subViewportDraw(mode);}
Александр Ривилис:
Используй AcGiContext::isPlotGeneration для проверки это для печати или для просмотра.
Михаил Голубев:
Спасибо. Я сейчас не за компьютером, этот контекст как достать из subViewportDraw()?
Александр Ривилис:
--- Цитата: Михаил Голубев от 12-09-2021, 18:31:18 ---mode
--- Конец цитаты ---
В твоём коде:
--- Код - C++ [Выбрать] ---if (mode->context().isPlotGeneration()) { // Идёт печать} else { // Вывод на экран}
Александр Ривилис:
Кстати, возможны нюансы при задании угла поворота при печати. С ходу не скажу как это повлияет и как это анализировать в классе Custom Entity, так как эту информацию можно получить из AcDbPlotSettings::plotRotation.
И еще. Убедись, что при печати срабатывает метод subViewportDraw(). Вполне возможно, что раз ты унаследовался от AcDbText, срабатывает метод subWorldDraw()
Навигация
Перейти к полной версии