Logo Search packages:      
Sourcecode: tagua version File versions  Download package

bool Loader::Image::drawGlyph ( Context ctx,
const QRectF &  dest,
const QString &  font,
unsigned int  glyph,
const QBrush &  fg = Qt::black,
const QBrush &  bg = Qt::white,
double  border = 0.0,
bool  draw_inner_bg = true 
)

Draws a font glyph over the image.

Parameters:
ctx The current context (theme) reference (should be implicit in lua)
dest The destination rectangle.
font The font file to load.
glyph The unicode glyph code.
fg The foreground color.
bg The background color.
border The background expansion.
draw_inner_bg If true the 'inner part' (detected with a flood fill algorithm) will be filled with the background brush.
Returns:
True if it was possible to load the font file and find the glyph.

Definition at line 209 of file image.cpp.

References Loader::Context::get(), and Loader::Context::put().

                                    {
  QChar glyph(glyph_num);
  FontGlyphPtr font_glyph;

  QString k = file + QString(":%04x").arg(glyph_num);
  if(FontGlyphPtr *f = ctx->get<FontGlyphPtr>(k))
    font_glyph = *f;
  else {
    /* get the font (from cache if possible) */
    FontPtr font = Font::create(ctx, file);

    if(!font)
      return false;


    font_glyph = FontGlyphPtr(new FontGlyph);


    /* get a few metrics */
    QFontMetrics fm(font->m_font);

    if(!fm.inFont(glyph))
      return false;

    int h = fm.height();
    int w = fm.width(glyph);
    font_glyph->m_height = h;

    /* create the path from the char */
    font_glyph->m_path.addText((h-w)/2, fm.ascent(), font->m_font, glyph);

    /* save in cache */
    ctx->put(k, font_glyph);
  }

  /* create lazily the inner background region */
  if(!font_glyph->m_inner_background_init && draw_inner_bg
    && (_bg.style() != Qt::NoBrush && !(_bg.style() <= 14 && _bg.color().alpha()==0))) {
    //14 is the last color-based brush

    int h = font_glyph->m_height;
    QImage bg_img(h, h, QImage::Format_ARGB32_Premultiplied );
    bg_img.fill( QColor(Qt::black).rgba() ); //fill all black

    /* render the piece in blue */
    QPainter p;
    p.begin(&bg_img);
    p.setBrush( Qt::blue );
    p.setPen( Qt::NoPen);
    p.setCompositionMode(QPainter::CompositionMode_Source);
    p.setRenderHint(QPainter::Antialiasing, true);
    p.drawPath(font_glyph->m_path);
    p.end();

    /* flood fill the connected component where blue is <192 with a transparent color */
    ImageEffects::floodFillBlueThreshold(bg_img, QPoint(0,0), Qt::transparent, 192, true);

    /* And we've got our region */
    font_glyph->m_inner_background = bg_img.createAlphaMask();
    font_glyph->m_inner_background.setColor(0, Qt::transparent);
    font_glyph->m_inner_background_init = true;
  }

  /* draw the glyph, at last :) */
  int h = font_glyph->m_height;
  QPainter p(&m_image);
  init_painter(&p);

  p.translate(dest.x(), dest.y());
  p.scale(dest.width()/h, dest.height()/h);

  //14 is the last color-based brush
  if(_bg.style() != Qt::NoBrush && !(_bg.style() <= 14 && _bg.color().alpha()==0)) {
    QBrush bg = _bg;
    QMatrix m = bg.matrix();
    m = m * QMatrix().translate(-dest.x(), -dest.y());
    m = m * QMatrix().scale(h/dest.width(), h/dest.height());
    bg.setMatrix(m);

    if(draw_inner_bg) {
      QMatrix m = p.matrix();
      QRectF r = m.mapRect(QRectF(0,0,h,h));
      QRect ir = r.toRect();
      QImage tmp(ir.size(), QImage::Format_ARGB32_Premultiplied);
      tmp.fill(0);
      {
        QPainter ptmp(&tmp);
        ptmp.setRenderHint(QPainter::Antialiasing);
        ptmp.setRenderHint(QPainter::TextAntialiasing);
        ptmp.setRenderHint(QPainter::SmoothPixmapTransform);
        ptmp.translate(-ir.x(), -ir.y());
        ptmp.setMatrix(m, true);
        ptmp.drawImage(QRect(0,0,h,h), font_glyph->m_inner_background);
        if(border > 0.0 || !_fg.isOpaque() ) {
          ptmp.setBrush( _fg.isOpaque() ? QBrush(Qt::NoBrush) : QBrush(Qt::red) );
          ptmp.setPen( (border > 0.0)
            ? QPen( Qt::green, h*border/100.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)
            : Qt::NoPen );
          ptmp.drawPath(font_glyph->m_path);
        }
        ptmp.setCompositionMode(QPainter::CompositionMode_SourceIn);
        ptmp.fillRect(QRect(0,0,h,h), bg);
      }
      p.resetMatrix();
      p.drawImage(ir, tmp);
      p.setMatrix(m);
    }
    else if(border > 0.0 || !_fg.isOpaque() ) {
      p.setBrush( _fg.isOpaque() ? Qt::NoBrush : bg );
      p.setPen( (border > 0.0)
        ? QPen(bg, h*border/100.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)
        : Qt::NoPen );
      p.drawPath(font_glyph->m_path);
    }
  }
  if(_fg.style() != Qt::NoBrush) {
    QBrush fg = _fg;
    QMatrix m = fg.matrix();
    m = m * QMatrix().translate(-dest.x(), -dest.y());
    m = m * QMatrix().scale(h/dest.width(), h/dest.height());
    fg.setMatrix(m);

    p.setBrush( fg );
    p.setPen( Qt::NoPen );
    p.drawPath(font_glyph->m_path);
  }
  return true;
}


Generated by  Doxygen 1.6.0   Back to index