65 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright 2022 Google LLC
 | |
|  *
 | |
|  * Use of this source code is governed by a BSD-style license that can be
 | |
|  * found in the LICENSE file.
 | |
|  */
 | |
| 
 | |
| #include "gm/gm.h"
 | |
| #include "include/core/SkCanvas.h"
 | |
| #include "include/core/SkPath.h"
 | |
| 
 | |
| static SkPath get_path() {
 | |
|     SkPath path;
 | |
|     path.setFillType(SkPathFillType::kWinding);
 | |
|     path.moveTo(SkBits2Float(0x45034ec4), SkBits2Float(0x42e7fb80));  // 2100.92f, 115.991f
 | |
|     path.quadTo(SkBits2Float(0x4500f46c),
 | |
|                 SkBits2Float(0x43333300),
 | |
|                 SkBits2Float(0x4500f46c),
 | |
|                 SkBits2Float(0x431f0ec0));  // 2063.28f, 179.199f, 2063.28f, 159.058f
 | |
|     path.quadTo(SkBits2Float(0x4500f46c),
 | |
|                 SkBits2Float(0x430ad7c0),
 | |
|                 SkBits2Float(0x45019462),
 | |
|                 SkBits2Float(0x42fed580));  // 2063.28f, 138.843f, 2073.27f, 127.417f
 | |
|     path.quadTo(SkBits2Float(0x45023458),
 | |
|                 SkBits2Float(0x42e7fb80),
 | |
|                 SkBits2Float(0x45034ec4),
 | |
|                 SkBits2Float(0x42e7fb80));  // 2083.27f, 115.991f, 2100.92f, 115.991f
 | |
|     path.close();
 | |
|     return path;
 | |
| }
 | |
| 
 | |
| // Reproduces the underlying problem from skbug.com/12866.
 | |
| // The path (part of a glyph) was being drawn stroked, and with a perspective matrix.
 | |
| // The perspective matrix forces a very large resScale when stroking the path.
 | |
| // The resulting filled path is incorrect. Note that stroking with a smaller resScale works fine.
 | |
| DEF_SIMPLE_GM(bug12866, canvas, 128, 64) {
 | |
|     SkPaint strokePaint;
 | |
|     strokePaint.setAntiAlias(true);
 | |
|     strokePaint.setStyle(SkPaint::kStroke_Style);
 | |
|     strokePaint.setStrokeWidth(3);
 | |
| 
 | |
|     SkPaint fillPaint;
 | |
|     fillPaint.setAntiAlias(true);
 | |
| 
 | |
|     SkPath strokePath = get_path();
 | |
|     SkPath fillPath;
 | |
|     strokePaint.getFillPath(strokePath, &fillPath, nullptr, 1200.0f);
 | |
| 
 | |
|     SkRect strokeBounds = strokePath.getBounds();
 | |
|     SkRect fillBounds = fillPath.getBounds();
 | |
| 
 | |
|     // Draw the stroked path. This (internally) uses a resScale of 1.0, and looks good.
 | |
|     canvas->save();
 | |
|     canvas->translate(10 - strokeBounds.fLeft, 10 - strokeBounds.fTop);
 | |
|     canvas->drawPath(strokePath, strokePaint);
 | |
|     canvas->restore();
 | |
| 
 | |
|     // With a perspective CTM, it's possible for resScale to become large. Draw the filled
 | |
|     // path produced by the stroker in that situation, which ends up being incorrect.
 | |
|     canvas->save();
 | |
|     canvas->translate(74 - fillBounds.fLeft, 10 - fillBounds.fTop);
 | |
|     canvas->drawPath(fillPath, fillPaint);
 | |
|     canvas->restore();
 | |
| }
 |