/** 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; } } }
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(); }