Exemple #1
0
/**
    Use HarfBuzz to shape segment in question
 */
void shapeGlyphs(StoryText *itemText, int startIndex, int endIndex)
{
    if(startIndex < 0 || endIndex < 1) { return; }

    QString text = itemText->text(startIndex, endIndex-startIndex); //this one takes pos, len

    ScText * scitem = itemText->item(startIndex);
    ScFace scface = scitem->font();
    qreal size = scitem->fontSize();
    
    ShaperFontInfo font(scface, size / 10.0);
    ShaperItemInfo shaper(&font);
    ShaperOutput out = shaper.shapeItem(text); //HarfBuzz Magic

    //out.glyphs has our glyphs
    for(uint i = 0; i < out.num_glyphs; i++)
    {
        GlyphLayout &glyph = itemText->item(startIndex + i)->glyph;
        glyph.glyph = out.glyphs[i];

        // XXX: I can't figure out how to use the advances returned by harfbuzz
        //      to position the glyphs, so I'm going to ask the scribus font
        //      class to get the advances for me, then I'll handle marks as
        //      a special case where there's no advance
        //
        //      Please somebody FIXME
        //
        glyph.xadvance = scface.glyphWidth(glyph.glyph, size); //works .. sorta!!

        if(out.attributes[i].mark) //HACK vowel marks
        {
            glyph.xadvance = 0;
        }

        //debugging
        // qDebug() << "glyphs[" << i << "] =" << out.glyphs[i];
        // qDebug() << "advance[" << i << "] =" << out.advances[i];
    }

    if(out.num_glyphs < (uint)text.length())
    {
        // There were some ligatures, so zero-out the extra characters at the end of this run
        for(int i = out.num_glyphs; i < text.length(); i++)
        {
            GlyphLayout &glyph = itemText->item(startIndex + i)->glyph;
            glyph.glyph = scface.char2CMap(QChar::Nbsp);
            glyph.xadvance = 0;
        }

    }
}
Exemple #2
0
QVariant CharTableModel::data(const QModelIndex &index, int role) const
{
	if (!index.isValid() || m_doc == 0)
		return QVariant();

	int ix = index.row() * m_cols + index.column();
	uint currentChar;
	QString currentFont = m_fontInUse;
	if (ix < m_characters.count())
	{
		currentChar = m_characters[ix];
		currentFont = m_fonts[ix];
	}
	else
		return QVariant();

	// for mimeData()
	if (role == CharTableModel::CharTextRole)
		return QString("%1").arg(QChar(currentChar));

	if (role == CharTableModel::CharTextAndFontRole)
		return QString("%1#%2").arg(currentChar).arg(currentFont);

	// tooltip
	if (role == Qt::ToolTipRole)
		return QString("Unicode:\n0x%1").arg(currentChar, 4, 16, QChar('0'));

	// status tip
	if ( role == Qt::StatusTipRole )
	{
		QString tmp = QString("%1").arg(currentChar, 4, 16, QChar('0')).toUpper();
		QStringList lst;
		lst << tmp << currentFont;
		return lst;
	}

	// pixmap
	if (role == Qt::DecorationRole)
	{
		// m_cols should not become 0. Never.
		int baseSize = m_viewWidth / m_cols;
		QTransform chma;
		chma.scale(baseSize/10, baseSize/10);

		ScFace face = (*m_doc->AllFonts)[currentFont];
		uint gl = face.char2CMap(currentChar);
		int size = baseSize + qRound(-face.descent() * baseSize) + 1;
		double ww = baseSize - face.glyphWidth(gl, baseSize);

		QImage pix(baseSize, size, QImage::Format_ARGB32_Premultiplied);
		ScPainter *p = new ScPainter(&pix, baseSize, size);
		p->clear();
		FPointArray gly = face.glyphOutline(gl, 1);
		if (gly.size() > 4)
		{
			gly.map(chma);
			p->translate(ww / 2, 1);
			p->setBrush(Qt::black);
			p->setFillMode(1);
			p->setupPolygon(&gly);
			p->fillPath();
			p->end();
		}
		delete p;
		return QVariant(QPixmap::fromImage(pix));
	}
	// trash
	return QVariant();
}