static void drawChar(uchar ch, float x, float y, AbstractFont *font, int alignFlags, short /*textFlags*/) { if(alignFlags & ALIGN_RIGHT) { x -= font->glyphPosCoords(ch).width(); } else if(!(alignFlags & ALIGN_LEFT)) { x -= font->glyphPosCoords(ch).width() / 2; } int const ascent = font->ascent(); int const lineHeight = ascent? ascent : font->glyphPosCoords(ch).height(); if(alignFlags & ALIGN_BOTTOM) { y -= topToAscent(font) + lineHeight; } else if(!(alignFlags & ALIGN_TOP)) { y -= (topToAscent(font) + lineHeight) / 2; } LIBGUI_GL.glMatrixMode(GL_MODELVIEW); LIBGUI_GL.glTranslatef(x, y, 0); Rectanglei geometry = font->glyphPosCoords(ch); if(BitmapFont *bmapFont = font->maybeAs<BitmapFont>()) { /// @todo Filtering should be determined at a higher level. /// @todo We should not need to re-bind this texture here. GL_BindTextureUnmanaged(bmapFont->textureGLName(), gl::ClampToEdge, gl::ClampToEdge, filterUI? gl::Linear : gl::Nearest); geometry = geometry.expanded(bmapFont->textureMargin().toVector2i()); } else if(CompositeBitmapFont *compFont = font->maybeAs<CompositeBitmapFont>()) { GL_BindTexture(compFont->glyphTexture(ch)); geometry = geometry.expanded(compFont->glyphTextureBorder(ch)); } Vector2i coords[4] = { font->glyphTexCoords(ch).topLeft, font->glyphTexCoords(ch).topRight(), font->glyphTexCoords(ch).bottomRight, font->glyphTexCoords(ch).bottomLeft() }; GL_DrawRectWithCoords(geometry, coords); if(font->is<CompositeBitmapFont>()) { GL_SetNoTexture(); } LIBGUI_GL.glMatrixMode(GL_MODELVIEW); LIBGUI_GL.glTranslatef(-x, -y, 0); }
/** * Submits the image to the backing store, or commits it if no backing * store is available. * * @param image Image. * @param rect Rectangle for the image determined by an IAllocator. */ void submitImage(Image const &image, Rectanglei const &rect) { Rectanglei const noBorders = rect.shrunk(border); Rectanglei const withMargin = rect.expanded(margin); if (hasBacking()) { // The margin is cleared to transparent black. backing.fill(withMargin, Image::Color(0, 0, 0, 0)); if (border > 0) { if (flags.testFlag(WrapBordersInBackingStore)) { // Wrap using the source image (left, right, top, bottom edges). backing.drawPartial(image, Rectanglei(0, 0, border, image.height()), rect.topRight() + Vector2i(-border, border)); backing.drawPartial(image, Rectanglei(image.width() - border, 0, border, image.height()), rect.topLeft + Vector2i(0, border)); backing.drawPartial(image, Rectanglei(0, 0, image.width(), border), rect.bottomLeft() + Vector2i(border, -border)); backing.drawPartial(image, Rectanglei(0, image.height() - border, image.width(), border), rect.topLeft + Vector2i(border, 0)); } } backing.draw(image, noBorders.topLeft); //backing.toQImage().save(QString("backing-%1.png").arg(uint64_t(this))); markAsChanged(rect); } else { // No backing, must commit immediately. if (border > 0) { // Expand with borders (repeat edges). QImage const srcImg = image.toQImage(); int const sw = srcImg.width(); int const sh = srcImg.height(); QImage bordered(QSize(rect.width(), rect.height()), srcImg.format()); int const w = bordered.width(); int const h = bordered.height(); QPainter painter(&bordered); painter.setCompositionMode(QPainter::CompositionMode_Source); painter.fillRect(bordered.rect(), QColor(0, 0, 0, 0)); /// @todo This really only works for a border of 1 pixels. Should /// repeat the same outmost edge pixels for every border. -jk painter.drawImage(border, border, srcImg); painter.drawImage(border, 0, srcImg, 0, 0, sw, 1); // top painter.drawImage(border, h - 1, srcImg, 0, sh - 1, sw, 1); // bottom painter.drawImage(0, border, srcImg, 0, 0, 1, sh); // left painter.drawImage(w - 1, border, srcImg, sw - 1, 0, 1, sh); // right // Corners. painter.drawImage(0, 0, srcImg, 0, 0, 1, 1); painter.drawImage(w - 1, 0, srcImg, sw - 1, 0, 1, 1); painter.drawImage(0, h - 1, srcImg, 0, sh - 1, 1, 1); painter.drawImage(w - 1, h - 1, srcImg, sw - 1, sh - 1, 1, 1); self().commit(bordered, rect.topLeft); } else { self().commit(image, noBorders.topLeft); } } }