OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 "SkDraw.h" | 8 #include "SkDraw.h" |
9 #include "SkBlitter.h" | 9 #include "SkBlitter.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 1848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1859 } | 1859 } |
1860 } | 1860 } |
1861 } | 1861 } |
1862 | 1862 |
1863 #if defined _WIN32 && _MSC_VER >= 1300 | 1863 #if defined _WIN32 && _MSC_VER >= 1300 |
1864 #pragma warning ( pop ) | 1864 #pragma warning ( pop ) |
1865 #endif | 1865 #endif |
1866 | 1866 |
1867 /////////////////////////////////////////////////////////////////////////////// | 1867 /////////////////////////////////////////////////////////////////////////////// |
1868 | 1868 |
1869 #include "SkPathMeasure.h" | |
1870 | |
1871 static void morphpoints(SkPoint dst[], const SkPoint src[], int count, | |
1872 SkPathMeasure& meas, const SkMatrix& matrix) { | |
1873 SkMatrix::MapXYProc proc = matrix.getMapXYProc(); | |
1874 | |
1875 for (int i = 0; i < count; i++) { | |
1876 SkPoint pos; | |
1877 SkVector tangent; | |
1878 | |
1879 proc(matrix, src[i].fX, src[i].fY, &pos); | |
1880 SkScalar sx = pos.fX; | |
1881 SkScalar sy = pos.fY; | |
1882 | |
1883 if (!meas.getPosTan(sx, &pos, &tangent)) { | |
1884 // set to 0 if the measure failed, so that we just set dst == pos | |
1885 tangent.set(0, 0); | |
1886 } | |
1887 | |
1888 /* This is the old way (that explains our approach but is way too slow | |
1889 SkMatrix matrix; | |
1890 SkPoint pt; | |
1891 | |
1892 pt.set(sx, sy); | |
1893 matrix.setSinCos(tangent.fY, tangent.fX); | |
1894 matrix.preTranslate(-sx, 0); | |
1895 matrix.postTranslate(pos.fX, pos.fY); | |
1896 matrix.mapPoints(&dst[i], &pt, 1); | |
1897 */ | |
1898 dst[i].set(pos.fX - SkScalarMul(tangent.fY, sy), | |
1899 pos.fY + SkScalarMul(tangent.fX, sy)); | |
1900 } | |
1901 } | |
1902 | |
1903 /* TODO | |
1904 | |
1905 Need differentially more subdivisions when the follow-path is curvy. Not sur
e how to | |
1906 determine that, but we need it. I guess a cheap answer is let the caller tel
l us, | |
1907 but that seems like a cop-out. Another answer is to get Rob Johnson to figur
e it out. | |
1908 */ | |
1909 static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas, | |
1910 const SkMatrix& matrix) { | |
1911 SkPath::Iter iter(src, false); | |
1912 SkPoint srcP[4], dstP[3]; | |
1913 SkPath::Verb verb; | |
1914 | |
1915 while ((verb = iter.next(srcP)) != SkPath::kDone_Verb) { | |
1916 switch (verb) { | |
1917 case SkPath::kMove_Verb: | |
1918 morphpoints(dstP, srcP, 1, meas, matrix); | |
1919 dst->moveTo(dstP[0]); | |
1920 break; | |
1921 case SkPath::kLine_Verb: | |
1922 // turn lines into quads to look bendy | |
1923 srcP[0].fX = SkScalarAve(srcP[0].fX, srcP[1].fX); | |
1924 srcP[0].fY = SkScalarAve(srcP[0].fY, srcP[1].fY); | |
1925 morphpoints(dstP, srcP, 2, meas, matrix); | |
1926 dst->quadTo(dstP[0], dstP[1]); | |
1927 break; | |
1928 case SkPath::kQuad_Verb: | |
1929 morphpoints(dstP, &srcP[1], 2, meas, matrix); | |
1930 dst->quadTo(dstP[0], dstP[1]); | |
1931 break; | |
1932 case SkPath::kCubic_Verb: | |
1933 morphpoints(dstP, &srcP[1], 3, meas, matrix); | |
1934 dst->cubicTo(dstP[0], dstP[1], dstP[2]); | |
1935 break; | |
1936 case SkPath::kClose_Verb: | |
1937 dst->close(); | |
1938 break; | |
1939 default: | |
1940 SkDEBUGFAIL("unknown verb"); | |
1941 break; | |
1942 } | |
1943 } | |
1944 } | |
1945 | |
1946 void SkDraw::drawTextOnPath(const char text[], size_t byteLength, | |
1947 const SkPath& follow, const SkMatrix* matrix, | |
1948 const SkPaint& paint) const { | |
1949 SkASSERT(byteLength == 0 || text != NULL); | |
1950 | |
1951 // nothing to draw | |
1952 if (text == NULL || byteLength == 0 || fRC->isEmpty()) { | |
1953 return; | |
1954 } | |
1955 | |
1956 SkTextToPathIter iter(text, byteLength, paint, true); | |
1957 SkPathMeasure meas(follow, false); | |
1958 SkScalar hOffset = 0; | |
1959 | |
1960 // need to measure first | |
1961 if (paint.getTextAlign() != SkPaint::kLeft_Align) { | |
1962 SkScalar pathLen = meas.getLength(); | |
1963 if (paint.getTextAlign() == SkPaint::kCenter_Align) { | |
1964 pathLen = SkScalarHalf(pathLen); | |
1965 } | |
1966 hOffset += pathLen; | |
1967 } | |
1968 | |
1969 const SkPath* iterPath; | |
1970 SkScalar xpos; | |
1971 SkMatrix scaledMatrix; | |
1972 SkScalar scale = iter.getPathScale(); | |
1973 | |
1974 scaledMatrix.setScale(scale, scale); | |
1975 | |
1976 while (iter.next(&iterPath, &xpos)) { | |
1977 if (iterPath) { | |
1978 SkPath tmp; | |
1979 SkMatrix m(scaledMatrix); | |
1980 | |
1981 tmp.setIsVolatile(true); | |
1982 m.postTranslate(xpos + hOffset, 0); | |
1983 if (matrix) { | |
1984 m.postConcat(*matrix); | |
1985 } | |
1986 morphpath(&tmp, *iterPath, meas, m); | |
1987 if (fDevice) { | |
1988 fDevice->drawPath(*this, tmp, iter.getPaint(), NULL, true); | |
1989 } else { | |
1990 this->drawPath(tmp, iter.getPaint(), NULL, true); | |
1991 } | |
1992 } | |
1993 } | |
1994 } | |
1995 | |
1996 /////////////////////////////////////////////////////////////////////////////// | |
1997 | |
1998 typedef void (*HairProc)(const SkPoint&, const SkPoint&, const SkRasterClip&, | 1869 typedef void (*HairProc)(const SkPoint&, const SkPoint&, const SkRasterClip&, |
1999 SkBlitter*); | 1870 SkBlitter*); |
2000 | 1871 |
2001 static HairProc ChooseHairProc(bool doAntiAlias) { | 1872 static HairProc ChooseHairProc(bool doAntiAlias) { |
2002 return doAntiAlias ? SkScan::AntiHairLine : SkScan::HairLine; | 1873 return doAntiAlias ? SkScan::AntiHairLine : SkScan::HairLine; |
2003 } | 1874 } |
2004 | 1875 |
2005 static bool texture_to_matrix(const VertState& state, const SkPoint verts[], | 1876 static bool texture_to_matrix(const VertState& state, const SkPoint verts[], |
2006 const SkPoint texs[], SkMatrix* matrix) { | 1877 const SkPoint texs[], SkMatrix* matrix) { |
2007 SkPoint src[3], dst[3]; | 1878 SkPoint src[3], dst[3]; |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2394 mask->fImage = SkMask::AllocImage(size); | 2265 mask->fImage = SkMask::AllocImage(size); |
2395 memset(mask->fImage, 0, mask->computeImageSize()); | 2266 memset(mask->fImage, 0, mask->computeImageSize()); |
2396 } | 2267 } |
2397 | 2268 |
2398 if (SkMask::kJustComputeBounds_CreateMode != mode) { | 2269 if (SkMask::kJustComputeBounds_CreateMode != mode) { |
2399 draw_into_mask(*mask, devPath, style); | 2270 draw_into_mask(*mask, devPath, style); |
2400 } | 2271 } |
2401 | 2272 |
2402 return true; | 2273 return true; |
2403 } | 2274 } |
OLD | NEW |