GrPathRange* GrGLPathRendering::createGlyphs(const SkTypeface* typeface, const SkDescriptor* desc, const SkStrokeRec& stroke) { if (NULL != desc || !caps().glyphLoadingSupport) { return GrPathRendering::createGlyphs(typeface, desc, stroke); } if (NULL == typeface) { typeface = SkTypeface::GetDefaultTypeface(); SkASSERT(NULL != typeface); } int faceIndex; SkAutoTDelete<SkStream> fontStream(typeface->openStream(&faceIndex)); const size_t fontDataLength = fontStream->getLength(); if (0 == fontDataLength) { return GrPathRendering::createGlyphs(typeface, NULL, stroke); } SkTArray<uint8_t> fontTempBuffer; const void* fontData = fontStream->getMemoryBase(); if (NULL == fontData) { // TODO: Find a more efficient way to pass the font data (e.g. open file descriptor). fontTempBuffer.reset(SkToInt(fontDataLength)); fontStream->read(&fontTempBuffer.front(), fontDataLength); fontData = &fontTempBuffer.front(); } const int numPaths = typeface->countGlyphs(); const GrGLuint basePathID = this->genPaths(numPaths); SkAutoTUnref<GrGLPath> templatePath(SkNEW_ARGS(GrGLPath, (fGpu, SkPath(), stroke))); GrGLenum status; GL_CALL_RET(status, PathMemoryGlyphIndexArray(basePathID, GR_GL_STANDARD_FONT_FORMAT, fontDataLength, fontData, faceIndex, 0, numPaths, templatePath->pathID(), SkPaint::kCanonicalTextSizeForPaths)); if (GR_GL_FONT_GLYPHS_AVAILABLE != status) { this->deletePaths(basePathID, numPaths); return GrPathRendering::createGlyphs(typeface, NULL, stroke); } // This is a crude approximation. We may want to consider giving this class // a pseudo PathGenerator whose sole purpose is to track the approximate gpu // memory size. const size_t gpuMemorySize = fontDataLength / 4; return SkNEW_ARGS(GrGLPathRange, (fGpu, basePathID, numPaths, gpuMemorySize, stroke)); }
// finds the index of ext in strings or a negative result if ext is not found. static int find_string(const SkTArray<SkString>& strings, const char ext[]) { if (strings.empty()) { return -1; } SkString extensionStr(ext); int idx = SkTSearch<SkString, extension_compare>(&strings.front(), strings.count(), extensionStr, sizeof(SkString)); return idx; }