OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrOvalRenderer.h" | 8 #include "GrOvalRenderer.h" |
9 | 9 |
10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
(...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 if (hasStroke) { | 1039 if (hasStroke) { |
1040 if (SkScalarNearlyZero(scaledStroke.length())) { | 1040 if (SkScalarNearlyZero(scaledStroke.length())) { |
1041 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); | 1041 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); |
1042 } else { | 1042 } else { |
1043 scaledStroke.scale(SK_ScalarHalf); | 1043 scaledStroke.scale(SK_ScalarHalf); |
1044 } | 1044 } |
1045 | 1045 |
1046 // we only handle thick strokes for near-circular ellipses | 1046 // we only handle thick strokes for near-circular ellipses |
1047 if (scaledStroke.length() > SK_ScalarHalf && | 1047 if (scaledStroke.length() > SK_ScalarHalf && |
1048 (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)
) { | 1048 (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)
) { |
1049 return NULL; | 1049 return nullptr; |
1050 } | 1050 } |
1051 | 1051 |
1052 // we don't handle it if curvature of the stroke is less than curvature
of the ellipse | 1052 // we don't handle it if curvature of the stroke is less than curvature
of the ellipse |
1053 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY
)*xRadius || | 1053 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY
)*xRadius || |
1054 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX
)*yRadius) { | 1054 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX
)*yRadius) { |
1055 return NULL; | 1055 return nullptr; |
1056 } | 1056 } |
1057 | 1057 |
1058 // this is legit only if scale & translation (which should be the case a
t the moment) | 1058 // this is legit only if scale & translation (which should be the case a
t the moment) |
1059 if (isStrokeOnly) { | 1059 if (isStrokeOnly) { |
1060 innerXRadius = xRadius - scaledStroke.fX; | 1060 innerXRadius = xRadius - scaledStroke.fX; |
1061 innerYRadius = yRadius - scaledStroke.fY; | 1061 innerYRadius = yRadius - scaledStroke.fY; |
1062 } | 1062 } |
1063 | 1063 |
1064 xRadius += scaledStroke.fX; | 1064 xRadius += scaledStroke.fX; |
1065 yRadius += scaledStroke.fY; | 1065 yRadius += scaledStroke.fY; |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 | 1279 |
1280 if (SkScalarNearlyZero(strokeWidth)) { | 1280 if (SkScalarNearlyZero(strokeWidth)) { |
1281 strokeWidth = SK_ScalarHalf; | 1281 strokeWidth = SK_ScalarHalf; |
1282 } else { | 1282 } else { |
1283 strokeWidth *= SK_ScalarHalf; | 1283 strokeWidth *= SK_ScalarHalf; |
1284 } | 1284 } |
1285 | 1285 |
1286 // we only handle thick strokes for near-circular ellipses | 1286 // we only handle thick strokes for near-circular ellipses |
1287 if (strokeWidth > SK_ScalarHalf && | 1287 if (strokeWidth > SK_ScalarHalf && |
1288 (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)
) { | 1288 (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)
) { |
1289 return NULL; | 1289 return nullptr; |
1290 } | 1290 } |
1291 | 1291 |
1292 // we don't handle it if curvature of the stroke is less than curvature
of the ellipse | 1292 // we don't handle it if curvature of the stroke is less than curvature
of the ellipse |
1293 if (strokeWidth*(yRadius*yRadius) < (strokeWidth*strokeWidth)*xRadius || | 1293 if (strokeWidth*(yRadius*yRadius) < (strokeWidth*strokeWidth)*xRadius || |
1294 strokeWidth*(xRadius*xRadius) < (strokeWidth*strokeWidth)*yRadius) { | 1294 strokeWidth*(xRadius*xRadius) < (strokeWidth*strokeWidth)*yRadius) { |
1295 return NULL; | 1295 return nullptr; |
1296 } | 1296 } |
1297 | 1297 |
1298 // set inner radius (if needed) | 1298 // set inner radius (if needed) |
1299 if (SkStrokeRec::kStroke_Style == style) { | 1299 if (SkStrokeRec::kStroke_Style == style) { |
1300 innerXRadius = xRadius - strokeWidth; | 1300 innerXRadius = xRadius - strokeWidth; |
1301 innerYRadius = yRadius - strokeWidth; | 1301 innerYRadius = yRadius - strokeWidth; |
1302 } | 1302 } |
1303 | 1303 |
1304 xRadius += strokeWidth; | 1304 xRadius += strokeWidth; |
1305 yRadius += strokeWidth; | 1305 yRadius += strokeWidth; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1408 if (!viewMatrix.isIdentity()) { | 1408 if (!viewMatrix.isIdentity()) { |
1409 if (!origInner.transform(viewMatrix, inner.writable())) { | 1409 if (!origInner.transform(viewMatrix, inner.writable())) { |
1410 return false; | 1410 return false; |
1411 } | 1411 } |
1412 } | 1412 } |
1413 GrPrimitiveEdgeType edgeType = applyAA ? | 1413 GrPrimitiveEdgeType edgeType = applyAA ? |
1414 kInverseFillAA_GrProcessorEdgeType : | 1414 kInverseFillAA_GrProcessorEdgeType : |
1415 kInverseFillBW_GrProcessorEdgeType; | 1415 kInverseFillBW_GrProcessorEdgeType; |
1416 // TODO this needs to be a geometry processor | 1416 // TODO this needs to be a geometry processor |
1417 GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); | 1417 GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); |
1418 if (NULL == fp) { | 1418 if (nullptr == fp) { |
1419 return false; | 1419 return false; |
1420 } | 1420 } |
1421 arfps.set(&pipelineBuilder); | 1421 arfps.set(&pipelineBuilder); |
1422 arfps.addCoverageFragmentProcessor(fp)->unref(); | 1422 arfps.addCoverageFragmentProcessor(fp)->unref(); |
1423 } | 1423 } |
1424 | 1424 |
1425 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); | 1425 SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); |
1426 if (DrawRRect(target, pipelineBuilder, color, viewMatrix, useAA, origOuter,
fillRec)) { | 1426 if (DrawRRect(target, pipelineBuilder, color, viewMatrix, useAA, origOuter,
fillRec)) { |
1427 return true; | 1427 return true; |
1428 } | 1428 } |
1429 | 1429 |
1430 SkASSERT(!origOuter.isEmpty()); | 1430 SkASSERT(!origOuter.isEmpty()); |
1431 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); | 1431 SkTCopyOnFirstWrite<SkRRect> outer(origOuter); |
1432 if (!viewMatrix.isIdentity()) { | 1432 if (!viewMatrix.isIdentity()) { |
1433 if (!origOuter.transform(viewMatrix, outer.writable())) { | 1433 if (!origOuter.transform(viewMatrix, outer.writable())) { |
1434 return false; | 1434 return false; |
1435 } | 1435 } |
1436 } | 1436 } |
1437 GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : | 1437 GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : |
1438 kFillBW_GrProcessorEdgeType; | 1438 kFillBW_GrProcessorEdgeType; |
1439 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); | 1439 GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); |
1440 if (NULL == effect) { | 1440 if (nullptr == effect) { |
1441 return false; | 1441 return false; |
1442 } | 1442 } |
1443 if (!arfps.isSet()) { | 1443 if (!arfps.isSet()) { |
1444 arfps.set(&pipelineBuilder); | 1444 arfps.set(&pipelineBuilder); |
1445 } | 1445 } |
1446 | 1446 |
1447 SkMatrix invert; | 1447 SkMatrix invert; |
1448 if (!viewMatrix.invert(&invert)) { | 1448 if (!viewMatrix.invert(&invert)) { |
1449 return false; | 1449 return false; |
1450 } | 1450 } |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1856 scaledStroke.set(1, 1); | 1856 scaledStroke.set(1, 1); |
1857 } else { | 1857 } else { |
1858 scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSc
aleX] + | 1858 scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSc
aleX] + |
1859 viewMatrix[SkMatrix::kMSk
ewY])); | 1859 viewMatrix[SkMatrix::kMSk
ewY])); |
1860 scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSk
ewX] + | 1860 scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSk
ewX] + |
1861 viewMatrix[SkMatrix::kMSc
aleY])); | 1861 viewMatrix[SkMatrix::kMSc
aleY])); |
1862 } | 1862 } |
1863 | 1863 |
1864 // if half of strokewidth is greater than radius, we don't handle that r
ight now | 1864 // if half of strokewidth is greater than radius, we don't handle that r
ight now |
1865 if (SK_ScalarHalf*scaledStroke.fX > xRadius || SK_ScalarHalf*scaledStrok
e.fY > yRadius) { | 1865 if (SK_ScalarHalf*scaledStroke.fX > xRadius || SK_ScalarHalf*scaledStrok
e.fY > yRadius) { |
1866 return NULL; | 1866 return nullptr; |
1867 } | 1867 } |
1868 } | 1868 } |
1869 | 1869 |
1870 // The way the effect interpolates the offset-to-ellipse/circle-center attri
bute only works on | 1870 // The way the effect interpolates the offset-to-ellipse/circle-center attri
bute only works on |
1871 // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner r
ect of the nine- | 1871 // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner r
ect of the nine- |
1872 // patch will have fractional coverage. This only matters when the interior
is actually filled. | 1872 // patch will have fractional coverage. This only matters when the interior
is actually filled. |
1873 // We could consider falling back to rect rendering here, since a tiny radiu
s is | 1873 // We could consider falling back to rect rendering here, since a tiny radiu
s is |
1874 // indistinguishable from a square corner. | 1874 // indistinguishable from a square corner. |
1875 if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) { | 1875 if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) { |
1876 return NULL; | 1876 return nullptr; |
1877 } | 1877 } |
1878 | 1878 |
1879 // if the corners are circles, use the circle renderer | 1879 // if the corners are circles, use the circle renderer |
1880 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius
) { | 1880 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius
) { |
1881 SkScalar innerRadius = 0.0f; | 1881 SkScalar innerRadius = 0.0f; |
1882 SkScalar outerRadius = xRadius; | 1882 SkScalar outerRadius = xRadius; |
1883 SkScalar halfWidth = 0; | 1883 SkScalar halfWidth = 0; |
1884 if (hasStroke) { | 1884 if (hasStroke) { |
1885 if (SkScalarNearlyZero(scaledStroke.fX)) { | 1885 if (SkScalarNearlyZero(scaledStroke.fX)) { |
1886 halfWidth = SK_ScalarHalf; | 1886 halfWidth = SK_ScalarHalf; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1924 if (hasStroke) { | 1924 if (hasStroke) { |
1925 if (SkScalarNearlyZero(scaledStroke.length())) { | 1925 if (SkScalarNearlyZero(scaledStroke.length())) { |
1926 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); | 1926 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); |
1927 } else { | 1927 } else { |
1928 scaledStroke.scale(SK_ScalarHalf); | 1928 scaledStroke.scale(SK_ScalarHalf); |
1929 } | 1929 } |
1930 | 1930 |
1931 // we only handle thick strokes for near-circular ellipses | 1931 // we only handle thick strokes for near-circular ellipses |
1932 if (scaledStroke.length() > SK_ScalarHalf && | 1932 if (scaledStroke.length() > SK_ScalarHalf && |
1933 (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRad
ius)) { | 1933 (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRad
ius)) { |
1934 return NULL; | 1934 return nullptr; |
1935 } | 1935 } |
1936 | 1936 |
1937 // we don't handle it if curvature of the stroke is less than curvat
ure of the ellipse | 1937 // we don't handle it if curvature of the stroke is less than curvat
ure of the ellipse |
1938 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStrok
e.fY)*xRadius || | 1938 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStrok
e.fY)*xRadius || |
1939 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStrok
e.fX)*yRadius) { | 1939 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStrok
e.fX)*yRadius) { |
1940 return NULL; | 1940 return nullptr; |
1941 } | 1941 } |
1942 | 1942 |
1943 // this is legit only if scale & translation (which should be the ca
se at the moment) | 1943 // this is legit only if scale & translation (which should be the ca
se at the moment) |
1944 if (isStrokeOnly) { | 1944 if (isStrokeOnly) { |
1945 innerXRadius = xRadius - scaledStroke.fX; | 1945 innerXRadius = xRadius - scaledStroke.fX; |
1946 innerYRadius = yRadius - scaledStroke.fY; | 1946 innerYRadius = yRadius - scaledStroke.fY; |
1947 } | 1947 } |
1948 | 1948 |
1949 xRadius += scaledStroke.fX; | 1949 xRadius += scaledStroke.fX; |
1950 yRadius += scaledStroke.fY; | 1950 yRadius += scaledStroke.fY; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2033 } | 2033 } |
2034 | 2034 |
2035 DRAW_BATCH_TEST_DEFINE(RRectBatch) { | 2035 DRAW_BATCH_TEST_DEFINE(RRectBatch) { |
2036 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); | 2036 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); |
2037 GrColor color = GrRandomColor(random); | 2037 GrColor color = GrRandomColor(random); |
2038 const SkRRect& rrect = GrTest::TestRRectSimple(random); | 2038 const SkRRect& rrect = GrTest::TestRRectSimple(random); |
2039 return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(ra
ndom)); | 2039 return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(ra
ndom)); |
2040 } | 2040 } |
2041 | 2041 |
2042 #endif | 2042 #endif |
OLD | NEW |