michael@0: michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #ifndef SkDraw_DEFINED michael@0: #define SkDraw_DEFINED michael@0: michael@0: #include "SkCanvas.h" michael@0: #include "SkMask.h" michael@0: #include "SkPaint.h" michael@0: michael@0: class SkBitmap; michael@0: class SkBounder; michael@0: class SkClipStack; michael@0: class SkBaseDevice; michael@0: class SkMatrix; michael@0: class SkPath; michael@0: class SkRegion; michael@0: class SkRasterClip; michael@0: struct SkDrawProcs; michael@0: struct SkRect; michael@0: class SkRRect; michael@0: michael@0: class SkDraw { michael@0: public: michael@0: SkDraw(); michael@0: SkDraw(const SkDraw& src); michael@0: michael@0: void drawPaint(const SkPaint&) const; michael@0: void drawPoints(SkCanvas::PointMode, size_t count, const SkPoint[], michael@0: const SkPaint&, bool forceUseDevice = false) const; michael@0: void drawRect(const SkRect&, const SkPaint&) const; michael@0: void drawRRect(const SkRRect&, const SkPaint&) const; michael@0: /** michael@0: * To save on mallocs, we allow a flag that tells us that srcPath is michael@0: * mutable, so that we don't have to make copies of it as we transform it. michael@0: * michael@0: * If prePathMatrix is not null, it should logically be applied before any michael@0: * stroking or other effects. If there are no effects on the paint that michael@0: * affect the geometry/rasterization, then the pre matrix can just be michael@0: * pre-concated with the current matrix. michael@0: */ michael@0: void drawPath(const SkPath& path, const SkPaint& paint, michael@0: const SkMatrix* prePathMatrix, bool pathIsMutable) const { michael@0: this->drawPath(path, paint, prePathMatrix, pathIsMutable, false); michael@0: } michael@0: michael@0: void drawPath(const SkPath& path, const SkPaint& paint) const { michael@0: this->drawPath(path, paint, NULL, false, false); michael@0: } michael@0: michael@0: void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) const; michael@0: void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const; michael@0: void drawText(const char text[], size_t byteLength, SkScalar x, michael@0: SkScalar y, const SkPaint& paint) const; michael@0: void drawPosText(const char text[], size_t byteLength, michael@0: const SkScalar pos[], SkScalar constY, michael@0: int scalarsPerPosition, const SkPaint& paint) const; michael@0: void drawTextOnPath(const char text[], size_t byteLength, michael@0: const SkPath&, const SkMatrix*, const SkPaint&) const; michael@0: void drawVertices(SkCanvas::VertexMode mode, int count, michael@0: const SkPoint vertices[], const SkPoint textures[], michael@0: const SkColor colors[], SkXfermode* xmode, michael@0: const uint16_t indices[], int ptCount, michael@0: const SkPaint& paint) const; michael@0: michael@0: /** michael@0: * Overwrite the target with the path's coverage (i.e. its mask). michael@0: * Will overwrite the entire device, so it need not be zero'd first. michael@0: * michael@0: * Only device A8 is supported right now. michael@0: */ michael@0: void drawPathCoverage(const SkPath& src, const SkPaint& paint) const { michael@0: this->drawPath(src, paint, NULL, false, true); michael@0: } michael@0: michael@0: /** Helper function that creates a mask from a path and an optional maskfilter. michael@0: Note however, that the resulting mask will not have been actually filtered, michael@0: that must be done afterwards (by calling filterMask). The maskfilter is provided michael@0: solely to assist in computing the mask's bounds (if the mode requests that). michael@0: */ michael@0: static bool DrawToMask(const SkPath& devPath, const SkIRect* clipBounds, michael@0: const SkMaskFilter*, const SkMatrix* filterMatrix, michael@0: SkMask* mask, SkMask::CreateMode mode, michael@0: SkPaint::Style style); michael@0: michael@0: enum RectType { michael@0: kHair_RectType, michael@0: kFill_RectType, michael@0: kStroke_RectType, michael@0: kPath_RectType michael@0: }; michael@0: michael@0: /** michael@0: * Based on the paint's style, strokeWidth, and the matrix, classify how michael@0: * to draw the rect. If no special-case is available, returns michael@0: * kPath_RectType. michael@0: * michael@0: * Iff RectType == kStroke_RectType, then strokeSize is set to the device michael@0: * width and height of the stroke. michael@0: */ michael@0: static RectType ComputeRectType(const SkPaint&, const SkMatrix&, michael@0: SkPoint* strokeSize); michael@0: michael@0: static bool ShouldDrawTextAsPaths(const SkPaint&, const SkMatrix&); michael@0: void drawText_asPaths(const char text[], size_t byteLength, michael@0: SkScalar x, SkScalar y, const SkPaint&) const; michael@0: void drawPosText_asPaths(const char text[], size_t byteLength, michael@0: const SkScalar pos[], SkScalar constY, michael@0: int scalarsPerPosition, const SkPaint&) const; michael@0: michael@0: private: michael@0: void drawDevMask(const SkMask& mask, const SkPaint&) const; michael@0: void drawBitmapAsMask(const SkBitmap&, const SkPaint&) const; michael@0: michael@0: void drawPath(const SkPath&, const SkPaint&, const SkMatrix* preMatrix, michael@0: bool pathIsMutable, bool drawCoverage) const; michael@0: michael@0: /** michael@0: * Return the current clip bounds, in local coordinates, with slop to account michael@0: * for antialiasing or hairlines (i.e. device-bounds outset by 1, and then michael@0: * run through the inverse of the matrix). michael@0: * michael@0: * If the matrix cannot be inverted, or the current clip is empty, return michael@0: * false and ignore bounds parameter. michael@0: */ michael@0: bool SK_WARN_UNUSED_RESULT michael@0: computeConservativeLocalClipBounds(SkRect* bounds) const; michael@0: michael@0: public: michael@0: const SkBitmap* fBitmap; // required michael@0: const SkMatrix* fMatrix; // required michael@0: const SkRegion* fClip; // DEPRECATED michael@0: const SkRasterClip* fRC; // required michael@0: michael@0: const SkClipStack* fClipStack; // optional michael@0: SkBaseDevice* fDevice; // optional michael@0: SkBounder* fBounder; // optional michael@0: SkDrawProcs* fProcs; // optional michael@0: michael@0: #ifdef SK_DEBUG michael@0: void validate() const; michael@0: #else michael@0: void validate() const {} michael@0: #endif michael@0: }; michael@0: michael@0: #endif