inline std::unique_ptr<GrAtlasTextOp> GrTextBlob::makeOp( const Run::SubRunInfo& info, int glyphCount, uint16_t run, uint16_t subRun, const SkMatrix& viewMatrix, SkScalar x, SkScalar y, const SkIRect& clipRect, const SkPaint& paint, GrColor filteredColor, const SkSurfaceProps& props, const GrDistanceFieldAdjustTable* distanceAdjustTable, GrTextTarget* target) { GrMaskFormat format = info.maskFormat(); GrPaint grPaint; target->makeGrPaint(info.maskFormat(), paint, viewMatrix, &grPaint); std::unique_ptr<GrAtlasTextOp> op; if (info.drawAsDistanceFields()) { // TODO: Can we be even smarter based on the dest transfer function? op = GrAtlasTextOp::MakeDistanceField( target->getContext(), std::move(grPaint), glyphCount, distanceAdjustTable, target->colorSpaceInfo().isLinearlyBlended(), paint.computeLuminanceColor(), props, info.isAntiAliased(), info.hasUseLCDText()); } else { op = GrAtlasTextOp::MakeBitmap(target->getContext(), std::move(grPaint), format, glyphCount, info.needsTransform()); } GrAtlasTextOp::Geometry& geometry = op->geometry(); geometry.fViewMatrix = viewMatrix; geometry.fClipRect = clipRect; geometry.fBlob = SkRef(this); geometry.fRun = run; geometry.fSubRun = subRun; geometry.fColor = info.maskFormat() == kARGB_GrMaskFormat ? GrColor_WHITE : filteredColor; geometry.fX = x; geometry.fY = y; op->init(); return op; }
void GrTextBlob::appendGlyph(int runIndex, const SkRect& positions, GrColor color, const sk_sp<GrTextStrike>& strike, GrGlyph* glyph, bool preTransformed) { Run& run = fRuns[runIndex]; GrMaskFormat format = glyph->fMaskFormat; Run::SubRunInfo* subRun = &run.fSubRunInfo.back(); if (run.fInitialized && subRun->maskFormat() != format) { subRun = &run.push_back(); subRun->setStrike(strike); } else if (!run.fInitialized) { subRun->setStrike(strike); } run.fInitialized = true; bool hasW = subRun->hasWCoord(); // glyphs drawn in perspective must always have a w coord. SkASSERT(hasW || !fInitialViewMatrix.hasPerspective()); size_t vertexStride = GetVertexStride(format, hasW); subRun->setMaskFormat(format); subRun->joinGlyphBounds(positions); subRun->setColor(color); intptr_t vertex = reinterpret_cast<intptr_t>(this->fVertices + subRun->vertexEndIndex()); // We always write the third position component used by SDFs. If it is unused it gets // overwritten. Similarly, we always write the color and the blob will later overwrite it // with texture coords if it is unused. size_t colorOffset = hasW ? sizeof(SkPoint3) : sizeof(SkPoint); // V0 *reinterpret_cast<SkPoint3*>(vertex) = {positions.fLeft, positions.fTop, 1.f}; *reinterpret_cast<GrColor*>(vertex + colorOffset) = color; vertex += vertexStride; // V1 *reinterpret_cast<SkPoint3*>(vertex) = {positions.fLeft, positions.fBottom, 1.f}; *reinterpret_cast<GrColor*>(vertex + colorOffset) = color; vertex += vertexStride; // V2 *reinterpret_cast<SkPoint3*>(vertex) = {positions.fRight, positions.fTop, 1.f}; *reinterpret_cast<GrColor*>(vertex + colorOffset) = color; vertex += vertexStride; // V3 *reinterpret_cast<SkPoint3*>(vertex) = {positions.fRight, positions.fBottom, 1.f}; *reinterpret_cast<GrColor*>(vertex + colorOffset) = color; subRun->appendVertices(vertexStride); fGlyphs[subRun->glyphEndIndex()] = glyph; subRun->glyphAppended(); subRun->setNeedsTransform(!preTransformed); }
void GrAtlasTextBlob::appendGlyph(int runIndex, const SkRect& positions, GrColor color, GrBatchTextStrike* strike, GrGlyph* glyph, SkGlyphCache* cache, const SkGlyph& skGlyph, SkScalar x, SkScalar y, SkScalar scale, bool applyVM) { // If the glyph is too large we fall back to paths if (glyph->fTooLargeForAtlas) { this->appendLargeGlyph(glyph, cache, skGlyph, x, y, scale, applyVM); return; } Run& run = fRuns[runIndex]; GrMaskFormat format = glyph->fMaskFormat; Run::SubRunInfo* subRun = &run.fSubRunInfo.back(); if (run.fInitialized && subRun->maskFormat() != format) { subRun = &run.push_back(); subRun->setStrike(strike); } else if (!run.fInitialized) { subRun->setStrike(strike); } run.fInitialized = true; size_t vertexStride = GetVertexStride(format); subRun->setMaskFormat(format); subRun->joinGlyphBounds(positions); subRun->setColor(color); intptr_t vertex = reinterpret_cast<intptr_t>(this->fVertices + subRun->vertexEndIndex()); if (kARGB_GrMaskFormat != glyph->fMaskFormat) { // V0 SkPoint* position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fLeft, positions.fTop); SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); *colorPtr = color; vertex += vertexStride; // V1 position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fLeft, positions.fBottom); colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); *colorPtr = color; vertex += vertexStride; // V2 position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fRight, positions.fBottom); colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); *colorPtr = color; vertex += vertexStride; // V3 position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fRight, positions.fTop); colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)); *colorPtr = color; } else { // V0 SkPoint* position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fLeft, positions.fTop); vertex += vertexStride; // V1 position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fLeft, positions.fBottom); vertex += vertexStride; // V2 position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fRight, positions.fBottom); vertex += vertexStride; // V3 position = reinterpret_cast<SkPoint*>(vertex); position->set(positions.fRight, positions.fTop); } subRun->appendVertices(vertexStride); fGlyphs[subRun->glyphEndIndex()] = glyph; subRun->glyphAppended(); }