Chromium Code Reviews| Index: core/fxge/skia/fx_skia_device.cpp |
| diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp |
| index acebf35eb877772294544f726fa559640727762f..a06eac80b4821a309c6fed4b413af382046b9b9f 100644 |
| --- a/core/fxge/skia/fx_skia_device.cpp |
| +++ b/core/fxge/skia/fx_skia_device.cpp |
| @@ -32,6 +32,16 @@ static void DebugShowSkiaPath(const SkPath& path) { |
| #endif // SHOW_SKIA_PATH |
| } |
| +static void DebugShowCanvasMatrix(const SkCanvas* canvas) { |
| +#if SHOW_SKIA_PATH |
| + SkMatrix matrix = canvas->getTotalMatrix(); |
| + SkScalar m[9]; |
| + matrix.get9(m); |
| + printf("(%g,%g,%g) (%g,%g,%g) (%g,%g,%g)\n", m[0], m[1], m[2], m[3], m[4], m[5], m[6], |
|
Tom Sepez
2016/03/17 16:05:50
nit: 80 cols.
caryclark
2016/03/18 18:22:12
Done.
|
| + m[7], m[8]); |
| +#endif // SHOW_SKIA_PATH |
| +} |
| + |
| #if DRAW_SKIA_CLIP |
| static SkPaint DebugClipPaint() { |
| @@ -62,8 +72,7 @@ static void DebugDrawSkiaClipPath(SkCanvas* canvas, const SkPath& path) {} |
| #undef SHOW_SKIA_PATH |
| #undef DRAW_SKIA_CLIP |
| -static SkPath BuildPath(const CFX_PathData* pPathData, |
| - const CFX_Matrix* pObject2Device) { |
| +static SkPath BuildPath(const CFX_PathData* pPathData) { |
| SkPath skPath; |
| const CFX_PathData* pFPath = pPathData; |
| int nPoints = pFPath->GetPointCount(); |
| @@ -71,8 +80,6 @@ static SkPath BuildPath(const CFX_PathData* pPathData, |
| for (int i = 0; i < nPoints; i++) { |
| FX_FLOAT x = pPoints[i].m_PointX; |
| FX_FLOAT y = pPoints[i].m_PointY; |
| - if (pObject2Device) |
| - pObject2Device->Transform(x, y); |
| int point_type = pPoints[i].m_Flag & FXPT_TYPE; |
| if (point_type == FXPT_MOVETO) { |
| skPath.moveTo(x, y); |
| @@ -81,10 +88,6 @@ static SkPath BuildPath(const CFX_PathData* pPathData, |
| } else if (point_type == FXPT_BEZIERTO) { |
| FX_FLOAT x2 = pPoints[i + 1].m_PointX, y2 = pPoints[i + 1].m_PointY; |
| FX_FLOAT x3 = pPoints[i + 2].m_PointX, y3 = pPoints[i + 2].m_PointY; |
| - if (pObject2Device) { |
| - pObject2Device->Transform(x2, y2); |
| - pObject2Device->Transform(x3, y3); |
| - } |
| skPath.cubicTo(x, y, x2, y2, x3, y3); |
| i += 2; |
| } |
| @@ -96,7 +99,8 @@ static SkPath BuildPath(const CFX_PathData* pPathData, |
| // convert a stroking path to scanlines |
| void CFX_SkiaDeviceDriver::PaintStroke(SkPaint* spaint, |
| - const CFX_GraphStateData* pGraphState) { |
| + const CFX_GraphStateData* pGraphState, |
| + const SkMatrix& matrix) { |
| SkPaint::Cap cap; |
| switch (pGraphState->m_LineCap) { |
| case CFX_GraphStateData::LineCapRound: |
| @@ -121,8 +125,15 @@ void CFX_SkiaDeviceDriver::PaintStroke(SkPaint* spaint, |
| join = SkPaint::kMiter_Join; |
| break; |
| } |
| - FX_FLOAT width = pGraphState->m_LineWidth; |
| - |
| + SkMatrix inverse; |
| + if (!matrix.invert(&inverse)) |
| + return; // give up if the matrix is degenerate, and not invertable |
| + inverse.set(SkMatrix::kMTransX, 0); |
| + inverse.set(SkMatrix::kMTransY, 0); |
| + SkVector deviceUnits[2] = {{0, 1}, {1, 0}}; |
| + inverse.mapPoints(deviceUnits, SK_ARRAY_COUNT(deviceUnits)); |
| + FX_FLOAT width = SkTMax(pGraphState->m_LineWidth, |
| + SkTMin(deviceUnits[0].length(), deviceUnits[1].length())); |
|
Tom Sepez
2016/03/17 16:05:50
nit: ditto. git cl format should have fixed these
caryclark
2016/03/18 18:22:12
Done.
|
| if (pGraphState->m_DashArray) { |
| int count = (pGraphState->m_DashCount + 1) / 2; |
| SkScalar* intervals = FX_Alloc2D(SkScalar, count, sizeof(SkScalar)); |
| @@ -192,6 +203,19 @@ CFX_SkiaDeviceDriver::~CFX_SkiaDeviceDriver() { |
| delete m_pAggDriver; |
| } |
| +static SkMatrix ToSkMatrix(const CFX_Matrix& m) { |
|
Tom Sepez
2016/03/17 16:05:50
nit: an we put these up top in the file with the
caryclark
2016/03/18 18:22:12
Done.
|
| + SkMatrix skMatrix; |
| + skMatrix.setAll(m.a, m.b, m.e, m.c, m.d, m.f, 0, 0, 1); |
|
Tom Sepez
2016/03/17 16:05:50
nit: Pity SkMatrix doesn't have a constructor of t
caryclark
2016/03/18 18:22:12
Would you like a bug filed to request this feature
|
| + return skMatrix; |
| +} |
| + |
| +// use when pdf's y-axis points up insead of down |
| +static SkMatrix ToFlippedSkMatrix(const CFX_Matrix& m) { |
| + SkMatrix skMatrix; |
| + skMatrix.setAll(m.a, m.b, m.e, -m.c, -m.d, m.f, 0, 0, 1); |
| + return skMatrix; |
| +} |
| + |
| FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars, |
| const FXTEXT_CHARPOS* pCharPos, |
| CFX_Font* pFont, |
| @@ -210,10 +234,7 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars, |
| paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| paint.setTextSize(font_size); |
| m_pCanvas->save(); |
| - SkMatrix skMatrix; |
| - const CFX_Matrix& m = *pObject2Device; |
| - // note that PDF's y-axis goes up; Skia's y-axis goes down |
| - skMatrix.setAll(m.a, m.b, m.e, -m.c, -m.d, m.f, 0, 0, 1); |
| + SkMatrix skMatrix = ToFlippedSkMatrix(*pObject2Device); |
| m_pCanvas->concat(skMatrix); |
| for (int index = 0; index < nChars; ++index) { |
| const FXTEXT_CHARPOS& cp = pCharPos[index]; |
| @@ -248,24 +269,14 @@ int CFX_SkiaDeviceDriver::GetDeviceCaps(int caps_id) { |
| void CFX_SkiaDeviceDriver::SaveState() { |
| m_pCanvas->save(); |
| - if (m_pAggDriver) |
| - m_pAggDriver->SaveState(); |
| } |
| void CFX_SkiaDeviceDriver::RestoreState(FX_BOOL bKeepSaved) { |
| - if (m_pAggDriver) |
| - m_pAggDriver->RestoreState(bKeepSaved); |
| m_pCanvas->restore(); |
| if (bKeepSaved) |
| m_pCanvas->save(); |
| } |
| -void CFX_SkiaDeviceDriver::SetClipMask( |
| - agg::rasterizer_scanline_aa& rasterizer) { |
| - if (m_pAggDriver) |
| - m_pAggDriver->SetClipMask(rasterizer); |
| -} |
| - |
| FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathFill( |
| const CFX_PathData* pPathData, // path info |
| const CFX_Matrix* pObject2Device, // flips object's y-axis |
| @@ -285,10 +296,12 @@ FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathFill( |
| return TRUE; |
| } |
| } |
| - SkPath skClipPath = BuildPath(pPathData, pObject2Device); |
| + SkPath skClipPath = BuildPath(pPathData); |
| skClipPath.setFillType((fill_mode & 3) == FXFILL_WINDING |
| ? SkPath::kWinding_FillType |
| : SkPath::kEvenOdd_FillType); |
| + SkMatrix skMatrix = ToSkMatrix(*pObject2Device); |
|
Tom Sepez
2016/03/17 16:05:50
nit: local not needed.
caryclark
2016/03/18 18:22:12
While that's strictly true, it is easier to debug
|
| + skClipPath.transform(skMatrix); |
| DebugShowSkiaPath(skClipPath); |
| DebugDrawSkiaClipPath(m_pCanvas, skClipPath); |
| m_pCanvas->clipPath(skClipPath); |
| @@ -302,31 +315,20 @@ FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathStroke( |
| const CFX_GraphStateData* pGraphState // graphic state, for pen attributes |
| ) { |
| // build path data |
| - SkPath skPath = BuildPath(pPathData, NULL); |
| + SkPath skPath = BuildPath(pPathData); |
| skPath.setFillType(SkPath::kWinding_FillType); |
| + SkMatrix skMatrix = ToSkMatrix(*pObject2Device); |
| SkPaint spaint; |
| - PaintStroke(&spaint, pGraphState); |
| + PaintStroke(&spaint, pGraphState, skMatrix); |
| SkPath dst_path; |
| spaint.getFillPath(skPath, &dst_path); |
| + dst_path.transform(skMatrix); |
| DebugDrawSkiaClipPath(m_pCanvas, dst_path); |
| m_pCanvas->clipPath(dst_path); |
| return TRUE; |
| } |
| -FX_BOOL CFX_SkiaDeviceDriver::RenderRasterizer( |
| - agg::rasterizer_scanline_aa& rasterizer, |
| - FX_DWORD color, |
| - FX_BOOL bFullCover, |
| - FX_BOOL bGroupKnockout, |
| - int alpha_flag, |
| - void* pIccTransform) { |
| - return m_pAggDriver && |
| - m_pAggDriver->RenderRasterizer(rasterizer, color, bFullCover, |
| - bGroupKnockout, alpha_flag, |
| - pIccTransform); |
| -} |
| - |
| FX_BOOL CFX_SkiaDeviceDriver::DrawPath( |
| const CFX_PathData* pPathData, // path info |
| const CFX_Matrix* pObject2Device, // optional transformation |
| @@ -340,9 +342,12 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawPath( |
| SkIRect rect; |
| rect.set(0, 0, GetDeviceCaps(FXDC_PIXEL_WIDTH), |
| GetDeviceCaps(FXDC_PIXEL_HEIGHT)); |
| - SkPath skPath = BuildPath(pPathData, pObject2Device); |
| + SkPath skPath = BuildPath(pPathData); |
| SkPaint spaint; |
| spaint.setAntiAlias(true); |
| + m_pCanvas->save(); |
| + SkMatrix skMatrix = ToSkMatrix(*pObject2Device); |
| + m_pCanvas->concat(skMatrix); |
| if ((fill_mode & 3) && fill_color) { |
| skPath.setFillType((fill_mode & 3) == FXFILL_WINDING |
| ? SkPath::kWinding_FillType |
| @@ -358,22 +363,15 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawPath( |
| if (pGraphState && stroke_alpha) { |
| spaint.setColor(stroke_color); |
| - PaintStroke(&spaint, pGraphState); |
| + PaintStroke(&spaint, pGraphState, skMatrix); |
| + DebugShowSkiaPath(skPath); |
| + DebugShowCanvasMatrix(m_pCanvas); |
| m_pCanvas->drawPath(skPath, spaint); |
| } |
| - |
| + m_pCanvas->restore(); |
| return TRUE; |
| } |
| -FX_BOOL CFX_SkiaDeviceDriver::SetPixel(int x, |
| - int y, |
| - FX_DWORD color, |
| - int alpha_flag, |
| - void* pIccTransform) { |
| - return m_pAggDriver && |
| - m_pAggDriver->SetPixel(x, y, color, alpha_flag, pIccTransform); |
| -} |
| - |
| FX_BOOL CFX_SkiaDeviceDriver::FillRect(const FX_RECT* pRect, |
| FX_DWORD fill_color, |
| int alpha_flag, |
| @@ -514,7 +512,7 @@ FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, |
| m_pCanvas->concat(skMatrix); |
| SkPaint paint; |
| paint.setAntiAlias(true); |
| - paint.setFilterQuality(kLow_SkFilterQuality); |
| + paint.setFilterQuality(kHigh_SkFilterQuality); |
| m_pCanvas->drawBitmap(skBitmap, 0, 0, &paint); |
| m_pCanvas->restore(); |
| return TRUE; |