void ScFace_ttf::load() const { if ( !kernFeature ) kernFeature = new KernFeature ( ftFace() ); FtFace::load(); sfnt::PostTable checkPost; FT_Face face = ftFace(); checkPost.readFrom(face); // if (!checkPost.usable) // qDebug() << "can't use post table from " << face->family_name << face->style_name << ":" << checkPost.errorMsg; // else // qDebug() << "posttable from" << face->family_name << face->style_name << "has names for" << checkPost.numberOfGlyphs() << "glyphs and" << maxGlyph << "glyphs in charmap"; const_cast<bool&>(hasGlyphNames) = checkPost.usable && checkPost.numberOfGlyphs() >= maxGlyph; }
bool ScFace_ttf::glyphNames(ScFace::FaceEncoding& GList) const { FT_ULong charcode; FT_UInt gindex = 0; FT_Face face = ftFace(); if (!face) return false; // The glyph name table embedded in Truetype fonts is not reliable. // For those fonts we consequently use Adobe Glyph names whenever possible. const bool avoidFntNames = (formatCode != ScFace::TYPE42 && typeCode == ScFace::TTF) && hasMicrosoftUnicodeCmap(face); if (!avoidFntNames) return FtFace::glyphNames(GList); // qDebug() << "reading metrics for" << face->family_name << face->style_name; charcode = FT_Get_First_Char(face, &gindex); while (gindex != 0) { GList.insert(gindex, std::make_pair(static_cast<ScFace::ucs4_type>(charcode), adobeGlyphName(charcode))); charcode = FT_Get_Next_Char(face, charcode, &gindex ); } return true; }
bool ScFace_ttf::isSymbolic() const { FT_Face face = ftFace(); if (!face || !face->charmap) return false; return (m_face->charmap->encoding == FT_ENCODING_MS_SYMBOL); }
void* ScFace::ScFaceData::hbFont() { if (!m_hbFont) { if (!ftFace()) return NULL; if (formatCode == ScFace::SFNT || formatCode == ScFace::TTCF || formatCode == ScFace::TYPE42) { // use HarfBuzz internal font functions for formats it supports, // gives us more consistent glyph metrics. FT_Reference_Face(ftFace()); hb_face_t *hbFace = hb_face_create_for_tables(referenceTable, ftFace(), (hb_destroy_func_t) FT_Done_Face); hb_face_set_index(hbFace, ftFace()->face_index); hb_face_set_upem(hbFace, ftFace()->units_per_EM); m_hbFont = hb_font_create(hbFace); hb_ot_font_set_funcs(reinterpret_cast<hb_font_t*>(m_hbFont)); hb_face_destroy(hbFace); } else { m_hbFont = hb_ft_font_create_referenced(ftFace()); } } return m_hbFont; }
bool ScFace_ttf::hasNames() const { FT_Face face = ftFace(); if (!face) return false; // The glyph name table embedded in Truetype fonts is not reliable. // For those fonts we consequently use Adobe Glyph names whenever possible. const bool avoidFntNames = (formatCode != ScFace::TYPE42 && typeCode == ScFace::TTF) && hasMicrosoftUnicodeCmap(face); if (avoidFntNames) return true; // We use Adobe Glyph List or 'uniXXXX' names in such case return FtFace::hasNames(); }
bool ScFace_ttf::EmbedFont(QByteArray &str) const { QByteArray bb; FtFace::RawData(bb); if (formatCode == ScFace::TYPE42) { //easy: str = bb; return true; } QString tmp4; QString tmp2 = ""; QString tmp3 = ""; int counter = 0; char *buf[50]; FT_ULong charcode; FT_UInt gindex; FT_Face face = ftFace(); if (!face) { return false; } const FT_Stream fts = face->stream; if (ftIOFunc(fts, 0L, NULL, 0)) { return(false); } str+="%!PS-TrueTypeFont\n"; str+="11 dict begin\n"; str+="/FontName /" + psName + " def\n"; str+="/Encoding /ISOLatin1Encoding where {pop ISOLatin1Encoding} {StandardEncoding} ifelse def\n"; str+="/PaintType 0 def\n/FontMatrix [1 0 0 1 0 0] def\n"; str+="/FontBBox ["+m_pdfFontBBox+"] def\n"; str+="/FontType 42 def\n"; str+="/FontInfo 8 dict dup begin\n"; str+="/FamilyName (" + psName + ") def\n"; str+="end readonly def\n"; unsigned char *tmp = new unsigned char[65535]; int length; char linebuf[80]; str += "/sfnts ["; int poso=0; do { int posi=0; length= fts->size - fts->pos; if (length > 65534) { length = 65534; } if (!ftIOFunc(fts, 0L, tmp, length)) { str+="\n<\n"; for (int j = 0; j < length; j++) { unsigned char u=tmp[posi]; linebuf[poso]=((u >> 4) & 15) + '0'; if (u>0x9f) linebuf[poso]+='a'-':'; ++poso; u&=15; linebuf[poso]=u + '0'; if (u>0x9) linebuf[poso]+='a'-':'; ++posi; ++poso; if (poso > 70) { linebuf[poso++]='\n'; linebuf[poso++]=0; str += linebuf; poso = 0; } } linebuf[poso++]=0; str += linebuf; poso = 0; str += "00\n>"; } else { sDebug(QObject::tr("Font %1 is broken (read stream), no embedding").arg(fontFile)); str += "\n] def\n"; status = qMax(status,ScFace::BROKENGLYPHS); return false; } } while (length==65534);