diff --git a/include/osgQt/QFontImplementation b/include/osgQt/QFontImplementation new file mode 100644 index 000000000..2f4fedf49 --- /dev/null +++ b/include/osgQt/QFontImplementation @@ -0,0 +1,48 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 2009-2010 Mathias Froehlich + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ +#ifndef QFontImplementation_H +#define QFontImplementation_H + +#include +#include + +#include + +#include + +namespace osgQt { + +class OSGQT_EXPORT QFontImplementation : public osgText::Font::FontImplementation +{ +public: + QFontImplementation(const QFont& font); + virtual ~QFontImplementation(); + + virtual std::string getFileName() const; + + void setFontResolution(const osgText::FontResolution& fontSize); + virtual osgText::Font::Glyph* getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode); + virtual osg::Vec2 getKerning(const osgText::FontResolution& fontRes, unsigned int leftcharcode, + unsigned int rightcharcode, osgText::KerningType kerningType); + virtual bool hasVertical() const; + +protected: + + std::string _filename; + osgText::FontResolution _currentRes; + QFont _font; +}; + +} + +#endif diff --git a/src/osgQt/CMakeLists.txt b/src/osgQt/CMakeLists.txt index 7ac5b60fd..d14bd8ff9 100644 --- a/src/osgQt/CMakeLists.txt +++ b/src/osgQt/CMakeLists.txt @@ -17,6 +17,7 @@ QT4_WRAP_CPP( SOURCES_H_MOC ${SOURCES_H} ) SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/Export + ${HEADER_PATH}/QFontImplementation ${HEADER_PATH}/QGraphicsViewAdapter ${HEADER_PATH}/QWebViewImage ) @@ -25,6 +26,7 @@ SET(LIB_PUBLIC_HEADERS ADD_LIBRARY(${LIB_NAME} ${OPENSCENEGRAPH_USER_DEFINED_DYNAMIC_OR_STATIC} ${LIB_PUBLIC_HEADERS} + QFontImplementation.cpp QGraphicsViewAdapter.cpp QWebViewImage.cpp ${SOURCES_H_MOC} diff --git a/src/osgQt/QFontImplementation.cpp b/src/osgQt/QFontImplementation.cpp new file mode 100644 index 000000000..4927c1b44 --- /dev/null +++ b/src/osgQt/QFontImplementation.cpp @@ -0,0 +1,143 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 2009-2010 Mathias Froehlich + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace osgQt { + +QFontImplementation::QFontImplementation(const QFont& font) : + _filename(font.toString().toStdString() + ".qfont"), + _font(font) +{ + _currentRes.first = 0; + _currentRes.second = 0; +} + +QFontImplementation::~QFontImplementation() +{ +} + +std::string +QFontImplementation::getFileName() const +{ + return _filename; +} + +void +QFontImplementation::setFontResolution(const osgText::FontResolution& fontSize) +{ + if (fontSize == _currentRes) + return; + + _currentRes = fontSize; + _font.setPixelSize(fontSize.second); +} + +osgText::Font::Glyph* +QFontImplementation::getGlyph(const osgText::FontResolution& fontRes, unsigned int charcode) +{ + setFontResolution(fontRes); + + QFontMetrics fontMetrics(_font); + QFontMetricsF fontMetricsF(_font); + + QRect rect = fontMetrics.boundingRect(QChar(charcode)); + QRectF rectF = fontMetricsF.boundingRect(QChar(charcode)); + + int margin = 1; + + int imageWidth = rect.width() + 2*margin; + int imageHeight = rect.height() + 2*margin; + + // Now paint the glyph into the image + QImage image(imageWidth, imageHeight, QImage::Format_ARGB32); + image.fill(0); + QPainter painter(&image); + painter.setRenderHint(QPainter::TextAntialiasing); + + painter.setFont(_font); + + painter.setBackgroundMode(Qt::TransparentMode); + painter.setBrush(Qt::white); + painter.setPen(Qt::white); + + painter.drawText(margin - rect.left(), imageHeight - 1 - (margin + rect.bottom()), QString(QChar(charcode))); + painter.end(); + + // Transfer the rendered image to osg + osg::ref_ptr glyph = new osgText::Font::Glyph(charcode); + + unsigned int dataSize = imageWidth*imageHeight; + unsigned char* data = new unsigned char[dataSize]; + + // copy the qimage into the texture memory + for (int x = 0; x < imageWidth; ++x) + { + for (int y = 0; y < imageHeight; ++y) + { + data[x + y*imageWidth] = qAlpha(image.pixel(x, imageHeight - 1 - y)); + } + } + + // the glyph texture in osg + glyph->setImage(imageWidth, imageHeight, 1, + GL_ALPHA, + GL_ALPHA, GL_UNSIGNED_BYTE, + data, + osg::Image::USE_NEW_DELETE, + 1); + glyph->setInternalTextureFormat(GL_ALPHA); + + // Layout parameters + float leftBearing = fontMetricsF.leftBearing(QChar(charcode)); + float rightBearing = fontMetricsF.rightBearing(QChar(charcode)); + + // for horizonal layout + osg::Vec2 bottomLeft(leftBearing - margin, - rectF.bottom() - margin); + glyph->setHorizontalBearing(bottomLeft); + glyph->setHorizontalAdvance(fontMetricsF.width(QChar(charcode))); + + // for vertical layout + osg::Vec2 topMiddle(- margin + 0.5*(leftBearing - rect.width() - rightBearing), + rectF.top() - margin); + glyph->setVerticalBearing(topMiddle); + glyph->setVerticalAdvance(rectF.height() + fontMetricsF.overlinePos() - fontMetricsF.xHeight()); + + // ... ready + addGlyph(fontRes, charcode, glyph.get()); + + return glyph.release(); +} + +osg::Vec2 +QFontImplementation::getKerning(const osgText::FontResolution& fontRes, unsigned int leftcharcode, + unsigned int rightcharcode, osgText::KerningType kerningType) +{ + return osg::Vec2(0, 0); +} + +bool +QFontImplementation::hasVertical() const +{ + return true; +} + +}