のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

setupComplexFont

    727 void TextRunWalker::setupFontForScriptRun()
    728 {
    729     const FontData* fontData = m_font->glyphDataForCharacter(m_run[0], false).fontData;
    730     const FontPlatformData& platformData =
    731         fontData->fontDataForCharacter(' ')->platformData();
    732     const FontPlatformData* complexPlatformData = setupComplexFont(m_item.item.script, platformData); <=====
    733 
    734     m_item.face = complexPlatformData->harfbuzzFace();
    735     m_item.font->userData = const_cast<FontPlatformData*>(complexPlatformData);
    736 
    737     int size = complexPlatformData->size();
    738     m_item.font->x_ppem = size;
    739     m_item.font->y_ppem = size;
    740     // x_ and y_scale are the conversion factors from font design space (fEmSize) to 1/64th of device pixels in 16.16 format.
    741     const int devicePixelFraction = 64;
    742     const int multiplyFor16Dot16 = 1 << 16;
    743     int scale = devicePixelFraction * size * multiplyFor16Dot16 / complexPlatformData->emSizeInFontUnits();
    744     m_item.font->x_scale = scale;
    745     m_item.font->y_scale = scale;
    746 }
  266 HB_FaceRec_* FontPlatformData::harfbuzzFace() const
    267 {
    268 #ifdef SUPPORT_COMPLEX_SCRIPTS
    269     if (!m_harfbuzzFace)
    270         m_harfbuzzFace = RefCountedHarfbuzzFace::create(
    271             HB_NewFace(const_cast<FontPlatformData*>(this), harfbuzzSkiaGetTable));
    272 
    273     return m_harfbuzzFace->face();
    274 #else
    275     return NULL;
    276 #endif
    277 }
   970 HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc)
    971 {
    972     HB_Face face = (HB_Face )malloc(sizeof(HB_FaceRec));
    973     if (!face)
    974         return 0;
    975 
    976     face->isSymbolFont = false;
    977     face->gdef = 0;
    978     face->gpos = 0;
    979     face->gsub = 0;
    980     face->current_script = HB_ScriptCount;
    981     face->current_flags = HB_ShaperFlag_Default;
    982     face->has_opentype_kerning = false;
    983     face->tmpAttributes = 0;
    984     face->tmpLogClusters = 0;
    985     face->glyphs_substituted = false;
    986     face->buffer = 0;
    987 
    988     HB_Error error = HB_Err_Ok;
    989     HB_Stream stream;
    990     HB_Stream gdefStream;
    991 
    992     gdefStream = getTableStream(font, tableFunc, TTAG_GDEF);
    993     error = HB_Err_Not_Covered;
    994     if (!gdefStream || (error = HB_Load_GDEF_Table(gdefStream, &face->gdef))) {
    995         //DEBUG("error loading gdef table: %d", error);
    996         face->gdef = 0;
    997     }
    998 
    999     //DEBUG() << "trying to load gsub table";
   1000     stream = getTableStream(font, tableFunc, TTAG_GSUB);
   1001     error = HB_Err_Not_Covered;
   1002     if (!stream || (error = HB_Load_GSUB_Table(stream, &face->gsub, face->gdef, gdefStream))) {
   1003         face->gsub = 0;
   1004         if (error != HB_Err_Not_Covered) {
   1005             //DEBUG("error loading gsub table: %d", error);
   1006         } else {
   1007             //DEBUG("face doesn't have a gsub table");
   1008         }
   1009     }
   1010     _hb_close_stream(stream);
   1011 
   1012     stream = getTableStream(font, tableFunc, TTAG_GPOS);
   1013     error = HB_Err_Not_Covered;
   1014     if (!stream || (error = HB_Load_GPOS_Table(stream, &face->gpos, face->gdef, gdefStream))) {
   1015         face->gpos = 0;
   1016         DEBUG("error loading gpos table: %d", error);
   1017     }
   1018     _hb_close_stream(stream);
   1019 
   1020     _hb_close_stream(gdefStream);
   1021 
   1022     for (unsigned int i = 0; i < HB_ScriptCount; ++i)
   1023         face->supported_scripts[i] = checkScript(face, i);
   1024 
   1025     if (hb_buffer_new(&face->buffer) != HB_Err_Ok) {
   1026         HB_FreeFace(face);
   1027         return 0;
   1028     }
   1029 
   1030     return face;
   1031 }
    691 const FontPlatformData* TextRunWalker::setupComplexFont(
    692     HB_Script script, const FontPlatformData& platformData)
    693 {
    694     static FallbackHash fallbackPlatformData;
    695 
    696     // generate scriptStyleIndex - we need unique hash IDs for each style
    697     // of each script - normal, bold, italic, bolditalic. the first set of
    698     // NUM_SCRIPTS are the normal style version, followed by bold, then
    699     // italic, then bold italic. additional fake style bits can be added.
    700     int scriptStyleIndex = script;
    701     if (platformData.isFakeBold())
    702         scriptStyleIndex += HB_ScriptCount;
    703     if (platformData.isFakeItalic())
    704         scriptStyleIndex += HB_ScriptCount << 1;
    705 
    706     FallbackFontKey key(scriptStyleIndex, platformData.size());
    707     FontPlatformData* newPlatformData = 0;
    708 
    709     if (!fallbackPlatformData.contains(key)) {
    710         SkTypeface::Style currentStyle = SkTypeface::kNormal;
    711         if (platformData.typeface())
    712             currentStyle = platformData.typeface()->style();
    713         SkTypeface* typeface = SkCreateTypefaceForScript(script, currentStyle,
    714             SkPaint::kElegant_Variant);
    715         newPlatformData = new FontPlatformData(platformData, typeface);
    716         SkSafeUnref(typeface);
    717         fallbackPlatformData.set(key, newPlatformData);
    718     }
    719 
    720     if (!newPlatformData)
    721         newPlatformData = fallbackPlatformData.get(key);
    722 
    723     // If we couldn't allocate a new FontPlatformData, revert to the one passed
    724     return newPlatformData ? newPlatformData : &platformData;
    725 }