void GrDistanceFieldTextContext::flush() { if (NULL == fDrawTarget) { return; } if (fCurrVertex > 0) { GrDrawState drawState; drawState.setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTarget()); bool useColorVerts = !fUseLCDText; set_vertex_attributes(&drawState, useColorVerts); // setup our sampler state for our text texture/atlas SkASSERT(SkIsAlign4(fCurrVertex)); // get our current color SkColor filteredColor; SkColorFilter* colorFilter = fSkPaint.getColorFilter(); if (colorFilter) { filteredColor = colorFilter->filterColor(fSkPaint.getColor()); } else { filteredColor = fSkPaint.getColor(); } this->setupCoverageEffect(filteredColor); // Effects could be stored with one of the cache objects (atlas?) drawState.setGeometryProcessor(fCachedGeometryProcessor.get()); // Set draw state if (fUseLCDText) { GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor); if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() || kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() || fPaint.numColorStages()) { SkDebugf("LCD Text will not draw correctly.\n"); } SkASSERT(!drawState.hasColorVertexAttribute()); // We don't use the GrPaint's color in this case because it's been premultiplied by // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by // the mask texture color. The end result is that we get // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor int a = SkColorGetA(fSkPaint.getColor()); // paintAlpha drawState.setColor(SkColorSetARGB(a, a, a, a)); // paintColor drawState.setBlendConstant(colorNoPreMul); drawState.setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); } else { if (0xFF == GrColorUnpackA(fPaint.getColor())) { drawState.setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); } // set back to normal in case we took LCD path previously. drawState.setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff()); // We're using per-vertex color. SkASSERT(drawState.hasColorVertexAttribute()); } int nGlyphs = fCurrVertex / kVerticesPerGlyph; fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); fDrawTarget->drawIndexedInstances(&drawState, kTriangles_GrPrimitiveType, nGlyphs, kVerticesPerGlyph, kIndicesPerGlyph, &fVertexBounds); fDrawTarget->resetVertexSource(); fVertices = NULL; fTotalVertexCount -= fCurrVertex; fCurrVertex = 0; SkSafeSetNull(fCurrTexture); fVertexBounds.setLargestInverted(); } }