#define VERTEX_DEBUG 0
#include <SkPath.h>
-#include <SkPaint.h>
+#include <SkStrokeRec.h>
#include <stdlib.h>
#include <stdint.h>
#endif
}
-void PathRenderer::ConvexPathVertices(const SkPath &path, const SkPaint* paint,
+void PathRenderer::ConvexPathVertices(const SkPath &path, const SkStrokeRec& stroke, bool isAA,
const SkMatrix* transform, VertexBuffer* vertexBuffer) {
SK_TRACE_EVENT0("PathRenderer::convexPathVertices");
- SkPaint::Style style = paint->getStyle();
- bool isAA = paint->isAntiAlias();
+ SkStrokeRec::Style style = stroke.getStyle();
float inverseScaleX, inverseScaleY;
computeInverseScales(transform, inverseScaleX, inverseScaleY);
SkTArray<Vertex, true> tempVertices;
float threshInvScaleX = inverseScaleX;
float threshInvScaleY = inverseScaleY;
- if (style == SkPaint::kStroke_Style) {
+ if (style == SkStrokeRec::kStroke_Style) {
// alter the bezier recursion threshold values we calculate in order to compensate for
// expansion done after the path vertices are found
SkRect bounds = path.getBounds();
if (!bounds.isEmpty()) {
- threshInvScaleX *= bounds.width() / (bounds.width() + paint->getStrokeWidth());
- threshInvScaleY *= bounds.height() / (bounds.height() + paint->getStrokeWidth());
+ threshInvScaleX *= bounds.width() / (bounds.width() + stroke.getWidth());
+ threshInvScaleY *= bounds.height() / (bounds.height() + stroke.getWidth());
}
}
// force close if we're filling the path, since fill path expects closed perimeter.
- bool forceClose = style != SkPaint::kStroke_Style;
+ bool forceClose = style != SkStrokeRec::kStroke_Style;
bool wasClosed = ConvexPathPerimeterVertices(path, forceClose, threshInvScaleX * threshInvScaleX,
threshInvScaleY * threshInvScaleY, &tempVertices);
}
#endif
- if (style == SkPaint::kStroke_Style) {
- float halfStrokeWidth = paint->getStrokeWidth() * 0.5f;
+ if (style == SkStrokeRec::kStroke_Style) {
+ float halfStrokeWidth = stroke.getWidth() * 0.5f;
if (!isAA) {
if (wasClosed) {
getStrokeVerticesFromPerimeter(tempVertices, halfStrokeWidth, vertexBuffer,
public:
static SkRect ComputePathBounds(const SkPath& path, const SkPaint* paint);
- static void ConvexPathVertices(const SkPath& path, const SkPaint* paint,
+ static void ConvexPathVertices(const SkPath& path, const SkStrokeRec& stroke, bool isAA,
const SkMatrix* transform, VertexBuffer* vertexBuffer);
private:
--- /dev/null
+\r
+/*\r
+ * Copyright 2012 Google Inc.\r
+ *\r
+ * Use of this source code is governed by a BSD-style license that can be\r
+ * found in the LICENSE file.\r
+ */\r
+\r
+#include "GrAndroidPathRenderer.h"\r
+#include "AndroidPathRenderer.h"\r
+#include "Vertex.h"\r
+\r
+GrAndroidPathRenderer::GrAndroidPathRenderer() {\r
+}\r
+\r
+bool GrAndroidPathRenderer::canDrawPath(const SkPath& path,\r
+ const SkStrokeRec& stroke,\r
+ const GrDrawTarget* target,\r
+ bool antiAlias) const {\r
+ return ((stroke.isFillStyle() || stroke.getStyle() == SkStrokeRec::kStroke_Style) \r
+ && !path.isInverseFillType() && path.isConvex());\r
+}\r
+\r
+struct ColorVertex {\r
+ SkPoint pos;\r
+ GrColor color;\r
+};\r
+\r
+bool GrAndroidPathRenderer::onDrawPath(const SkPath& origPath,\r
+ const SkStrokeRec& stroke,\r
+ GrDrawTarget* target,\r
+ bool antiAlias) {\r
+\r
+ // generate verts using Android algorithm\r
+ android::uirenderer::VertexBuffer vertices;\r
+ android::uirenderer::PathRenderer::ConvexPathVertices(origPath, stroke, antiAlias, NULL, \r
+ &vertices);\r
+ \r
+ // set vertex layout depending on anti-alias\r
+ GrVertexLayout layout = antiAlias ? GrDrawTarget::kCoverage_VertexLayoutBit : 0;\r
+\r
+ // allocate our vert buffer\r
+ int vertCount = vertices.getSize();\r
+ GrDrawTarget::AutoReleaseGeometry geo(target, layout, vertCount, 0);\r
+ if (!geo.succeeded()) {\r
+ GrPrintf("Failed to get space for vertices!\n");\r
+ return false;\r
+ }\r
+\r
+ // copy android verts to our vertex buffer\r
+ if (antiAlias) {\r
+ ColorVertex* outVert = reinterpret_cast<ColorVertex*>(geo.vertices());\r
+ android::uirenderer::AlphaVertex* inVert = \r
+ reinterpret_cast<android::uirenderer::AlphaVertex*>(vertices.getBuffer());\r
+\r
+ for (int i = 0; i < vertCount; ++i) {\r
+ // copy vertex position\r
+ outVert->pos.set(inVert->position[0], inVert->position[1]);\r
+ // copy alpha\r
+ int coverage = static_cast<int>(inVert->alpha * 0xff);\r
+ outVert->color = GrColorPackRGBA(coverage, coverage, coverage, coverage);\r
+ ++outVert;\r
+ ++inVert;\r
+ }\r
+ } else {\r
+ size_t vsize = GrDrawTarget::VertexSize(layout);\r
+ size_t copySize = vsize*vertCount;\r
+ memcpy(geo.vertices(), vertices.getBuffer(), copySize);\r
+ }\r
+ \r
+ // render it\r
+ target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, vertCount);\r
+\r
+ return true;\r
+}\r
--- /dev/null
+
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrPathRenderer.h"
+
+
+class GrAndroidPathRenderer : public GrPathRenderer {
+public:
+ GrAndroidPathRenderer();
+
+ virtual bool canDrawPath(const SkPath& path,
+ const SkStrokeRec& stroke,
+ const GrDrawTarget* target,
+ bool antiAlias) const SK_OVERRIDE;
+
+protected:
+ virtual bool onDrawPath(const SkPath& path,
+ const SkStrokeRec& stroke,
+ GrDrawTarget* target,
+ bool antiAlias) SK_OVERRIDE;
+
+private:
+ typedef GrPathRenderer INHERITED;
+};
'skia_mesa%': 0,
'skia_nv_path_rendering%': 0,
'skia_stroke_path_rendering%': 0,
+ 'skia_android_path_rendering%': 0,
'skia_texture_cache_mb_limit%': 0,
'skia_angle%': 0,
'skia_directwrite%': 0,
'skia_mesa%': '<(skia_mesa)',
'skia_nv_path_rendering%': '<(skia_nv_path_rendering)',
'skia_stroke_path_rendering%': '<(skia_stroke_path_rendering)',
+ 'skia_android_path_rendering%': '<(skia_android_path_rendering)',
'skia_texture_cache_mb_limit%': '<(skia_texture_cache_mb_limit)',
'skia_angle%': '<(skia_angle)',
'skia_arch_width%': '<(skia_arch_width)',
'include_dirs': [
'../include/config',
'../include/core',
- '../experimental/AndroidPathRenderer',
],
'sources': [
'../experimental/SkSetPoly3To3.cpp',
'../experimental/SkSetPoly3To3_A.cpp',
'../experimental/SkSetPoly3To3_D.cpp',
- '../experimental/AndroidPathRenderer/AndroidPathRenderer.cpp',
],
'direct_dependent_settings': {
'include_dirs': [
'GR_STROKE_PATH_RENDERING=1',
],
}],
+ [ 'skia_android_path_rendering', {
+ 'sources': [
+ '../experimental/AndroidPathRenderer/GrAndroidPathRenderer.cpp',
+ '../experimental/AndroidPathRenderer/GrAndroidPathRenderer.h',
+ '../experimental/AndroidPathRenderer/AndroidPathRenderer.cpp',
+ '../experimental/AndroidPathRenderer/AndroidPathRenderer.h',
+ '../experimental/AndroidPathRenderer/Vertex.h',
+ ],
+ 'defines': [
+ 'GR_ANDROID_PATH_RENDERING=1',
+ ],
+ }],
[ 'skia_os == "linux"', {
'sources!': [
'../src/gpu/gl/GrGLDefaultInterface_none.cpp',
#if GR_STROKE_PATH_RENDERING
#include "../../experimental/StrokePathRenderer/GrStrokePathRenderer.h"
#endif
+#if GR_ANDROID_PATH_RENDERING
+#include "../../experimental/AndroidPathRenderer/GrAndroidPathRenderer.h"
+#endif
void GrPathRenderer::AddPathRenderers(GrContext* ctx, GrPathRendererChain* chain) {
#if GR_STROKE_PATH_RENDERING
chain->addPathRenderer(SkNEW(GrStrokePathRenderer))->unref();
+#endif
+#if GR_ANDROID_PATH_RENDERING
+ chain->addPathRenderer(SkNEW(GrAndroidPathRenderer))->unref();
#endif
if (GrPathRenderer* pr = GrStencilAndCoverPathRenderer::Create(ctx)) {
chain->addPathRenderer(pr)->unref();