void SkScalerContext::getMetrics(SkGlyph* glyph) { generateMetrics(glyph); // for now we have separate cache entries for devkerning on and off // in the future we might share caches, but make our measure/draw // code make the distinction. Thus we zap the values if the caller // has not asked for them. if ((fRec.fFlags & SkScalerContext::kDevKernText_Flag) == 0) { // no devkern, so zap the fields glyph->fLsbDelta = glyph->fRsbDelta = 0; } // if either dimension is empty, zap the image bounds of the glyph if (0 == glyph->fWidth || 0 == glyph->fHeight) { glyph->fWidth = 0; glyph->fHeight = 0; glyph->fTop = 0; glyph->fLeft = 0; glyph->fMaskFormat = 0; return; } if (fGenerateImageFromPath) { SkPath devPath, fillPath; SkMatrix fillToDevMatrix; this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix); if (fRasterizer) { SkMask mask; if (fRasterizer->rasterize(fillPath, fillToDevMatrix, nullptr, fMaskFilter, &mask, SkMask::kJustComputeBounds_CreateMode)) { glyph->fLeft = mask.fBounds.fLeft; glyph->fTop = mask.fBounds.fTop; glyph->fWidth = SkToU16(mask.fBounds.width()); glyph->fHeight = SkToU16(mask.fBounds.height()); } else { goto SK_ERROR; } } else { // just use devPath const SkIRect ir = devPath.getBounds().roundOut(); if (ir.isEmpty() || !ir.is16Bit()) { goto SK_ERROR; } glyph->fLeft = ir.fLeft; glyph->fTop = ir.fTop; glyph->fWidth = SkToU16(ir.width()); glyph->fHeight = SkToU16(ir.height()); if (glyph->fWidth > 0) { switch (fRec.fMaskFormat) { case SkMask::kLCD16_Format: glyph->fWidth += 2; glyph->fLeft -= 1; break; default: break; } } } } if (SkMask::kARGB32_Format != glyph->fMaskFormat) { glyph->fMaskFormat = fRec.fMaskFormat; } // If we are going to create the mask, then we cannot keep the color if ((fGenerateImageFromPath || fMaskFilter) && SkMask::kARGB32_Format == glyph->fMaskFormat) { glyph->fMaskFormat = SkMask::kA8_Format; } if (fMaskFilter) { SkMask src, dst; SkMatrix matrix; glyph->toMask(&src); fRec.getMatrixFrom2x2(&matrix); src.fImage = nullptr; // only want the bounds from the filter if (fMaskFilter->filterMask(&dst, src, matrix, nullptr)) { if (dst.fBounds.isEmpty() || !dst.fBounds.is16Bit()) { goto SK_ERROR; } SkASSERT(dst.fImage == nullptr); glyph->fLeft = dst.fBounds.fLeft; glyph->fTop = dst.fBounds.fTop; glyph->fWidth = SkToU16(dst.fBounds.width()); glyph->fHeight = SkToU16(dst.fBounds.height()); glyph->fMaskFormat = dst.fFormat; } } return; SK_ERROR: // draw nothing 'cause we failed glyph->fLeft = 0; glyph->fTop = 0; glyph->fWidth = 0; glyph->fHeight = 0; // put a valid value here, in case it was earlier set to // MASK_FORMAT_JUST_ADVANCE glyph->fMaskFormat = fRec.fMaskFormat; }
void SkScalerContext_CairoFT::generateAdvance(SkGlyph* glyph) { generateMetrics(glyph); }