/** * takes a utf16 string and runs Harfbuzz to create a list of glyphs * * @param aContext void context * @param aUtf16String the utf16 string * @param aHarfBuzz structure containing Harfbuzz stuff * @return error */ static int Utf16_To_Harfbuzz( void *aContext, uint16_t *aUtf16String, int nChars, HarfBuzz_t *aHarfBuzz ) { ft_Context_t *ftContext = FT_CONTEXT( aContext ); HB_FontRec hbFont; HB_Face hbFace = NULL; HB_ShaperItem hbShaperItem; memset( aHarfBuzz->str, 0, sizeof( aHarfBuzz->str ) ); memset( aHarfBuzz->out_glyphs, 0, sizeof( aHarfBuzz->out_glyphs ) ); memset( aHarfBuzz->out_attrs, 0, sizeof( aHarfBuzz->out_attrs ) ); memset( aHarfBuzz->out_advs, 0, sizeof( aHarfBuzz->out_advs ) ); memset( aHarfBuzz->out_offsets, 0, sizeof( aHarfBuzz->out_offsets ) ); memset( aHarfBuzz->out_logClusters, 0, sizeof( aHarfBuzz->out_logClusters ) ); memset( &hbFont, 0, sizeof( HB_FontRec ) ); memset( &hbFace, 0, sizeof( HB_Face ) ); hbFace = HB_NewFace( ftContext->m_face, hb_freetype_table_sfnt_get ); memcpy( aHarfBuzz->str, aUtf16String, nChars * sizeof( uint16_t ) ); aHarfBuzz->n_Chars = nChars; assert( ftContext->m_face != NULL ); hbFont.klass = &hb_freetype_class; hbFont.userData = ftContext->m_face; hbFont.x_ppem = ftContext->m_face->size->metrics.x_ppem; hbFont.y_ppem = ftContext->m_face->size->metrics.y_ppem; hbFont.x_scale = ftContext->m_face->size->metrics.x_scale; hbFont.y_scale = ftContext->m_face->size->metrics.y_scale; memset( &hbShaperItem, 0, sizeof( HB_ShaperItem ) ); hbShaperItem.kerning_applied = FALSE; hbShaperItem.string = ( HB_UChar16 * )aHarfBuzz->str; hbShaperItem.stringLength = nChars; hbShaperItem.item.bidiLevel = 0; hbShaperItem.item.script = HB_Script_Arabic; hbShaperItem.item.pos = 0; hbShaperItem.item.length = hbShaperItem.stringLength; hbShaperItem.shaperFlags = 0; hbShaperItem.font = &hbFont; hbShaperItem.face = hbFace; hbShaperItem.glyphIndicesPresent = FALSE; hbShaperItem.initialGlyphCount = 0; hbShaperItem.glyphs = aHarfBuzz->out_glyphs; hbShaperItem.attributes = aHarfBuzz->out_attrs; hbShaperItem.advances = aHarfBuzz->out_advs; hbShaperItem.offsets = aHarfBuzz->out_offsets; hbShaperItem.log_clusters = aHarfBuzz->out_logClusters; hbShaperItem.num_glyphs = MAX_CHARS; HB_ShapeItem( &hbShaperItem ); HB_FreeFace( hbFace ); return 0; }
~TextRunWalker() { fastFree(m_item.font); deleteGlyphArrays(); delete[] m_item.log_clusters; if (m_item.face) HB_FreeFace(m_item.face); }
void setupFontForScriptRun() { const FontData* fontData = m_font->fontDataAt(0); if (!fontData->containsCharacters(m_item.string + m_item.item.pos, m_item.item.length)) fontData = m_font->fontDataForCharacters(m_item.string + m_item.item.pos, m_item.item.length); const FontPlatformData& platformData = fontData->fontDataForCharacter(' ')->platformData(); void* opaquePlatformData = const_cast<FontPlatformData*>(&platformData); m_item.font->userData = opaquePlatformData; if (m_item.face) HB_FreeFace(m_item.face); m_item.face = HB_NewFace(opaquePlatformData, harfbuzzSkiaGetTable); }
Shaper::Shaper(FT_Face face, HB_Script script, const QString &str) { HB_Face hbFace = HB_NewFace(face, hb_getSFntTable); hbFont.klass = &hb_fontClass; 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; shaper_item.kerning_applied = false; shaper_item.string = reinterpret_cast<const HB_UChar16 *>(str.constData()); shaper_item.stringLength = str.length(); shaper_item.item.script = script; shaper_item.item.pos = 0; shaper_item.item.length = shaper_item.stringLength; shaper_item.item.bidiLevel = 0; // ### shaper_item.shaperFlags = 0; shaper_item.font = &hbFont; shaper_item.face = hbFace; shaper_item.num_glyphs = shaper_item.item.length; shaper_item.glyphIndicesPresent = false; shaper_item.initialGlyphCount = 0; while (1) { hb_glyphs.resize(shaper_item.num_glyphs); hb_attributes.resize(shaper_item.num_glyphs); hb_advances.resize(shaper_item.num_glyphs); hb_offsets.resize(shaper_item.num_glyphs); hb_logClusters.resize(shaper_item.num_glyphs); memset(hb_glyphs.data(), 0, hb_glyphs.size() * sizeof(HB_Glyph)); memset(hb_attributes.data(), 0, hb_attributes.size() * sizeof(HB_GlyphAttributes)); memset(hb_advances.data(), 0, hb_advances.size() * sizeof(HB_Fixed)); memset(hb_offsets.data(), 0, hb_offsets.size() * sizeof(HB_FixedPoint)); shaper_item.glyphs = hb_glyphs.data(); shaper_item.attributes = hb_attributes.data(); shaper_item.advances = hb_advances.data(); shaper_item.offsets = hb_offsets.data(); shaper_item.log_clusters = hb_logClusters.data(); if (HB_ShapeItem(&shaper_item)) break; } HB_FreeFace(hbFace); }
FMShaper::~ FMShaper() { qDebug() << "FMShaper "<< this <<" destructor"; if (faceisset) { if(m.font) { qDebug() << "Freeing m.font at "<< m.font; delete m.font; } if(m.face) { qDebug() << "Freeing m.face at "<< m.face; HB_FreeFace(m.face); } } qDebug() << "FMShaper "<< this <<" destroyed"; }
void qHBFreeFace(HB_Face face) { HB_FreeFace(face); }
FontPlatformData::RefCountedHarfbuzzFace::~RefCountedHarfbuzzFace() { HB_FreeFace(m_harfbuzzFace); }
FontPlatformData::RefCountedHarfbuzzFace::~RefCountedHarfbuzzFace() { #ifdef SUPPORT_COMPLEX_SCRIPTS HB_FreeFace(m_harfbuzzFace); #endif }