| 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 |