Пример #1
0
/**
    The FT_Face should be initialized already in scribus, but I can't access it!!!

    based on tests/fuzzing/fuzz.cc
 */
ShaperFontInfo::ShaperFontInfo(ScFace scface, qreal size)
{
    face = 0;
    FT_Library library = 0;
    // XXX: deal with error
    bool error = FT_Init_FreeType(&library);
    if(error)
    {
        qDebug() << "error initing FT library";
    }
    // qDebug() << "font file:" << scface.fontFilePath();
    error = FT_New_Face(library, 
            scface.fontFilePath().toUtf8().data(), 
            scface.faceIndex(), &face);
    if(error)
    {
        qDebug() << "error loading FT font?";
    }
    error = FT_Set_Char_Size(face, 0, 10, 72, 72); // XXX: not sure what should I put here!! fonts/ftface puts 10 for the size, why?
    if(error)
    {
        qDebug() << "error setting font size";
    }
    hbFace = HB_NewFace(face, hb_freetype_table_sfnt_get);
    hbFont.klass = &hb_freetype_class;
    hbFont.userData = face;
    hbFont.x_ppem  = face->size->metrics.x_ppem;
    hbFont.y_ppem  = face->size->metrics.y_ppem;
    hbFont.x_scale = face->size->metrics.x_scale;
    hbFont.y_scale = face->size->metrics.y_scale;
}
Пример #2
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;
        }

    }
}
Пример #3
0
/** two ScFaces are equal if they either are both NULLFACEs or they
agree on family, style, variant and fontpath
*/
bool ScFace::operator==(const ScFace& other) const
{
	return m_replacedName == other.m_replacedName && 
		( (isNone() && other.isNone() )
			 || (m_m == other.m_m)
			 || (m_m->family == other.m_m->family
				 && m_m->style == other.m_m->style
				 && m_m->variant == other.m_m->variant
				 && m_m->fontFile == other.m_m->fontFile
				 && m_m-> faceIndex == other.m_m->faceIndex) );
}
Пример #4
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();
}
Пример #5
0
// FIXME: the following should not be in desaxe:
Xml_string toXMLString(const ScFace& val)
{
	return val.scName();
}