blob: ce74a28d0e588815e2580640245a46bb47a6ce9d [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
10#ifndef SkBlitter_DEFINED
11#define SkBlitter_DEFINED
12
13#include "SkBitmap.h"
14#include "SkMatrix.h"
15#include "SkPaint.h"
16#include "SkRefCnt.h"
17#include "SkRegion.h"
18#include "SkMask.h"
19
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000020/** SkBlitter and its subclasses are responsible for actually writing pixels
21 into memory. Besides efficiency, they handle clipping and antialiasing.
22*/
reed@android.com8a1c16f2008-12-17 15:59:43 +000023class SkBlitter {
24public:
25 virtual ~SkBlitter();
26
tomhudson@google.coma31ac732011-12-29 16:09:31 +000027 /// Blit a horizontal run of one or more pixels.
reed@android.com8a1c16f2008-12-17 15:59:43 +000028 virtual void blitH(int x, int y, int width);
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000029 /// Blit a horizontal run of antialiased pixels; runs[] is a *sparse*
30 /// zero-terminated run-length encoding of spans of constant alpha values.
31 virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
32 const int16_t runs[]);
reed@google.coma89c77b2011-12-01 21:47:26 +000033 /// Blit a vertical run of pixels with a constant alpha value.
reed@android.com8a1c16f2008-12-17 15:59:43 +000034 virtual void blitV(int x, int y, int height, SkAlpha alpha);
tomhudson@google.coma31ac732011-12-29 16:09:31 +000035 /// Blit a solid rectangle one or more pixels wide.
reed@android.com8a1c16f2008-12-17 15:59:43 +000036 virtual void blitRect(int x, int y, int width, int height);
tomhudson@google.com49eac192011-12-27 13:59:20 +000037 /** Blit a rectangle with one alpha-blended column on the left,
tomhudson@google.com47143592011-12-28 17:58:07 +000038 width (zero or more) opaque pixels, and one alpha-blended column
39 on the right.
40 The result will always be at least two pixels wide.
tomhudson@google.com49eac192011-12-27 13:59:20 +000041 */
42 virtual void blitAntiRect(int x, int y, int width, int height,
43 SkAlpha leftAlpha, SkAlpha rightAlpha);
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000044 /// Blit a pattern of pixels defined by a rectangle-clipped mask;
45 /// typically used for text.
reed@android.com8a1c16f2008-12-17 15:59:43 +000046 virtual void blitMask(const SkMask&, const SkIRect& clip);
47
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000048 /** If the blitter just sets a single value for each pixel, return the
reed@android.com8a1c16f2008-12-17 15:59:43 +000049 bitmap it draws into, and assign value. If not, return NULL and ignore
50 the value parameter.
51 */
52 virtual const SkBitmap* justAnOpaqueColor(uint32_t* value);
53
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000054 ///@name non-virtual helpers
reed@android.com8a1c16f2008-12-17 15:59:43 +000055 void blitMaskRegion(const SkMask& mask, const SkRegion& clip);
56 void blitRectRegion(const SkIRect& rect, const SkRegion& clip);
57 void blitRegion(const SkRegion& clip);
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000058 ///@}
reed@android.com8a1c16f2008-12-17 15:59:43 +000059
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000060 /** @name Factories
61 Return the correct blitter to use given the specified context.
62 */
reed@android.com8a1c16f2008-12-17 15:59:43 +000063 static SkBlitter* Choose(const SkBitmap& device,
64 const SkMatrix& matrix,
65 const SkPaint& paint) {
66 return Choose(device, matrix, paint, NULL, 0);
67 }
68
69 static SkBlitter* Choose(const SkBitmap& device,
70 const SkMatrix& matrix,
71 const SkPaint& paint,
72 void* storage, size_t storageSize);
73
74 static SkBlitter* ChooseSprite(const SkBitmap& device,
75 const SkPaint&,
76 const SkBitmap& src,
77 int left, int top,
78 void* storage, size_t storageSize);
tomhudson@google.com05fffdc2011-12-01 20:41:24 +000079 ///@}
reed@android.com8a1c16f2008-12-17 15:59:43 +000080
81private:
82};
83
84/** This blitter silently never draws anything.
85*/
86class SkNullBlitter : public SkBlitter {
87public:
tomhudson@google.com13413042011-10-03 16:01:10 +000088 virtual void blitH(int x, int y, int width) SK_OVERRIDE;
89 virtual void blitAntiH(int x, int y, const SkAlpha[],
90 const int16_t runs[]) SK_OVERRIDE;
91 virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE;
92 virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
93 virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
94 virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
reed@android.com8a1c16f2008-12-17 15:59:43 +000095};
96
97/** Wraps another (real) blitter, and ensures that the real blitter is only
98 called with coordinates that have been clipped by the specified clipRect.
99 This means the caller need not perform the clipping ahead of time.
100*/
101class SkRectClipBlitter : public SkBlitter {
102public:
103 void init(SkBlitter* blitter, const SkIRect& clipRect) {
104 SkASSERT(!clipRect.isEmpty());
105 fBlitter = blitter;
106 fClipRect = clipRect;
107 }
108
tomhudson@google.com13413042011-10-03 16:01:10 +0000109 virtual void blitH(int x, int y, int width) SK_OVERRIDE;
110 virtual void blitAntiH(int x, int y, const SkAlpha[],
111 const int16_t runs[]) SK_OVERRIDE;
112 virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE;
113 virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
tomhudson@google.com49eac192011-12-27 13:59:20 +0000114 virtual void blitAntiRect(int x, int y, int width, int height,
115 SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE;
tomhudson@google.com13413042011-10-03 16:01:10 +0000116 virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
117 virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000118
119private:
120 SkBlitter* fBlitter;
121 SkIRect fClipRect;
122};
123
124/** Wraps another (real) blitter, and ensures that the real blitter is only
tomhudson@google.com05fffdc2011-12-01 20:41:24 +0000125 called with coordinates that have been clipped by the specified clipRgn.
126 This means the caller need not perform the clipping ahead of time.
reed@android.com8a1c16f2008-12-17 15:59:43 +0000127*/
128class SkRgnClipBlitter : public SkBlitter {
129public:
130 void init(SkBlitter* blitter, const SkRegion* clipRgn) {
131 SkASSERT(clipRgn && !clipRgn->isEmpty());
132 fBlitter = blitter;
133 fRgn = clipRgn;
134 }
135
tomhudson@google.com13413042011-10-03 16:01:10 +0000136 virtual void blitH(int x, int y, int width) SK_OVERRIDE;
137 virtual void blitAntiH(int x, int y, const SkAlpha[],
138 const int16_t runs[]) SK_OVERRIDE;
139 virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE;
140 virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
tomhudson@google.com49eac192011-12-27 13:59:20 +0000141 virtual void blitAntiRect(int x, int y, int width, int height,
142 SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE;
tomhudson@google.com13413042011-10-03 16:01:10 +0000143 virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
144 virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000145
146private:
147 SkBlitter* fBlitter;
148 const SkRegion* fRgn;
149};
150
tomhudson@google.com05fffdc2011-12-01 20:41:24 +0000151/** Factory to set up the appropriate most-efficient wrapper blitter
152 to apply a clip. Returns a pointer to a member, so lifetime must
153 be managed carefully.
154*/
reed@android.com8a1c16f2008-12-17 15:59:43 +0000155class SkBlitterClipper {
156public:
157 SkBlitter* apply(SkBlitter* blitter, const SkRegion* clip,
158 const SkIRect* bounds = NULL);
159
160private:
161 SkNullBlitter fNullBlitter;
162 SkRectClipBlitter fRectBlitter;
163 SkRgnClipBlitter fRgnBlitter;
164};
165
166#endif