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
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
996 face->gdef = 0;
997 }
998
999
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
1006 } else {
1007
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
697
698
699
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
724 return newPlatformData ? newPlatformData : &platformData;
725 }