Avoid drawing NVPR DIF text when text size is 0

Avoid drawing text when using NVPR and device independent fonts.
The drawing calculations cause division by zero and produce NaNs
to transforms (due to fTextInverseRatio).

Reproed by top25desk_twitter.skp as well as the added testcase.
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1760163002

Review URL: https://codereview.chromium.org/1760163002
This commit is contained in:
kkinnunen 2016-03-04 00:12:33 -08:00 committed by Commit bot
parent 56fb57a051
commit 68c63b3727
4 changed files with 55 additions and 10 deletions

View File

@ -73,6 +73,13 @@ protected:
sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, yOffset);
// Zero size.
paint.measureText(text, strlen(text), &bounds);
yOffset += bounds.height();
paint.setTextSize(0);
sk_tool_utils::add_to_text_blob(&builder, text, paint, 0, yOffset);
// build
fBlob.reset(builder.build());
}

View File

@ -79,6 +79,14 @@ inline GrGLenum cap_to_gl_cap(SkPaint::Cap cap) {
GR_STATIC_ASSERT(SK_ARRAY_COUNT(gSkCapsToGrGLCaps) == SkPaint::kCapCount);
}
#ifdef SK_DEBUG
inline void verify_floats(const float* floats, int count) {
for (int i = 0; i < count; ++i) {
SkASSERT(!SkScalarIsNaN(SkFloatToScalar(floats[i])));
}
}
#endif
inline void points_to_coords(const SkPoint points[], size_t first_point, size_t amount,
GrGLfloat coords[]) {
for (size_t i = 0; i < amount; ++i) {
@ -170,6 +178,7 @@ inline bool init_path_object_for_general_path(GrGLGpu* gpu, GrGLuint pathID,
continue;
}
SkDEBUGCODE(numCoords += num_coords(verb));
SkDEBUGCODE(verify_floats(coords, coordsForVerb));
pathCoords.push_back_n(coordsForVerb, coords);
}
SkASSERT(verbCnt == pathCommands.count());
@ -232,6 +241,7 @@ void GrGLPath::InitPathObjectPathData(GrGLGpu* gpu,
}
SkASSERT(verbCnt == pathCommands.count());
SkASSERT(verbCoordCnt == pathCoords.count());
SkDEBUGCODE(verify_floats(&pathCoords[0], pathCoords.count()));
GR_GL_CALL(gpu->glInterface(), PathCommands(pathID, pathCommands.count(), &pathCommands[0],
pathCoords.count(), GR_GL_FLOAT,
&pathCoords[0]));

View File

@ -49,6 +49,22 @@ GR_STATIC_ASSERT(3 == GrPathRendering::kTranslate_PathTransformType);
GR_STATIC_ASSERT(4 == GrPathRendering::kAffine_PathTransformType);
GR_STATIC_ASSERT(GrPathRendering::kAffine_PathTransformType == GrPathRendering::kLast_PathTransformType);
#ifdef SK_DEBUG
static const GrGLenum gXformType2ComponentCount[] = {
0,
1,
1,
2,
6
};
static void verify_floats(const float* floats, int count) {
for (int i = 0; i < count; ++i) {
SkASSERT(!SkScalarIsNaN(SkFloatToScalar(floats[i])));
}
}
#endif
static GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) {
switch (op) {
default:
@ -155,6 +171,8 @@ void GrGLPathRendering::onDrawPaths(const DrawPathArgs& args, const GrPathRange*
const void* indices, PathIndexType indexType,
const float transformValues[], PathTransformType transformType,
int count) {
SkDEBUGCODE(verify_floats(transformValues, gXformType2ComponentCount[transformType] * count));
if (!this->gpu()->flushGLState(args)) {
return;
}
@ -210,6 +228,7 @@ void GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, G
coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]);
coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]);
}
SkDEBUGCODE(verify_floats(coefficients, components * 3));
GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components, coefficients));
}
@ -232,6 +251,7 @@ void GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix,
float glMatrix[4 * 4];
fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix);
SkDEBUGCODE(verify_floats(glMatrix, SK_ARRAY_COUNT(glMatrix)));
GL_CALL(MatrixLoadf(GR_GL_PATH_PROJECTION, glMatrix));
}

View File

@ -80,11 +80,13 @@ void GrStencilAndCoverTextContext::drawText(GrContext* context, GrDrawContext* d
if (context->abandoned()) {
return;
} else if (this->canDraw(skPaint, viewMatrix)) {
TextRun run(skPaint);
GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip);
run.setText(text, byteLength, x, y);
run.draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, props, 0, 0,
clipBounds, fFallbackTextContext, skPaint);
if (skPaint.getTextSize() > 0) {
TextRun run(skPaint);
GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip);
run.setText(text, byteLength, x, y);
run.draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, props, 0, 0,
clipBounds, fFallbackTextContext, skPaint);
}
return;
} else if (fFallbackTextContext->canDraw(skPaint, viewMatrix, props,
*context->caps()->shaderCaps())) {
@ -113,11 +115,13 @@ void GrStencilAndCoverTextContext::drawPosText(GrContext* context, GrDrawContext
if (context->abandoned()) {
return;
} else if (this->canDraw(skPaint, viewMatrix)) {
TextRun run(skPaint);
GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip);
run.setPosText(text, byteLength, pos, scalarsPerPosition, offset);
run.draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, props, 0, 0,
clipBounds, fFallbackTextContext, skPaint);
if (skPaint.getTextSize() > 0) {
TextRun run(skPaint);
GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip);
run.setPosText(text, byteLength, pos, scalarsPerPosition, offset);
run.draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, props, 0, 0,
clipBounds, fFallbackTextContext, skPaint);
}
return;
} else if (fFallbackTextContext->canDraw(skPaint, viewMatrix, props,
*context->caps()->shaderCaps())) {
@ -294,6 +298,9 @@ void GrStencilAndCoverTextContext::TextBlob::init(const SkTextBlob* skBlob,
SkPaint runPaint(skPaint);
for (SkTextBlobRunIterator iter(skBlob); !iter.done(); iter.next()) {
iter.applyFontToPaint(&runPaint); // No need to re-seed the paint.
if (runPaint.getTextSize() <= 0) {
continue;
}
TextRun* run = this->addToTail(runPaint);
const char* text = reinterpret_cast<const char*>(iter.glyphs());
@ -352,6 +359,7 @@ GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke)
fFallbackGlyphCount(0),
fDetachedGlyphCache(nullptr),
fLastDrawnGlyphsID(SK_InvalidUniqueID) {
SkASSERT(fFont.getTextSize() > 0);
SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported.
// Setting to "fill" ensures that no strokes get baked into font outlines. (We use the GPU path